From 003f42a1295b85ae209a8e4f58fc87e05b8c2074 Mon Sep 17 00:00:00 2001 From: Arindam Mondal Date: Fri, 23 Aug 2019 12:13:33 +0900 Subject: Upgrade swagger Issue-ID: SDC-2154 Change-Id: I95f6326a088f9a29c4ccb3b7a741d57ecf27ae7a Signed-off-by: arindamm --- .../sdc/be/distribution/AuditHandler.java | 122 +- .../be/distribution/DistributionBusinessLogic.java | 626 ++-- .../servlet/DistributionCatalogServlet.java | 622 ++-- .../distribution/servlet/DistributionServlet.java | 755 ++--- .../servlet/ArtifactExternalServlet.java | 2072 +++++++------ .../be/externalapi/servlet/AssetsDataServlet.java | 849 +++--- .../externalapi/servlet/CrudExternalServlet.java | 1112 +++---- .../servlet/ServiceActivationServlet.java | 425 +-- .../be/servlets/AdditionalInformationServlet.java | 1131 ++++---- .../openecomp/sdc/be/servlets/ArchiveEndpoint.java | 364 +-- .../openecomp/sdc/be/servlets/ArtifactServlet.java | 1444 +++++----- .../sdc/be/servlets/AttributeServlet.java | 597 ++-- .../sdc/be/servlets/AutomatedUpgradeEndpoint.java | 254 +- .../sdc/be/servlets/BeMonitoringServlet.java | 376 +-- .../sdc/be/servlets/CapabilityServlet.java | 676 ++--- .../sdc/be/servlets/ComponentInstanceServlet.java | 3043 +++++++++++--------- .../sdc/be/servlets/ComponentPropertyServlet.java | 875 +++--- .../sdc/be/servlets/ComponentServlet.java | 865 +++--- .../openecomp/sdc/be/servlets/ConsumerServlet.java | 441 +-- .../be/servlets/DistributionServiceServlet.java | 320 +- .../openecomp/sdc/be/servlets/ElementServlet.java | 1351 +++++---- .../be/servlets/GenericArtifactBrowserServlet.java | 222 +- .../openecomp/sdc/be/servlets/GroupEndpoint.java | 225 +- .../openecomp/sdc/be/servlets/GroupServlet.java | 484 ++-- .../sdc/be/servlets/GroupTypesEndpoint.java | 145 +- .../openecomp/sdc/be/servlets/InputsServlet.java | 1103 +++---- .../sdc/be/servlets/InterfaceOperationServlet.java | 687 ++--- .../sdc/be/servlets/LifecycleServlet.java | 366 +-- .../openecomp/sdc/be/servlets/PolicyServlet.java | 861 +++--- .../sdc/be/servlets/PolicyTypesEndpoint.java | 147 +- .../openecomp/sdc/be/servlets/ProductServlet.java | 616 ++-- .../sdc/be/servlets/RequirementServlet.java | 679 ++--- .../sdc/be/servlets/RequirementsServlet.java | 170 +- .../sdc/be/servlets/ResourceUploadServlet.java | 352 +-- .../sdc/be/servlets/ResourcesServlet.java | 1100 +++---- .../sdc/be/servlets/ServiceConsumptionServlet.java | 535 ++-- .../sdc/be/servlets/ServiceFilterServlet.java | 590 ++-- .../be/servlets/ServiceForwardingPathServlet.java | 544 ++-- .../openecomp/sdc/be/servlets/ServiceServlet.java | 1466 +++++----- .../sdc/be/servlets/TypesFetchServlet.java | 767 ++--- .../sdc/be/servlets/TypesUploadEndpoint.java | 261 +- .../sdc/be/servlets/TypesUploadServlet.java | 751 ++--- .../sdc/be/servlets/UserAdminServlet.java | 842 +++--- 43 files changed, 16529 insertions(+), 14704 deletions(-) (limited to 'catalog-be/src/main/java') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java index c7e145b8be..801f53002c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java @@ -1,61 +1,61 @@ -/*- - * ============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.distribution; - -import org.openecomp.sdc.be.components.distribution.engine.CambriaErrorResponse; -import org.openecomp.sdc.be.components.distribution.engine.SubscriberTypeEnum; -import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.resources.data.auditing.model.DistributionTopicData; - -public class AuditHandler { - ComponentsUtils componentsUtils; - String instanceID; - private RegistrationRequest registrationRequest; - - public AuditHandler(ComponentsUtils componentsUtils, String instanceID, RegistrationRequest registrationRequest) { - super(); - this.componentsUtils = componentsUtils; - this.instanceID = instanceID; - this.registrationRequest = registrationRequest; - } - - - public void auditRegisterACL(CambriaErrorResponse registerResponse, SubscriberTypeEnum subscriberRole , DistributionTopicData distributionTopicData) { - componentsUtils.auditDistributionEngine(AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL, registrationRequest.getDistrEnvName(), distributionTopicData, subscriberRole.name(), registrationRequest.getApiPublicKey(), String.valueOf(registerResponse.getHttpCode())); - } - - public void auditUnRegisterACL(CambriaErrorResponse registerResponse, SubscriberTypeEnum subscriberRole, DistributionTopicData distributionTopicData) { - componentsUtils.auditDistributionEngine(AuditingActionEnum.REMOVE_KEY_FROM_TOPIC_ACL, registrationRequest.getDistrEnvName(), distributionTopicData, subscriberRole.name(), registrationRequest.getApiPublicKey(), String.valueOf(registerResponse.getHttpCode())); - } - - public void auditRegisterRequest(CambriaErrorResponse registerResponse) { - componentsUtils.auditRegisterOrUnRegisterEvent(AuditingActionEnum.DISTRIBUTION_REGISTER, instanceID, registrationRequest.getApiPublicKey(), registrationRequest.getDistrEnvName(), String.valueOf(registerResponse.getHttpCode()), - registerResponse.getOperationStatus().name(), DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()), DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName())); - - } - - public void auditUnRegisterRequest(CambriaErrorResponse registerResponse) { - componentsUtils.auditRegisterOrUnRegisterEvent(AuditingActionEnum.DISTRIBUTION_UN_REGISTER, instanceID, registrationRequest.getApiPublicKey(), registrationRequest.getDistrEnvName(), String.valueOf(registerResponse.getHttpCode()), - registerResponse.getOperationStatus().name(), DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()), DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName())); - } -} +/*- + * ============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.distribution; + +import org.openecomp.sdc.be.components.distribution.engine.CambriaErrorResponse; +import org.openecomp.sdc.be.components.distribution.engine.SubscriberTypeEnum; +import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.model.DistributionTopicData; + +public class AuditHandler { + ComponentsUtils componentsUtils; + String instanceID; + private RegistrationRequest registrationRequest; + + public AuditHandler(ComponentsUtils componentsUtils, String instanceID, RegistrationRequest registrationRequest) { + super(); + this.componentsUtils = componentsUtils; + this.instanceID = instanceID; + this.registrationRequest = registrationRequest; + } + + + public void auditRegisterACL(CambriaErrorResponse registerResponse, SubscriberTypeEnum subscriberRole , DistributionTopicData distributionTopicData) { + componentsUtils.auditDistributionEngine(AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL, registrationRequest.getDistrEnvName(), distributionTopicData, subscriberRole.name(), registrationRequest.getApiPublicKey(), String.valueOf(registerResponse.getHttpCode())); + } + + public void auditUnRegisterACL(CambriaErrorResponse registerResponse, SubscriberTypeEnum subscriberRole, DistributionTopicData distributionTopicData) { + componentsUtils.auditDistributionEngine(AuditingActionEnum.REMOVE_KEY_FROM_TOPIC_ACL, registrationRequest.getDistrEnvName(), distributionTopicData, subscriberRole.name(), registrationRequest.getApiPublicKey(), String.valueOf(registerResponse.getHttpCode())); + } + + public void auditRegisterRequest(CambriaErrorResponse registerResponse) { + componentsUtils.auditRegisterOrUnRegisterEvent(AuditingActionEnum.DISTRIBUTION_REGISTER, instanceID, registrationRequest.getApiPublicKey(), registrationRequest.getDistrEnvName(), String.valueOf(registerResponse.getHttpCode()), + registerResponse.getOperationStatus().name(), DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()), DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName())); + + } + + public void auditUnRegisterRequest(CambriaErrorResponse registerResponse) { + componentsUtils.auditRegisterOrUnRegisterEvent(AuditingActionEnum.DISTRIBUTION_UN_REGISTER, instanceID, registrationRequest.getApiPublicKey(), registrationRequest.getDistrEnvName(), String.valueOf(registerResponse.getHttpCode()), + registerResponse.getOperationStatus().name(), DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()), DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName())); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java index afad7d0b5f..1589b93822 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java @@ -1,313 +1,313 @@ -/*- - * ============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.distribution; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import fj.data.Either; -import org.apache.http.HttpStatus; -import org.openecomp.sdc.be.components.distribution.engine.*; -import org.openecomp.sdc.be.components.impl.ResponseFormatManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.config.DistributionEngineConfiguration; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.distribution.api.client.*; -import org.openecomp.sdc.be.resources.data.auditing.model.DistributionTopicData; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; -import javax.ws.rs.core.Response; -import java.util.List; - -import static org.apache.commons.lang.BooleanUtils.isTrue; -import static org.openecomp.sdc.be.components.distribution.engine.DistributionEngineInitTask.buildTopicName; -import static org.openecomp.sdc.be.config.ConfigurationManager.getConfigurationManager; - -@Component("distributionBusinessLogic") -public class DistributionBusinessLogic { - public static final String REGISTER_IN_DISTRIBUTION_ENGINE = "registerInDistributionEngine"; - public static final String UN_REGISTER_IN_DISTRIBUTION_ENGINE = "unregisterInDistributionEngine"; - private Gson gson = new GsonBuilder().setPrettyPrinting().create(); - private static final Logger log = Logger.getLogger(DistributionBusinessLogic.class); - @Resource - private IDistributionEngine distributionEngine; - - private ResponseFormatManager responseFormatManager = ResponseFormatManager.getInstance(); - private CambriaHandler cambriaHandler; - - private void initRequestEnvEndPoints(RegistrationRequest registrationRequest, DistributionEngineConfiguration config) { - if(registrationRequest.getDistEnvEndPoints() == null || registrationRequest.getDistEnvEndPoints().isEmpty()){ - registrationRequest.setDistEnvEndPoints(config.getUebServers()); - } - } - public Either getUebServerList() { - - DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager() - .getDistributionEngineConfiguration(); - - List serverList = distributionEngineConfiguration.getUebServers(); - - if (serverList != null && !serverList.isEmpty()) { - - ServerListResponse serverListResponse = new ServerListResponse(); - - serverListResponse.setUebServerList(serverList); - - return Either.left(serverListResponse); - } else { - ResponseFormat errorResponseWrapper = getResponseFormatManager() - .getResponseFormat(ActionStatus.GENERAL_ERROR); - return Either.right(errorResponseWrapper); - } - - } - - public void handleRegistration(Wrapper responseWrapper, RegistrationRequest registrationRequest, - AuditHandler auditHandler) { - CambriaErrorResponse registerResponse = null; - try { - DistributionEngineConfiguration config = getConfigurationManager().getDistributionEngineConfiguration(); - String statusTopicName = buildTopicName(config.getDistributionStatusTopicName(), - registrationRequest.getDistrEnvName()); - registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, - SubscriberTypeEnum.PRODUCER, statusTopicName); - - auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.PRODUCER, - DistributionTopicData.newBuilder() - .statusTopic(statusTopicName) - .build()); - boolean isRegisteredAsProducerOnStatusSuccess = responseWrapper.isEmpty(); - - // Story [347698] Distribution Client Get Indication from - // component whether to register as consumer and producer on - // status topic - boolean registeredAsConsumerOnStatus = false; - if (isRegisteredAsProducerOnStatusSuccess && isTrue(registrationRequest.getIsConsumerToSdcDistrStatusTopic())) { - registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, - SubscriberTypeEnum.CONSUMER, statusTopicName); - auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.CONSUMER, - DistributionTopicData.newBuilder() - .statusTopic(statusTopicName) - .build()); - registeredAsConsumerOnStatus = responseWrapper.isEmpty(); - - } - - if (responseWrapper.isEmpty()) { - String notificationTopicName = buildTopicName(config.getDistributionNotifTopicName(), - registrationRequest.getDistrEnvName()); - registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, - SubscriberTypeEnum.CONSUMER, notificationTopicName); - auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.CONSUMER, - DistributionTopicData.newBuilder() - .notificationTopic(notificationTopicName) - .build()); - } - // Unregister Rollback - if (!responseWrapper.isEmpty()) { - if (isRegisteredAsProducerOnStatusSuccess) { - CambriaErrorResponse unRegisterResponse = unRegisterDistributionClientFromTopic(registrationRequest, - SubscriberTypeEnum.PRODUCER, statusTopicName); - auditHandler.auditUnRegisterACL(unRegisterResponse, SubscriberTypeEnum.PRODUCER, - DistributionTopicData.newBuilder() - .statusTopic(statusTopicName) - .build()); - } - if (registeredAsConsumerOnStatus) { - CambriaErrorResponse unRegisterResponse = unRegisterDistributionClientFromTopic(registrationRequest, - SubscriberTypeEnum.CONSUMER, statusTopicName); - auditHandler.auditUnRegisterACL(unRegisterResponse, SubscriberTypeEnum.CONSUMER, - DistributionTopicData.newBuilder() - .statusTopic(statusTopicName) - .build()); - } - } - - if (responseWrapper.isEmpty()) { - TopicRegistrationResponse okTopicResponse = buildTopicResponse(registrationRequest); - responseWrapper.setInnerElement(Response.status(HttpStatus.SC_OK).entity(okTopicResponse).build()); - } - - } catch (Exception e) { - log.error("registration to topic failed", e); - BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(REGISTER_IN_DISTRIBUTION_ENGINE, - "registration of subscriber to topic"); - Response errorResponse = buildErrorResponse( - getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); - responseWrapper.setInnerElement(errorResponse); - } finally { - auditHandler.auditRegisterRequest(registerResponse); - } - } - - public void handleUnRegistration(Wrapper responseWrapper, RegistrationRequest unRegistrationRequest, - AuditHandler auditHandler) { - Wrapper cambriaResponseWrapper = new Wrapper<>(); - try { - String statusTopicName = getStatusTopicName(unRegistrationRequest.getDistrEnvName()); - CambriaErrorResponse unregisterClientProducerTopicResponse = unRegisterDistributionClientFromTopic( - unRegistrationRequest, SubscriberTypeEnum.PRODUCER, statusTopicName); - auditHandler.auditUnRegisterACL(unregisterClientProducerTopicResponse, SubscriberTypeEnum.PRODUCER, - DistributionTopicData.newBuilder() - .statusTopic(statusTopicName) - .build()); - updateResponseWrapper(cambriaResponseWrapper, unregisterClientProducerTopicResponse); - - String notificationTopicName = getNotificationTopicName(unRegistrationRequest.getDistrEnvName()); - CambriaErrorResponse unregisterClientConsumerTopicResponse = unRegisterDistributionClientFromTopic( - unRegistrationRequest, SubscriberTypeEnum.CONSUMER, notificationTopicName); - auditHandler.auditUnRegisterACL(unregisterClientConsumerTopicResponse, SubscriberTypeEnum.CONSUMER, - DistributionTopicData.newBuilder() - .notificationTopic(notificationTopicName) - .build()); - updateResponseWrapper(cambriaResponseWrapper, unregisterClientConsumerTopicResponse); - - // Success unregister both topics - TopicUnregistrationResponse unregisterResponse = new TopicUnregistrationResponse( - getNotificationTopicName(unRegistrationRequest.getDistrEnvName()), - getStatusTopicName(unRegistrationRequest.getDistrEnvName()), - unregisterClientConsumerTopicResponse.getOperationStatus(), - unregisterClientProducerTopicResponse.getOperationStatus()); - - if (cambriaResponseWrapper.getInnerElement().getOperationStatus() == CambriaOperationStatus.OK) { - responseWrapper.setInnerElement(Response.status(HttpStatus.SC_OK).entity(unregisterResponse).build()); - } else { - BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(UN_REGISTER_IN_DISTRIBUTION_ENGINE, - "unregistration failed"); - responseWrapper.setInnerElement( - Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(unregisterResponse).build()); - } - } catch (Exception e) { - log.error("unregistered to topic failed", e); - Response errorResponse = buildErrorResponse( - getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); - responseWrapper.setInnerElement(errorResponse); - - } finally { - auditHandler.auditUnRegisterRequest(cambriaResponseWrapper.getInnerElement()); - } - } - - private void updateResponseWrapper(Wrapper cambriaResponseWrapper, - CambriaErrorResponse currentResponse) { - if (cambriaResponseWrapper.isEmpty()) { - cambriaResponseWrapper.setInnerElement(currentResponse); - } else if (currentResponse.getOperationStatus() != CambriaOperationStatus.OK) { - cambriaResponseWrapper.setInnerElement(currentResponse); - - } - - } - - public static String getNotificationTopicName(String envName) { - DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() - .getDistributionEngineConfiguration(); - return DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), envName); - - } - - public static String getStatusTopicName(String envName) { - DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() - .getDistributionEngineConfiguration(); - return DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), envName); - - } - - protected CambriaErrorResponse unRegisterDistributionClientFromTopic(RegistrationRequest unRegistrationRequest, - SubscriberTypeEnum subscriberType, String topicName) { - DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() - .getDistributionEngineConfiguration(); - initRequestEnvEndPoints(unRegistrationRequest, config); - - log.debug("unregistering client as {} , from topic: {}, using DistEnvPoints: {}", subscriberType, topicName, unRegistrationRequest.getDistEnvEndPoints()); - return getCambriaHandler().unRegisterFromTopic(unRegistrationRequest.getDistEnvEndPoints(), config.getUebPublicKey(), - config.getUebSecretKey(), unRegistrationRequest.getApiPublicKey(), subscriberType, topicName); - } - - private TopicRegistrationResponse buildTopicResponse(RegistrationRequest registrationRequest) { - DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() - .getDistributionEngineConfiguration(); - String statusTopicName = DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), - registrationRequest.getDistrEnvName()); - String notificationTopicName = DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), - registrationRequest.getDistrEnvName()); - - TopicRegistrationResponse topicResponse = new TopicRegistrationResponse(); - topicResponse.setDistrNotificationTopicName(notificationTopicName); - topicResponse.setDistrStatusTopicName(statusTopicName); - return topicResponse; - } - - protected CambriaErrorResponse registerDistributionClientToTopic(Wrapper responseWrapper, - RegistrationRequest registrationRequest, SubscriberTypeEnum subscriberType, String topicName) { - DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() - .getDistributionEngineConfiguration(); - initRequestEnvEndPoints(registrationRequest, config); - String errorMsg; - - // Register for notifications as consumer - if (subscriberType == SubscriberTypeEnum.CONSUMER) { - errorMsg = "registration of subscriber to topic:" + topicName + " as consumer failed"; - } - // Register for status as producer - else { - errorMsg = "registration of subscriber to topic:" + topicName + " as producer failed"; - } - log.debug("registering client as {} , from topic: {}, using DistEnvPoints: {}", subscriberType, topicName, registrationRequest.getDistEnvEndPoints()); - CambriaErrorResponse registerToTopic = getCambriaHandler().registerToTopic(registrationRequest.getDistEnvEndPoints(), - config.getUebPublicKey(), config.getUebSecretKey(), registrationRequest.getApiPublicKey(), - subscriberType, topicName); - - if (registerToTopic.getOperationStatus() != CambriaOperationStatus.OK) { - Response failedRegistrationResponse = buildErrorResponse( - getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); - BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(REGISTER_IN_DISTRIBUTION_ENGINE, - errorMsg); - responseWrapper.setInnerElement(failedRegistrationResponse); - } - return registerToTopic; - } - - protected Response buildErrorResponse(ResponseFormat requestErrorWrapper) { - return Response.status(requestErrorWrapper.getStatus()) - .entity(gson.toJson(requestErrorWrapper.getRequestError())).build(); - } - - public ResponseFormatManager getResponseFormatManager() { - return responseFormatManager; - } - - public IDistributionEngine getDistributionEngine() { - return distributionEngine; - } - - public CambriaHandler getCambriaHandler() { - if (cambriaHandler == null) { - cambriaHandler = new CambriaHandler(); - } - return cambriaHandler; - } - -} +/*- + * ============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.distribution; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import fj.data.Either; +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.components.distribution.engine.*; +import org.openecomp.sdc.be.components.impl.ResponseFormatManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.distribution.api.client.*; +import org.openecomp.sdc.be.resources.data.auditing.model.DistributionTopicData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.ws.rs.core.Response; +import java.util.List; + +import static org.apache.commons.lang.BooleanUtils.isTrue; +import static org.openecomp.sdc.be.components.distribution.engine.DistributionEngineInitTask.buildTopicName; +import static org.openecomp.sdc.be.config.ConfigurationManager.getConfigurationManager; + +@Component("distributionBusinessLogic") +public class DistributionBusinessLogic { + public static final String REGISTER_IN_DISTRIBUTION_ENGINE = "registerInDistributionEngine"; + public static final String UN_REGISTER_IN_DISTRIBUTION_ENGINE = "unregisterInDistributionEngine"; + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + private static final Logger log = Logger.getLogger(DistributionBusinessLogic.class); + @Resource + private IDistributionEngine distributionEngine; + + private ResponseFormatManager responseFormatManager = ResponseFormatManager.getInstance(); + private CambriaHandler cambriaHandler; + + private void initRequestEnvEndPoints(RegistrationRequest registrationRequest, DistributionEngineConfiguration config) { + if(registrationRequest.getDistEnvEndPoints() == null || registrationRequest.getDistEnvEndPoints().isEmpty()){ + registrationRequest.setDistEnvEndPoints(config.getUebServers()); + } + } + public Either getUebServerList() { + + DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager() + .getDistributionEngineConfiguration(); + + List serverList = distributionEngineConfiguration.getUebServers(); + + if (serverList != null && !serverList.isEmpty()) { + + ServerListResponse serverListResponse = new ServerListResponse(); + + serverListResponse.setUebServerList(serverList); + + return Either.left(serverListResponse); + } else { + ResponseFormat errorResponseWrapper = getResponseFormatManager() + .getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(errorResponseWrapper); + } + + } + + public void handleRegistration(Wrapper responseWrapper, RegistrationRequest registrationRequest, + AuditHandler auditHandler) { + CambriaErrorResponse registerResponse = null; + try { + DistributionEngineConfiguration config = getConfigurationManager().getDistributionEngineConfiguration(); + String statusTopicName = buildTopicName(config.getDistributionStatusTopicName(), + registrationRequest.getDistrEnvName()); + registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, + SubscriberTypeEnum.PRODUCER, statusTopicName); + + auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.PRODUCER, + DistributionTopicData.newBuilder() + .statusTopic(statusTopicName) + .build()); + boolean isRegisteredAsProducerOnStatusSuccess = responseWrapper.isEmpty(); + + // Story [347698] Distribution Client Get Indication from + // component whether to register as consumer and producer on + // status topic + boolean registeredAsConsumerOnStatus = false; + if (isRegisteredAsProducerOnStatusSuccess && isTrue(registrationRequest.getIsConsumerToSdcDistrStatusTopic())) { + registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, + SubscriberTypeEnum.CONSUMER, statusTopicName); + auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.CONSUMER, + DistributionTopicData.newBuilder() + .statusTopic(statusTopicName) + .build()); + registeredAsConsumerOnStatus = responseWrapper.isEmpty(); + + } + + if (responseWrapper.isEmpty()) { + String notificationTopicName = buildTopicName(config.getDistributionNotifTopicName(), + registrationRequest.getDistrEnvName()); + registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, + SubscriberTypeEnum.CONSUMER, notificationTopicName); + auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.CONSUMER, + DistributionTopicData.newBuilder() + .notificationTopic(notificationTopicName) + .build()); + } + // Unregister Rollback + if (!responseWrapper.isEmpty()) { + if (isRegisteredAsProducerOnStatusSuccess) { + CambriaErrorResponse unRegisterResponse = unRegisterDistributionClientFromTopic(registrationRequest, + SubscriberTypeEnum.PRODUCER, statusTopicName); + auditHandler.auditUnRegisterACL(unRegisterResponse, SubscriberTypeEnum.PRODUCER, + DistributionTopicData.newBuilder() + .statusTopic(statusTopicName) + .build()); + } + if (registeredAsConsumerOnStatus) { + CambriaErrorResponse unRegisterResponse = unRegisterDistributionClientFromTopic(registrationRequest, + SubscriberTypeEnum.CONSUMER, statusTopicName); + auditHandler.auditUnRegisterACL(unRegisterResponse, SubscriberTypeEnum.CONSUMER, + DistributionTopicData.newBuilder() + .statusTopic(statusTopicName) + .build()); + } + } + + if (responseWrapper.isEmpty()) { + TopicRegistrationResponse okTopicResponse = buildTopicResponse(registrationRequest); + responseWrapper.setInnerElement(Response.status(HttpStatus.SC_OK).entity(okTopicResponse).build()); + } + + } catch (Exception e) { + log.error("registration to topic failed", e); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(REGISTER_IN_DISTRIBUTION_ENGINE, + "registration of subscriber to topic"); + Response errorResponse = buildErrorResponse( + getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(errorResponse); + } finally { + auditHandler.auditRegisterRequest(registerResponse); + } + } + + public void handleUnRegistration(Wrapper responseWrapper, RegistrationRequest unRegistrationRequest, + AuditHandler auditHandler) { + Wrapper cambriaResponseWrapper = new Wrapper<>(); + try { + String statusTopicName = getStatusTopicName(unRegistrationRequest.getDistrEnvName()); + CambriaErrorResponse unregisterClientProducerTopicResponse = unRegisterDistributionClientFromTopic( + unRegistrationRequest, SubscriberTypeEnum.PRODUCER, statusTopicName); + auditHandler.auditUnRegisterACL(unregisterClientProducerTopicResponse, SubscriberTypeEnum.PRODUCER, + DistributionTopicData.newBuilder() + .statusTopic(statusTopicName) + .build()); + updateResponseWrapper(cambriaResponseWrapper, unregisterClientProducerTopicResponse); + + String notificationTopicName = getNotificationTopicName(unRegistrationRequest.getDistrEnvName()); + CambriaErrorResponse unregisterClientConsumerTopicResponse = unRegisterDistributionClientFromTopic( + unRegistrationRequest, SubscriberTypeEnum.CONSUMER, notificationTopicName); + auditHandler.auditUnRegisterACL(unregisterClientConsumerTopicResponse, SubscriberTypeEnum.CONSUMER, + DistributionTopicData.newBuilder() + .notificationTopic(notificationTopicName) + .build()); + updateResponseWrapper(cambriaResponseWrapper, unregisterClientConsumerTopicResponse); + + // Success unregister both topics + TopicUnregistrationResponse unregisterResponse = new TopicUnregistrationResponse( + getNotificationTopicName(unRegistrationRequest.getDistrEnvName()), + getStatusTopicName(unRegistrationRequest.getDistrEnvName()), + unregisterClientConsumerTopicResponse.getOperationStatus(), + unregisterClientProducerTopicResponse.getOperationStatus()); + + if (cambriaResponseWrapper.getInnerElement().getOperationStatus() == CambriaOperationStatus.OK) { + responseWrapper.setInnerElement(Response.status(HttpStatus.SC_OK).entity(unregisterResponse).build()); + } else { + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(UN_REGISTER_IN_DISTRIBUTION_ENGINE, + "unregistration failed"); + responseWrapper.setInnerElement( + Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(unregisterResponse).build()); + } + } catch (Exception e) { + log.error("unregistered to topic failed", e); + Response errorResponse = buildErrorResponse( + getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(errorResponse); + + } finally { + auditHandler.auditUnRegisterRequest(cambriaResponseWrapper.getInnerElement()); + } + } + + private void updateResponseWrapper(Wrapper cambriaResponseWrapper, + CambriaErrorResponse currentResponse) { + if (cambriaResponseWrapper.isEmpty()) { + cambriaResponseWrapper.setInnerElement(currentResponse); + } else if (currentResponse.getOperationStatus() != CambriaOperationStatus.OK) { + cambriaResponseWrapper.setInnerElement(currentResponse); + + } + + } + + public static String getNotificationTopicName(String envName) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() + .getDistributionEngineConfiguration(); + return DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), envName); + + } + + public static String getStatusTopicName(String envName) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() + .getDistributionEngineConfiguration(); + return DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), envName); + + } + + protected CambriaErrorResponse unRegisterDistributionClientFromTopic(RegistrationRequest unRegistrationRequest, + SubscriberTypeEnum subscriberType, String topicName) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() + .getDistributionEngineConfiguration(); + initRequestEnvEndPoints(unRegistrationRequest, config); + + log.debug("unregistering client as {} , from topic: {}, using DistEnvPoints: {}", subscriberType, topicName, unRegistrationRequest.getDistEnvEndPoints()); + return getCambriaHandler().unRegisterFromTopic(unRegistrationRequest.getDistEnvEndPoints(), config.getUebPublicKey(), + config.getUebSecretKey(), unRegistrationRequest.getApiPublicKey(), subscriberType, topicName); + } + + private TopicRegistrationResponse buildTopicResponse(RegistrationRequest registrationRequest) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() + .getDistributionEngineConfiguration(); + String statusTopicName = DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), + registrationRequest.getDistrEnvName()); + String notificationTopicName = DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), + registrationRequest.getDistrEnvName()); + + TopicRegistrationResponse topicResponse = new TopicRegistrationResponse(); + topicResponse.setDistrNotificationTopicName(notificationTopicName); + topicResponse.setDistrStatusTopicName(statusTopicName); + return topicResponse; + } + + protected CambriaErrorResponse registerDistributionClientToTopic(Wrapper responseWrapper, + RegistrationRequest registrationRequest, SubscriberTypeEnum subscriberType, String topicName) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager() + .getDistributionEngineConfiguration(); + initRequestEnvEndPoints(registrationRequest, config); + String errorMsg; + + // Register for notifications as consumer + if (subscriberType == SubscriberTypeEnum.CONSUMER) { + errorMsg = "registration of subscriber to topic:" + topicName + " as consumer failed"; + } + // Register for status as producer + else { + errorMsg = "registration of subscriber to topic:" + topicName + " as producer failed"; + } + log.debug("registering client as {} , from topic: {}, using DistEnvPoints: {}", subscriberType, topicName, registrationRequest.getDistEnvEndPoints()); + CambriaErrorResponse registerToTopic = getCambriaHandler().registerToTopic(registrationRequest.getDistEnvEndPoints(), + config.getUebPublicKey(), config.getUebSecretKey(), registrationRequest.getApiPublicKey(), + subscriberType, topicName); + + if (registerToTopic.getOperationStatus() != CambriaOperationStatus.OK) { + Response failedRegistrationResponse = buildErrorResponse( + getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(REGISTER_IN_DISTRIBUTION_ENGINE, + errorMsg); + responseWrapper.setInnerElement(failedRegistrationResponse); + } + return registerToTopic; + } + + protected Response buildErrorResponse(ResponseFormat requestErrorWrapper) { + return Response.status(requestErrorWrapper.getStatus()) + .entity(gson.toJson(requestErrorWrapper.getRequestError())).build(); + } + + public ResponseFormatManager getResponseFormatManager() { + return responseFormatManager; + } + + public IDistributionEngine getDistributionEngine() { + return distributionEngine; + } + + public CambriaHandler getCambriaHandler() { + if (cambriaHandler == null) { + cambriaHandler = new CambriaHandler(); + } + return cambriaHandler; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java index 0da23ede9c..bd644e3edb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java @@ -1,303 +1,319 @@ -/*- - * ============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.distribution.servlet; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData; -import org.openecomp.sdc.be.servlets.BeGenericServlet; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * This Servlet serves external users to download artifacts. - * - * @author tgitelman - * - */ - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Distribution Catalog Servlet", description = "This Servlet serves external users to download artifacts.") -@Singleton -public class DistributionCatalogServlet extends BeGenericServlet { - - private static final String DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION = "download artifact failed with exception"; - private static final String MISSING_X_ECOMP_INSTANCE_ID_HEADER = "Missing X-ECOMP-InstanceID header"; - private static final Logger log = Logger.getLogger(DistributionCatalogServlet.class); - private final ArtifactsBusinessLogic artifactsBusinessLogic; - - @Autowired - public DistributionCatalogServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - ArtifactsBusinessLogic artifactsBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.artifactsBusinessLogic = artifactsBusinessLogic; - } - - @Context - private HttpServletRequest request; - - // ******************************************************* - // Download (GET) artifacts - // **********************************************************/ - /** - * - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param serviceName - * @param serviceVersion - * @param artifactName - * @return - */ - @GET - @Path("/services/{serviceName}/{serviceVersion}/artifacts/{artifactName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download service artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"), - @ApiResponse(code = 404, message = "Specified Service Version is not found - SVC4504"), - @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response downloadServiceArtifact( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @PathParam("serviceName") final String serviceName, - @PathParam("serviceVersion") final String serviceVersion, - @PathParam("artifactName") final String artifactName) { - - Response response = null; - String requestURI = request.getRequestURI(); - if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { - log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - return buildErrorResponse(responseFormat); - } - - try { - Either downloadRsrcArtifactEither = artifactsBusinessLogic - .downloadServiceArtifactByNames(serviceName, serviceVersion, artifactName); - if (downloadRsrcArtifactEither.isRight()) { - ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - response = buildErrorResponse(responseFormat); - } else { - byte[] value = downloadRsrcArtifactEither.left().value(); - InputStream is = new ByteArrayInputStream(value); - - Map headers = new HashMap<>(); - headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - response = buildOkResponse(responseFormat, is, headers); - } - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download Murano package artifact for service - external API"); - log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /** - * - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param serviceName - * @param serviceVersion - * @param resourceName - * @param resourceVersion - * @param artifactName - * @return - */ - @GET - @Path("/services/{serviceName}/{serviceVersion}/resources/{resourceName}/{resourceVersion}/artifacts/{artifactName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download resource artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"), - @ApiResponse(code = 404, message = "Specified Resource Instance is not found - SVC4526"), - @ApiResponse(code = 404, message = "Specified Service Version is not found - SVC4504"), - @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response downloadResourceArtifact( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @PathParam("serviceName") final String serviceName, - @PathParam("serviceVersion") final String serviceVersion, - @PathParam("resourceName") final String resourceName, - @PathParam("resourceVersion") final String resourceVersion, - @PathParam("artifactName") final String artifactName) { - - Response response = null; - String requestURI = request.getRequestURI(); - - if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { - log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - return buildErrorResponse(responseFormat); - } - - try { - Either downloadRsrcArtifactEither = artifactsBusinessLogic - .downloadRsrcArtifactByNames(serviceName, serviceVersion, resourceName, resourceVersion, artifactName); - if (downloadRsrcArtifactEither.isRight()) { - ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - response = buildErrorResponse(responseFormat); - } else { - byte[] value = downloadRsrcArtifactEither.left().value(); - // Returning 64-encoded as it was received during upload - InputStream is = new ByteArrayInputStream(value); - Map headers = new HashMap<>(); - headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - response = buildOkResponse(responseFormat, is, headers); - } - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API"); - log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /** - * - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param serviceName - * @param serviceVersion - * @param resourceInstanceName - * @param artifactName - * @return - */ - @GET - @Path("/services/{serviceName}/{serviceVersion}/resourceInstances/{resourceInstanceName}/artifacts/{artifactName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"), - @ApiResponse(code = 404, message = "Specified Resource Instance is not found - SVC4526"), - @ApiResponse(code = 404, message = "Specified Service Version is not found - SVC4504"), - @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response downloadResourceInstanceArtifactByName( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @PathParam("serviceName") final String serviceName, - @PathParam("serviceVersion") final String serviceVersion, - @PathParam("resourceInstanceName") final String resourceInstanceName, - @PathParam("artifactName") final String artifactName) { - - Response response = null; - String requestURI = request.getRequestURI(); - - if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { - log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - return buildErrorResponse(responseFormat); - } - - try { - Either downloadRsrcArtifactEither = artifactsBusinessLogic - .downloadRsrcInstArtifactByNames(serviceName, serviceVersion, resourceInstanceName, artifactName); - if (downloadRsrcArtifactEither.isRight()) { - ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - response = buildErrorResponse(responseFormat); - } else { - byte[] value = downloadRsrcArtifactEither.left().value(); - // Returning 64-encoded as it was received during upload - InputStream is = new ByteArrayInputStream(value); - Map headers = new HashMap<>(); - headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); - response = buildOkResponse(responseFormat, is, headers); - } - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API"); - log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } -} +/*- + * ============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.distribution.servlet; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData; +import org.openecomp.sdc.be.servlets.BeGenericServlet; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.beans.factory.annotation.Autowired; +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; + +/** + * This Servlet serves external users to download artifacts. + * + * @author tgitelman + * + */ + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Distribution Catalog Servlet",description = "This Servlet serves external users to download artifacts.")) +@Singleton +public class DistributionCatalogServlet extends BeGenericServlet { + + private static final String DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION = "download artifact failed with exception"; + private static final String MISSING_X_ECOMP_INSTANCE_ID_HEADER = "Missing X-ECOMP-InstanceID header"; + private static final Logger log = Logger.getLogger(DistributionCatalogServlet.class); + private final ArtifactsBusinessLogic artifactsBusinessLogic; + + @Autowired + public DistributionCatalogServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + ArtifactsBusinessLogic artifactsBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.artifactsBusinessLogic = artifactsBusinessLogic; + } + + @Context + private HttpServletRequest request; + + // ******************************************************* + // Download (GET) artifacts + // **********************************************************/ + /** + * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param serviceName + * @param serviceVersion + * @param artifactName + * @return + */ + @GET + @Path("/services/{serviceName}/{serviceVersion}/artifacts/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Operation(description = "Download service artifact", method = "GET", summary = "Returns downloaded artifact", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "The artifact is found and streamed.", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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 = "Specified Service is not found - SVC4503"), + @ApiResponse(responseCode = "404", description = "Specified Service Version is not found - SVC4504"), + @ApiResponse(responseCode = "404", description = "Specified artifact is not found - SVC4505"), + @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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) + public Response downloadServiceArtifact( + @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, + @PathParam("serviceName") final String serviceName, + @PathParam("serviceVersion") final String serviceVersion, + @PathParam("artifactName") final String artifactName) { + + Response response = null; + String requestURI = request.getRequestURI(); + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + return buildErrorResponse(responseFormat); + } + + try { + Either downloadRsrcArtifactEither = artifactsBusinessLogic + .downloadServiceArtifactByNames(serviceName, serviceVersion, artifactName); + if (downloadRsrcArtifactEither.isRight()) { + ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = downloadRsrcArtifactEither.left().value(); + InputStream is = new ByteArrayInputStream(value); + + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download Murano package artifact for service - external API"); + log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /** + * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param serviceName + * @param serviceVersion + * @param resourceName + * @param resourceVersion + * @param artifactName + * @return + */ + @GET + @Path("/services/{serviceName}/{serviceVersion}/resources/{resourceName}/{resourceVersion}/artifacts/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Operation(description = "Download resource artifact", method = "GET", summary = "Returns downloaded artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "The artifact is found and streamed.", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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 = "Specified Service is not found - SVC4503"), + @ApiResponse(responseCode = "404", description = "Specified Resource Instance is not found - SVC4526"), + @ApiResponse(responseCode = "404", description = "Specified Service Version is not found - SVC4504"), + @ApiResponse(responseCode = "404", description = "Specified artifact is not found - SVC4505"), + @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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) + public Response downloadResourceArtifact( + @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, + @PathParam("serviceName") final String serviceName, + @PathParam("serviceVersion") final String serviceVersion, + @PathParam("resourceName") final String resourceName, + @PathParam("resourceVersion") final String resourceVersion, + @PathParam("artifactName") final String artifactName) { + + Response response = null; + String requestURI = request.getRequestURI(); + + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + return buildErrorResponse(responseFormat); + } + + try { + Either downloadRsrcArtifactEither = artifactsBusinessLogic + .downloadRsrcArtifactByNames(serviceName, serviceVersion, resourceName, resourceVersion, artifactName); + if (downloadRsrcArtifactEither.isRight()) { + ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = downloadRsrcArtifactEither.left().value(); + // Returning 64-encoded as it was received during upload + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API"); + log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /** + * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param serviceName + * @param serviceVersion + * @param resourceInstanceName + * @param artifactName + * @return + */ + @GET + @Path("/services/{serviceName}/{serviceVersion}/resourceInstances/{resourceInstanceName}/artifacts/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Operation(description = "Download resource instance artifact", method = "GET", summary = "Returns downloaded artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "The artifact is found and streamed.", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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 = "Specified Service is not found - SVC4503"), + @ApiResponse(responseCode = "404", description = "Specified Resource Instance is not found - SVC4526"), + @ApiResponse(responseCode = "404", description = "Specified Service Version is not found - SVC4504"), + @ApiResponse(responseCode = "404", description = "Specified artifact is not found - SVC4505"), + @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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) + public Response downloadResourceInstanceArtifactByName( + @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, + @PathParam("serviceName") final String serviceName, + @PathParam("serviceVersion") final String serviceVersion, + @PathParam("resourceInstanceName") final String resourceInstanceName, + @PathParam("artifactName") final String artifactName) { + + Response response = null; + String requestURI = request.getRequestURI(); + + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + return buildErrorResponse(responseFormat); + } + + try { + Either downloadRsrcArtifactEither = artifactsBusinessLogic + .downloadRsrcInstArtifactByNames(serviceName, serviceVersion, resourceInstanceName, artifactName); + if (downloadRsrcArtifactEither.isRight()) { + ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = downloadRsrcArtifactEither.left().value(); + // Returning 64-encoded as it was received during upload + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI)); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API"); + log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java index c660b3b07e..70556d6561 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java @@ -1,370 +1,385 @@ -/*- - * ============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.distribution.servlet; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.distribution.AuditHandler; -import org.openecomp.sdc.be.distribution.DistributionBusinessLogic; -import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; -import org.openecomp.sdc.be.distribution.api.client.ServerListResponse; -import org.openecomp.sdc.be.distribution.api.client.TopicRegistrationResponse; -import org.openecomp.sdc.be.distribution.api.client.TopicUnregistrationResponse; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.servlets.BeGenericServlet; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.ArtifactTypeEnum; -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.HttpUtil; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * This Servlet serves external users for distribution purposes. - * - * @author tgitelman - * - */ - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1") -@Api(value = "Distribution Servlet", description = "This Servlet serves external users for distribution purposes.") -@Singleton -public class DistributionServlet extends BeGenericServlet { - - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; - private static final Logger log = Logger.getLogger(DistributionServlet.class); - private final DistributionBusinessLogic distributionLogic; - @Context - private HttpServletRequest request; - - @Inject - public DistributionServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, DistributionBusinessLogic distributionLogic) { - super(userBusinessLogic, componentsUtils); - this.distributionLogic = distributionLogic; - } - - /** - * - * @param requestId - * @param instanceId - * @param accept - * @param authorization - * @return - */ - @GET - @Path("/distributionUebCluster") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "UEB Server List", httpMethod = "GET", notes = "return the available UEB Server List", - //TODO Tal G fix response headers - responseHeaders = { - @ResponseHeader(name = Constants.CONTENT_TYPE_HEADER, description = "Determines the format of the response body", response = String.class), - @ResponseHeader(name = "Content-Length", description = "Length of the response body", response = String.class)}) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Cambria API server’s FQDNs is returned", response = ServerListResponse.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its credentials for Basic Authentication - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response getUebServerList( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - Response response = null; - ResponseFormat responseFormat = null; - - if (instanceId == null) { - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - response = buildErrorResponse(responseFormat); - getComponentsUtils().auditGetUebCluster(null, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); - return response; - } - - try { - Either actionResponse = distributionLogic.getUebServerList(); - - if (actionResponse.isRight()) { - responseFormat = actionResponse.right().value(); - response = buildErrorResponse(responseFormat); - } else { - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - response = buildOkResponse(responseFormat, actionResponse.left().value()); - } - - getComponentsUtils().auditGetUebCluster(instanceId, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("failed to get ueb serbver list from cofiguration"); - log.debug("failed to get ueb serbver list from cofiguration", e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - getComponentsUtils().auditGetUebCluster(instanceId, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); - response = buildErrorResponse(responseFormat); - return response; - } - - } - - /** - * - * @param requestId - * @param instanceId - * @param accept - * @param contentType - * @param contenLength - * @param authorization - * @param requestJson - * @return - */ - @POST - @Path("/registerForDistribution") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Subscription status", httpMethod = "POST", notes = "Subscribes for distribution notifications") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "ECOMP component is successfully registered for distribution", response = TopicRegistrationResponse.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 400, message = "Missing Body - POL4500"), - @ApiResponse(code = 400, message = "Invalid Body : missing mandatory parameter 'apiPublicKey' - POL4501"), - @ApiResponse(code = 400, message = "Invalid Body : missing mandatory parameter 'distrEnvName' - POL4502"), - @ApiResponse(code = 400, message = "Invalid Body : Specified 'distrEnvName' doesn’t exist - POL4137"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( PUT,DELETE,GET will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) - @ApiImplicitParams({@ApiImplicitParam(name = "requestJson", required = true, dataType = "org.openecomp.sdc.be.distribution.api.client.RegistrationRequest", paramType = "body", value = "json describe the artifact")}) - public Response registerForDistribution( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "Length of the request body", required = true)@HeaderParam(value = Constants.CONTENT_LENGTH_HEADER) String contenLength, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam( hidden = true) String requestJson) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper registrationRequestWrapper = new Wrapper<>(); - - validateHeaders(responseWrapper, request, AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL); - - if (responseWrapper.isEmpty()) { - validateJson(responseWrapper, registrationRequestWrapper, requestJson); - } - if (responseWrapper.isEmpty()) { - validateEnv(responseWrapper); - } - - if (responseWrapper.isEmpty()) { - distributionLogic.handleRegistration(responseWrapper, registrationRequestWrapper.getInnerElement(), buildAuditHandler(request, registrationRequestWrapper.getInnerElement())); - } else { - BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionBusinessLogic.REGISTER_IN_DISTRIBUTION_ENGINE, "registration validation failed"); - } - - return responseWrapper.getInnerElement(); - } - - /** - * Returns list of valid artifact types for validation done in the distribution client.
- * The list is the representation of the values of the enum ArtifactTypeEnum. - * - * @param requestId - * @param instanceId - * @param authorization - * @param accept - * @return - */ - @GET - @Path("/artifactTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Artifact types list", httpMethod = "GET", notes = "Fetches available artifact types list") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact types list fetched successfully", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( POST,PUT,DELETE will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) - public Response getValidArtifactTypes( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - Response response = null; - - Wrapper responseWrapper = new Wrapper<>(); - - //TODO check if in use - validateHeaders(responseWrapper, request, AuditingActionEnum.GET_VALID_ARTIFACT_TYPES); - if (responseWrapper.isEmpty()) { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), ArtifactTypeEnum.values()); - } else { - response = responseWrapper.getInnerElement(); - } - return response; - } - - /** - * Removes from subscription for distribution notifications - * - * @param requestId - * @param instanceId - * @param accept - * @param contentType - * @param contenLength - * @param authorization - * @param requestJson - * @return - */ - @POST - @Path("/unRegisterForDistribution") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Subscription status", httpMethod = "POST", notes = "Removes from subscription for distribution notifications") - //TODO Edit the responses - @ApiResponses(value = { - @ApiResponse(code = 204, message = "ECOMP component is successfully unregistered", response = TopicUnregistrationResponse.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 400, message = "Missing Body - POL4500"), - @ApiResponse(code = 400, message = "Invalid Body : missing mandatory parameter 'apiPublicKey' - POL4501"), - @ApiResponse(code = 400, message = "Invalid Body : missing mandatory parameter 'distrEnvName' - SVC4506"), - @ApiResponse(code = 400, message = "Invalid Body : Specified 'distrEnvName' doesn’t exist - POL4137"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( PUT,DELETE,GET will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) - @ApiImplicitParams({@ApiImplicitParam(name = "requestJson", required = true, dataType = "org.openecomp.sdc.be.distribution.api.client.RegistrationRequest", paramType = "body", value = "json describe the artifact")}) - public Response unRegisterForDistribution( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "Length of the request body", required = true)@HeaderParam(value = Constants.CONTENT_LENGTH_HEADER) String contenLength, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam( hidden = true) String requestJson) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper unRegistrationRequestWrapper = new Wrapper<>(); - - validateHeaders(responseWrapper, request, AuditingActionEnum.REMOVE_KEY_FROM_TOPIC_ACL); - - if (responseWrapper.isEmpty()) { - validateJson(responseWrapper, unRegistrationRequestWrapper, requestJson); - } - if (responseWrapper.isEmpty()) { - validateEnv(responseWrapper); - } - if (responseWrapper.isEmpty()) { - distributionLogic.handleUnRegistration(responseWrapper, unRegistrationRequestWrapper.getInnerElement(), buildAuditHandler(request, unRegistrationRequestWrapper.getInnerElement())); - } else { - BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionBusinessLogic.UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration validation failed"); - } - - return responseWrapper.getInnerElement(); - } - - private void validateEnv(Wrapper responseWrapper) { - - // DE194021 - StorageOperationStatus environmentStatus = distributionLogic.getDistributionEngine().isEnvironmentAvailable(); - if (environmentStatus != StorageOperationStatus.OK) { - if (environmentStatus == StorageOperationStatus.DISTR_ENVIRONMENT_NOT_FOUND) { - Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.DISTRIBUTION_ENV_DOES_NOT_EXIST)); - responseWrapper.setInnerElement(missingHeaderResponse); - } else { - Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); - responseWrapper.setInnerElement(missingHeaderResponse); - } - } - - } - - private void validateHeaders(Wrapper responseWrapper, HttpServletRequest request, AuditingActionEnum auditingAction) { - if (request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER) == null) { - Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID)); - responseWrapper.setInnerElement(missingHeaderResponse); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditMissingInstanceIdAsDistributionEngineEvent(auditingAction, responseFormat.getStatus().toString()); - - } - - } - - private void validateJson(Wrapper responseWrapper, Wrapper registrationRequestWrapper, String requestJson) { - if (requestJson == null || requestJson.isEmpty()) { - Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_BODY)); - responseWrapper.setInnerElement(missingBodyResponse); - } else { - Either eitherRegistration = HttpUtil.convertJsonStringToObject(requestJson, RegistrationRequest.class); - if (eitherRegistration.isLeft()) { - RegistrationRequest registrationRequest = eitherRegistration.left().value(); - if (registrationRequest.getApiPublicKey() == null) { - Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_PUBLIC_KEY)); - responseWrapper.setInnerElement(missingBodyResponse); - - } else if (registrationRequest.getDistrEnvName() == null) { - Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_ENV_NAME)); - responseWrapper.setInnerElement(missingBodyResponse); - } else { - registrationRequestWrapper.setInnerElement(registrationRequest); - } - } else { - Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_BODY)); - responseWrapper.setInnerElement(missingBodyResponse); - } - } - - } - - private AuditHandler buildAuditHandler(HttpServletRequest request, RegistrationRequest registrationRequest) { - return new AuditHandler(getComponentsUtils(), request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER), registrationRequest); - } -} +/*- + * ============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.distribution.servlet; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +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.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.distribution.AuditHandler; +import org.openecomp.sdc.be.distribution.DistributionBusinessLogic; +import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; +import org.openecomp.sdc.be.distribution.api.client.ServerListResponse; +import org.openecomp.sdc.be.distribution.api.client.TopicRegistrationResponse; +import org.openecomp.sdc.be.distribution.api.client.TopicUnregistrationResponse; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.BeGenericServlet; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +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.HttpUtil; +import org.openecomp.sdc.exception.ResponseFormat; +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; + +/** + * This Servlet serves external users for distribution purposes. + * + * @author tgitelman + * + */ + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1") +@OpenAPIDefinition(info = @Info(title = "Distribution Servlet",description = "This Servlet serves external users for distribution purposes.")) + +@Singleton +public class DistributionServlet extends BeGenericServlet { + + private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + private static final Logger log = Logger.getLogger(DistributionServlet.class); + private final DistributionBusinessLogic distributionLogic; + @Context + private HttpServletRequest request; + + @Inject + public DistributionServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, DistributionBusinessLogic distributionLogic) { + super(userBusinessLogic, componentsUtils); + this.distributionLogic = distributionLogic; + } + + /** + * + * @param requestId + * @param instanceId + * @param accept + * @param authorization + * @return + */ + @GET + @Path("/distributionUebCluster") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "UEB Server List", method = "GET", summary = "return the available UEB Server List") + //TODO Tal G fix response headers + /*responseHeaders = { + @ResponseHeader(name = Constants.CONTENT_TYPE_HEADER, description = "Determines the format of the response body", response = String.class), + @ResponseHeader(name = "Content-Length", description = "Length of the response body", response = String.class)})*/ + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "ECOMP component is authenticated and list of Cambria API server’s FQDNs is returned", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ServerListResponse.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 credentials for Basic Authentication - POL5002"), + @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"), + @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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) + public Response getUebServerList( + @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) String instanceId, + @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) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + Response response = null; + ResponseFormat responseFormat = null; + + if (instanceId == null) { + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + response = buildErrorResponse(responseFormat); + getComponentsUtils().auditGetUebCluster(null, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + return response; + } + + try { + Either actionResponse = distributionLogic.getUebServerList(); + + if (actionResponse.isRight()) { + responseFormat = actionResponse.right().value(); + response = buildErrorResponse(responseFormat); + } else { + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, actionResponse.left().value()); + } + + getComponentsUtils().auditGetUebCluster(instanceId, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("failed to get ueb serbver list from cofiguration"); + log.debug("failed to get ueb serbver list from cofiguration", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + getComponentsUtils().auditGetUebCluster(instanceId, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + response = buildErrorResponse(responseFormat); + return response; + } + + } + + /** + * + * @param requestId + * @param instanceId + * @param accept + * @param contentType + * @param contenLength + * @param authorization + * @param requestJson + * @return + */ + @POST + @Path("/registerForDistribution") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(parameters = @Parameter(name = "requestJson", required = true ), description = "Subscription status", method = "POST", summary = "Subscribes for distribution notifications") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "ECOMP component is successfully registered for distribution",content = @Content(array = @ArraySchema(schema = @Schema(implementation = TopicRegistrationResponse.class)))), + @ApiResponse(responseCode = "400", description = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), + @ApiResponse(responseCode = "400", description = "Missing Body - POL4500"), + @ApiResponse(responseCode = "400", description = "Invalid Body : missing mandatory parameter 'apiPublicKey' - POL4501"), + @ApiResponse(responseCode = "400", description = "Invalid Body : missing mandatory parameter 'distrEnvName' - POL4502"), + @ApiResponse(responseCode = "400", description = "Invalid Body : Specified 'distrEnvName' doesn’t exist - POL4137"), + @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 = "405", description = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( PUT,DELETE,GET will be rejected) - POL4050"), + @ApiResponse(responseCode = "500", description = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) + + //@ApiImplicitParams({@ApiImplicitParam(name = "requestJson", required = true, dataType = "org.openecomp.sdc.be.distribution.api.client.RegistrationRequest", paramType = "body", value = "json describe the artifact")}) + + public Response registerForDistribution( + @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) String instanceId, + @Parameter(description = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @Parameter(description = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, + @Parameter(description = "Length of the request body", required = true)@HeaderParam(value = Constants.CONTENT_LENGTH_HEADER) String contenLength, + @Parameter(description = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @Parameter( hidden = true) String requestJson) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper registrationRequestWrapper = new Wrapper<>(); + + validateHeaders(responseWrapper, request, AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL); + + if (responseWrapper.isEmpty()) { + validateJson(responseWrapper, registrationRequestWrapper, requestJson); + } + if (responseWrapper.isEmpty()) { + validateEnv(responseWrapper); + } + + if (responseWrapper.isEmpty()) { + distributionLogic.handleRegistration(responseWrapper, registrationRequestWrapper.getInnerElement(), buildAuditHandler(request, registrationRequestWrapper.getInnerElement())); + } else { + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionBusinessLogic.REGISTER_IN_DISTRIBUTION_ENGINE, "registration validation failed"); + } + + return responseWrapper.getInnerElement(); + } + + /** + * Returns list of valid artifact types for validation done in the distribution client.
+ * The list is the representation of the values of the enum ArtifactTypeEnum. + * + * @param requestId + * @param instanceId + * @param authorization + * @param accept + * @return + */ + @GET + @Path("/artifactTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Artifact types list", method = "GET", summary = "Fetches available artifact types list") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact types list fetched successfully", content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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 = "405", description = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( POST,PUT,DELETE will be rejected) - POL4050"), + @ApiResponse(responseCode = "500", description = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) + public Response getValidArtifactTypes( + @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) String instanceId, + @Parameter(description = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @Parameter(description = "The username and password", required = true)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + Response response = null; + + Wrapper responseWrapper = new Wrapper<>(); + + //TODO check if in use + validateHeaders(responseWrapper, request, AuditingActionEnum.GET_VALID_ARTIFACT_TYPES); + if (responseWrapper.isEmpty()) { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), ArtifactTypeEnum.values()); + } else { + response = responseWrapper.getInnerElement(); + } + return response; + } + + /** + * Removes from subscription for distribution notifications + * + * @param requestId + * @param instanceId + * @param accept + * @param contentType + * @param contenLength + * @param authorization + * @param requestJson + * @return + */ + @POST + @Path("/unRegisterForDistribution") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(parameters = @Parameter(name = "requestJson", required = true ),description = "Subscription status", method = "POST", summary = "Removes from subscription for distribution notifications") + //TODO Edit the responses + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "ECOMP component is successfully unregistered", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = TopicUnregistrationResponse.class)))), + @ApiResponse(responseCode = "400", description = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), + @ApiResponse(responseCode = "400", description = "Missing Body - POL4500"), + @ApiResponse(responseCode = "400", description = "Invalid Body : missing mandatory parameter 'apiPublicKey' - POL4501"), + @ApiResponse(responseCode = "400", description = "Invalid Body : missing mandatory parameter 'distrEnvName' - SVC4506"), + @ApiResponse(responseCode = "400", description = "Invalid Body : Specified 'distrEnvName' doesn’t exist - POL4137"), + @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 = "405", description = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( PUT,DELETE,GET will be rejected) - POL4050"), + @ApiResponse(responseCode = "500", description = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) + //@ApiImplicitParams({@ApiImplicitParam(name = "requestJson", required = true, dataType = "org.openecomp.sdc.be.distribution.api.client.RegistrationRequest", paramType = "body", value = "json describe the artifact")}) + public Response unRegisterForDistribution( + @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) String instanceId, + @Parameter(description = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @Parameter(description = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, + @Parameter(description = "Length of the request body", required = true)@HeaderParam(value = Constants.CONTENT_LENGTH_HEADER) String contenLength, + @Parameter(description = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @Parameter( hidden = true) String requestJson) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper unRegistrationRequestWrapper = new Wrapper<>(); + + validateHeaders(responseWrapper, request, AuditingActionEnum.REMOVE_KEY_FROM_TOPIC_ACL); + + if (responseWrapper.isEmpty()) { + validateJson(responseWrapper, unRegistrationRequestWrapper, requestJson); + } + if (responseWrapper.isEmpty()) { + validateEnv(responseWrapper); + } + if (responseWrapper.isEmpty()) { + distributionLogic.handleUnRegistration(responseWrapper, unRegistrationRequestWrapper.getInnerElement(), buildAuditHandler(request, unRegistrationRequestWrapper.getInnerElement())); + } else { + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionBusinessLogic.UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration validation failed"); + } + + return responseWrapper.getInnerElement(); + } + + private void validateEnv(Wrapper responseWrapper) { + + // DE194021 + StorageOperationStatus environmentStatus = distributionLogic.getDistributionEngine().isEnvironmentAvailable(); + if (environmentStatus != StorageOperationStatus.OK) { + if (environmentStatus == StorageOperationStatus.DISTR_ENVIRONMENT_NOT_FOUND) { + Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.DISTRIBUTION_ENV_DOES_NOT_EXIST)); + responseWrapper.setInnerElement(missingHeaderResponse); + } else { + Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(missingHeaderResponse); + } + } + + } + + private void validateHeaders(Wrapper responseWrapper, HttpServletRequest request, AuditingActionEnum auditingAction) { + if (request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER) == null) { + Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID)); + responseWrapper.setInnerElement(missingHeaderResponse); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditMissingInstanceIdAsDistributionEngineEvent(auditingAction, responseFormat.getStatus().toString()); + + } + + } + + private void validateJson(Wrapper responseWrapper, Wrapper registrationRequestWrapper, String requestJson) { + if (requestJson == null || requestJson.isEmpty()) { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_BODY)); + responseWrapper.setInnerElement(missingBodyResponse); + } else { + Either eitherRegistration = HttpUtil.convertJsonStringToObject(requestJson, RegistrationRequest.class); + if (eitherRegistration.isLeft()) { + RegistrationRequest registrationRequest = eitherRegistration.left().value(); + if (registrationRequest.getApiPublicKey() == null) { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_PUBLIC_KEY)); + responseWrapper.setInnerElement(missingBodyResponse); + + } else if (registrationRequest.getDistrEnvName() == null) { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_ENV_NAME)); + responseWrapper.setInnerElement(missingBodyResponse); + } else { + registrationRequestWrapper.setInnerElement(registrationRequest); + } + } else { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_BODY)); + responseWrapper.setInnerElement(missingBodyResponse); + } + } + + } + + private AuditHandler buildAuditHandler(HttpServletRequest request, RegistrationRequest registrationRequest) { + return new AuditHandler(getComponentsUtils(), request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER), registrationRequest); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java index bed28f5712..a4e465eaf8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java @@ -1,937 +1,1135 @@ -/*- - * ============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.jcabi.aspects.Loggable; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; -import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.ArtifactDefinition; -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.common.api.Constants; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.util.GeneralUtility; -import org.openecomp.sdc.exception.ResponseFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -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.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * This Servlet serves external users operations on artifacts. - * - * @author mshitrit - * - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Artifact External Servlet", description = "Servlet serves external users operations on artifacts.") -@Singleton -public class ArtifactExternalServlet extends AbstractValidationsServlet { - - private static final String FAILED_TO_UPDATE_ARTIFACT = "failed to update artifact"; - - @Context - private HttpServletRequest request; - - private final ArtifactsBusinessLogic artifactsBusinessLogic; - - private static final Logger log = LoggerFactory.getLogger(ArtifactExternalServlet.class); - - private static String startLog = "Start handle request of "; - - @Inject - public ArtifactExternalServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ArtifactsBusinessLogic artifactsBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.artifactsBusinessLogic = artifactsBusinessLogic; - } - - - @POST - @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "uploads of artifact to VF operation workflow", httpMethod = "POST", notes = "uploads of artifact to VF operation workflow") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 400, message = "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 - SVC4086"), - @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) - public Response uploadInterfaceOperationArtifact( - @ApiParam(value = "Determines the format of the body of the request", required = true) @HeaderParam(value = HttpHeaders.CONTENT_TYPE) String contentType, - @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "Asset type") @PathParam("assetType") String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the interface", required = true)@PathParam("interfaceUUID") final String interfaceUUID, - @ApiParam(value = "The uuid of the operation", required = true)@PathParam("operationUUID") final String operationUUID, - @ApiParam(value = "The uuid of the artifact", required = true)@PathParam("artifactUUID") final String artifactUUID, - @ApiParam( hidden = true) String data) { - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(assetType); - ArtifactDefinition artifactDefinition = null; - - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("updateArtifact: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { - log.debug("updateArtifact: Missing USER_ID"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic - .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum - .findByParamName(assetType), uuid, interfaceUUID, operationUUID, artifactUUID, - resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE)); - if (uploadArtifactEither.isRight()) { - log.debug(FAILED_TO_UPDATE_ARTIFACT); - responseFormat = uploadArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - artifactDefinition=uploadArtifactEither.left().value(); - Object representation = RepresentationUtils.toRepresentation(artifactDefinition); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); - } - } - } catch (Exception e) { - final String message = "failed to update artifact on a resource or service"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } finally { - getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, - resourceCommonInfo, request, artifactDefinition, null); - } - return responseWrapper.getInnerElement(); - } - - /** - * Uploads an artifact to resource or service - * - * @param contentType - * @param checksum - * @param userId - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param assetType - * @param uuid - * @param data - * @return - */ - @POST - @Path("/{assetType}/{uuid}/artifacts") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "uploads of artifact to a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 400, message = "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 - SVC4086"), - @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) - public Response uploadArtifact( - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam( hidden = true) String data) { - - init(); - - Wrapper responseWrapper = new Wrapper<>(); - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); - - if (componentType == null) { - log.debug("uploadArtifact: assetType parameter {} is not valid", assetType); - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - if (responseWrapper.isEmpty()) { - validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); - } - if (responseWrapper.isEmpty() ) { - validateHttpCspUserIdHeader(userId, responseWrapper); - } - Response response = null; - ArtifactDefinition artifactDefinition = null; - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic - .uploadArtifactToComponentByUUID(data, request, componentType, uuid, - resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.CREATE)); - if (uploadArtifactEither.isRight()) { - log.debug("failed to upload artifact"); - responseWrapper.setInnerElement(uploadArtifactEither.right().value()); - } else { - artifactDefinition = uploadArtifactEither.left().value(); - Object representation = RepresentationUtils.toRepresentation(artifactDefinition); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.OK)); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers); - } - } - } catch (IOException e) { - final String message = "failed to upload artifact to a resource or service"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - response = buildErrorResponse(responseWrapper.getInnerElement()); - } catch (ComponentException e){ - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(e)); - }finally { - if( response == null ){ - response = buildErrorResponse(responseWrapper.getInnerElement()); - } - getComponentsUtils().auditExternalCrudApi(responseWrapper.getInnerElement(), AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, - resourceCommonInfo, request, artifactDefinition, null); - } - return response; - } - - /** - * Uploads an artifact to resource instance - * - * @param assetType - * @param uuid - * @param resourceInstanceName - * @return - */ - @POST - @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "uploads an artifact to a resource instance", httpMethod = "POST", notes = "uploads an artifact to a resource instance") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 400, message = "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 - SVC4086"), - @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) - public Response uploadArtifactToInstance( - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName, - @ApiParam( hidden = true) String data) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue); - ArtifactDefinition artifactDefinition = null; - - if (componentType == null) { - log.debug("uploadArtifact: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("uploadArtifact: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { - log.debug("uploadArtifact: Missing USER_ID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic - .uploadArtifactToRiByUUID(data, request, componentType, uuid, resourceInstanceName, - artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.CREATE)); - if (uploadArtifactEither.isRight()) { - log.debug("failed to upload artifact"); - responseFormat = uploadArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); - } - } - }catch (IOException e) { - final String message = "failed to upload artifact to a resource instance"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - }catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - }finally { - getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, - resourceCommonInfo, request, artifactDefinition, null); - } - return responseWrapper.getInnerElement(); - } - - /** - * - * @param contentType - * @param checksum - * @param userId - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param assetType - * @param uuid - * @param artifactUUID - * @param data - * @return - */ - @POST - @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "updates an artifact on a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact updated", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 403, message = "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 - SVC4086"), - @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) - public Response updateArtifact( - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, - @ApiParam(hidden = true) String data) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); - if (componentType == null) { - log.debug("updateArtifact: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("updateArtifact: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { - log.debug("updateArtifact: Missing USER_ID"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - ArtifactDefinition artifactDefinition = null; - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic - .updateArtifactOnComponentByUUID(data, request, componentType, uuid, artifactUUID, - resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE)); - if (uploadArtifactEither.isRight()) { - log.debug(FAILED_TO_UPDATE_ARTIFACT); - responseFormat = uploadArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); - } - } - } catch (IOException e) { - final String message = "failed to update artifact on a resource or service"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - } - finally{ - getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPDATE_BY_API, resourceCommonInfo, - request, artifactDefinition, artifactUUID); - } - return responseWrapper.getInnerElement(); - } - - /** - * updates an artifact on a resource instance - * - * @param assetType - * @param uuid - * @param resourceInstanceName - * @param artifactUUID - * @return - */ - @POST - @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "updates an artifact on a resource instance", httpMethod = "POST", notes = "uploads of artifact to a resource or service") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact updated", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 403, message = "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 - SVC4086"), - @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) - public Response updateArtifactOnResourceInstance( - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, - @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName, - @ApiParam( hidden = true) String data) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue); - if (componentType == null) { - log.debug("updateArtifactOnResourceInstance: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("updateArtifactOnResourceInstance: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { - log.debug("updateArtifactOnResourceInstance: Missing USER_ID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - ArtifactDefinition artifactDefinition = null; - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic - .updateArtifactOnRiByUUID(data, request, componentType, uuid, resourceInstanceName, artifactUUID, - artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE)); - if (uploadArtifactEither.isRight()) { - log.debug(FAILED_TO_UPDATE_ARTIFACT); - responseFormat = uploadArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); - } - } - } catch (IOException e) { - final String message = "failed to update artifact on resource instance"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - } - finally{ - getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPDATE_BY_API, resourceCommonInfo, - request, artifactDefinition, artifactUUID); - } - return responseWrapper.getInnerElement(); - } - - /** - * deletes an artifact of a resource or service - * - * @param assetType - * @param uuid - * @param artifactUUID - * @return - */ - @DELETE - @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "deletes an artifact of a resource or service", httpMethod = "DELETE", notes = "deletes an artifact of a resource or service", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact deleted", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 403, message = "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 - SVC4086"), - @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - public Response deleteArtifact( - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); - ArtifactDefinition artifactDefinition = null; - if (componentType == null) { - log.debug("deleteArtifact: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("deleteArtifact: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { - log.debug("deleteArtifact: Missing USER_ID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic.deleteArtifactOnComponentByUUID(request, componentType, uuid, artifactUUID, - resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.DELETE)); - if (uploadArtifactEither.isRight()) { - log.debug("failed to delete artifact"); - responseFormat = uploadArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); - } - } - } catch (IOException e) { - final String message = "failed to delete an artifact of a resource or service"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - } - finally{ - getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_DELETE_BY_API, resourceCommonInfo, - request, artifactDefinition, artifactUUID); - } - return responseWrapper.getInnerElement(); - } - - /** - * deletes an artifact of a resource instance - * - * @param assetType - * @param uuid - * @param resourceInstanceName - * @return - */ - @DELETE - @Path("{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "deletes an artifact of a resource insatnce", httpMethod = "DELETE", notes = "deletes an artifact of a resource insatnce", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact deleted", response = ArtifactDefinition.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 403, message = "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 - SVC4086"), - @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - public Response deleteArtifactOnResourceInstance( - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, - @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue); - if (componentType == null) { - log.debug("deleteArtifactOnResourceInsatnce: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("deleteArtifactOnResourceInsatnce: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { - log.debug("deleteArtifactOnResourceInsatnce: Missing USER_ID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - ArtifactDefinition artifactDefinition = null; - try { - if (responseWrapper.isEmpty()) { - Either uploadArtifactEither = artifactsBusinessLogic.deleteArtifactOnRiByUUID(request, componentType, uuid, resourceInstanceName, artifactUUID, - artifactsBusinessLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.DELETE)); - if (uploadArtifactEither.isRight()) { - log.debug("failed to delete artifact"); - responseFormat = uploadArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); - } - } - } catch (IOException e) { - final String message = "failed to delete an artifact of a resource instance"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - } - finally{ - getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_DELETE_BY_API, resourceCommonInfo, - request, artifactDefinition, artifactUUID); - } - return responseWrapper.getInnerElement(); - } - - /** - * downloads an artifact of a component (either a service or a resource) by artifactUUID - * - * @param assetType - * @param uuid - * @param artifactUUID - * @return - */ - @GET - @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download component artifact", httpMethod = "GET", notes = "Returns downloaded artifact") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact downloaded", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 404, message = "Artifact was not found - SVC4505")}) - public Response downloadComponentArtifact( - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - if (componentType == null) { - log.debug("downloadComponentArtifact: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("downloadComponentArtifact: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); - try { - if (responseWrapper.isEmpty()) { - Either downloadComponentArtifactEither = artifactsBusinessLogic - .downloadComponentArtifactByUUIDs(componentType, uuid, artifactUUID, resourceCommonInfo); - if (downloadComponentArtifactEither.isRight()) { - responseFormat = downloadComponentArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - byte[] value = downloadComponentArtifactEither.left().value(); - InputStream is = new ByteArrayInputStream(value); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers)); - } - } - } catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - } - finally{ - getComponentsUtils().auditExternalDownloadArtifact(responseFormat, resourceCommonInfo, - new DistributionData(instanceIdHeader, requestURI), requestId, artifactUUID, userId); - } - return responseWrapper.getInnerElement(); - } - - /** - * downloads an artifact of a resource instance of a component (either a service or a resource) by artifactUUID - * - * @param assetType - * @param uuid - * @param resourceInstanceName - * @param artifactUUID - * @return - */ - @GET - @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact downloaded", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 404, message = "Artifact was not found - SVC4505")}) - public Response downloadResourceInstanceArtifact( - @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, - @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName) { - - Wrapper responseWrapper = new Wrapper<>(); - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - String componentTypeValue = componentType == null ? null : componentType.getValue(); - if (componentType == null) { - log.debug("downloadResourceInstanceArtifact: assetType parameter {} is not valid", assetType); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { - log.debug("downloadResourceInstanceArtifact: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } - try { - if (responseWrapper.isEmpty()) { - Either downloadResourceArtifactEither = artifactsBusinessLogic - .downloadResourceInstanceArtifactByUUIDs(componentType, uuid, resourceInstanceName, artifactUUID); - if (downloadResourceArtifactEither.isRight()) { - responseFormat = downloadResourceArtifactEither.right().value(); - responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); - } else { - byte[] value = downloadResourceArtifactEither.left().value(); - InputStream is = new ByteArrayInputStream(value); - Map headers = new HashMap<>(); - headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers)); - } - } - } catch (ComponentException e){ - responseFormat = getComponentsUtils().getResponseFormat(e); - } - finally{ - getComponentsUtils().auditExternalDownloadArtifact(responseFormat, new ResourceCommonInfo(resourceInstanceName, componentTypeValue), - new DistributionData(instanceIdHeader, requestURI), requestId, artifactUUID, userId); - } - return responseWrapper.getInnerElement(); - } -} +/*- + * ============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.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +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.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; +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.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +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.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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; + +/** + * This Servlet serves external users operations on artifacts. + * + * @author mshitrit + * + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") + +@OpenAPIDefinition(info = @Info(title = "Artifact External Servlet", + description = "Servlet serves external users operations on artifacts.")) +@Singleton +public class ArtifactExternalServlet extends AbstractValidationsServlet { + + private static final String FAILED_TO_UPDATE_ARTIFACT = "failed to update artifact"; + + @Context + private HttpServletRequest request; + + private final ArtifactsBusinessLogic artifactsBusinessLogic; + + private static final Logger log = LoggerFactory.getLogger(ArtifactExternalServlet.class); + + private static String startLog = "Start handle request of "; + + @Inject + public ArtifactExternalServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, + ServletUtils servletUtils, ResourceImportManager resourceImportManager, + ArtifactsBusinessLogic artifactsBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.artifactsBusinessLogic = artifactsBusinessLogic; + } + + + @POST + @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(parameters = @Parameter(required = true ),description = "uploads of artifact to VF operation workflow", method = "POST", + summary = "uploads of artifact to VF operation workflow") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact uploaded", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", + description = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @ApiResponse(responseCode = "400", + 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 - SVC4086"), + @ApiResponse(responseCode = "400", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = + // "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the + // artifact")}) + public Response uploadInterfaceOperationArtifact( + @Parameter(description = "Determines the format of the body of the request", + required = true) @HeaderParam(value = HttpHeaders.CONTENT_TYPE) String contentType, + @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", + required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = "Asset type") @PathParam("assetType") String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter(description = "The uuid of the interface", + required = true) @PathParam("interfaceUUID") final String interfaceUUID, + @Parameter(description = "The uuid of the operation", + required = true) @PathParam("operationUUID") final String operationUUID, + @Parameter(description = "The uuid of the artifact", + required = true) @PathParam("artifactUUID") final String artifactUUID, + @Parameter(hidden = true) String data) { + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(assetType); + ArtifactDefinition artifactDefinition = null; + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("updateArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("updateArtifact: Missing USER_ID"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.updateArtifactOnInterfaceOperationByResourceUUID(data, request, + ComponentTypeEnum.findByParamName(assetType), uuid, interfaceUUID, operationUUID, + artifactUUID, resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, + false, ArtifactOperationEnum.UPDATE)); + if (uploadArtifactEither.isRight()) { + log.debug(FAILED_TO_UPDATE_ARTIFACT); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + artifactDefinition = uploadArtifactEither.left().value(); + Object representation = RepresentationUtils.toRepresentation(artifactDefinition); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse( + getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (Exception e) { + final String message = "failed to update artifact on a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } finally { + getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, + resourceCommonInfo, request, artifactDefinition, null); + } + return responseWrapper.getInnerElement(); + } + + /** + * Uploads an artifact to resource or service + * + * @param contentType + * @param checksum + * @param userId + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param assetType + * @param uuid + * @param data + * @return + */ + @POST + @Path("/{assetType}/{uuid}/artifacts") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "uploads of artifact to a resource or service", method = "POST", + summary = "uploads of artifact to a resource or service") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact uploaded", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", + description = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @ApiResponse(responseCode = "400", + 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 - SVC4086"), + @ApiResponse(responseCode = "400", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = + // "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the + // artifact")}) + public Response uploadArtifact( + @Parameter(description = "Determines the format of the body of the request", + required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, + @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", + required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter(hidden = true) String data) { + + init(); + + Wrapper responseWrapper = new Wrapper<>(); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); + + if (componentType == null) { + log.debug("uploadArtifact: assetType parameter {} is not valid", assetType); + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + if (responseWrapper.isEmpty()) { + validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); + } + if (responseWrapper.isEmpty()) { + validateHttpCspUserIdHeader(userId, responseWrapper); + } + Response response = null; + ArtifactDefinition artifactDefinition = null; + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.uploadArtifactToComponentByUUID(data, request, componentType, uuid, + resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, false, + ArtifactOperationEnum.CREATE)); + if (uploadArtifactEither.isRight()) { + log.debug("failed to upload artifact"); + responseWrapper.setInnerElement(uploadArtifactEither.right().value()); + } else { + artifactDefinition = uploadArtifactEither.left().value(); + Object representation = RepresentationUtils.toRepresentation(artifactDefinition); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.OK)); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, + headers); + } + } + } catch (IOException e) { + final String message = "failed to upload artifact to a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + response = buildErrorResponse(responseWrapper.getInnerElement()); + } catch (ComponentException e) { + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(e)); + } finally { + if (response == null) { + response = buildErrorResponse(responseWrapper.getInnerElement()); + } + getComponentsUtils().auditExternalCrudApi(responseWrapper.getInnerElement(), + AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, resourceCommonInfo, request, artifactDefinition, null); + } + return response; + } + + /** + * Uploads an artifact to resource instance + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @return + */ + @POST + @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "uploads an artifact to a resource instance", method = "POST", + summary = "uploads an artifact to a resource instance") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact uploaded", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", + description = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @ApiResponse(responseCode = "400", + 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 - SVC4086"), + @ApiResponse(responseCode = "400", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = + // "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the + // artifact")}) + public Response uploadArtifactToInstance( + @Parameter(description = "Determines the format of the body of the request", + required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, + @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", + required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(schema = @Schema(allowableValues = {"resources,services"}),description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", + required = true) @PathParam("resourceInstanceName") final String resourceInstanceName, + @Parameter(hidden = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue); + ArtifactDefinition artifactDefinition = null; + + if (componentType == null) { + log.debug("uploadArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("uploadArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("uploadArtifact: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.uploadArtifactToRiByUUID(data, request, componentType, uuid, + resourceInstanceName, artifactsBusinessLogic.new ArtifactOperationInfo(true, false, + ArtifactOperationEnum.CREATE)); + if (uploadArtifactEither.isRight()) { + log.debug("failed to upload artifact"); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse( + getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (IOException e) { + final String message = "failed to upload artifact to a resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, + resourceCommonInfo, request, artifactDefinition, null); + } + return responseWrapper.getInnerElement(); + } + + /** + * + * @param contentType + * @param checksum + * @param userId + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param assetType + * @param uuid + * @param artifactUUID + * @param data + * @return + */ + @POST + @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "updates an artifact on a resource or service", method = "POST", + summary = "uploads of artifact to a resource or service") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact updated", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @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 - SVC4086"), + @ApiResponse(responseCode = "409", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = + // "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the + // artifact")}) + public Response updateArtifact( + @Parameter(description = "Determines the format of the body of the request", + required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, + @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", + required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter( + description = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", + required = true) @PathParam("artifactUUID") final String artifactUUID, + @Parameter(hidden = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); + if (componentType == null) { + log.debug("updateArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("updateArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("updateArtifact: Missing USER_ID"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + ArtifactDefinition artifactDefinition = null; + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.updateArtifactOnComponentByUUID(data, request, componentType, uuid, + artifactUUID, resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, + false, ArtifactOperationEnum.UPDATE)); + if (uploadArtifactEither.isRight()) { + log.debug(FAILED_TO_UPDATE_ARTIFACT); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse( + getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (IOException e) { + final String message = "failed to update artifact on a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPDATE_BY_API, + resourceCommonInfo, request, artifactDefinition, artifactUUID); + } + return responseWrapper.getInnerElement(); + } + + /** + * updates an artifact on a resource instance + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @param artifactUUID + * @return + */ + @POST + @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "updates an artifact on a resource instance", method = "POST", + summary = "uploads of artifact to a resource or service") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact updated", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @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 - SVC4086"), + @ApiResponse(responseCode = "409", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = + // "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the + // artifact")}) + public Response updateArtifactOnResourceInstance( + @Parameter(description = "Determines the format of the body of the request", + required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, + @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", + required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter( + description = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", + required = true) @PathParam("artifactUUID") final String artifactUUID, + @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", + required = true) @PathParam("resourceInstanceName") final String resourceInstanceName, + @Parameter(hidden = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue); + if (componentType == null) { + log.debug("updateArtifactOnResourceInstance: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("updateArtifactOnResourceInstance: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("updateArtifactOnResourceInstance: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + ArtifactDefinition artifactDefinition = null; + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.updateArtifactOnRiByUUID(data, request, componentType, uuid, + resourceInstanceName, artifactUUID, artifactsBusinessLogic.new ArtifactOperationInfo( + true, false, ArtifactOperationEnum.UPDATE)); + if (uploadArtifactEither.isRight()) { + log.debug(FAILED_TO_UPDATE_ARTIFACT); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse( + getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (IOException e) { + final String message = "failed to update artifact on resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPDATE_BY_API, + resourceCommonInfo, request, artifactDefinition, artifactUUID); + } + return responseWrapper.getInnerElement(); + } + + /** + * deletes an artifact of a resource or service + * + * @param assetType + * @param uuid + * @param artifactUUID + * @return + */ + @DELETE + @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "deletes an artifact of a resource or service", method = "DELETE", + summary = "deletes an artifact of a resource or service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact deleted", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @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 - SVC4086"), + @ApiResponse(responseCode = "409", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + public Response deleteArtifact( + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter( + description = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", + required = true) @PathParam("artifactUUID") final String artifactUUID) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); + ArtifactDefinition artifactDefinition = null; + if (componentType == null) { + log.debug("deleteArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("deleteArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("deleteArtifact: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.deleteArtifactOnComponentByUUID(request, componentType, uuid, + artifactUUID, resourceCommonInfo, artifactsBusinessLogic.new ArtifactOperationInfo(true, + false, ArtifactOperationEnum.DELETE)); + if (uploadArtifactEither.isRight()) { + log.debug("failed to delete artifact"); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse( + getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (IOException e) { + final String message = "failed to delete an artifact of a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_DELETE_BY_API, + resourceCommonInfo, request, artifactDefinition, artifactUUID); + } + return responseWrapper.getInnerElement(); + } + + /** + * deletes an artifact of a resource instance + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @return + */ + @DELETE + @Path("{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "deletes an artifact of a resource insatnce", method = "DELETE", + summary = "deletes an artifact of a resource insatnce", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact deleted", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", + description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @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 - SVC4086"), + @ApiResponse(responseCode = "409", + description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + public Response deleteArtifactOnResourceInstance( + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter( + description = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", + required = true) @PathParam("artifactUUID") final String artifactUUID, + @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", + required = true) @PathParam("resourceInstanceName") final String resourceInstanceName) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue); + if (componentType == null) { + log.debug("deleteArtifactOnResourceInsatnce: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("deleteArtifactOnResourceInsatnce: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("deleteArtifactOnResourceInsatnce: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + ArtifactDefinition artifactDefinition = null; + try { + if (responseWrapper.isEmpty()) { + Either uploadArtifactEither = + artifactsBusinessLogic.deleteArtifactOnRiByUUID(request, componentType, uuid, + resourceInstanceName, artifactUUID, artifactsBusinessLogic.new ArtifactOperationInfo( + true, false, ArtifactOperationEnum.DELETE)); + if (uploadArtifactEither.isRight()) { + log.debug("failed to delete artifact"); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, + GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse( + getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (IOException e) { + final String message = "failed to delete an artifact of a resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_DELETE_BY_API, + resourceCommonInfo, request, artifactDefinition, artifactUUID); + } + return responseWrapper.getInnerElement(); + } + + /** + * downloads an artifact of a component (either a service or a resource) by artifactUUID + * + * @param assetType + * @param uuid + * @param artifactUUID + * @return + */ + @GET + @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Operation(description = "Download component artifact", method = "GET", summary = "Returns downloaded artifact") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact downloaded", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "404", description = "Artifact was not found - SVC4505")}) + public Response downloadComponentArtifact( + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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 = {"resources,services"}),description = "The requested asset type", + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter( + description = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", + required = true) @PathParam("artifactUUID") final String artifactUUID) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + if (componentType == null) { + log.debug("downloadComponentArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("downloadComponentArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); + try { + if (responseWrapper.isEmpty()) { + Either downloadComponentArtifactEither = artifactsBusinessLogic + .downloadComponentArtifactByUUIDs(componentType, uuid, artifactUUID, resourceCommonInfo); + if (downloadComponentArtifactEither.isRight()) { + responseFormat = downloadComponentArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + byte[] value = downloadComponentArtifactEither.left().value(); + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers)); + } + } + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, resourceCommonInfo, + new DistributionData(instanceIdHeader, requestURI), requestId, artifactUUID, userId); + } + return responseWrapper.getInnerElement(); + } + + /** + * downloads an artifact of a resource instance of a component (either a service or a resource) by + * artifactUUID + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @param artifactUUID + * @return + */ + @GET + @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Operation(description = "Download resource instance artifact", method = "GET", + summary = "Returns downloaded artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact downloaded", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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 = "Specified resource is 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 or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(responseCode = "404", description = "Artifact was not found - SVC4505")}) + public Response downloadResourceInstanceArtifact( + @Parameter(description = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", + 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) @PathParam("assetType") final String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", + required = true) @PathParam("uuid") final String uuid, + @Parameter( + description = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", + required = true) @PathParam("artifactUUID") final String artifactUUID, + @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", + required = true) @PathParam("resourceInstanceName") final String resourceInstanceName) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + String componentTypeValue = componentType == null ? null : componentType.getValue(); + if (componentType == null) { + log.debug("downloadResourceInstanceArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("downloadResourceInstanceArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + try { + if (responseWrapper.isEmpty()) { + Either downloadResourceArtifactEither = + artifactsBusinessLogic.downloadResourceInstanceArtifactByUUIDs(componentType, uuid, + resourceInstanceName, artifactUUID); + if (downloadResourceArtifactEither.isRight()) { + responseFormat = downloadResourceArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + byte[] value = downloadResourceArtifactEither.left().value(); + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers)); + } + } + } catch (ComponentException e) { + responseFormat = getComponentsUtils().getResponseFormat(e); + } finally { + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, + new ResourceCommonInfo(resourceInstanceName, componentTypeValue), + new DistributionData(instanceIdHeader, requestURI), requestId, artifactUUID, userId); + } + return responseWrapper.getInnerElement(); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java index ebc0e62404..4c91ab4178 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java @@ -1,398 +1,451 @@ -/*- - * ============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.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentBusinessLogicProvider; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -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.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.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.common.util.GeneralUtility; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * This Servlet serves external users for retrieving component metadata. - * - * @author tgitelman - * - */ - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Asset Metadata External Servlet", description = "This Servlet serves external users for retrieving component metadata.") -@Singleton -public class AssetsDataServlet extends AbstractValidationsServlet { - - @Context - private HttpServletRequest request; - - private static final Logger log = Logger.getLogger(AssetsDataServlet.class); - private final ElementBusinessLogic elementBusinessLogic; - private final AssetMetadataConverter assetMetadataConverter; - private final ComponentBusinessLogicProvider componentBusinessLogicProvider; - - @Inject - public AssetsDataServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ElementBusinessLogic elementBusinessLogic, - AssetMetadataConverter assetMetadataConverter, - ComponentBusinessLogicProvider componentBusinessLogicProvider) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.elementBusinessLogic = elementBusinessLogic; - this.assetMetadataConverter = assetMetadataConverter; - this.componentBusinessLogicProvider = componentBusinessLogicProvider; - } - - /** - * - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param assetType - * @param category - * @param subCategory - * @param distributionStatus - * @param resourceType - * @return - */ - @GET - @Path("/{assetType}") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Fetch list of assets", httpMethod = "GET", notes = "Returns list of assets") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", response = AssetMetadata.class, responseContainer="List"), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response getAssetListExternal( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The filter key (resourceType only for resources)", required = false)@QueryParam("category") String category, - @ApiParam(value = "The filter key (resourceType only for resources)", required = false)@QueryParam("subCategory") String subCategory, - @ApiParam(value = "The filter key (resourceType only for resources)", required = false)@QueryParam("distributionStatus") String distributionStatus, - @ApiParam(value = "The filter key (resourceType only for resources)", required = false)@QueryParam("resourceType") String resourceType) { - - Response response = null; - ResponseFormat responseFormat = null; - String query = request.getQueryString(); - String requestURI = request.getRequestURI().endsWith("/")? - removeDuplicateSlashSeparator(request.getRequestURI()): request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("Start handle request of {}", url); - - AuditingActionEnum auditingActionEnum = query == null ? AuditingActionEnum.GET_ASSET_LIST : AuditingActionEnum.GET_FILTERED_ASSET_LIST; - - String resourceUrl = query == null ? requestURI : requestURI + "?" + query; - DistributionData distributionData = new DistributionData(instanceIdHeader, resourceUrl); - - // Mandatory - if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { - log.debug("getAssetList: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId); - return buildErrorResponse(responseFormat); - } - - try { - Map filters = new EnumMap<>(FilterKeyEnum.class); - - if (category != null) { - filters.put(FilterKeyEnum.CATEGORY, category); - } - if (subCategory != null) { - filters.put(FilterKeyEnum.SUB_CATEGORY, subCategory); - } - if (distributionStatus != null) { - filters.put(FilterKeyEnum.DISTRIBUTION_STATUS, distributionStatus); - } - if (resourceType != null) { - ResourceTypeEnum resourceTypeEnum = ResourceTypeEnum.getTypeIgnoreCase(resourceType); - if (resourceTypeEnum == null) { - log.debug("getAssetList: Asset Fetching Failed. Invalid resource type was received"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId); - return buildErrorResponse(responseFormat); - } - filters.put(FilterKeyEnum.RESOURCE_TYPE, resourceTypeEnum.name()); - } - - Either, ResponseFormat> assetTypeData = elementBusinessLogic.getFilteredCatalogComponents(assetType, filters, query); - - if (assetTypeData.isRight()) { - log.debug("getAssetList: Asset Fetching Failed"); - responseFormat = assetTypeData.right().value(); - getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId); - return buildErrorResponse(responseFormat); - } else { - log.debug("getAssetList: Asset Fetching Success"); - Either, ResponseFormat> resMetadata = assetMetadataConverter - .convertToAssetMetadata(assetTypeData.left().value(), requestURI, false); - if (resMetadata.isRight()) { - log.debug("getAssetList: Asset conversion Failed"); - responseFormat = resMetadata.right().value(); - getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId); - return buildErrorResponse(responseFormat); - } - Object result = RepresentationUtils.toRepresentation(resMetadata.left().value()); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId); - - response = buildOkResponse(responseFormat, result); - return response; - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch filtered list of assets"); - log.debug("getAssetList: Fetch list of assets failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /** - * - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param assetType - * @param uuid - * @return - */ - @GET - @Path("/{assetType}/{uuid}/metadata") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Detailed metadata of asset by uuid", httpMethod = "GET", notes = "Returns detailed metadata of an asset by uuid") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", response = AssetMetadata.class, responseContainer="List"), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response getAssetSpecificMetadataByUuidExternal( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The requested asset uuid", required = true)@PathParam("uuid") final String uuid) { - - Response response = null; - ResponseFormat responseFormat = null; - AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_ASSET_METADATA; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("Start handle request of {}", url); - - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue()); - DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI); - // Mandatory - if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { - log.debug("getAssetList: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - return buildErrorResponse(responseFormat); - } - - try { - Either, ResponseFormat> assetTypeData = - elementBusinessLogic.getCatalogComponentsByUuidAndAssetType(assetType, uuid); - - if (assetTypeData.isRight()) { - log.debug("getAssetList: Asset Fetching Failed"); - responseFormat = assetTypeData.right().value(); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - - return buildErrorResponse(responseFormat); - } - resourceCommonInfo.setResourceName(assetTypeData.left().value().iterator().next().getName()); - log.debug("getAssetList: Asset Fetching Success"); - Either, ResponseFormat> resMetadata = assetMetadataConverter - .convertToAssetMetadata(assetTypeData.left().value(), requestURI, true); - if (resMetadata.isRight()) { - log.debug("getAssetList: Asset conversion Failed"); - responseFormat = resMetadata.right().value(); - - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - return buildErrorResponse(responseFormat); - } - Object result = RepresentationUtils.toRepresentation(resMetadata.left().value().iterator().next()); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - - response = buildOkResponse(responseFormat, result); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch filtered list of assets"); - log.debug("getAssetList: Fetch list of assets failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /** - * - * @param requestId - * @param instanceIdHeader - * @param accept - * @param authorization - * @param assetType - * @param uuid - * @return - */ - @GET - @Path("/{assetType}/{uuid}/toscaModel") - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Fetch assets CSAR", httpMethod = "GET", notes = "Returns asset csar", response = String.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", response = String.class), - @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response getToscaModelExternal( - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam(value = "The requested asset uuid", required = true)@PathParam("uuid") final String uuid) { - - String url = request.getRequestURI(); - log.debug("Start handle request of {} {}", request.getMethod(), url); - Response response = null; - ResponseFormat responseFormat = null; - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_TOSCA_MODEL; - - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue()); - DistributionData distributionData = new DistributionData(instanceIdHeader, url); - - if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { - log.debug("getToscaModel: Missing X-ECOMP-InstanceID header"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - return buildErrorResponse(responseFormat); - } - - try { - ComponentBusinessLogic componentBL = componentBusinessLogicProvider.getInstance(componentType); - - - Either, ResponseFormat> csarArtifact = componentBL.getToscaModelByComponentUuid(componentType, uuid, resourceCommonInfo); - if (csarArtifact.isRight()) { - responseFormat = csarArtifact.right().value(); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - response = buildErrorResponse(responseFormat); - } else { - byte[] value = csarArtifact.left().value().getRight(); - InputStream is = new ByteArrayInputStream(value); - String contenetMD5 = GeneralUtility.calculateMD5Base64EncodedByByteArray(value); - Map headers = new HashMap<>(); - headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(csarArtifact.left().value().getLeft())); - headers.put(Constants.MD5_HEADER, contenetMD5); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - response = buildOkResponse(responseFormat, is, headers); - } - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get asset tosca model"); - log.debug("falied to get asset tosca model", e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - response = buildErrorResponse(responseFormat); - getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, - resourceCommonInfo, requestId, uuid); - return response; - } - } - - - private String removeDuplicateSlashSeparator(String requestUri) { - return requestUri.substring(0, requestUri.length()-1); - } - - -} +/*- + * ============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.ByteArrayInputStream; +import java.io.InputStream; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogicProvider; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +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.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.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.exception.ResponseFormat; +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; + +/** + * This Servlet serves external users for retrieving component metadata. + * + * @author tgitelman + * + */ + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +// for retrieving component metadata.") +@OpenAPIDefinition(info = @Info(title = "Asset Metadata External Servlet", + description = "This Servlet serves external users for retrieving component metadata.")) +@Singleton +public class AssetsDataServlet extends AbstractValidationsServlet { + + @Context + private HttpServletRequest request; + + private static final Logger log = Logger.getLogger(AssetsDataServlet.class); + private final ElementBusinessLogic elementBusinessLogic; + private final AssetMetadataConverter assetMetadataConverter; + private final ComponentBusinessLogicProvider componentBusinessLogicProvider; + + @Inject + public AssetsDataServlet(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager, + ElementBusinessLogic elementBusinessLogic, AssetMetadataConverter assetMetadataConverter, + ComponentBusinessLogicProvider componentBusinessLogicProvider) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.elementBusinessLogic = elementBusinessLogic; + this.assetMetadataConverter = assetMetadataConverter; + this.componentBusinessLogicProvider = componentBusinessLogicProvider; + } + + /** + * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param assetType + * @param category + * @param subCategory + * @param distributionStatus + * @param resourceType + * @return + */ + @GET + @Path("/{assetType}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Fetch list of assets", method = "GET", summary = "Returns list of assets") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", + 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 = "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")}) + public Response getAssetListExternal( + @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",schema = @Schema(allowableValues = {"resources", "services"}), + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The filter key (resourceType only for resources)", + required = false) @QueryParam("category") String category, + @Parameter(description = "The filter key (resourceType only for resources)", + required = false) @QueryParam("subCategory") String subCategory, + @Parameter(description = "The filter key (resourceType only for resources)", + required = false) @QueryParam("distributionStatus") String distributionStatus, + @Parameter(description = "The filter key (resourceType only for resources)", + required = false) @QueryParam("resourceType") String resourceType) { + + Response response = null; + ResponseFormat responseFormat = null; + String query = request.getQueryString(); + String requestURI = + request.getRequestURI().endsWith("/") ? removeDuplicateSlashSeparator(request.getRequestURI()) + : request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + + AuditingActionEnum auditingActionEnum = + query == null ? AuditingActionEnum.GET_ASSET_LIST : AuditingActionEnum.GET_FILTERED_ASSET_LIST; + + String resourceUrl = query == null ? requestURI : requestURI + "?" + query; + DistributionData distributionData = new DistributionData(instanceIdHeader, resourceUrl); + + // Mandatory + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("getAssetList: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, + requestId); + return buildErrorResponse(responseFormat); + } + + try { + Map filters = new EnumMap<>(FilterKeyEnum.class); + + if (category != null) { + filters.put(FilterKeyEnum.CATEGORY, category); + } + if (subCategory != null) { + filters.put(FilterKeyEnum.SUB_CATEGORY, subCategory); + } + if (distributionStatus != null) { + filters.put(FilterKeyEnum.DISTRIBUTION_STATUS, distributionStatus); + } + if (resourceType != null) { + ResourceTypeEnum resourceTypeEnum = ResourceTypeEnum.getTypeIgnoreCase(resourceType); + if (resourceTypeEnum == null) { + log.debug("getAssetList: Asset Fetching Failed. Invalid resource type was received"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, + requestId); + return buildErrorResponse(responseFormat); + } + filters.put(FilterKeyEnum.RESOURCE_TYPE, resourceTypeEnum.name()); + } + + Either, ResponseFormat> assetTypeData = + elementBusinessLogic.getFilteredCatalogComponents(assetType, filters, query); + + if (assetTypeData.isRight()) { + log.debug("getAssetList: Asset Fetching Failed"); + responseFormat = assetTypeData.right().value(); + getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, + requestId); + return buildErrorResponse(responseFormat); + } else { + log.debug("getAssetList: Asset Fetching Success"); + Either, ResponseFormat> resMetadata = + assetMetadataConverter.convertToAssetMetadata(assetTypeData.left().value(), requestURI, false); + if (resMetadata.isRight()) { + log.debug("getAssetList: Asset conversion Failed"); + responseFormat = resMetadata.right().value(); + getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, + requestId); + return buildErrorResponse(responseFormat); + } + Object result = RepresentationUtils.toRepresentation(resMetadata.left().value()); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, + requestId); + + response = buildOkResponse(responseFormat, result); + return response; + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch filtered list of assets"); + log.debug("getAssetList: Fetch list of assets failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /** + * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param assetType + * @param uuid + * @return + */ + @GET + @Path("/{assetType}/{uuid}/metadata") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Detailed metadata of asset by uuid", method = "GET", + summary = "Returns detailed metadata of an asset by uuid") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", + 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")}) + public Response getAssetSpecificMetadataByUuidExternal( + @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",schema = @Schema(allowableValues = {"resources", "services"}), + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The requested asset uuid", + required = true) @PathParam("uuid") final String uuid) { + + Response response = null; + ResponseFormat responseFormat = null; + AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_ASSET_METADATA; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue()); + DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI); + // Mandatory + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("getAssetList: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + return buildErrorResponse(responseFormat); + } + + try { + Either, ResponseFormat> assetTypeData = + elementBusinessLogic.getCatalogComponentsByUuidAndAssetType(assetType, uuid); + + if (assetTypeData.isRight()) { + log.debug("getAssetList: Asset Fetching Failed"); + responseFormat = assetTypeData.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + + return buildErrorResponse(responseFormat); + } + resourceCommonInfo.setResourceName(assetTypeData.left().value().iterator().next().getName()); + log.debug("getAssetList: Asset Fetching Success"); + Either, ResponseFormat> resMetadata = + assetMetadataConverter.convertToAssetMetadata(assetTypeData.left().value(), requestURI, true); + if (resMetadata.isRight()) { + log.debug("getAssetList: Asset conversion Failed"); + responseFormat = resMetadata.right().value(); + + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + return buildErrorResponse(responseFormat); + } + Object result = RepresentationUtils.toRepresentation(resMetadata.left().value().iterator().next()); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + + response = buildOkResponse(responseFormat, result); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch filtered list of assets"); + log.debug("getAssetList: Fetch list of assets failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /** + * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization + * @param assetType + * @param uuid + * @return + */ + @GET + @Path("/{assetType}/{uuid}/toscaModel") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Operation(description = "Fetch assets CSAR", method = "GET", summary = "Returns asset csar", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.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")}) + public Response getToscaModelExternal( + @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",schema = @Schema(allowableValues = {"resources", "services"}), + required = true) @PathParam("assetType") final String assetType, + @Parameter(description = "The requested asset uuid", + required = true) @PathParam("uuid") final String uuid) { + + String url = request.getRequestURI(); + log.debug("Start handle request of {} {}", request.getMethod(), url); + Response response = null; + ResponseFormat responseFormat = null; + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_TOSCA_MODEL; + + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue()); + DistributionData distributionData = new DistributionData(instanceIdHeader, url); + + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("getToscaModel: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + return buildErrorResponse(responseFormat); + } + + try { + ComponentBusinessLogic componentBL = componentBusinessLogicProvider.getInstance(componentType); + + + Either, ResponseFormat> csarArtifact = + componentBL.getToscaModelByComponentUuid(componentType, uuid, resourceCommonInfo); + if (csarArtifact.isRight()) { + responseFormat = csarArtifact.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = csarArtifact.left().value().getRight(); + InputStream is = new ByteArrayInputStream(value); + String contenetMD5 = GeneralUtility.calculateMD5Base64EncodedByByteArray(value); + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, + getContentDispositionValue(csarArtifact.left().value().getLeft())); + headers.put(Constants.MD5_HEADER, contenetMD5); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get asset tosca model"); + log.debug("falied to get asset tosca model", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + response = buildErrorResponse(responseFormat); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, + resourceCommonInfo, requestId, uuid); + return response; + } + } + + + private String removeDuplicateSlashSeparator(String requestUri) { + return requestUri.substring(0, requestUri.length() - 1); + } + + +} 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 26b91a3625..b4c9c42867 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,527 +1,585 @@ -/*- - * ============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.annotations.*; -import javax.inject.Inject; -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.GroupBusinessLogic; -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 javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -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") -@Api(value = "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) - @ApiOperation(value = "creates a resource", httpMethod = "POST", notes = "Creates a resource") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "ECOMP component is authenticated and Asset created", response = Resource.class), - @ApiResponse(code = 400, message = "Missing X-ECOMP-InstanceID HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "The name provided for the newly created resource is already in use for another resource in SDC - SVC4050"), - @ApiResponse(code = 400, message = "Invalid field format. One of the provided fields does not comply with the field rules - SVC4126"), - @ApiResponse(code = 400, message = "Missing request body. The post request did not contain the expected body - SVC4500"), - @ApiResponse(code = 400, message = "The resource name is missing in the request body - SVC4062"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT description has wrong format - SVC4064"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT description has wrong format (exceeds limit) - SVC4065"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT tags exceeds character limit - SVC4066"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor name exceeds character limit - SVC4067"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor release exceeds character limit - SVC4068"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT ATT Contact has wrong format - SVC4069"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT name has wrong format - SVC4070"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor name has wrong format - SVC4071"), - @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor release has wrong format - SVC4072"), - @ApiResponse(code = 400, message = "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( - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The user id", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, - @ApiParam( hidden = true) String data) { - - init(); - - Wrapper 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 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) - @ApiOperation(value = "Change Resource lifecycle State", httpMethod = "POST") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Resource state changed", response = AssetMetadata.class), - @ApiResponse(code = 400, message = "Missing X-ECOMP-InstanceID HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 403, message = "Asset is already checked-out by another user - SVC4085"), - @ApiResponse(code = 403, message = "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( - @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The user id", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(allowableValues = "checkout, checkin", required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition, - @ApiParam(value = "id of component to be changed") @PathParam(value = "uuid") final String uuid, - @ApiParam(value = "validValues: resources / services ", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam(value = "assetType") final String assetType, - @ApiParam( 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 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 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 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 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 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 responseWrapper) throws IOException { - ResponseFormat responseFormat; - Response response; - Either 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 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, 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, ActionStatus> allResourceCategories, - Wrapper responseWrapper) { - Optional 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 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 runValidations(final String assetType) { - Wrapper 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 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 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 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 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 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 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 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 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 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 responseWrapper) throws IOException { + ResponseFormat responseFormat; + Response response; + Either 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 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, 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, ActionStatus> allResourceCategories, + Wrapper responseWrapper) { + Optional 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 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 runValidations(final String assetType) { + Wrapper 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 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/externalapi/servlet/ServiceActivationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ServiceActivationServlet.java index 6f00168a77..32fb87419c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ServiceActivationServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ServiceActivationServlet.java @@ -1,200 +1,225 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.annotations.*; -import javax.inject.Inject; -import org.apache.commons.lang3.StringUtils; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo; -import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionRespInfo; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData; -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.common.api.Constants; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; - -/** - * Created by chaya on 10/17/2017. - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Service Activation External Servlet", description = "This Servlet serves external users for activating a specific service") -@Singleton -public class ServiceActivationServlet extends AbstractValidationsServlet { - - @Context - private HttpServletRequest request; - - private static final Logger log = Logger.getLogger(ServiceActivationServlet.class); - private final ServiceBusinessLogic serviceBusinessLogic; - - @Inject - public ServiceActivationServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ServiceBusinessLogic serviceBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.serviceBusinessLogic = serviceBusinessLogic; - } - - - /** - * Activates a service on a specific environment - * - * @param serviceUUID - * @param opEnvId - * @param userId - * @param instanceIdHeader - * @return - */ - @POST - @Path("/services/{serviceUUID}/distribution/{opEnvId}/activate") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "activate a service", httpMethod = "POST", notes = "Activates a service") - @ApiResponses(value = { - @ApiResponse(code = 202, message = "ECOMP component is authenticated and required service may be distributed"), - @ApiResponse(code = 400, message = "Missing X-ECOMP-InstanceID HTTP header - POL5001"), - @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), - @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), - @ApiResponse(code = 500, message = "The request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"), - @ApiResponse(code = 400, message = "Invalid field format. One of the provided fields does not comply with the field rules - SVC4126"), - @ApiResponse(code = 400, message = "Missing request body. The post request did not contain the expected body - SVC4500"), - @ApiResponse(code = 400, message = "The resource name is missing in the request body - SVC4062"), - @ApiResponse(code = 409, message = "Service state is invalid for this action"), - @ApiResponse(code = 502, message = "The server was acting as a gateway or proxy and received an invalid response from the upstream server")}) - public Response activateServiceExternal( - @ApiParam(value = "Determines the format of the body of the request", required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType, - @ApiParam(value = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @ApiParam(value = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @ApiParam(value = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @ApiParam(value = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @ApiParam(value = "The serviceUUid to activate", required = true) @PathParam("serviceUUID") final String serviceUUID, - @ApiParam(value = "The operational environment on which to activate the service on", required = true) @PathParam("opEnvId") final String opEnvId, - String data) { - - init(); - - ResponseFormat responseFormat = null; - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("Start handle request of {}", url); - - User modifier = new User(); - - try { - - Wrapper responseWrapper = validateRequestHeaders(instanceIdHeader, userId); - - if (responseWrapper.isEmpty()) { - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - ServiceDistributionReqInfo reqMetadata = convertJsonToActivationMetadata(data); - Either distResponse = serviceBusinessLogic.activateServiceOnTenantEnvironment(serviceUUID, opEnvId, modifier, reqMetadata); - - if (distResponse.isRight()) { - log.debug("failed to activate service distribution"); - responseFormat = distResponse.right().value(); - return buildErrorResponse(responseFormat); - } - String distributionId = distResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(new ServiceDistributionRespInfo(distributionId)); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.ACCEPTED); - return buildOkResponse(responseFormat, result); - } else { - log.debug("request instanceId/userId header validation failed"); - responseFormat = responseWrapper.getInnerElement(); - return buildErrorResponse(responseFormat); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Activate Distribution"); - log.debug("activate distribution failed with exception", e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } finally { - getComponentsUtils().auditExternalActivateService(responseFormat, - new DistributionData(instanceIdHeader, requestURI), requestId, serviceUUID, modifier); - } - } - - private Wrapper validateRequestHeaders(String instanceIdHeader, String userId) { - Wrapper responseWrapper = new Wrapper<>(); - if (responseWrapper.isEmpty()) { - validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); - } - if (responseWrapper.isEmpty()) { - validateHttpCspUserIdHeader(userId, responseWrapper); - } - return responseWrapper; - } - - private ServiceDistributionReqInfo convertJsonToActivationMetadata(String data) { - ObjectMapper mapper = new ObjectMapper(); - try { - return mapper.readValue(data, ServiceDistributionReqInfo.class); - } catch (IOException e) { - log.error("#convertJsonToActivationMetadata - json deserialization failed with error: ", e); - return new ServiceDistributionReqInfo(null); - } - } - - @Override - protected void validateHttpCspUserIdHeader(String header, Wrapper responseWrapper) { - ResponseFormat responseFormat; - if( StringUtils.isEmpty(header)){ - log.debug("MissingUSER_ID"); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED); - responseWrapper.setInnerElement(responseFormat); - } - } -} - - - +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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 javax.inject.Inject; +import javax.inject.Singleton; +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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo; +import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionRespInfo; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData; +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.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +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.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +/** + * Created by chaya on 10/17/2017. + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Service Activation External Servlet", description = "This Servlet serves external users for activating a specific service")) +@Singleton +public class ServiceActivationServlet extends AbstractValidationsServlet { + + @Context + private HttpServletRequest request; + + private static final Logger log = Logger.getLogger(ServiceActivationServlet.class); + private final ServiceBusinessLogic serviceBusinessLogic; + + @Inject + public ServiceActivationServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + ServiceBusinessLogic serviceBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.serviceBusinessLogic = serviceBusinessLogic; + } + + + /** + * Activates a service on a specific environment + * + * @param serviceUUID + * @param opEnvId + * @param userId + * @param instanceIdHeader + * @return + */ + @POST + @Path("/services/{serviceUUID}/distribution/{opEnvId}/activate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "activate a service", method = "POST", summary = "Activates a service") + @ApiResponses(value = { + @ApiResponse(responseCode = "202", + description = "ECOMP component is authenticated and required service may be distributed"), + @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 request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @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 = "409", description = "Service state is invalid for this action"), + @ApiResponse(responseCode = "502", + description = "The server was acting as a gateway or proxy and received an invalid response from the upstream server")}) + public Response activateServiceExternal( + @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 serviceUUid to activate", + required = true) @PathParam("serviceUUID") final String serviceUUID, + @Parameter(description = "The operational environment on which to activate the service on", + required = true) @PathParam("opEnvId") final String opEnvId, + String data) { + + init(); + + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + + User modifier = new User(); + + try { + + Wrapper responseWrapper = validateRequestHeaders(instanceIdHeader, userId); + + if (responseWrapper.isEmpty()) { + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + ServiceDistributionReqInfo reqMetadata = convertJsonToActivationMetadata(data); + Either distResponse = serviceBusinessLogic + .activateServiceOnTenantEnvironment(serviceUUID, opEnvId, modifier, reqMetadata); + + if (distResponse.isRight()) { + log.debug("failed to activate service distribution"); + responseFormat = distResponse.right().value(); + return buildErrorResponse(responseFormat); + } + String distributionId = distResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(new ServiceDistributionRespInfo(distributionId)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.ACCEPTED); + return buildOkResponse(responseFormat, result); + } else { + log.debug("request instanceId/userId header validation failed"); + responseFormat = responseWrapper.getInnerElement(); + return buildErrorResponse(responseFormat); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Activate Distribution"); + log.debug("activate distribution failed with exception", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } finally { + getComponentsUtils().auditExternalActivateService(responseFormat, + new DistributionData(instanceIdHeader, requestURI), requestId, serviceUUID, modifier); + } + } + + private Wrapper validateRequestHeaders(String instanceIdHeader, String userId) { + Wrapper responseWrapper = new Wrapper<>(); + if (responseWrapper.isEmpty()) { + validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); + } + if (responseWrapper.isEmpty()) { + validateHttpCspUserIdHeader(userId, responseWrapper); + } + return responseWrapper; + } + + private ServiceDistributionReqInfo convertJsonToActivationMetadata(String data) { + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.readValue(data, ServiceDistributionReqInfo.class); + } catch (IOException e) { + log.error("#convertJsonToActivationMetadata - json deserialization failed with error: ", e); + return new ServiceDistributionReqInfo(null); + } + } + + @Override + protected void validateHttpCspUserIdHeader(String header, Wrapper responseWrapper) { + ResponseFormat responseFormat; + if( StringUtils.isEmpty(header)){ + log.debug("MissingUSER_ID"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED); + responseWrapper.setInnerElement(responseFormat); + } + } +} + + + diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java index 2583797598..c137e6f072 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java @@ -1,522 +1,609 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.AdditionalInformationBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo; -import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.AdditionalInformationDefinition; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Additional Information Servlet", description = "Additional Information Servlet") -@Singleton -public class AdditionalInformationServlet extends BeGenericServlet { - - private static final Logger log = Logger.getLogger(AdditionalInformationServlet.class); - private final AdditionalInformationBusinessLogic businessLogic; - - @Inject - public AdditionalInformationServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - AdditionalInformationBusinessLogic businessLogic) { - super(userBusinessLogic, componentsUtils); - this.businessLogic = businessLogic; - } - - /** - * - * @param resourceId - * @param data - * @param request - * @param userUserId - * @return - */ - @POST - @Path("/resources/{resourceId}/additionalinfo") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "POST", notes = "Returns created Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Additional information created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response createResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userUserId) { - - return createAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, request, userUserId, data); - - } - - /** - * - * @param serviceId - * @param data - * @param request - * @param userUserId - * @return - */ - @POST - @Path("/services/{serviceId}/additionalinfo") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "POST", notes = "Returns created Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Additional information created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response createServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userUserId) { - - return createAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, request, userUserId, data); - - } - - /** - * - * @param resourceId - * @param labelId - * @param data - * @param request - * @param userId - * @return - */ - @PUT - @Path("/resources/{resourceId}/additionalinfo/{labelId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Additional Information Label and Value", httpMethod = "PUT", notes = "Returns updated Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response updateResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return updateAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId, data); - - } - - /** - * - * @param serviceId - * @param labelId - * @param data - * @param request - * @param userId - * @return - */ - @PUT - @Path("/services/{serviceId}/additionalinfo/{labelId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Additional Information Label and Value", httpMethod = "PUT", notes = "Returns updated Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response updateServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return updateAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId, data); - - } - - /** - * - * @param resourceId - * @param labelId - * @param request - * @param userId - * @return - */ - @DELETE - @Path("/resources/{resourceId}/additionalinfo/{labelId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "DELETE", notes = "Returns deleted Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response updateResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return deleteAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId); - - } - - /** - * - * @param serviceId - * @param labelId - * @param request - * @param userId - * @return - */ - @DELETE - @Path("/services/{serviceId}/additionalinfo/{labelId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "DELETE", notes = "Returns deleted Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response deleteServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return deleteAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId); - - } - - /** - * - * @param resourceId - * @param labelId - * @param request - * @param userId - * @return - */ - @GET - @Path("/resources/{resourceId}/additionalinfo/{labelId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Additional Information by id", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "fetched additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response getResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId); - - } - - /** - * - * @param serviceId - * @param labelId - * @param request - * @param userId - * @return - */ - @GET - @Path("/services/{serviceId}/additionalinfo/{labelId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Additional Information by id", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "fetched additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response getServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId); - - } - - /** - * - * @param resourceId - * @param request - * @param userId - * @return - */ - @GET - @Path("/resources/{resourceId}/additionalinfo") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get all Additional Information under resource", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "list of additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response getAllResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getAllAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, request, userId); - - } - - /** - * - * @param serviceId - * @param request - * @param userId - * @return - */ - @GET - @Path("/services/{serviceId}/additionalinfo") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get all Additional Information under service", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "list of additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Additional information key already exist") }) - public Response getAllServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getAllAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, request, userId); - - } - - /** - * - * Create additional information property under given resource/service - * - * @param nodeType - * @param uniqueId - * @param request - * @param userId - * @param data - * @return - */ - protected Response createAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, HttpServletRequest request, String userId, String data) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - log.debug("modifier id is {}", userId); - log.debug("data is {}", data); - - try { - // convert json to AdditionalInfoParameterInfo - AdditionalInfoParameterInfo additionalInfoParameterInfo = gson.fromJson(data, AdditionalInfoParameterInfo.class); - - Either either = businessLogic.createAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); - - if (either.isRight()) { - ResponseFormat responseFormat = either.right().value(); - log.info("Failed to create additional information {}. Reason - {}", additionalInfoParameterInfo, responseFormat); - return buildErrorResponse(responseFormat); - } - - AdditionalInfoParameterInfo createdAI = either.left().value(); - - log.debug("Additional information {}={} created successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); - return buildOkResponse(responseFormat, createdAI); - - } catch (Exception e) { - log.debug("Create additional information failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - - } - - /** - * Update additional information property by id under given resource/service - * - * @param nodeType - * @param uniqueId - * @param labelId - * @param request - * @param userId - * @param data - * @return - */ - protected Response updateAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId, String data) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - log.debug("modifier id is {}", userId); - log.debug("data is {}", data); - - try { - // convert json to AdditionalInfoParameterInfo - AdditionalInfoParameterInfo additionalInfoParameterInfo = gson.fromJson(data, AdditionalInfoParameterInfo.class); - - additionalInfoParameterInfo.setUniqueId(labelId); - - Either either = businessLogic.updateAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); - - if (either.isRight()) { - ResponseFormat responseFormat = either.right().value(); - log.info("Failed to update additional information property. Reason - {}", responseFormat); - return buildErrorResponse(responseFormat); - } - - AdditionalInfoParameterInfo createdAI = either.left().value(); - - log.debug("Additional information {}={} updated successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - return buildOkResponse(responseFormat, createdAI); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Additional Information"); - log.debug("Update additional information failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - - } - - /** - * - * Delete an additional information property by id under given resource/service - * - * @param nodeType - * @param uniqueId - * @param labelId - * @param request - * @param userId - * @return - */ - protected Response deleteAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - log.debug("modifier id is {}", userId); - - try { - - AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); - additionalInfoParameterInfo.setUniqueId(labelId); - - Either either = businessLogic.deleteAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); - - if (either.isRight()) { - ResponseFormat responseFormat = either.right().value(); - log.info("Failed to update additional information property. Reason - {}", responseFormat); - return buildErrorResponse(responseFormat); - } - - AdditionalInfoParameterInfo createdAI = either.left().value(); - - log.debug("Additional information {}={} deleted successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - return buildOkResponse(responseFormat, createdAI); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Additional Information"); - log.debug("Delete additional information failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - - } - - /** - * Get a specific additional information property by a given id under given resource/service - * - * @param nodeType - * @param uniqueId - * @param labelId - * @param request - * @param userId - * @return - */ - protected Response getAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - log.debug("modifier id is {}", userId); - - try { - - AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); - additionalInfoParameterInfo.setUniqueId(labelId); - - Either either = businessLogic.getAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); - - if (either.isRight()) { - ResponseFormat responseFormat = either.right().value(); - log.info("Failed to update additional information property. Reason - {}", responseFormat); - return buildErrorResponse(responseFormat); - } - - AdditionalInfoParameterInfo createdAI = either.left().value(); - - log.debug("Additional information {}={} fetched successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - return buildOkResponse(responseFormat, createdAI); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Additional Information"); - - log.debug("get additional information failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - - } - - /** - * Get all additional information properties under given resource/service - * - * @param nodeType - * @param uniqueId - * @param request - * @param userId - * @return - */ - protected Response getAllAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, HttpServletRequest request, String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - log.debug("modifier id is {}", userId); - - try { - Either either = businessLogic.getAllAdditionalInformation(nodeType, uniqueId, userId); - if (either.isRight()) { - ResponseFormat responseFormat = either.right().value(); - log.info("Failed to update additional information property. Reason - {}", responseFormat); - return buildErrorResponse(responseFormat); - } - - AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); - - log.debug("All Additional information retrieved for component {} is {}", uniqueId, additionalInformationDefinition); - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - return buildOkResponse(responseFormat, additionalInformationDefinition); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Additional Information"); - log.debug("Get all addiotanl information properties failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - - } - -} +/*- + * ============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.servlets; + +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.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.AdditionalInformationBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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 = "Additional Information Servlet", description = "Additional Information Servlet")) +@Singleton +public class AdditionalInformationServlet extends BeGenericServlet { + + private static final Logger log = Logger.getLogger(AdditionalInformationServlet.class); + private final AdditionalInformationBusinessLogic businessLogic; + + @Inject + public AdditionalInformationServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + AdditionalInformationBusinessLogic businessLogic) { + super(userBusinessLogic, componentsUtils); + this.businessLogic = businessLogic; + } + + /** + * + * @param resourceId + * @param data + * @param request + * @param userUserId + * @return + */ + @POST + @Path("/resources/{resourceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Additional Information Label and Value", method = "POST", + summary = "Returns created Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Additional information created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response createResourceAdditionalInformationLabel( + @Parameter(description = "resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "Additional information key value to be created", required = true) String data, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userUserId) { + + return createAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, request, userUserId, + data); + + } + + /** + * + * @param serviceId + * @param data + * @param request + * @param userUserId + * @return + */ + @POST + @Path("/services/{serviceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Additional Information Label and Value", method = "POST", + summary = "Returns created Additional Inforamtion property",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Additional information created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response createServiceAdditionalInformationLabel( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "Additional information key value to be created", required = true) String data, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userUserId) { + + return createAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, request, userUserId, data); + + } + + /** + * + * @param resourceId + * @param labelId + * @param data + * @param request + * @param userId + * @return + */ + @PUT + @Path("/resources/{resourceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Additional Information Label and Value", method = "PUT", + summary = "Returns updated Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Additional information updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response updateResourceAdditionalInformationLabel( + @Parameter(description = "resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "label id", required = true) @PathParam("labelId") final String labelId, + @Parameter(description = "Additional information key value to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return updateAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId, + data); + + } + + /** + * + * @param serviceId + * @param labelId + * @param data + * @param request + * @param userId + * @return + */ + @PUT + @Path("/services/{serviceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Additional Information Label and Value", method = "PUT", + summary = "Returns updated Additional Inforamtion property",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Additional information updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response updateServiceAdditionalInformationLabel( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "label id", required = true) @PathParam("labelId") final String labelId, + @Parameter(description = "Additional information key value to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return updateAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId, + data); + + } + + /** + * + * @param resourceId + * @param labelId + * @param request + * @param userId + * @return + */ + @DELETE + @Path("/resources/{resourceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Additional Information Label and Value", method = "DELETE", + summary = "Returns deleted Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Additional information deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response updateResourceAdditionalInformationLabel( + @Parameter(description = "resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "label id", required = true) @PathParam("labelId") final String labelId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return deleteAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, + userId); + + } + + /** + * + * @param serviceId + * @param labelId + * @param request + * @param userId + * @return + */ + @DELETE + @Path("/services/{serviceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Additional Information Label and Value", method = "DELETE", + summary = "Returns deleted Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Additional information deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response deleteServiceAdditionalInformationLabel( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "label id", required = true) @PathParam("labelId") final String labelId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return deleteAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId); + + } + + /** + * + * @param resourceId + * @param labelId + * @param request + * @param userId + * @return + */ + @GET + @Path("/resources/{resourceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Additional Information by id", method = "GET", + summary = "Returns Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "fetched additional information"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response getResourceAdditionalInformationLabel( + @Parameter(description = "resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "label id", required = true) @PathParam("labelId") final String labelId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId); + + } + + /** + * + * @param serviceId + * @param labelId + * @param request + * @param userId + * @return + */ + @GET + @Path("/services/{serviceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Additional Information by id", method = "GET", + summary = "Returns Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "fetched additional information"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response getServiceAdditionalInformationLabel( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "label id", required = true) @PathParam("labelId") final String labelId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId); + + } + + /** + * + * @param resourceId + * @param request + * @param userId + * @return + */ + @GET + @Path("/resources/{resourceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get all Additional Information under resource", method = "GET", + summary = "Returns Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "list of additional information"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response getAllResourceAdditionalInformationLabel( + @Parameter(description = "resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAllAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, request, userId); + + } + + /** + * + * @param serviceId + * @param request + * @param userId + * @return + */ + @GET + @Path("/services/{serviceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get all Additional Information under service", method = "GET", + summary = "Returns Additional Inforamtion property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "list of additional information"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Additional information key already exist")}) + public Response getAllServiceAdditionalInformationLabel( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAllAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, request, userId); + + } + + /** + * + * Create additional information property under given resource/service + * + * @param nodeType + * @param uniqueId + * @param request + * @param userId + * @param data + * @return + */ + protected Response createAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, HttpServletRequest request, String userId, String data) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + log.debug("data is {}", data); + + try { + // convert json to AdditionalInfoParameterInfo + AdditionalInfoParameterInfo additionalInfoParameterInfo = gson.fromJson(data, AdditionalInfoParameterInfo.class); + + Either either = businessLogic.createAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to create additional information {}. Reason - {}", additionalInfoParameterInfo, responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} created successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + log.debug("Create additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * Update additional information property by id under given resource/service + * + * @param nodeType + * @param uniqueId + * @param labelId + * @param request + * @param userId + * @param data + * @return + */ + protected Response updateAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId, String data) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + log.debug("data is {}", data); + + try { + // convert json to AdditionalInfoParameterInfo + AdditionalInfoParameterInfo additionalInfoParameterInfo = gson.fromJson(data, AdditionalInfoParameterInfo.class); + + additionalInfoParameterInfo.setUniqueId(labelId); + + Either either = businessLogic.updateAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} updated successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Additional Information"); + log.debug("Update additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * + * Delete an additional information property by id under given resource/service + * + * @param nodeType + * @param uniqueId + * @param labelId + * @param request + * @param userId + * @return + */ + protected Response deleteAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); + additionalInfoParameterInfo.setUniqueId(labelId); + + Either either = businessLogic.deleteAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} deleted successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Additional Information"); + log.debug("Delete additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * Get a specific additional information property by a given id under given resource/service + * + * @param nodeType + * @param uniqueId + * @param labelId + * @param request + * @param userId + * @return + */ + protected Response getAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); + additionalInfoParameterInfo.setUniqueId(labelId); + + Either either = businessLogic.getAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} fetched successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Additional Information"); + + log.debug("get additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * Get all additional information properties under given resource/service + * + * @param nodeType + * @param uniqueId + * @param request + * @param userId + * @return + */ + protected Response getAllAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, HttpServletRequest request, String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + Either either = businessLogic.getAllAdditionalInformation(nodeType, uniqueId, userId); + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + + log.debug("All Additional information retrieved for component {} is {}", uniqueId, additionalInformationDefinition); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, additionalInformationDefinition); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Additional Information"); + log.debug("Get all addiotanl information properties failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArchiveEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArchiveEndpoint.java index 423181a3a5..3dd582c07e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArchiveEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArchiveEndpoint.java @@ -1,178 +1,186 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ArchiveBusinessLogic; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.model.catalog.CatalogComponent; -import org.openecomp.sdc.common.api.Constants; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestBody; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Archive Endpoint") -@Controller -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class ArchiveEndpoint { - - private final ArchiveBusinessLogic archiveBusinessLogic; - - @Inject - public ArchiveEndpoint(ArchiveBusinessLogic archiveBusinessLogic) { - this.archiveBusinessLogic = archiveBusinessLogic; - } - - @POST - @Path("/resources/{componentId}/archive") - @ApiOperation(value = "Archive Resource", httpMethod = "POST", notes = "Marks a resource as archived. Can be restored with restore action", response = String.class, responseContainer = "") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Archive successful"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Resource not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Response archiveResources(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - archiveBusinessLogic.archiveComponent(ComponentTypeEnum.RESOURCE_PARAM_NAME, userId, componentId); - return Response.ok().build(); - } - - @POST - @Path("/resources/{componentId}/restore") - @ApiOperation(value = "Restore Resource", httpMethod = "POST", notes = "Restores a resource from archive.", response = String.class, responseContainer = "") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Restore successful"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Resource not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Response restoreResource(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - archiveBusinessLogic.restoreComponent(ComponentTypeEnum.RESOURCE_PARAM_NAME, userId, componentId); - return Response.ok().build(); - } - - @POST - @Path("/services/{componentId}/archive") - @ApiOperation(value = "Archive Service", httpMethod = "POST", notes = "Marks a service as archived. Can be restored with restore action", response = String.class, responseContainer = "") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Archive successful"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Service not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Response archiveService(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - archiveBusinessLogic.archiveComponent(ComponentTypeEnum.SERVICE_PARAM_NAME, userId, componentId); - return Response.ok().build(); - } - - - @POST - @Path("/services/{componentId}/restore") - @ApiOperation(value = "Restore Service", httpMethod = "POST", notes = "Restores a service from archive.", response = String.class, responseContainer = "") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Restore successful"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Service not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Response restoreService(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - archiveBusinessLogic.restoreComponent(ComponentTypeEnum.SERVICE_PARAM_NAME, userId, componentId); - return Response.ok().build(); - } - - @GET - @Path("/archive") - @ApiOperation(value = "Get all Archived Components", httpMethod = "GET", notes = "Get all Archived Components", response = String.class, responseContainer = "") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Map> getArchivedComponents(@HeaderParam(value = Constants.USER_ID_HEADER) String userId){ - return this.archiveBusinessLogic.getArchiveComponents(userId, new LinkedList<>()); - } - - @POST - @Path("/notif/vsp/archived") - @ApiOperation(value = "Notify about an archived VSP. All VFs with relation to the given CSAR IDs will be martked as vspArchived=true", httpMethod = "POST") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 500, message = "Internal Error. A list of the failed CSAR IDs may be returned.") - }) - public Response onVspArchived(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @RequestBody List csarIds){ - List failedCsarIds = this.archiveBusinessLogic.onVspArchive(userId, csarIds); - if (!failedCsarIds.isEmpty()){ - //There are some failed CSAR IDs, return 500 and the list of failed CSAR IDs - Map> entity = new HashMap<>(); - entity.put("failedIds", failedCsarIds); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(entity) - .build(); - } - return Response.ok().build(); - } - - @POST - @Path("/notif/vsp/restored") - @ApiOperation(value = "Notify about a restored VSP. All VFs with relation to the given CSAR IDs will be martked as vspArchived=false", httpMethod = "POST") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Success"), - @ApiResponse(code = 400, message = "Bad request"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 500, message = "Internal Error. A list of the failed CSAR IDs may be returned.") - }) - public Response onVspRestored(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @RequestBody List csarIds){ - List failedCsarIds = this.archiveBusinessLogic.onVspRestore(userId, csarIds); - if (!failedCsarIds.isEmpty()){ - //There are some failed CSAR IDs, return 500 and the list of failed CSAR IDs - Map> entity = new HashMap<>(); - entity.put("failedIds", failedCsarIds); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(entity) - .build(); - } - return Response.ok().build(); - } - -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import com.jcabi.aspects.Loggable; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +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 javax.inject.Inject; +import org.openecomp.sdc.be.components.impl.ArchiveBusinessLogic; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.catalog.CatalogComponent; +import org.openecomp.sdc.common.api.Constants; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Archive Endpoint")) +@Controller +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class ArchiveEndpoint { + + private final ArchiveBusinessLogic archiveBusinessLogic; + + @Inject + public ArchiveEndpoint(ArchiveBusinessLogic archiveBusinessLogic) { + this.archiveBusinessLogic = archiveBusinessLogic; + } + + @POST + @Path("/resources/{componentId}/archive") + @Operation(description = "Archive Resource", method = "POST", summary = "Marks a resource as archived. Can be restored with restore action", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Archive successful"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found"), + @ApiResponse(responseCode = "500", description = "Internal Error") + }) + public Response archiveResources(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + archiveBusinessLogic.archiveComponent(ComponentTypeEnum.RESOURCE_PARAM_NAME, userId, componentId); + return Response.ok().build(); + } + + @POST + @Path("/resources/{componentId}/restore") + @Operation(description = "Restore Resource", method = "POST", summary = "Restores a resource from archive.", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Restore successful"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found"), + @ApiResponse(responseCode = "500", description = "Internal Error") + }) + public Response restoreResource(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + archiveBusinessLogic.restoreComponent(ComponentTypeEnum.RESOURCE_PARAM_NAME, userId, componentId); + return Response.ok().build(); + } + + @POST + @Path("/services/{componentId}/archive") + @Operation(description = "Archive Service", method = "POST", summary = "Marks a service as archived. Can be restored with restore action",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Archive successful"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found"), + @ApiResponse(responseCode = "500", description = "Internal Error") + }) + public Response archiveService(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + archiveBusinessLogic.archiveComponent(ComponentTypeEnum.SERVICE_PARAM_NAME, userId, componentId); + return Response.ok().build(); + } + + + @POST + @Path("/services/{componentId}/restore") + @Operation(description = "Restore Service", method = "POST", summary = "Restores a service from archive.", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Restore successful"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found"), + @ApiResponse(responseCode = "500", description = "Internal Error") + }) + public Response restoreService(@PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + archiveBusinessLogic.restoreComponent(ComponentTypeEnum.SERVICE_PARAM_NAME, userId, componentId); + return Response.ok().build(); + } + + @GET + @Path("/archive") + @Operation(description = "Get all Archived Components", method = "GET", summary = "Get all Archived Components", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Error") + }) + public Map> getArchivedComponents(@HeaderParam(value = Constants.USER_ID_HEADER) String userId){ + return this.archiveBusinessLogic.getArchiveComponents(userId, new LinkedList<>()); + } + + @POST + @Path("/notif/vsp/archived") + @Operation(description = "Notify about an archived VSP. All VFs with relation to the given CSAR IDs will be martked as vspArchived=true", method = "POST") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Error. A list of the failed CSAR IDs may be returned.") + }) + public Response onVspArchived(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @RequestBody List csarIds){ + List failedCsarIds = this.archiveBusinessLogic.onVspArchive(userId, csarIds); + if (!failedCsarIds.isEmpty()){ + //There are some failed CSAR IDs, return 500 and the list of failed CSAR IDs + Map> entity = new HashMap<>(); + entity.put("failedIds", failedCsarIds); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(entity) + .build(); + } + return Response.ok().build(); + } + + @POST + @Path("/notif/vsp/restored") + @Operation(description = "Notify about a restored VSP. All VFs with relation to the given CSAR IDs will be martked as vspArchived=false", method = "POST") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "400", description = "Bad request"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Error. A list of the failed CSAR IDs may be returned.") + }) + public Response onVspRestored(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @RequestBody List csarIds){ + List failedCsarIds = this.archiveBusinessLogic.onVspRestore(userId, csarIds); + if (!failedCsarIds.isEmpty()){ + //There are some failed CSAR IDs, return 500 and the list of failed CSAR IDs + Map> entity = new HashMap<>(); + entity.put("failedIds", failedCsarIds); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(entity) + .build(); + } + return Response.ok().build(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java index ce7df4c652..2b55ffa2c8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java @@ -1,648 +1,796 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; -import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.ArtifactDefinition; -import org.openecomp.sdc.be.model.ArtifactUiDownloadData; -import org.openecomp.sdc.be.model.Operation; -import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.Map; - -/** - * Root resource (exposed at "/" path) - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Resource Artifact Servlet", description = "Resource Artifact Servlet") -@Singleton -public class ArtifactServlet extends BeGenericServlet { - - private final ArtifactsBusinessLogic artifactsBusinessLogic; - - @Inject - public ArtifactServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, ArtifactsBusinessLogic artifactsBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.artifactsBusinessLogic = artifactsBusinessLogic; - } - - private static final Logger log = Logger.getLogger(ArtifactServlet.class); - - // *************** Resources - @POST - @Path("/resources/{resourceId}/artifacts") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Artifact", httpMethod = "POST", notes = "Returns created ArtifactDefinition", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Artifact already exist") }) - public Response loadArtifact(@PathParam("resourceId") final String resourceId, @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleUploadRequest(data, request, resourceId, ComponentTypeEnum.RESOURCE); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifact"); - log.debug("loadArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/resources/{resourceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Artifact", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId, @ApiParam(value = "json describe the artifact", required = true) String data, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleUpdateRequest(data, request, resourceId, artifactId, ComponentTypeEnum.RESOURCE); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifact"); - log.debug("updateArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @DELETE - @Path("/resources/{resourceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete Artifact", httpMethod = "DELETE", notes = "Returns delete artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response deleteArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, null, null); - } catch (Exception e) { - log.debug("deleteArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - // *************** Services - @POST - @Path("/services/{serviceId}/artifacts") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Artifact", httpMethod = "POST", notes = "Returns created ArtifactDefinition", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Artifact already exist") }) - public Response loadInformationArtifact(@PathParam("serviceId") final String serviceId, @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleUploadRequest(data, request, serviceId, ComponentTypeEnum.SERVICE); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadInformationArtifact"); - log.debug("loadInformationArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/services/{serviceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Artifact", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service artifact created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateInformationArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @ApiParam(value = "json describe the artifact", required = true) String data, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateInformationArtifact"); - log.debug("updateInformationArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - // *************** Services api artifacts - @POST - @Path("/services/{serviceId}/artifacts/api/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Api Artifact", httpMethod = "POST", notes = "Returns created ArtifactDefinition", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Api Artifact Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @ApiParam(value = "json describe the artifact", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateApiArtifact"); - log.debug("updateApiArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @DELETE - @Path("/services/{serviceId}/artifacts/api/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete Api Artifact", httpMethod = "DELETE", notes = "Returns Deleted ArtifactDefinition", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "Api Artifact deleted"), @ApiResponse(code = 403, message = "Restricted operation") }) - public Response deleteApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @HeaderParam(value = Constants.MD5_HEADER) String origMd5) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteApiArtifact"); - log.debug("deleteApiArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @DELETE - @Path("/services/{serviceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete Artifact", httpMethod = "DELETE", notes = "Returns delete artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service artifact deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response deleteInformationalArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteInformationalArtifact"); - log.debug("deleteInformationalArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /* - * DOWNLOAD Artifacts by json body in base 64 (because of userId problem with href) - */ - - @GET - @Path("/services/{serviceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Download service Artifact in Base64", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service artifact downloaded"), @ApiResponse(code = 404, message = "Service/Artifact not found") }) - public Response downloadServiceArtifactBase64(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDownloadRequest(request, serviceId, artifactId, null, ComponentTypeEnum.SERVICE, null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadServiceArtifactBase64"); - log.debug("downloadServiceArtifactBase64 unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/resources/{resourceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Download resource Artifact in Base64", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource artifact downloaded"), @ApiResponse(code = 404, message = "Resource/Artifact not found") }) - public Response downloadResourceArtifactBase64(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDownloadRequest(request, resourceId, artifactId, null, ComponentTypeEnum.RESOURCE, null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceArtifactBase64"); - log.debug("downloadResourceArtifactBase64 unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Download component Artifact in Base64", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "ResourceInstance artifact downloaded"), @ApiResponse(code = 404, message = "ResourceInstance/Artifact not found") }) - public Response downloadResourceInstanceArtifactBase64( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDownloadRequest(request, componentInstanceId, artifactId, componentId, ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentType); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); - log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - // *************** Resource lifecycle ( interfces ) - - @POST - @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Artifact and Attach to interface", httpMethod = "POST", notes = "Returns created resource", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Artifact already exist") }) - public Response loadArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @ApiParam(value = "json describe the artifact", required = true) String data, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleArtifactRequest(data, request, resourceId, interfaceType, operation, null, ComponentTypeEnum.RESOURCE, ArtifactOperationEnum.CREATE, null, null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifactToInterface"); - log.debug("loadArtifactToInterface unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @DELETE - @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "delete Artifact from interface", httpMethod = "delete", notes = "delete matching artifact from interface", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "delete artifact under interface deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Artifact already exist") }) - public Response deleteArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, @PathParam("artifactId") final String artifactId, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, interfaceType, operation); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteArtifactToInterface"); - log.debug("deleteArtifactToInterface unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "update Artifact Attach to interface", httpMethod = "post", notes = "updates artifact by interface", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "delete artifact under interface deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Artifact already exist") }) - public Response updateArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, @PathParam("artifactId") final String artifactId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @Context final HttpServletRequest request, - @ApiParam(value = "json describe the artifact", required = true) String data) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleArtifactRequest(data, request, resourceId, interfaceType, operation, artifactId, ComponentTypeEnum.RESOURCE, ArtifactOperationEnum.UPDATE, null, null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifactToInterface"); - log.debug("updateArtifactToInterface unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}/heatParams") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource Instance HEAT_ENV parameters", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateRIArtifact( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, - @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperationEnum.UPDATE, componentId, containerComponentType); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateRIArtifact"); - log.debug("updateRIArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource Instance artifact payload", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, - @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperationEnum.UPDATE, componentId, containerComponentType); - } catch (Exception e) { - log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Load Resource Instance artifact payload", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response loadComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "json describe the artifact", required = true) String data, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleArtifactRequest(data, request, componentInstanceId, null, null, null, ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperationEnum.CREATE, componentId, containerComponentType); - } catch (Exception e) { - log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @DELETE - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete Resource Instance artifact", httpMethod = "POST", notes = "Returns deleted artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response deleteComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, - @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleDeleteRequest(request, componentInstanceId, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, null, null, componentId); - } catch (Exception e) { - log.debug("deleteArtifact unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - - @GET - @Path("/{containerComponentType}/{componentId}/artifactsByType/{artifactGroupType}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get component Artifacts", httpMethod = "GET", notes = "Returns artifacts", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component artifacts"), @ApiResponse(code = 404, message = "Resource/Artifact not found") }) - public Response getComponentArtifacts( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleGetArtifactsRequest(request, componentId, null, artifactGroupType, containerComponentType); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); - log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifactsByType/{artifactGroupType}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get component Artifacts", httpMethod = "GET", notes = "Returns artifacts", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component artifacts"), @ApiResponse(code = 404, message = "Resource/Artifact not found") }) - public Response getComponentInstanceArtifacts( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - try { - return handleGetArtifactsRequest(request,componentInstanceId , componentId, artifactGroupType, containerComponentType); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); - log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - - @POST - @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "uploads of artifact to component operation workflow", httpMethod = "POST", notes = "uploads of artifact to component operation workflow") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), - @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), - @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), - @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), - @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), - @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), - @ApiResponse(code = 400, message = "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 - SVC4086"), - @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) - @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) - public Response uploadInterfaceOperationArtifact( - @ApiParam(value = "Asset type") @PathParam("assetType") String assetType, - @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, - @ApiParam(value = "The uuid of the interface", required = true)@PathParam("interfaceUUID") final String interfaceUUID, - @ApiParam(value = "The uuid of the operation", required = true)@PathParam("operationUUID") final String operationUUID, - @ApiParam(value = "The uuid of the artifact", required = true)@PathParam("artifactUUID") final String artifactUUID, - @ApiParam( hidden = true) String data, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @HeaderParam(value = Constants.MD5_HEADER) String origMd5, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - try { - Either uploadArtifactEither = - artifactsBusinessLogic.updateArtifactOnInterfaceOperationByResourceUUID(data, request, - ComponentTypeEnum.findByParamName(assetType), uuid, interfaceUUID, operationUUID, artifactUUID, - new ResourceCommonInfo(assetType), artifactsBusinessLogic.new ArtifactOperationInfo(true, - false, ArtifactOperationEnum.UPDATE)); - if (uploadArtifactEither.isRight()) { - log.debug("failed to update artifact"); - return buildErrorResponse(uploadArtifactEither.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), uploadArtifactEither.left().value()); - } - catch (Exception e) { - final String message = "failed to update artifact on a resource or service"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - // ////////// API END /////////////////////////// - - // ************ private ********************* - - private Response handleUploadRequest(String data, HttpServletRequest request, String componentId, ComponentTypeEnum componentType) { - return handleArtifactRequest(data, componentId, null, componentType, ArtifactOperationEnum.CREATE); - } - - private Response handleUpdateRequest(String data, HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType) { - return handleArtifactRequest(data, componentId, artifactId, componentType, ArtifactOperationEnum.UPDATE); - } - - private Response handleDownloadRequest(HttpServletRequest request, String componentId, String artifactId, String parentId, ComponentTypeEnum componentType, String containerComponentType) { - String userId = request.getHeader(Constants.USER_ID_HEADER); - ServletContext context = request.getSession().getServletContext(); - Either, ResponseFormat> actionResult = artifactsBusinessLogic - .handleDownloadRequestById(componentId, artifactId, userId, componentType, parentId, containerComponentType); - - Response response; - if (actionResult.isRight()) { - response = buildErrorResponse(actionResult.right().value()); - } else { - byte[] file = actionResult.left().value().getRight(); - String base64Contents = new String(Base64.encodeBase64(file)); - String artifactName = actionResult.left().value().getLeft(); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - ArtifactUiDownloadData artifactUiDownloadData = new ArtifactUiDownloadData(); - artifactUiDownloadData.setArtifactName(artifactName); - artifactUiDownloadData.setBase64Contents(base64Contents); - response = buildOkResponse(responseFormat, artifactUiDownloadData); - } - return response; - } - - private Response handleGetArtifactsRequest(HttpServletRequest request, String componentId, String parentId, String artifactGroupType, String containerComponentType) { - String userId = request.getHeader(Constants.USER_ID_HEADER); - ComponentTypeEnum componentTypeEnum = parentId == null || parentId.isEmpty()? ComponentTypeEnum.findByParamName(containerComponentType): ComponentTypeEnum.RESOURCE_INSTANCE; - Either, ResponseFormat> actionResult = artifactsBusinessLogic.handleGetArtifactsByType(containerComponentType, parentId, componentTypeEnum, componentId, artifactGroupType, userId); - - Response response; - if (actionResult.isRight()) { - response = buildErrorResponse(actionResult.right().value()); - } else { - - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResult.left().value()); - } - - return response; - } - - - private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, String interfaceType, String operationName) { - return handleDeleteRequest(request, componentId, artifactId, componentType, interfaceType, operationName, null); - } - - private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, String interfaceType, String operationName, String parentId) { - String userId = request.getHeader(Constants.USER_ID_HEADER); - ServletContext context = request.getSession().getServletContext(); - Either, ResponseFormat> actionResult = artifactsBusinessLogic.handleArtifactRequest(componentId, userId, componentType, artifactsBusinessLogic.new ArtifactOperationInfo (false, false, ArtifactOperationEnum.DELETE), artifactId, null, null, null, interfaceType, operationName, - parentId, null); - Response response; - if (actionResult.isRight()) { - response = buildErrorResponse(actionResult.right().value()); - } else { - Either result = actionResult.left().value(); - if (result.isLeft()) { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value()); - } - } - return response; - - } - - private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String interfaceName, String operationName, String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operationEnum, String parentId, - String containerComponentType) { - ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); - String origMd5 = request.getHeader(Constants.MD5_HEADER); - - String userId = request.getHeader(Constants.USER_ID_HEADER); - - Either, ResponseFormat> actionResult = artifactsBusinessLogic.handleArtifactRequest(componentId, userId, componentType, - artifactsBusinessLogic.new ArtifactOperationInfo (false, false,operationEnum), artifactId, artifactInfo, origMd5, data, interfaceName, operationName, parentId, - containerComponentType); - Response response; - if (actionResult.isRight()) { - response = buildErrorResponse(actionResult.right().value()); - } else { - Either result = actionResult.left().value(); - if (result.isLeft()) { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value()); - } - } - return response; - - } - - private Response handleArtifactRequest(String data, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operation) { - return handleArtifactRequest(data, servletRequest, componentId, null, null, artifactId, componentType, operation, null, null); - } - -} +/*- + * ============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.servlets; + +import java.util.Map; +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.DELETE; +import javax.ws.rs.GET; +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.codec.binary.Base64; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import com.jcabi.aspects.Loggable; +import fj.data.Either; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +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; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Resource Artifact Servlet", description = "Resource Artifact Servlet")) +@Singleton +public class ArtifactServlet extends BeGenericServlet { + + private final ArtifactsBusinessLogic artifactsBusinessLogic; + + @Inject + public ArtifactServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, ArtifactsBusinessLogic artifactsBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.artifactsBusinessLogic = artifactsBusinessLogic; + } + + private static final Logger log = Logger.getLogger(ArtifactServlet.class); + + // *************** Resources + @POST + @Path("/resources/{resourceId}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", + responses = @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Artifact already exist")}) + public Response loadArtifact(@PathParam("resourceId") final String resourceId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUploadRequest(data, request, resourceId, ComponentTypeEnum.RESOURCE); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifact"); + log.debug("loadArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/resources/{resourceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", + responses = @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateArtifact(@PathParam("resourceId") final String resourceId, + @PathParam("artifactId") final String artifactId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + try { + return handleUpdateRequest(data, request, resourceId, artifactId, ComponentTypeEnum.RESOURCE); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifact"); + log.debug("updateArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/resources/{resourceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Delete Artifact", method = "DELETE", + summary = "Returns delete artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteArtifact(@PathParam("resourceId") final String resourceId, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + try { + return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, null, null); + } catch (Exception e) { + log.debug("deleteArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // *************** Services + @POST + @Path("/services/{serviceId}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Create Artifact", method = "POST", + summary = "Returns created ArtifactDefinition", responses = @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Artifact already exist")}) + public Response loadInformationArtifact(@PathParam("serviceId") final String serviceId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUploadRequest(data, request, serviceId, ComponentTypeEnum.SERVICE); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadInformationArtifact"); + log.debug("loadInformationArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/services/{serviceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Update Artifact", method = "POST", + summary = "Returns updated artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service artifact created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateInformationArtifact(@PathParam("serviceId") final String serviceId, + @PathParam("artifactId") final String artifactId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateInformationArtifact"); + log.debug("updateInformationArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // *************** Services api artifacts + @POST + @Path("/services/{serviceId}/artifacts/api/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Update Api Artifact", method = "POST", + summary = "Returns created ArtifactDefinition", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Api Artifact Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateApiArtifact(@PathParam("serviceId") final String serviceId, + @PathParam("artifactId") final String artifactId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateApiArtifact"); + log.debug("updateApiArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/services/{serviceId}/artifacts/api/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Delete Api Artifact", method = "DELETE", + summary = "Returns Deleted ArtifactDefinition", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Api Artifact deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation")}) + public Response deleteApiArtifact(@PathParam("serviceId") final String serviceId, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteApiArtifact"); + log.debug("deleteApiArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/services/{serviceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Delete Artifact", method = "DELETE", + summary = "Returns delete artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service artifact deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteInformationalArtifact(@PathParam("serviceId") final String serviceId, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteInformationalArtifact"); + log.debug("deleteInformationalArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /* + * DOWNLOAD Artifacts by json body in base 64 (because of userId problem with href) + */ + + @GET + @Path("/services/{serviceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Download service Artifact in Base64", method = "GET", + summary = "Returns downloaded artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service artifact downloaded"), + @ApiResponse(responseCode = "404", description = "Service/Artifact not found")}) + public Response downloadServiceArtifactBase64(@PathParam("serviceId") final String serviceId, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDownloadRequest(request, serviceId, artifactId, null, ComponentTypeEnum.SERVICE, null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadServiceArtifactBase64"); + log.debug("downloadServiceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/resources/{resourceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Download resource Artifact in Base64", method = "GET", + summary = "Returns downloaded artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource artifact downloaded"), + @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")}) + public Response downloadResourceArtifactBase64(@PathParam("resourceId") final String resourceId, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDownloadRequest(request, resourceId, artifactId, null, ComponentTypeEnum.RESOURCE, null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceArtifactBase64"); + log.debug("downloadResourceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Download component Artifact in Base64", method = "GET", + summary = "Returns downloaded artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "ResourceInstance artifact downloaded"), + @ApiResponse(responseCode = "404", description = "ResourceInstance/Artifact not found")}) + public Response downloadResourceInstanceArtifactBase64(@Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDownloadRequest(request, componentInstanceId, artifactId, componentId, + ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentType); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); + log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // *************** Resource lifecycle ( interfces ) + + @POST + @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Create Artifact and Attach to interface", method = "POST", + summary = "Returns created resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Artifact already exist")}) + public Response loadArtifactToInterface(@PathParam("resourceId") final String resourceId, + @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, resourceId, interfaceType, operation, null, + ComponentTypeEnum.RESOURCE, ArtifactOperationEnum.CREATE, null, null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifactToInterface"); + log.debug("loadArtifactToInterface unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "delete Artifact from interface", method = "delete", + summary = "delete matching artifact from interface", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Artifact already exist")}) + public Response deleteArtifactToInterface(@PathParam("resourceId") final String resourceId, + @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, + @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, interfaceType, + operation); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteArtifactToInterface"); + log.debug("deleteArtifactToInterface unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "update Artifact Attach to interface", method = "post", + summary = "updates artifact by interface", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Artifact already exist")}) + public Response updateArtifactToInterface(@PathParam("resourceId") final String resourceId, + @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, + @PathParam("artifactId") final String artifactId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @Context final HttpServletRequest request, + @Parameter(description = "json describe the artifact", required = true) String data) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, resourceId, interfaceType, operation, artifactId, + ComponentTypeEnum.RESOURCE, ArtifactOperationEnum.UPDATE, null, null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifactToInterface"); + log.debug("updateArtifactToInterface unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}/heatParams") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Update Resource Instance HEAT_ENV parameters", + method = "POST", summary = "Returns updated artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Artifact updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateRIArtifact(@Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("artifactId") final String artifactId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, + ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperationEnum.UPDATE, componentId, + containerComponentType); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateRIArtifact"); + log.debug("updateRIArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Update Resource Instance artifact payload", method = "POST", + summary = "Returns updated artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Artifact updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("artifactId") final String artifactId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, + ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperationEnum.UPDATE, componentId, + containerComponentType); + } catch (Exception e) { + log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Load Resource Instance artifact payload", method = "POST", + summary = "Returns updated artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Artifact updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response loadComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, componentInstanceId, null, null, null, + ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperationEnum.CREATE, componentId, + containerComponentType); + } catch (Exception e) { + log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Delete Resource Instance artifact", method = "POST", + summary = "Returns deleted artifact", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Artifact updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("artifactId") final String artifactId, + @Parameter(description = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, componentInstanceId, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, + null, null, componentId); + } catch (Exception e) { + log.debug("deleteArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + + @GET + @Path("/{containerComponentType}/{componentId}/artifactsByType/{artifactGroupType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Get component Artifacts", method = "GET", + summary = "Returns artifacts", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component artifacts"), + @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")}) + public Response getComponentArtifacts(@Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleGetArtifactsRequest(request, componentId, null, artifactGroupType, containerComponentType); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); + log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifactsByType/{artifactGroupType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Get component Artifacts", method = "GET", + summary = "Returns artifacts", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component artifacts"), + @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")}) + public Response getComponentInstanceArtifacts(@Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleGetArtifactsRequest(request, componentInstanceId, componentId, artifactGroupType, + containerComponentType); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); + log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + + @POST + @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "uploads of artifact to component operation workflow", method = "POST", summary = "uploads of artifact to component operation workflow") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Artifact uploaded",content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))), + @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"), + @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"), + @ApiResponse(responseCode = "400", 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 - SVC4086"), + @ApiResponse(responseCode = "400", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + //@ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) + public Response uploadInterfaceOperationArtifact( + @Parameter(description = "Asset type") @PathParam("assetType") String assetType, + @Parameter(description = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @Parameter(description = "The uuid of the interface", required = true)@PathParam("interfaceUUID") final String interfaceUUID, + @Parameter(description = "The uuid of the operation", required = true)@PathParam("operationUUID") final String operationUUID, + @Parameter(description = "The uuid of the artifact", required = true)@PathParam("artifactUUID") final String artifactUUID, + @Parameter( hidden = true) String data, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + try { + Either uploadArtifactEither = + artifactsBusinessLogic.updateArtifactOnInterfaceOperationByResourceUUID(data, request, + ComponentTypeEnum.findByParamName(assetType), uuid, interfaceUUID, operationUUID, artifactUUID, + new ResourceCommonInfo(assetType), artifactsBusinessLogic.new ArtifactOperationInfo(true, + false, ArtifactOperationEnum.UPDATE)); + if (uploadArtifactEither.isRight()) { + log.debug("failed to update artifact"); + return buildErrorResponse(uploadArtifactEither.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), uploadArtifactEither.left().value()); + } + catch (Exception e) { + final String message = "failed to update artifact on a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // ////////// API END /////////////////////////// + + // ************ private ********************* + + private Response handleUploadRequest(String data, HttpServletRequest request, String componentId, ComponentTypeEnum componentType) { + return handleArtifactRequest(data, componentId, null, componentType, ArtifactOperationEnum.CREATE); + } + + private Response handleUpdateRequest(String data, HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType) { + return handleArtifactRequest(data, componentId, artifactId, componentType, ArtifactOperationEnum.UPDATE); + } + + private Response handleDownloadRequest(HttpServletRequest request, String componentId, String artifactId, String parentId, ComponentTypeEnum componentType, String containerComponentType) { + String userId = request.getHeader(Constants.USER_ID_HEADER); + ServletContext context = request.getSession().getServletContext(); + Either, ResponseFormat> actionResult = artifactsBusinessLogic + .handleDownloadRequestById(componentId, artifactId, userId, componentType, parentId, containerComponentType); + + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + byte[] file = actionResult.left().value().getRight(); + String base64Contents = new String(Base64.encodeBase64(file)); + String artifactName = actionResult.left().value().getLeft(); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + ArtifactUiDownloadData artifactUiDownloadData = new ArtifactUiDownloadData(); + artifactUiDownloadData.setArtifactName(artifactName); + artifactUiDownloadData.setBase64Contents(base64Contents); + response = buildOkResponse(responseFormat, artifactUiDownloadData); + } + return response; + } + + private Response handleGetArtifactsRequest(HttpServletRequest request, String componentId, String parentId, String artifactGroupType, String containerComponentType) { + String userId = request.getHeader(Constants.USER_ID_HEADER); + ComponentTypeEnum componentTypeEnum = parentId == null || parentId.isEmpty()? ComponentTypeEnum.findByParamName(containerComponentType): ComponentTypeEnum.RESOURCE_INSTANCE; + Either, ResponseFormat> actionResult = artifactsBusinessLogic.handleGetArtifactsByType(containerComponentType, parentId, componentTypeEnum, componentId, artifactGroupType, userId); + + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResult.left().value()); + } + + return response; + } + + + private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, String interfaceType, String operationName) { + return handleDeleteRequest(request, componentId, artifactId, componentType, interfaceType, operationName, null); + } + + private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, String interfaceType, String operationName, String parentId) { + String userId = request.getHeader(Constants.USER_ID_HEADER); + ServletContext context = request.getSession().getServletContext(); + Either, ResponseFormat> actionResult = artifactsBusinessLogic.handleArtifactRequest(componentId, userId, componentType, artifactsBusinessLogic.new ArtifactOperationInfo (false, false, ArtifactOperationEnum.DELETE), artifactId, null, null, null, interfaceType, operationName, + parentId, null); + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + Either result = actionResult.left().value(); + if (result.isLeft()) { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value()); + } + } + return response; + + } + + private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String interfaceName, String operationName, String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operationEnum, String parentId, + String containerComponentType) { + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either, ResponseFormat> actionResult = artifactsBusinessLogic.handleArtifactRequest(componentId, userId, componentType, + artifactsBusinessLogic.new ArtifactOperationInfo (false, false,operationEnum), artifactId, artifactInfo, origMd5, data, interfaceName, operationName, parentId, + containerComponentType); + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + Either result = actionResult.left().value(); + if (result.isLeft()) { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value()); + } + } + return response; + + } + + private Response handleArtifactRequest(String data, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operation) { + return handleArtifactRequest(data, servletRequest, componentId, null, null, artifactId, componentType, operation, null, null); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java index f2c4286c01..1ed1e404da 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java @@ -1,277 +1,320 @@ -/*- - * ============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.servlets; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.AttributeBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.PropertyDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.user.UserBusinessLogic; -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.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * Web Servlet for actions on Attributes - * - * @author mshitrit - * - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Resource Attribute Servlet", description = "Resource Attribute Servlet") -@Singleton -public class AttributeServlet extends AbstractValidationsServlet { - private static final Logger log = Logger.getLogger(AttributeServlet.class); - - @Inject - public AttributeServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - } - - /** - * Creates new Attribute on a resource with given resource ID - * - * @param resourceId - * @param data - * @param request - * @param userId - * @return - */ - @POST - @Path("resources/{resourceId}/attributes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Resource Attribute", httpMethod = "POST", notes = "Returns created resource attribute", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Resource attribute already exist") }) - public Response createAttribute(@ApiParam(value = "resource id to update with new attribute", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource attribute to be created", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data); - - try { - Wrapper errorWrapper = new Wrapper<>(); - Wrapper attributesWrapper = new Wrapper<>(); - // convert json to AttributeDefinition - - buildAttributeFromString(data, attributesWrapper, errorWrapper); - if (errorWrapper.isEmpty()) { - AttributeBusinessLogic businessLogic = getClassFromWebAppContext(context, () -> AttributeBusinessLogic.class); - Either createAttribute = businessLogic.createAttribute(resourceId, attributesWrapper.getInnerElement(), userId); - if (createAttribute.isRight()) { - errorWrapper.setInnerElement(createAttribute.right().value()); - } else { - attributesWrapper.setInnerElement(createAttribute.left().value()); - } - } - - Response response; - if (!errorWrapper.isEmpty()) { - log.info("Failed to create Attribute. Reason - ", errorWrapper.getInnerElement()); - response = buildErrorResponse(errorWrapper.getInnerElement()); - } else { - PropertyDefinition createdAttDef = attributesWrapper.getInnerElement(); - log.debug("Attribute {} created successfully with id {}", createdAttDef.getName(), createdAttDef.getUniqueId()); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); - response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(createdAttDef)); - } - - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Attribute"); - log.debug("create property failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - - } - } - - /** - * Updates existing Attribute with given attributeID on a resource with given resourceID - * - * @param resourceId - * @param attributeId - * @param data - * @param request - * @param userId - * @return - */ - @PUT - @Path("resources/{resourceId}/attributes/{attributeId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource Attribute", httpMethod = "PUT", notes = "Returns updated attribute", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource attribute updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateAttribute(@ApiParam(value = "resource id to update with new attribute", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "attribute id to update", required = true) @PathParam("attributeId") final String attributeId, @ApiParam(value = "Resource attribute to update", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - try { - // convert json to PropertyDefinition - Wrapper errorWrapper = new Wrapper<>(); - Wrapper attributesWrapper = new Wrapper<>(); - // convert json to AttributeDefinition - - buildAttributeFromString(data, attributesWrapper, errorWrapper); - - if (errorWrapper.isEmpty()) { - AttributeBusinessLogic businessLogic = getClassFromWebAppContext(context, () -> AttributeBusinessLogic.class); - Either eitherUpdateAttribute = businessLogic.updateAttribute(resourceId, attributeId, attributesWrapper.getInnerElement(), userId); - // update property - if (eitherUpdateAttribute.isRight()) { - errorWrapper.setInnerElement(eitherUpdateAttribute.right().value()); - } else { - attributesWrapper.setInnerElement(eitherUpdateAttribute.left().value()); - } - } - - Response response; - if (!errorWrapper.isEmpty()) { - log.info("Failed to update Attribute. Reason - ", errorWrapper.getInnerElement()); - response = buildErrorResponse(errorWrapper.getInnerElement()); - } else { - PropertyDefinition updatedAttribute = attributesWrapper.getInnerElement(); - log.debug("Attribute id {} updated successfully ", updatedAttribute.getUniqueId()); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(updatedAttribute)); - } - - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Attribute"); - log.debug("update attribute failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - - } - } - - /** - * Deletes existing Attribute with given attributeID on a resource with given resourceID - * - * @param resourceId - * @param attributeId - * @param request - * @param userId - * @return - */ - @DELETE - @Path("resources/{resourceId}/attributes/{attributeId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Resource Attribute", httpMethod = "DELETE", notes = "Returns deleted attribute", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted attribute"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Resource property not found") }) - public Response deleteAttribute(@ApiParam(value = "resource id of attribute", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "Attribute id to delete", required = true) @PathParam("attributeId") final String attributeId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - log.debug("modifier id is {}", userId); - - try { - - // delete the property - AttributeBusinessLogic businessLogic = getClassFromWebAppContext(context, () -> AttributeBusinessLogic.class); - Either eitherAttribute = businessLogic.deleteAttribute(resourceId, attributeId, userId); - if (eitherAttribute.isRight()) { - log.debug("Failed to delete Attribute. Reason - ", eitherAttribute.right().value()); - return buildErrorResponse(eitherAttribute.right().value()); - } - PropertyDefinition attributeDefinition = eitherAttribute.left().value(); - String name = attributeDefinition.getName(); - - log.debug("Attribute {} deleted successfully with id {}", name, attributeDefinition.getUniqueId()); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); - return buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(attributeDefinition)); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Attribute"); - log.debug("delete attribute failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - - } - } - - private void buildAttributeFromString(String data, Wrapper attributesWrapper, Wrapper errorWrapper) { - - try { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - final PropertyDefinition attribute = gson.fromJson(data, PropertyDefinition.class); - if (attribute == null) { - log.info("Attribute content is invalid - {}", data); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - errorWrapper.setInnerElement(responseFormat); - } else { - attributesWrapper.setInnerElement(attribute); - } - - } catch (Exception e) { - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - errorWrapper.setInnerElement(responseFormat); - log.debug("Attribute content is invalid - {}", data, e); - log.info("Attribute content is invalid - {}", data); - } - } -} +/*- + * ============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.servlets; + +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.DELETE; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.AttributeBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.exception.ResponseFormat; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +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; + +/** + * Web Servlet for actions on Attributes + * + * @author mshitrit + * + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Resource Attribute Servlet", description = "Resource Attribute Servlet")) +@Singleton +public class AttributeServlet extends AbstractValidationsServlet { + private static final Logger log = Logger.getLogger(AttributeServlet.class); + + @Inject + public AttributeServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + } + + /** + * Creates new Attribute on a resource with given resource ID + * + * @param resourceId + * @param data + * @param request + * @param userId + * @return + */ + @POST + @Path("resources/{resourceId}/attributes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource Attribute", method = "POST", + summary = "Returns created resource attribute", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource property created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource attribute already exist")}) + public Response createAttribute( + @Parameter(description = "resource id to update with new attribute", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "Resource attribute to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data); + + try { + Wrapper errorWrapper = new Wrapper<>(); + Wrapper attributesWrapper = new Wrapper<>(); + // convert json to AttributeDefinition + + buildAttributeFromString(data, attributesWrapper, errorWrapper); + if (errorWrapper.isEmpty()) { + AttributeBusinessLogic businessLogic = + getClassFromWebAppContext(context, () -> AttributeBusinessLogic.class); + Either createAttribute = + businessLogic.createAttribute(resourceId, attributesWrapper.getInnerElement(), userId); + if (createAttribute.isRight()) { + errorWrapper.setInnerElement(createAttribute.right().value()); + } else { + attributesWrapper.setInnerElement(createAttribute.left().value()); + } + } + + Response response; + if (!errorWrapper.isEmpty()) { + log.info("Failed to create Attribute. Reason - ", errorWrapper.getInnerElement()); + response = buildErrorResponse(errorWrapper.getInnerElement()); + } else { + PropertyDefinition createdAttDef = attributesWrapper.getInnerElement(); + log.debug("Attribute {} created successfully with id {}", createdAttDef.getName(), + createdAttDef.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(createdAttDef)); + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Attribute"); + log.debug("create property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + /** + * Updates existing Attribute with given attributeID on a resource with given resourceID + * + * @param resourceId + * @param attributeId + * @param data + * @param request + * @param userId + * @return + */ + @PUT + @Path("resources/{resourceId}/attributes/{attributeId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource Attribute", method = "PUT", summary = "Returns updated attribute", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource attribute updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateAttribute( + @Parameter(description = "resource id to update with new attribute", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "attribute id to update", + required = true) @PathParam("attributeId") final String attributeId, + @Parameter(description = "Resource attribute to update", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + try { + // convert json to PropertyDefinition + Wrapper errorWrapper = new Wrapper<>(); + Wrapper attributesWrapper = new Wrapper<>(); + // convert json to AttributeDefinition + + buildAttributeFromString(data, attributesWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + AttributeBusinessLogic businessLogic = + getClassFromWebAppContext(context, () -> AttributeBusinessLogic.class); + Either eitherUpdateAttribute = businessLogic + .updateAttribute(resourceId, attributeId, attributesWrapper.getInnerElement(), userId); + // update property + if (eitherUpdateAttribute.isRight()) { + errorWrapper.setInnerElement(eitherUpdateAttribute.right().value()); + } else { + attributesWrapper.setInnerElement(eitherUpdateAttribute.left().value()); + } + } + + Response response; + if (!errorWrapper.isEmpty()) { + log.info("Failed to update Attribute. Reason - ", errorWrapper.getInnerElement()); + response = buildErrorResponse(errorWrapper.getInnerElement()); + } else { + PropertyDefinition updatedAttribute = attributesWrapper.getInnerElement(); + log.debug("Attribute id {} updated successfully ", updatedAttribute.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(updatedAttribute)); + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Attribute"); + log.debug("update attribute failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + /** + * Deletes existing Attribute with given attributeID on a resource with given resourceID + * + * @param resourceId + * @param attributeId + * @param request + * @param userId + * @return + */ + @DELETE + @Path("resources/{resourceId}/attributes/{attributeId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource Attribute", method = "DELETE", summary = "Returns deleted attribute", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "deleted attribute"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Resource property not found")}) + public Response deleteAttribute( + @Parameter(description = "resource id of attribute", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "Attribute id to delete", + required = true) @PathParam("attributeId") final String attributeId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + // delete the property + AttributeBusinessLogic businessLogic = + getClassFromWebAppContext(context, () -> AttributeBusinessLogic.class); + Either eitherAttribute = + businessLogic.deleteAttribute(resourceId, attributeId, userId); + if (eitherAttribute.isRight()) { + log.debug("Failed to delete Attribute. Reason - ", eitherAttribute.right().value()); + return buildErrorResponse(eitherAttribute.right().value()); + } + PropertyDefinition attributeDefinition = eitherAttribute.left().value(); + String name = attributeDefinition.getName(); + + log.debug("Attribute {} deleted successfully with id {}", name, attributeDefinition.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(attributeDefinition)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Attribute"); + log.debug("delete attribute failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + private void buildAttributeFromString(String data, Wrapper attributesWrapper, + Wrapper errorWrapper) { + try { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + final PropertyDefinition attribute = gson.fromJson(data, PropertyDefinition.class); + if (attribute == null) { + log.info("Attribute content is invalid - {}", data); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + errorWrapper.setInnerElement(responseFormat); + } else { + attributesWrapper.setInnerElement(attribute); + } + + } catch (Exception e) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + errorWrapper.setInnerElement(responseFormat); + log.debug("Attribute content is invalid - {}", data, e); + log.info("Attribute content is invalid - {}", data); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AutomatedUpgradeEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AutomatedUpgradeEndpoint.java index 9f12b51b17..ce4dfdd3d0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AutomatedUpgradeEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AutomatedUpgradeEndpoint.java @@ -1,117 +1,137 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.upgrade.UpgradeBusinessLogic; -import org.openecomp.sdc.be.components.upgrade.UpgradeRequest; -import org.openecomp.sdc.be.components.upgrade.UpgradeStatus; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.stereotype.Controller; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.List; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "policy types resource") -@Controller -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class AutomatedUpgradeEndpoint extends BeGenericServlet { - private static final Logger log = Logger.getLogger(PolicyTypesEndpoint.class); - - private final UpgradeBusinessLogic businessLogic; - - @Inject - public AutomatedUpgradeEndpoint(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - UpgradeBusinessLogic businessLogic) { - super(userBusinessLogic, componentsUtils); - this.businessLogic = businessLogic; - } - - @POST - @Path("/{componentType}/{componentId}/automatedupgrade") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Autometed upgrade", httpMethod = "POST", notes = "....", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response autometedUpgrade(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "json describes upgrade request", required = true) String data) { - - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(POST) Start handle request of {}", url); - - try { - - List inputsToUpdate = JsonParserUtils.toList(data, UpgradeRequest.class); - - if (log.isDebugEnabled()) { - log.debug("Received upgrade requests size is {}", inputsToUpdate == null ? 0 : inputsToUpdate.size()); - } - UpgradeStatus actionResponse = businessLogic.automatedUpgrade(componentId, inputsToUpdate, userId); - - return actionResponse.getStatus() == ActionStatus.OK ? buildOkResponse(actionResponse) : buildErrorResponse(actionResponse.getError()); - - } catch (Exception e) { - log.error("#autometedUpgrade - Exception occurred during autometed Upgrade", e); - return buildGeneralErrorResponse(); - } - } - - @GET - @Path("/{componentType}/{componentId}/dependencies") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Autometed upgrade", httpMethod = "POST", notes = "....", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getComponentDependencies(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "Consumer Object to be created", required = true) List data) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(GET) Start handle request of {}", url); - - try { - return businessLogic.getComponentDependencies(componentId, userId) - .either(this::buildOkResponse, this::buildErrorResponse); - } catch (Exception e) { - log.error("#getServicesForComponent - Exception occurred during autometed Upgrade", e); - return buildGeneralErrorResponse(); - } - - - } -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.util.List; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +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.openecomp.sdc.be.components.upgrade.UpgradeBusinessLogic; +import org.openecomp.sdc.be.components.upgrade.UpgradeRequest; +import org.openecomp.sdc.be.components.upgrade.UpgradeStatus; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.springframework.stereotype.Controller; +import com.jcabi.aspects.Loggable; +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 = "policy types resource")) +@Controller +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class AutomatedUpgradeEndpoint extends BeGenericServlet { + private static final Logger log = Logger.getLogger(PolicyTypesEndpoint.class); + + private final UpgradeBusinessLogic businessLogic; + + @Inject + public AutomatedUpgradeEndpoint(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + UpgradeBusinessLogic businessLogic) { + super(userBusinessLogic, componentsUtils); + this.businessLogic = businessLogic; + } + + @POST + @Path("/{componentType}/{componentId}/automatedupgrade") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Autometed upgrade", method = "POST", summary = "....", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response autometedUpgrade(@PathParam("componentType") final String componentType, + @Context final HttpServletRequest request, @PathParam("componentId") final String componentId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "json describes upgrade request", required = true) String data) { + + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(POST) Start handle request of {}", url); + + try { + + List inputsToUpdate = JsonParserUtils.toList(data, UpgradeRequest.class); + + if (log.isDebugEnabled()) { + log.debug("Received upgrade requests size is {}", inputsToUpdate == null ? 0 : inputsToUpdate.size()); + } + UpgradeStatus actionResponse = businessLogic.automatedUpgrade(componentId, inputsToUpdate, userId); + + return actionResponse.getStatus() == ActionStatus.OK ? buildOkResponse(actionResponse) : buildErrorResponse(actionResponse.getError()); + + } catch (Exception e) { + log.error("#autometedUpgrade - Exception occurred during autometed Upgrade", e); + return buildGeneralErrorResponse(); + } + } + + @GET + @Path("/{componentType}/{componentId}/dependencies") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Autometed upgrade", method = "POST", summary = "....", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getComponentDependencies(@PathParam("componentType") final String componentType, + @Context final HttpServletRequest request, @PathParam("componentId") final String componentId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "Consumer Object to be created", required = true) List data) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(GET) Start handle request of {}", url); + + try { + return businessLogic.getComponentDependencies(componentId, userId) + .either(this::buildOkResponse, this::buildErrorResponse); + } catch (Exception e) { + log.error("#getServicesForComponent - Exception occurred during autometed Upgrade", e); + return buildGeneralErrorResponse(); + } + + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java index 3750f20c45..5433bd5be3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java @@ -1,182 +1,194 @@ -/*- - * ============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.servlets; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.apache.commons.lang3.tuple.Pair; -import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.api.HealthCheckInfo; -import org.openecomp.sdc.common.api.HealthCheckWrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.common.monitoring.MonitoringEvent; -import org.openecomp.sdc.exception.ResponseFormat; -import org.springframework.beans.factory.annotation.Autowired; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.List; - -@Loggable(prepend = true, value = Loggable.TRACE, trim = false) -@Path("/") -@Api(value = "BE Monitoring", description = "BE Monitoring") -@Singleton -public class BeMonitoringServlet extends BeGenericServlet { - - Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); - - private static final Logger log = Logger.getLogger(ConfigServlet.class); - private final HealthCheckBusinessLogic healthCheckBusinessLogic; - private final MonitoringBusinessLogic monitoringBusinessLogic; - - @Inject - public BeMonitoringServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - HealthCheckBusinessLogic healthCheckBusinessLogic, - MonitoringBusinessLogic monitoringBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.healthCheckBusinessLogic = healthCheckBusinessLogic; - this.monitoringBusinessLogic = monitoringBusinessLogic; - } - - @GET - @Path("/healthCheck") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Return aggregate BE health check of SDC BE components", notes = "return BE health check", response = String.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "SDC BE components are all up"), @ApiResponse(code = 500, message = "One or more SDC BE components are down") }) - public Response getHealthCheck(@Context final HttpServletRequest request) { - try { - Pair> beHealthCheckInfosStatus = healthCheckBusinessLogic.getBeHealthCheckInfosStatus(); - Boolean aggregateStatus = beHealthCheckInfosStatus.getLeft(); - ActionStatus status = aggregateStatus ? ActionStatus.OK : ActionStatus.GENERAL_ERROR; - String sdcVersion = getVersionFromContext(request); - if (sdcVersion == null || sdcVersion.isEmpty()) { - sdcVersion = "UNKNOWN"; - } - String siteMode = healthCheckBusinessLogic.getSiteMode(); - HealthCheckWrapper healthCheck = new HealthCheckWrapper(beHealthCheckInfosStatus.getRight(), sdcVersion, siteMode); - // The response can be either with 200 or 500 aggregate status - the - // body of individual statuses is returned either way - - String healthCheckStr = prettyGson.toJson(healthCheck); - return buildOkResponse(getComponentsUtils().getResponseFormat(status), healthCheckStr); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeHealthCheckError("BeHealthCheck"); - log.debug("BE health check unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/monitoring") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response processMonitoringMetrics(@Context final HttpServletRequest request, String json) { - try { - MonitoringEvent monitoringEvent = convertContentToJson(json, MonitoringEvent.class); - if (monitoringEvent == null) { - return buildErrorResponse(getComponentsUtils().getResponseFormatAdditionalProperty(ActionStatus.GENERAL_ERROR)); - } - log.trace("Received monitoring metrics: {}", monitoringEvent); - Either result = monitoringBusinessLogic.logMonitoringEvent(monitoringEvent); - if (result.isRight()) { - return buildErrorResponse(result.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); - - } catch (Exception e) { - log.debug("BE system metrics unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormatAdditionalProperty(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/version") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "return the ASDC application version", notes = "return the ASDC application version", response = String.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "return ASDC version"), @ApiResponse(code = 500, message = "Internal Error") }) - public Response getSdcVersion(@Context final HttpServletRequest request) { - try { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - String version = getVersionFromContext(request); - log.debug("asdc version from manifest is: {}", version); - if (version == null || version.isEmpty()) { - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.ASDC_VERSION_NOT_FOUND)); - } - - HealthCheckInfo versionInfo = new HealthCheckInfo(); - versionInfo.setVersion(version); - - // The response can be either with 200 or 500 aggregate status - the - // body of individual statuses is returned either way - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), versionInfo); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getSDCVersion"); - log.debug("BE get ASDC version unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private String getVersionFromContext(HttpServletRequest request) { - ServletContext servletContext = request.getSession().getServletContext(); - return (String) servletContext.getAttribute(Constants.ASDC_RELEASE_VERSION_ATTR); - } - - protected MonitoringEvent convertContentToJson(String content, Class clazz) { - - MonitoringEvent object = null; - try { - object = gson.fromJson(content, clazz); - object.setFields(null); - } catch (Exception e) { - log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), e); - } - - return object; - } - -} +/*- + * ============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.servlets; + +import java.util.List; +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.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +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.tuple.Pair; +import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic; +import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.common.api.HealthCheckWrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.common.monitoring.MonitoringEvent; +import org.openecomp.sdc.exception.ResponseFormat; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +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.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.TRACE, trim = false) +@Path("/") +@OpenAPIDefinition(info = @Info(title = "BE Monitoring", description = "BE Monitoring")) +@Singleton +public class BeMonitoringServlet extends BeGenericServlet { + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + private static final Logger log = Logger.getLogger(ConfigServlet.class); + private final HealthCheckBusinessLogic healthCheckBusinessLogic; + private final MonitoringBusinessLogic monitoringBusinessLogic; + + @Inject + public BeMonitoringServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + HealthCheckBusinessLogic healthCheckBusinessLogic, + MonitoringBusinessLogic monitoringBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.healthCheckBusinessLogic = healthCheckBusinessLogic; + this.monitoringBusinessLogic = monitoringBusinessLogic; + } + + @GET + @Path("/healthCheck") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Return aggregate BE health check of SDC BE components", summary = "return BE health check", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "SDC BE components are all up"), + @ApiResponse(responseCode = "500", description = "One or more SDC BE components are down")}) + public Response getHealthCheck(@Context final HttpServletRequest request) { + try { + Pair> beHealthCheckInfosStatus = + healthCheckBusinessLogic.getBeHealthCheckInfosStatus(); + Boolean aggregateStatus = beHealthCheckInfosStatus.getLeft(); + ActionStatus status = aggregateStatus ? ActionStatus.OK : ActionStatus.GENERAL_ERROR; + String sdcVersion = getVersionFromContext(request); + if (sdcVersion == null || sdcVersion.isEmpty()) { + sdcVersion = "UNKNOWN"; + } + String siteMode = healthCheckBusinessLogic.getSiteMode(); + HealthCheckWrapper healthCheck = + new HealthCheckWrapper(beHealthCheckInfosStatus.getRight(), sdcVersion, siteMode); + // The response can be either with 200 or 500 aggregate status - the + // body of individual statuses is returned either way + + String healthCheckStr = prettyGson.toJson(healthCheck); + return buildOkResponse(getComponentsUtils().getResponseFormat(status), healthCheckStr); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeHealthCheckError("BeHealthCheck"); + log.debug("BE health check unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/monitoring") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response processMonitoringMetrics(@Context final HttpServletRequest request, String json) { + try { + MonitoringEvent monitoringEvent = convertContentToJson(json, MonitoringEvent.class); + if (monitoringEvent == null) { + return buildErrorResponse(getComponentsUtils().getResponseFormatAdditionalProperty(ActionStatus.GENERAL_ERROR)); + } + log.trace("Received monitoring metrics: {}", monitoringEvent); + Either result = monitoringBusinessLogic.logMonitoringEvent(monitoringEvent); + if (result.isRight()) { + return buildErrorResponse(result.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); + + } catch (Exception e) { + log.debug("BE system metrics unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormatAdditionalProperty(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/version") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "return the ASDC application version", summary = "return the ASDC application version", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "return ASDC version"), + @ApiResponse(responseCode = "500", description = "Internal Error")}) + public Response getSdcVersion(@Context final HttpServletRequest request) { + try { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + String version = getVersionFromContext(request); + log.debug("asdc version from manifest is: {}", version); + if (version == null || version.isEmpty()) { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.ASDC_VERSION_NOT_FOUND)); + } + + HealthCheckInfo versionInfo = new HealthCheckInfo(); + versionInfo.setVersion(version); + + // The response can be either with 200 or 500 aggregate status - the + // body of individual statuses is returned either way + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), versionInfo); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getSDCVersion"); + log.debug("BE get ASDC version unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private String getVersionFromContext(HttpServletRequest request) { + ServletContext servletContext = request.getSession().getServletContext(); + return (String) servletContext.getAttribute(Constants.ASDC_RELEASE_VERSION_ATTR); + } + + protected MonitoringEvent convertContentToJson(String content, Class clazz) { + + MonitoringEvent object = null; + try { + object = gson.fromJson(content, clazz); + object.setFields(null); + } catch (Exception e) { + log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), e); + } + + return object; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java index eacfbc774b..0e00e017d8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java @@ -1,334 +1,342 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * 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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.CapabilityDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -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 java.util.List; -import java.util.Optional; -import org.springframework.beans.factory.annotation.Autowired; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Capability Servlet", description = "Capability Servlet") -@Singleton -public class CapabilityServlet extends AbstractValidationsServlet { - private static final Logger LOGGER = Logger.getLogger(CapabilityServlet.class); - private final CapabilitiesBusinessLogic capabilitiesBusinessLogic; - - @Inject - public CapabilityServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - CapabilitiesBusinessLogic capabilitiesBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.capabilitiesBusinessLogic = capabilitiesBusinessLogic; - } - - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/capabilities") - @ApiOperation(value = "Create Capabilities on resource", httpMethod = "POST", - notes = "Create Capabilities on resource", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Capabilities"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Capability already exist")}) - public Response createCapabilitiesOnResource( - @ApiParam(value = "Capability to create", required = true) String data, - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "resources" , resourceId, - request, userId, false, "createCapabilities"); - } - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/capabilities") - @ApiOperation(value = "Update Capabilities on resource", httpMethod = "PUT", - notes = "Update Capabilities on resource", response = CapabilityDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Capabilities"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updateCapabilitiesOnResource( - @ApiParam(value = "Capabilities to update", required = true) String data, - @ApiParam(value = "Component Id") @PathParam("resourceId") String resourceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "resources", resourceId, - request, userId, true, "updateCapabilities"); - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/capabilities/{capabilityId}") - @ApiOperation(value = "Get Capability from resource", httpMethod = "GET", - notes = "GET Capability from resource", response = CapabilityDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Capability"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response getCapabilityOnResource( - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @ApiParam(value = "Capability Id") @PathParam("capabilityId") String capabilityId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return get(capabilityId, resourceId, request, userId); - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/capabilities/{capabilityId}") - @ApiOperation(value = "Delete capability from resource", httpMethod = "DELETE", - notes = "Delete capability from resource", response = CapabilityDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete capability"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response deleteCapabilityOnResource( - @ApiParam(value = "capability Id") @PathParam("capabilityId") String capabilityId, - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return delete(capabilityId, resourceId, request, userId); - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/capabilities") - @ApiOperation(value = "Create Capabilities on service", httpMethod = "POST", - notes = "Create Capabilities on service", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Capabilities"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Capability already exist")}) - public Response createCapabilitiesOnService( - @ApiParam(value = "Capability to create", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "services" , serviceId, - request, userId, false, "createCapabilities"); - } - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/capabilities") - @ApiOperation(value = "Update Capabilities on service", httpMethod = "PUT", - notes = "Update Capabilities on service", response = CapabilityDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Capabilities"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updateCapabilitiesOnService( - @ApiParam(value = "Capabilities to update", required = true) String data, - @ApiParam(value = "Component Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "services", serviceId, - request, userId, true, "updateCapabilities"); - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/capabilities/{capabilityId}") - @ApiOperation(value = "Get Capability from service", httpMethod = "GET", - notes = "GET Capability from service", response = CapabilityDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Capability"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response getCapabilityOnService( - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Capability Id") @PathParam("capabilityId") String capabilityId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return get(capabilityId, serviceId, request, userId); - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/capabilities/{capabilityId}") - @ApiOperation(value = "Delete capability from service", httpMethod = "DELETE", - notes = "Delete capability from service", response = CapabilityDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete capability"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response deleteCapabilityOnService( - @ApiParam(value = "capability Id") @PathParam("capabilityId") String capabilityId, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return delete(capabilityId, serviceId, request, userId); - } - - private Response createOrUpdate (String data, String componentType, String componentId, - HttpServletRequest request, - String userId, - boolean isUpdate, - String errorContext) { - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId); - try { - String componentIdLower = componentId.toLowerCase(); - - Either, ResponseFormat> mappedCapabilitiesDataEither - = getMappedCapabilitiesData(data, modifier, ComponentTypeEnum.findByParamName(componentType)); - if(mappedCapabilitiesDataEither.isRight()) { - LOGGER.error("Failed to create or update capabilities"); - buildErrorResponse(mappedCapabilitiesDataEither.right().value()); - } - List mappedCapabilitiesData = mappedCapabilitiesDataEither.left().value(); - Either, ResponseFormat> actionResponse; - if(isUpdate) { - actionResponse = capabilitiesBusinessLogic.updateCapabilities(componentIdLower, - mappedCapabilitiesData, modifier, errorContext, true); - } else { - actionResponse = capabilitiesBusinessLogic.createCapabilities(componentIdLower, - mappedCapabilitiesData, modifier, errorContext, true); - } - if (actionResponse.isRight()) { - LOGGER.error("Failed to create or update capabilities"); - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - actionResponse.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Capabilities create or update"); - LOGGER.error("Failed to create or update capabilities with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Response get (String capabilityIdToGet, String componentId, - HttpServletRequest request, String userId){ - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - LOGGER.debug("Start get request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - - Either actionResponse = capabilitiesBusinessLogic - .getCapability(componentIdLower, capabilityIdToGet, modifier, true); - if (actionResponse.isRight()) { - LOGGER.error("failed to get capability"); - return buildErrorResponse(actionResponse.right().value()); - } - Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get capability"); - LOGGER.error("get capabilities failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Response delete (String capabilityId, String componentId, HttpServletRequest - request, String userId){ - - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - LOGGER.debug("Start delete request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - - Either actionResponse = capabilitiesBusinessLogic - .deleteCapability(componentIdLower, capabilityId, modifier, true); - if (actionResponse.isRight()) { - LOGGER.error("failed to delete capability"); - return buildErrorResponse(actionResponse.right().value()); - } - Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete capability"); - LOGGER.error("Delete capability failed with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Either, ResponseFormat> getMappedCapabilitiesData(String inputJson, User user, - ComponentTypeEnum componentTypeEnum){ - Either mappedData = getComponentsUtils() - .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, - AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); - Optional> capabilityDefinitionList = - mappedData.left().value().getCapabilities().values().stream().findFirst(); - return capabilityDefinitionList., ResponseFormat>> - map(Either::left).orElseGet(() -> Either.right(getComponentsUtils() - .getResponseFormat(ActionStatus.GENERAL_ERROR))); - } -} +/* + * Copyright © 2016-2018 European Support Limited + * + * 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.servlets; + +import java.util.List; +import java.util.Optional; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Capability Servlet", description = "Capability Servlet")) +@Singleton +public class CapabilityServlet extends AbstractValidationsServlet { + private static final Logger LOGGER = Logger.getLogger(CapabilityServlet.class); + private final CapabilitiesBusinessLogic capabilitiesBusinessLogic; + + @Inject + public CapabilityServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + CapabilitiesBusinessLogic capabilitiesBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.capabilitiesBusinessLogic = capabilitiesBusinessLogic; + } + + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/capabilities") + @Operation(description = "Create Capabilities on resource", method = "POST", + summary = "Create Capabilities on resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Capabilities"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Capability already exist")}) + public Response createCapabilitiesOnResource( + @Parameter(description = "Capability to create", required = true) String data, + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "resources" , resourceId, + request, userId, false, "createCapabilities"); + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/capabilities") + @Operation(description = "Update Capabilities on resource", method = "PUT", + summary = "Update Capabilities on resource",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Capabilities"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateCapabilitiesOnResource( + @Parameter(description = "Capabilities to update", required = true) String data, + @Parameter(description = "Component Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "resources", resourceId, + request, userId, true, "updateCapabilities"); + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/capabilities/{capabilityId}") + @Operation(description = "Get Capability from resource", method = "GET", + summary = "GET Capability from resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET Capability"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response getCapabilityOnResource( + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Parameter(description = "Capability Id") @PathParam("capabilityId") String capabilityId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return get(capabilityId, resourceId, request, userId); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/capabilities/{capabilityId}") + @Operation(description = "Delete capability from resource", method = "DELETE", + summary = "Delete capability from resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete capability"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteCapabilityOnResource( + @Parameter(description = "capability Id") @PathParam("capabilityId") String capabilityId, + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return delete(capabilityId, resourceId, request, userId); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/capabilities") + @Operation(description = "Create Capabilities on service", method = "POST", + summary = "Create Capabilities on service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Capabilities"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Capability already exist")}) + public Response createCapabilitiesOnService( + @Parameter(description = "Capability to create", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "services" , serviceId, + request, userId, false, "createCapabilities"); + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/capabilities") + @Operation(description = "Update Capabilities on service", method = "PUT", + summary = "Update Capabilities on service",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Capabilities"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateCapabilitiesOnService( + @Parameter(description = "Capabilities to update", required = true) String data, + @Parameter(description = "Component Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "services", serviceId, + request, userId, true, "updateCapabilities"); + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/capabilities/{capabilityId}") + @Operation(description = "Get Capability from service", method = "GET", + summary = "GET Capability from service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET Capability"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response getCapabilityOnService( + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Capability Id") @PathParam("capabilityId") String capabilityId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return get(capabilityId, serviceId, request, userId); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/capabilities/{capabilityId}") + @Operation(description = "Delete capability from service", method = "DELETE", + summary = "Delete capability from service",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete capability"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteCapabilityOnService( + @Parameter(description = "capability Id") @PathParam("capabilityId") String capabilityId, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return delete(capabilityId, serviceId, request, userId); + } + + private Response createOrUpdate (String data, String componentType, String componentId, + HttpServletRequest request, + String userId, + boolean isUpdate, + String errorContext) { + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId); + try { + String componentIdLower = componentId.toLowerCase(); + + Either, ResponseFormat> mappedCapabilitiesDataEither + = getMappedCapabilitiesData(data, modifier, ComponentTypeEnum.findByParamName(componentType)); + if(mappedCapabilitiesDataEither.isRight()) { + LOGGER.error("Failed to create or update capabilities"); + buildErrorResponse(mappedCapabilitiesDataEither.right().value()); + } + List mappedCapabilitiesData = mappedCapabilitiesDataEither.left().value(); + Either, ResponseFormat> actionResponse; + if(isUpdate) { + actionResponse = capabilitiesBusinessLogic.updateCapabilities(componentIdLower, + mappedCapabilitiesData, modifier, errorContext, true); + } else { + actionResponse = capabilitiesBusinessLogic.createCapabilities(componentIdLower, + mappedCapabilitiesData, modifier, errorContext, true); + } + if (actionResponse.isRight()) { + LOGGER.error("Failed to create or update capabilities"); + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Capabilities create or update"); + LOGGER.error("Failed to create or update capabilities with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Response get (String capabilityIdToGet, String componentId, + HttpServletRequest request, String userId){ + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + LOGGER.debug("Start get request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + + Either actionResponse = capabilitiesBusinessLogic + .getCapability(componentIdLower, capabilityIdToGet, modifier, true); + if (actionResponse.isRight()) { + LOGGER.error("failed to get capability"); + return buildErrorResponse(actionResponse.right().value()); + } + Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get capability"); + LOGGER.error("get capabilities failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Response delete (String capabilityId, String componentId, HttpServletRequest + request, String userId){ + + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + LOGGER.debug("Start delete request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + + Either actionResponse = capabilitiesBusinessLogic + .deleteCapability(componentIdLower, capabilityId, modifier, true); + if (actionResponse.isRight()) { + LOGGER.error("failed to delete capability"); + return buildErrorResponse(actionResponse.right().value()); + } + Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete capability"); + LOGGER.error("Delete capability failed with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Either, ResponseFormat> getMappedCapabilitiesData(String inputJson, User user, + ComponentTypeEnum componentTypeEnum){ + Either mappedData = getComponentsUtils() + .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, + AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); + Optional> capabilityDefinitionList = + mappedData.left().value().getCapabilities().values().stream().findFirst(); + return capabilityDefinitionList., ResponseFormat>> + map(Either::left).orElseGet(() -> Either.right(getComponentsUtils() + .getResponseFormat(ActionStatus.GENERAL_ERROR))); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java index 638e929c97..e8e018ef71 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java @@ -1,1404 +1,1639 @@ -/*- - * ============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.servlets; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; -import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.ForwardingPaths; -import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.info.CreateAndAssotiateInfo; -import org.openecomp.sdc.be.info.GroupDefinitionInfo; -import org.openecomp.sdc.be.model.*; -import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; -import org.openecomp.sdc.be.user.UserBusinessLogic; -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.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.InputStream; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.Map; - -/** - * Root resource (exposed at "/" path) .json - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Resource Instance Servlet") -@Singleton -public class ComponentInstanceServlet extends AbstractValidationsServlet { - - private static final String FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID = "Failed to get properties of component instance ID: {} in {} with ID: {}"; - private static final String GET_GROUP_ARTIFACT_BY_ID = "getGroupArtifactById"; - private static final String GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION = "getGroupArtifactById unexpected exception"; - private static final String GET_START_HANDLE_REQUEST_OF = "(GET) Start handle request of {}"; - private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS = "Start handle request of updateResourceInstanceProperty. Received property is {}"; - private static final String UPDATE_RESOURCE_INSTANCE = "Update Resource Instance"; - private static final String RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE = "Resource Instance - updateResourceInstance"; - private static final String UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION = "update resource instance with exception"; - private static final String FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT = "Failed to convert received data to BE format."; - private static final String EMPTY_BODY_WAS_SENT = "Empty body was sent."; - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; - private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}"; - private static final Logger log = Logger.getLogger(ComponentInstanceServlet.class); - private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken() {}.getType(); - private static final Gson gsonDeserializer = new GsonBuilder().registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser()).create(); - private final GroupBusinessLogic groupBL; - private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic; - private final ServiceBusinessLogic serviceBusinessLogic; - - - @Inject - public ComponentInstanceServlet(UserBusinessLogic userBusinessLogic, - GroupBusinessLogic groupBL, ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ServiceBusinessLogic serviceBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.groupBL = groupBL; - this.componentInstanceBusinessLogic = componentInstanceBL; - this.serviceBusinessLogic = serviceBusinessLogic; - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create ComponentInstance", httpMethod = "POST", notes = "Returns created ComponentInstance", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Component created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Component instance already exist") }) - public Response createComponentInstance(@ApiParam(value = "RI object to be created", required = true) String data, @PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - - try { - - ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); - componentInstance.setInvariantName(null); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - Either actionResponse = componentInstanceBusinessLogic.createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance"); - log.debug("create component instance failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateComponentInstanceMetadata(@PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, - @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - try { - - log.debug(START_HANDLE_REQUEST_OF, url); - - InputStream inputStream = request.getInputStream(); - - byte[] bytes = IOUtils.toByteArray(inputStream); - - if (bytes == null || bytes.length == 0) { - log.info(EMPTY_BODY_WAS_SENT); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - String userId = request.getHeader(Constants.USER_ID_HEADER); - - String data = new String(bytes); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - Either convertResponse = convertToResourceInstance(data); - - if (convertResponse.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE); - log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); - return buildErrorResponse(convertResponse.right().value()); - } - - ComponentInstance resourceInstance = convertResponse.left().value(); - Either actionResponse = componentInstanceBusinessLogic.updateComponentInstanceMetadata(containerComponentType, componentId, componentInstanceId, userId, resourceInstance); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - ComponentInstance resultValue = actionResponse.left().value(); - if (componentTypeEnum.equals(ComponentTypeEnum.SERVICE)){ - boolean shouldCreateServiceFilter = resourceInstance.getDirectives() != null && resourceInstance.getDirectives().contains( - DirectivesUtils.SELECTABLE); - - if(shouldCreateServiceFilter) { - Either either = - serviceBusinessLogic.createIfNotAlreadyExistServiceFilter(componentId, componentInstanceId, userId, - true); - if (either.isRight()){ - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance Failed to create service filter."); - log.debug("Failed to create service filter."); - return buildErrorResponse(convertResponse.right().value()); - } - resultValue.setNodeFilter(either.left().value()); - } else { - Either either = serviceBusinessLogic.deleteIfNotAlreadyDeletedServiceFilter(componentId, componentInstanceId, userId,true); - if (either.isRight()){ - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance Failed to delete service filter."); - log.debug("Failed to delete service filter."); - return buildErrorResponse(convertResponse.right().value()); - } - resultValue.setNodeFilter(null); - } - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE); - log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance multiple component", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request, @ApiParam(value = "Component Instance JSON Array", required = true) final String componentInstanceJsonArray) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - try { - log.debug(START_HANDLE_REQUEST_OF, url); - - if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) { - log.info("Empty JSON list was sent."); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - String userId = request.getHeader(Constants.USER_ID_HEADER); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either, ResponseFormat> convertResponse = convertToMultipleResourceInstance(componentInstanceJsonArray); - - if (convertResponse.isRight()) { - // Using both ECOMP error methods, show to Sofer - BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE); - log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); - return buildErrorResponse(convertResponse.right().value()); - } - - List componentInstanceList = convertResponse.left().value(); - - Either, ResponseFormat> actionResponse = componentInstanceBusinessLogic - .updateComponentInstance(containerComponentType, componentId, userId, componentInstanceList, true); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE); - log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @DELETE - @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete ResourceInstance", httpMethod = "DELETE", notes = "Returns delete resourceInstance", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "ResourceInstance deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response deleteResourceInstance(@PathParam("componentId") final String componentId, @PathParam("resourceInstanceId") final String resourceInstanceId, - @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - Response response = null; - try { - log.debug(START_HANDLE_REQUEST_OF, url); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - String userId = request.getHeader(Constants.USER_ID_HEADER); - Either actionResponse = componentInstanceBusinessLogic.deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId); - - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - } - return response; - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance"); - log.debug("delete resource instance with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/associate") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Associate RI to RI", httpMethod = "POST", notes = "Returns created RelationshipInfo", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Relationship created"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Relationship already exist") }) - public Response associateRIToRI(@ApiParam(value = "unique id of the container component") @PathParam("componentId") final String componentId, - @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam("containerComponentType") final String containerComponentType, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "RelationshipInfo", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - Response response = null; - - try { - - log.debug(START_HANDLE_REQUEST_OF, url); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either regInfoW = convertToRequirementCapabilityRelDef(data); - - Either resultOp; - if (regInfoW.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - associateRIToRI"); - log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); - resultOp = Either.right(regInfoW.right().value()); - } else { - RequirementCapabilityRelDef requirementDef = regInfoW.left().value(); - requirementDef.setOriginUI(true); - resultOp = componentInstanceBusinessLogic.associateRIToRI(componentId, userId, requirementDef, componentTypeEnum); - } - - Either actionResponse = resultOp; - - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - } - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance"); - log.debug("associate resource instance to another RI with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @PUT - @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Dissociate RI from RI", httpMethod = "PUT", notes = "Returns deleted RelationshipInfo", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Relationship deleted"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response dissociateRIFromRI( - @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "unique id of the container component") @PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "RelationshipInfo", required = true) String data, @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - try { - - log.debug(START_HANDLE_REQUEST_OF, url); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either regInfoW = convertToRequirementCapabilityRelDef(data); - if (regInfoW.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - dissociateRIFromRI"); - log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); - return buildErrorResponse(regInfoW.right().value()); - } - - RequirementCapabilityRelDef requirementDef = regInfoW.left().value(); - Either actionResponse = componentInstanceBusinessLogic.dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance"); - log.debug("dissociate resource instance from service failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create RI and associate RI to RI", httpMethod = "POST", notes = "Returns created RI and RelationshipInfo", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "RI created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Relationship already exist") }) - public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - try { - - log.debug(START_HANDLE_REQUEST_OF, url); - - InputStream inputStream = request.getInputStream(); - - byte[] bytes = IOUtils.toByteArray(inputStream); - - if (bytes == null || bytes.length == 0) { - log.info(EMPTY_BODY_WAS_SENT); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - String userId = request.getHeader(Constants.USER_ID_HEADER); - - String data = new String(bytes); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class); - if (convertStatus.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI"); - log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); - Either formattedResponse = Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value())); - return buildErrorResponse(formattedResponse.right().value()); - } - - CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value(); - RequirementCapabilityRelDef requirementDef = createAndAssotiateInfo.getAssociate(); - requirementDef.setOriginUI(true); - Either actionResponse = componentInstanceBusinessLogic.createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance"); - log.debug("create and associate RI failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateResourceInstanceProperties(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Context final HttpServletRequest request, @ApiParam(value = "Component Instance Properties JSON Array", required = true) final String componentInstancePropertiesJsonArray) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - try { - Wrapper errorWrapper = new Wrapper<>(); - List propertiesToUpdate = new ArrayList<>(); - if (errorWrapper.isEmpty()) { - Either, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(componentInstancePropertiesJsonArray); - if (propertiesToUpdateEither.isRight()) { - errorWrapper.setInnerElement(propertiesToUpdateEither.right().value()); - } else { - propertiesToUpdate = propertiesToUpdateEither.left().value(); - } - } - - if (!errorWrapper.isEmpty()) { - return buildErrorResponse(errorWrapper.getInnerElement()); - } - - log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, propertiesToUpdate); - - ServletContext context = request.getSession().getServletContext(); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either, ResponseFormat> actionResponse = - componentInstanceBusinessLogic.createOrUpdatePropertiesValues(componentTypeEnum, componentId, componentInstanceId, propertiesToUpdate, userId); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - - List resourceInstanceProperties = actionResponse.left().value(); - ObjectMapper mapper = new ObjectMapper(); - String result = mapper.writeValueAsString(resourceInstanceProperties); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - log.error("create and associate RI failed with exception: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/inputs") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateResourceInstanceInput(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Context final HttpServletRequest request, @ApiParam(value = "Component Instance Properties JSON Array", required = true) final String componentInstanceInputsJsonArray) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - try { - Wrapper errorWrapper = new Wrapper<>(); - List inputsToUpdate = new ArrayList<>(); - if (errorWrapper.isEmpty()) { - Either, ResponseFormat> inputsToUpdateEither = convertMultipleInputs(componentInstanceInputsJsonArray); - if (inputsToUpdateEither.isRight()) { - errorWrapper.setInnerElement(inputsToUpdateEither.right().value()); - } else { - inputsToUpdate = inputsToUpdateEither.left().value(); - } - } - if (!errorWrapper.isEmpty()) { - return buildErrorResponse(errorWrapper.getInnerElement()); - } - - log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, inputsToUpdate); - - ServletContext context = request.getSession().getServletContext(); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either, ResponseFormat> actionResponse = - componentInstanceBusinessLogic.createOrUpdateInstanceInputValues(componentTypeEnum, componentId, componentInstanceId, inputsToUpdate, userId); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - - List resourceInstanceInput = actionResponse.left().value(); - ObjectMapper mapper = new ObjectMapper(); - String result = mapper.writeValueAsString(resourceInstanceInput); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - log.error("create and associate RI failed with exception: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - /** - * Updates ResourceInstance Attribute - * - * @param componentId - * @param containerComponentType - * @param componentInstanceId - * @param userId - * @param request - * @return - */ - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attribute") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance attribute", httpMethod = "POST", notes = "Returns updated resource instance attribute", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateResourceInstanceAttribute(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - try { - - Wrapper errorWrapper = new Wrapper<>(); - Wrapper dataWrapper = new Wrapper<>(); - Wrapper attributeWrapper = new Wrapper<>(); - Wrapper blWrapper = new Wrapper<>(); - - validateInputStream(request, dataWrapper, errorWrapper); - - if (errorWrapper.isEmpty()) { - validateClassParse(dataWrapper.getInnerElement(), attributeWrapper, () -> ComponentInstanceProperty.class, errorWrapper); - } - - if (errorWrapper.isEmpty()) { - validateComponentInstanceBusinessLogic(request, containerComponentType, blWrapper, errorWrapper); - } - - if (errorWrapper.isEmpty()) { - ComponentInstanceBusinessLogic componentInstanceLogic = blWrapper.getInnerElement(); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - log.debug("Start handle request of ComponentInstanceAttribute. Received attribute is {}", attributeWrapper.getInnerElement()); - Either eitherAttribute = componentInstanceLogic.createOrUpdateAttributeValue(componentTypeEnum, componentId, componentInstanceId, attributeWrapper.getInnerElement(), userId); - if (eitherAttribute.isRight()) { - errorWrapper.setInnerElement(eitherAttribute.right().value()); - } else { - attributeWrapper.setInnerElement(eitherAttribute.left().value()); - } - } - - return buildResponseFromElement(errorWrapper, attributeWrapper); - - } catch (Exception e) { - log.error("create and associate RI failed with exception: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @DELETE - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance", httpMethod = "DELETE", notes = "Returns deleted resource instance property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response deleteResourceInstanceProperty(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "property id") @PathParam("propertyId") final String propertyId, - @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - try { - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either actionResponse = componentInstanceBusinessLogic.deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId); - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - } catch (Exception e) { - log.error("create and associate RI failed with exception: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - try ( InputStream inputStream = request.getInputStream()) { - - byte[] bytes = IOUtils.toByteArray(inputStream); - - if (bytes == null || bytes.length == 0) { - log.info(EMPTY_BODY_WAS_SENT); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - String userId = request.getHeader(Constants.USER_ID_HEADER); - - String data = new String(bytes); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either convertResponse = convertToResourceInstance(data); - - if (convertResponse.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE); - log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); - return buildErrorResponse(convertResponse.right().value()); - } - - ComponentInstance newResourceInstance = convertResponse.left().value(); - Either actionResponse = componentInstanceBusinessLogic.changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE); - log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @POST - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}/property") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateGroupInstanceProperty(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "group instance id") @PathParam("groupInstanceId") final String groupInstanceId, - @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - try { - Wrapper dataWrapper = new Wrapper<>(); - Wrapper errorWrapper = new Wrapper<>(); - Wrapper propertyWrapper = new Wrapper<>(); - - validateInputStream(request, dataWrapper, errorWrapper); - - if (errorWrapper.isEmpty()) { - validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper); - } - - if (!errorWrapper.isEmpty()) { - return buildErrorResponse(errorWrapper.getInnerElement()); - } - - ComponentInstanceProperty property = propertyWrapper.getInnerElement(); - - log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, property); - - ServletContext context = request.getSession().getServletContext(); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either actionResponse = componentInstanceBusinessLogic.createOrUpdateGroupInstancePropertyValue(componentTypeEnum, componentId, componentInstanceId, groupInstanceId, property, userId); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - - ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value(); - ObjectMapper mapper = new ObjectMapper(); - String result = mapper.writeValueAsString(resourceInstanceProperty); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - log.error("create and associate RI failed with exception: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @GET - @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get group artifacts ", httpMethod = "GET", notes = "Returns artifacts metadata according to groupInstId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "group found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Group not found") }) - public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, - @PathParam("groupInstId") final String groupInstId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(GET_START_HANDLE_REQUEST_OF, url); - - try { - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - Either actionResponse = groupBL - .getGroupInstWithArtifactsById(componentTypeEnum, componentId, componentInstanceId, - groupInstId, userId, false); - - if (actionResponse.isRight()) { - log.debug("failed to get all non abstract {}", containerComponentType); - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); - log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - // US831698 - @GET - @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get component instance properties", httpMethod = "GET", notes = "Returns component instance properties", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Properties found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component/Component Instance - not found") }) - public Response getInstancePropertiesById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("containerComponentId") final String containerComponentId, - @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(GET_START_HANDLE_REQUEST_OF, url); - - try { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - - Either, ResponseFormat> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstancePropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId); - - if (componentInstancePropertiesById.isRight()) { - log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId); - return buildErrorResponse(componentInstancePropertiesById.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); - log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - // US330353 - @GET - @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get component instance capability properties", httpMethod = "GET", notes = "Returns component instance capability properties", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Properties found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component/Component Instance/Capability - not found") }) - public Response getInstanceCapabilityPropertiesById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("containerComponentId") final String containerComponentId, - @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @PathParam("capabilityType") final String capabilityType, @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(GET_START_HANDLE_REQUEST_OF, url); - - try { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - - Either, ResponseFormat> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstanceCapabilityPropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, - capabilityType, capabilityName, ownerId, userId); - - if (componentInstancePropertiesById.isRight()) { - log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId); - return buildErrorResponse(componentInstancePropertiesById.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); - log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - //US 331281 - @PUT - @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Instance Capabilty Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance capabilty property updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Component/Component Instance/Capability - not found") }) - public Response updateInstanceCapabilityProperty(@PathParam("containerComponentType") final String containerComponentType, @PathParam("containerComponentId") final String containerComponentId, - @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @PathParam("capabilityType") final String capabilityType, @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId, - @ApiParam(value = "Instance capabilty property to update", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(PUT) Start handle request of {}", url); - try { - Wrapper errorWrapper = new Wrapper<>(); - List propertiesToUpdate = new ArrayList<>(); - if (errorWrapper.isEmpty()) { - Either, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(data); - if (propertiesToUpdateEither.isRight()) { - errorWrapper.setInnerElement(propertiesToUpdateEither.right().value()); - } else { - propertiesToUpdate = propertiesToUpdateEither.left().value(); - } - } - - if (!errorWrapper.isEmpty()) { - return buildErrorResponse(errorWrapper.getInnerElement()); - } - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - - Either, ResponseFormat> updateCICapProperty = componentInstanceBusinessLogic.updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, propertiesToUpdate, userId); - - if (updateCICapProperty.isRight()) { - log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId); - return buildErrorResponse(updateCICapProperty.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateCICapProperty.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); - log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{containerComponentId}/serviceProxy") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create service proxy", httpMethod = "POST", notes = "Returns created service proxy", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service proxy created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Service proxy already exist") }) - public Response createServiceProxy(@ApiParam(value = "RI object to be created", required = true) String data, @PathParam("containerComponentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - - try { - - ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); - componentInstance.setInvariantName(null); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentTypeEnum != ComponentTypeEnum.SERVICE) { - log.debug("Unsupported container component type {}", containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - Either actionResponse = componentInstanceBusinessLogic.createServiceProxy(); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create service proxy"); - log.debug("Create service proxy failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @DELETE - @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete service proxy", httpMethod = "DELETE", notes = "Returns delete service proxy", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service proxy deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response deleteServiceProxy(@PathParam("containerComponentId") final String containerComponentId, @PathParam("serviceProxyId") final String serviceProxyId, - @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - Response response = null; - try { - log.debug(START_HANDLE_REQUEST_OF, url); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - String userId = request.getHeader(Constants.USER_ID_HEADER); - Either actionResponse = componentInstanceBusinessLogic.deleteServiceProxy(); - - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - } - return response; - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete service proxy"); - log.debug("Delete service proxy failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}/changeVersion/{newServiceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update service proxy with new version", httpMethod = "POST", notes = "Returns updated service proxy", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service proxy created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response changeServiceProxyVersion(@PathParam("containerComponentId") final String containerComponentId, @PathParam("serviceProxyId") final String serviceProxyId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - try { - - String userId = request.getHeader(Constants.USER_ID_HEADER); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - Either actionResponse = componentInstanceBusinessLogic.changeServiceProxyVersion(); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update service proxy with new version"); - log.debug("Update service proxy with new version failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - /** - * REST API GET relation by Id - * Allows to get relation contained in specified component according to received Id - * @param containerComponentType - * @param componentId - * @param relationId - * @param request - * @param userId - * @return Response - */ - @GET - @Path("/{containerComponentType}/{componentId}/relationId/{relationId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get relation", httpMethod = "GET", notes = "Returns relation metadata according to relationId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "relation found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Relation not found") }) - public Response getRelationById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("componentId") final String componentId, - @PathParam("relationId") final String relationId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(GET_START_HANDLE_REQUEST_OF, url); - try { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentTypeEnum == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either actionResponse = componentInstanceBusinessLogic.getRelationById(componentId, relationId, userId, componentTypeEnum); - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getRelationById"); - log.debug("getRelationById unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Either convertToResourceInstance(String data) { - - Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE); - if (convertStatus.isRight()) { - return Either.right(convertStatus.right().value()); - } - ComponentInstance resourceInstanceInfo = convertStatus.left().value(); - - return Either.left(resourceInstanceInfo); - } - - private Either, ResponseFormat> convertToMultipleResourceInstance(String dataList) { - - Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); - if (convertStatus.isRight()) { - return Either.right(convertStatus.right().value()); - } - - return Either.left(Arrays.asList(convertStatus.left().value())); - } - - private Either, ResponseFormat> convertMultipleProperties(String dataList) { - if (StringUtils.isEmpty(dataList)) { - return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceProperty[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); - if (convertStatus.isRight()) { - return Either.right(convertStatus.right().value()); - } - return Either.left(Arrays.asList(convertStatus.left().value())); - } - - private Either, ResponseFormat> convertMultipleInputs(String dataList) { - if (StringUtils.isEmpty(dataList)) { - return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceInput[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); - if (convertStatus.isRight()) { - return Either.right(convertStatus.right().value()); - } - return Either.left(Arrays.asList(convertStatus.left().value())); - } - - - private Either convertToRequirementCapabilityRelDef(String data) { - - Either convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class); - if (convertStatus.isRight()) { - return Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value())); - } - RequirementCapabilityRelDef requirementCapabilityRelDef = convertStatus.left().value(); - return Either.left(requirementCapabilityRelDef); - } - - public Either convertJsonToObject(String data, Class clazz) { - try { - log.trace("convert json to object. json=\n {}", data); - T t; - t = gsonDeserializer.fromJson(data, clazz); - if (t == null) { - BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); - log.debug("object is null after converting from json"); - return Either.right(ActionStatus.INVALID_CONTENT); - } - return Either.left(t); - } catch (Exception e) { - // INVALID JSON - BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); - log.debug("failed to convert from json", e); - return Either.right(ActionStatus.INVALID_CONTENT); - } - } - - - @GET - @Path("/{containerComponentType}/{componentId}/paths-to-delete") - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Check if forwarding path to delete on version change", httpMethod = "GET", notes = "Returns forwarding paths to delete", - response = Response.class) - public Response changeResourceInstanceVersion( @PathParam("componentId") String componentId, - @QueryParam("componentInstanceId") final String oldComponentInstanceId, - @QueryParam("newComponentInstanceId") final String newComponentInstanceId, - @ApiParam(value = "valid values: resources / services", - allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) - @PathParam("containerComponentType") final String containerComponentType, - @Context final HttpServletRequest request) { - if (oldComponentInstanceId == null){ - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_OLD_COMPONENT_INSTANCE)); - } - if (newComponentInstanceId == null){ - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_NEW_COMPONENT_INSTANCE)); - } - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - ComponentInstance newComponentInstance; - if(StringUtils.isNotEmpty(newComponentInstanceId)){ - newComponentInstance=new ComponentInstance(); - newComponentInstance.setToscaPresentationValue(JsonPresentationFields.CI_COMPONENT_UID,newComponentInstanceId); - }else{ - log.error("missing component id"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_DATA)); - } - Either,ResponseFormat> actionResponse= componentInstanceBusinessLogic.forwardingPathOnVersionChange( - containerComponentType,componentId,oldComponentInstanceId,newComponentInstance); - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - ForwardingPaths forwardingPaths=new ForwardingPaths(); - forwardingPaths.setForwardingPathToDelete(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), forwardingPaths); - - } - - @POST - @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces((MediaType.APPLICATION_JSON)) - @ApiOperation(value = "Copy Component Instance", httpMethod = "POST", notes = "Returns updated service information", response = Service.class) - @ApiResponses(value = { - @ApiResponse(code = 201, message = "Copy and Paste Success"), - @ApiResponse(code = 403, message = "Restricted Operation"), - @ApiResponse(code = 400, message = "Invalid Content / Missing content")}) - public Response copyComponentInstance( - @ApiParam(value = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId, - @ApiParam(value = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId, - @Context final HttpServletRequest request) { - log.info("Start to copy component instance"); - ServletContext context = request.getSession().getServletContext(); - String userId = request.getHeader(Constants.USER_ID_HEADER); - final String CNTAINER_CMPT_TYPE = "services"; - - try { - ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); - inputComponentInstance.setInvariantName(null); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE); - if (componentInstanceBusinessLogic == null) { - log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "services")); - } - Either, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic.copyComponentInstance( - inputComponentInstance, containerComponentId, componentInstanceId, userId); - - if (copyComponentInstance.isRight()) { - log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value()); - return buildErrorResponse(copyComponentInstance.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - copyComponentInstance.left().value()); - } catch (Exception e) { - log.error("Failed to convert json to Map { }", data, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED, - "Failed to get the copied component instance information")); - } - } - - @POST - @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Batch Delete ResourceInstances", httpMethod = "POST") - @ApiResponses(value = { - @ApiResponse(code = 203, message = "ResourceInstances deleted"), - @ApiResponse(code = 403, message = "Restricted Operation"), - @ApiResponse(code = 400, message = "Invalid Content / Missing Content") - }) - public Response batchDeleteResourceInstances( - @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + - ComponentTypeEnum.PRODUCT_PARAM_NAME) - @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @Context final HttpServletRequest request, - @ApiParam(value = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) { - try { - if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) { - log.error("Empty JSON List was sent",componentInstanceIdLisStr); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - - if (componentInstanceBusinessLogic == null) { - log.error("Unsupported component type {}", containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr); - - if (convertResponse.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances"); - log.error("Failed to convert received data to BE format."); - return buildErrorResponse(convertResponse.right().value()); - } - - String userId = request.getHeader(Constants.USER_ID_HEADER); - List componentInstanceIdList = convertResponse.left().value(); - log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList); - Map> deleteErrorMap = componentInstanceBusinessLogic.batchDeleteComponentInstance(containerComponentType, - componentId, componentInstanceIdList, userId); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances"); - log.error("batch delete resource instances with exception" , e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @PUT - @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Batch Dissociate RI from RI", httpMethod = "PUT", notes = "Returns deleted RelationShip Info", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 201, message = "Relationship deleted"), - @ApiResponse(code = 403, message = "Missing Information"), - @ApiResponse(code = 400, message = "Invalid Content / Missing Content") - }) - public Response batchDissociateRIFromRI( - @ApiParam(value = "allowed values are resources/services/products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) - @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "unique id of the container component") - @PathParam("componentId") final String componentId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "RelationshipInfo", required = true) String data, - @Context final HttpServletRequest request) { - - try { - if (data == null || data.length() == 0) { - log.info("Empty JSON list was sent"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - - if (componentInstanceBusinessLogic == null) { - log.debug("Unsupported component type {}", containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); - } - - Either, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data); - - if (regInfoWs.isRight()) { - BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI"); - log.debug("Failed to convert received data to BE format"); - return buildErrorResponse(regInfoWs.right().value()); - } - - List requirementDefList = regInfoWs.left().value(); - List delOkResult = componentInstanceBusinessLogic.batchDissociateRIFromRI( - componentId, userId, requirementDefList, componentTypeEnum); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance"); - log.debug("batch dissociate resource instance from service failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Either, ResponseFormat> convertToStringList(String datalist) { - Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null); - - if (convertStatus.isRight()) { - return Either.right(convertStatus.right().value()); - } - - return Either.left(Arrays.asList(convertStatus.left().value())); - } - - private Either, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) { - Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null); - - if (convertStatus.isRight()) { - return Either.right(convertStatus.right().value()); - } - - return Either.left(Arrays.asList(convertStatus.left().value())); - } - -} +/*- + * ============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.servlets; + +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +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.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.ForwardingPaths; +import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.info.CreateAndAssotiateInfo; +import org.openecomp.sdc.be.info.GroupDefinitionInfo; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.exception.ResponseFormat; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +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; + +/** + * Root resource (exposed at "/" path) .json + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Resource Instance Servlet")) +@Singleton +public class ComponentInstanceServlet extends AbstractValidationsServlet { + + private static final String FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID = + "Failed to get properties of component instance ID: {} in {} with ID: {}"; + private static final String GET_GROUP_ARTIFACT_BY_ID = "getGroupArtifactById"; + private static final String GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION = + "getGroupArtifactById unexpected exception"; + private static final String GET_START_HANDLE_REQUEST_OF = "(GET) Start handle request of {}"; + private static final String START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS = + "Start handle request of updateResourceInstanceProperty. Received property is {}"; + private static final String UPDATE_RESOURCE_INSTANCE = "Update Resource Instance"; + private static final String RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE = + "Resource Instance - updateResourceInstance"; + private static final String UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION = "update resource instance with exception"; + private static final String FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT = + "Failed to convert received data to BE format."; + private static final String EMPTY_BODY_WAS_SENT = "Empty body was sent."; + private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}"; + private static final Logger log = Logger.getLogger(ComponentInstanceServlet.class); + private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken() {}.getType(); + private static final Gson gsonDeserializer = new GsonBuilder() + .registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser()).create(); + private final GroupBusinessLogic groupBL; + private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + private final ServiceBusinessLogic serviceBusinessLogic; + + + @Inject + public ComponentInstanceServlet(UserBusinessLogic userBusinessLogic, + GroupBusinessLogic groupBL, ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + ServiceBusinessLogic serviceBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.groupBL = groupBL; + this.componentInstanceBusinessLogic = componentInstanceBL; + this.serviceBusinessLogic = serviceBusinessLogic; + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create ComponentInstance", method = "POST", summary = "Returns created ComponentInstance", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Component created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Component instance already exist")}) + public Response createComponentInstance(@Parameter(description = "RI object to be created", required = true) String data, + @PathParam("componentId") final String containerComponentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + try { + + ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); + componentInstance.setInvariantName(null); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + Either actionResponse = componentInstanceBusinessLogic + .createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), + actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance"); + log.debug("create component instance failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource instance updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateComponentInstanceMetadata(@PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "valid values: resources / services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + try { + + log.debug(START_HANDLE_REQUEST_OF, url); + + InputStream inputStream = request.getInputStream(); + + byte[] bytes = IOUtils.toByteArray(inputStream); + + if (bytes == null || bytes.length == 0) { + log.info(EMPTY_BODY_WAS_SENT); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + String data = new String(bytes); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + Either convertResponse = convertToResourceInstance(data); + + if (convertResponse.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE); + log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); + return buildErrorResponse(convertResponse.right().value()); + } + + ComponentInstance resourceInstance = convertResponse.left().value(); + Either actionResponse = + componentInstanceBusinessLogic.updateComponentInstanceMetadata(containerComponentType, componentId, + componentInstanceId, userId, resourceInstance); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + ComponentInstance resultValue = actionResponse.left().value(); + if (componentTypeEnum.equals(ComponentTypeEnum.SERVICE)) { + boolean shouldCreateServiceFilter = resourceInstance.getDirectives() != null + && resourceInstance.getDirectives().contains(DirectivesUtils.SELECTABLE); + + if (shouldCreateServiceFilter) { + Either either = serviceBusinessLogic + .createIfNotAlreadyExistServiceFilter(componentId, componentInstanceId, userId, true); + if (either.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError( + "Resource Instance - updateResourceInstance Failed to create service filter."); + log.debug("Failed to create service filter."); + return buildErrorResponse(convertResponse.right().value()); + } + resultValue.setNodeFilter(either.left().value()); + } else { + Either either = serviceBusinessLogic + .deleteIfNotAlreadyDeletedServiceFilter(componentId, componentInstanceId, userId, true); + if (either.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError( + "Resource Instance - updateResourceInstance Failed to delete service filter."); + log.debug("Failed to delete service filter."); + return buildErrorResponse(convertResponse.right().value()); + } + resultValue.setNodeFilter(null); + } + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE); + log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance multiple component", method = "POST", + summary = "Returns updated resource instance", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource instance updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId, @Parameter( + description = "valid values: resources / services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request, @Parameter(description = "Component Instance JSON Array", + required = true) final String componentInstanceJsonArray) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + log.debug(START_HANDLE_REQUEST_OF, url); + + if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) { + log.info("Empty JSON list was sent."); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either, ResponseFormat> convertResponse = + convertToMultipleResourceInstance(componentInstanceJsonArray); + + if (convertResponse.isRight()) { + // Using both ECOMP error methods, show to Sofer + BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE); + log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); + return buildErrorResponse(convertResponse.right().value()); + } + + List componentInstanceList = convertResponse.left().value(); + + Either, ResponseFormat> actionResponse = componentInstanceBusinessLogic + .updateComponentInstance(containerComponentType, componentId, userId, componentInstanceList, true); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE); + log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete ResourceInstance", method = "DELETE", summary = "Returns delete resourceInstance", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "ResourceInstance deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteResourceInstance(@PathParam("componentId") final String componentId, + @PathParam("resourceInstanceId") final String resourceInstanceId, + @Parameter(description = "valid values: resources / services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + Response response = null; + try { + log.debug(START_HANDLE_REQUEST_OF, url); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + String userId = request.getHeader(Constants.USER_ID_HEADER); + Either actionResponse = componentInstanceBusinessLogic + .deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + } + return response; + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance"); + log.debug("delete resource instance with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @Parameter(description = "allowed values are resources /services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/associate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Associate RI to RI", method = "POST", summary = "Returns created RelationshipInfo", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Relationship created"), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Relationship already exist")}) + public Response associateRIToRI(@Parameter( + description = "unique id of the container component") @PathParam("componentId") final String componentId, + @Parameter(description = "allowed values are resources /services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) @PathParam("containerComponentType") final String containerComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "RelationshipInfo", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + Response response = null; + + try { + + log.debug(START_HANDLE_REQUEST_OF, url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either regInfoW = convertToRequirementCapabilityRelDef(data); + + Either resultOp; + if (regInfoW.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - associateRIToRI"); + log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); + resultOp = Either.right(regInfoW.right().value()); + } else { + RequirementCapabilityRelDef requirementDef = regInfoW.left().value(); + requirementDef.setOriginUI(true); + resultOp = componentInstanceBusinessLogic.associateRIToRI(componentId, userId, requirementDef, componentTypeEnum); + } + + Either actionResponse = resultOp; + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance"); + log.debug("associate resource instance to another RI with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @PUT + @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Dissociate RI from RI", method = "PUT", summary = "Returns deleted RelationshipInfo", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Relationship deleted"), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response dissociateRIFromRI( + @Parameter(description = "allowed values are resources /services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "unique id of the container component") @PathParam("componentId") final String componentId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "RelationshipInfo", required = true) String data, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + + log.debug(START_HANDLE_REQUEST_OF, url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either regInfoW = convertToRequirementCapabilityRelDef(data); + if (regInfoW.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - dissociateRIFromRI"); + log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); + return buildErrorResponse(regInfoW.right().value()); + } + + RequirementCapabilityRelDef requirementDef = regInfoW.left().value(); + Either actionResponse = componentInstanceBusinessLogic.dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance"); + log.debug("dissociate resource instance from service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create RI and associate RI to RI", method = "POST", + summary = "Returns created RI and RelationshipInfo", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "RI created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Relationship already exist")}) + public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + try { + + log.debug(START_HANDLE_REQUEST_OF, url); + + InputStream inputStream = request.getInputStream(); + + byte[] bytes = IOUtils.toByteArray(inputStream); + + if (bytes == null || bytes.length == 0) { + log.info(EMPTY_BODY_WAS_SENT); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + String data = new String(bytes); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class); + if (convertStatus.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI"); + log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); + Either formattedResponse = Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value())); + return buildErrorResponse(formattedResponse.right().value()); + } + + CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value(); + RequirementCapabilityRelDef requirementDef = createAndAssotiateInfo.getAssociate(); + requirementDef.setOriginUI(true); + Either actionResponse = componentInstanceBusinessLogic.createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance"); + log.debug("create and associate RI failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance property", method = "POST", + summary = "Returns updated resource instance property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource instance created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateResourceInstanceProperties( + @Parameter(description = "service id") @PathParam("componentId") final String componentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "id of user initiating the operation") @HeaderParam( + value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request, + @Parameter(description = "Component Instance Properties JSON Array", + required = true) final String componentInstancePropertiesJsonArray) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + Wrapper errorWrapper = new Wrapper<>(); + List propertiesToUpdate = new ArrayList<>(); + if (errorWrapper.isEmpty()) { + Either, ResponseFormat> propertiesToUpdateEither = convertMultipleProperties(componentInstancePropertiesJsonArray); + if (propertiesToUpdateEither.isRight()) { + errorWrapper.setInnerElement(propertiesToUpdateEither.right().value()); + } else { + propertiesToUpdate = propertiesToUpdateEither.left().value(); + } + } + + if (!errorWrapper.isEmpty()) { + return buildErrorResponse(errorWrapper.getInnerElement()); + } + + log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, propertiesToUpdate); + + ServletContext context = request.getSession().getServletContext(); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either, ResponseFormat> actionResponse = + componentInstanceBusinessLogic.createOrUpdatePropertiesValues(componentTypeEnum, componentId, componentInstanceId, propertiesToUpdate, userId); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + List resourceInstanceProperties = actionResponse.left().value(); + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(resourceInstanceProperties); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + log.error("create and associate RI failed with exception: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/inputs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance property", method = "POST", + summary = "Returns updated resource instance property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource instance created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateResourceInstanceInput( + @Parameter(description = "service id") @PathParam("componentId") final String componentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "id of user initiating the operation") @HeaderParam( + value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request, + @Parameter(description = "Component Instance Properties JSON Array", + required = true) final String componentInstanceInputsJsonArray) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + Wrapper errorWrapper = new Wrapper<>(); + List inputsToUpdate = new ArrayList<>(); + if (errorWrapper.isEmpty()) { + Either, ResponseFormat> inputsToUpdateEither = convertMultipleInputs(componentInstanceInputsJsonArray); + if (inputsToUpdateEither.isRight()) { + errorWrapper.setInnerElement(inputsToUpdateEither.right().value()); + } else { + inputsToUpdate = inputsToUpdateEither.left().value(); + } + } + if (!errorWrapper.isEmpty()) { + return buildErrorResponse(errorWrapper.getInnerElement()); + } + + log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, inputsToUpdate); + + ServletContext context = request.getSession().getServletContext(); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either, ResponseFormat> actionResponse = + componentInstanceBusinessLogic.createOrUpdateInstanceInputValues(componentTypeEnum, componentId, componentInstanceId, inputsToUpdate, userId); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + List resourceInstanceInput = actionResponse.left().value(); + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(resourceInstanceInput); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + log.error("create and associate RI failed with exception: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + /** + * Updates ResourceInstance Attribute + * + * @param componentId + * @param containerComponentType + * @param componentInstanceId + * @param userId + * @param request + * @return + */ + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attribute") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance attribute", method = "POST", + summary = "Returns updated resource instance attribute", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource instance created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateResourceInstanceAttribute( + @Parameter(description = "service id") @PathParam("componentId") final String componentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "id of user initiating the operation") @HeaderParam( + value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + + Wrapper errorWrapper = new Wrapper<>(); + Wrapper dataWrapper = new Wrapper<>(); + Wrapper attributeWrapper = new Wrapper<>(); + Wrapper blWrapper = new Wrapper<>(); + + validateInputStream(request, dataWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + validateClassParse(dataWrapper.getInnerElement(), attributeWrapper, + () -> ComponentInstanceProperty.class, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + validateComponentInstanceBusinessLogic(request, containerComponentType, blWrapper, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + ComponentInstanceBusinessLogic componentInstanceLogic = blWrapper.getInnerElement(); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + log.debug("Start handle request of ComponentInstanceAttribute. Received attribute is {}", + attributeWrapper.getInnerElement()); + Either eitherAttribute = + componentInstanceLogic.createOrUpdateAttributeValue(componentTypeEnum, componentId, + componentInstanceId, attributeWrapper.getInnerElement(), userId); + if (eitherAttribute.isRight()) { + errorWrapper.setInnerElement(eitherAttribute.right().value()); + } else { + attributeWrapper.setInnerElement(eitherAttribute.left().value()); + } + } + + return buildResponseFromElement(errorWrapper, attributeWrapper); + + } catch (Exception e) { + log.error("create and associate RI failed with exception: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance", method = "DELETE", + summary = "Returns deleted resource instance property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource instance created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteResourceInstanceProperty( + @Parameter(description = "service id") @PathParam("componentId") final String componentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "property id") @PathParam("propertyId") final String propertyId, + @Parameter(description = "id of user initiating the operation") @HeaderParam( + value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either actionResponse = componentInstanceBusinessLogic + .deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId); + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + } catch (Exception e) { + log.error("create and associate RI failed with exception: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance", method = "POST", summary = "Returns updated resource instance", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource instance created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + try ( InputStream inputStream = request.getInputStream()) { + + byte[] bytes = IOUtils.toByteArray(inputStream); + + if (bytes == null || bytes.length == 0) { + log.info(EMPTY_BODY_WAS_SENT); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + String data = new String(bytes); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either convertResponse = convertToResourceInstance(data); + + if (convertResponse.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError(RESOURCE_INSTANCE_UPDATE_RESOURCE_INSTANCE); + log.debug(FAILED_TO_CONVERT_RECEIVED_DATA_TO_BE_FORMAT); + return buildErrorResponse(convertResponse.right().value()); + } + + ComponentInstance newResourceInstance = convertResponse.left().value(); + Either actionResponse = componentInstanceBusinessLogic.changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_RESOURCE_INSTANCE); + log.debug(UPDATE_RESOURCE_INSTANCE_WITH_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}/property") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update resource instance property", method = "POST", + summary = "Returns updated resource instance property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource instance created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateGroupInstanceProperty( + @Parameter(description = "service id") @PathParam("componentId") final String componentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, + @Parameter(description = "group instance id") @PathParam("groupInstanceId") final String groupInstanceId, + @Parameter(description = "id of user initiating the operation") @HeaderParam( + value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + Wrapper dataWrapper = new Wrapper<>(); + Wrapper errorWrapper = new Wrapper<>(); + Wrapper propertyWrapper = new Wrapper<>(); + + validateInputStream(request, dataWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper); + } + + if (!errorWrapper.isEmpty()) { + return buildErrorResponse(errorWrapper.getInnerElement()); + } + + ComponentInstanceProperty property = propertyWrapper.getInnerElement(); + + log.debug(START_HANDLE_REQUEST_OF_UPDATE_RESOURCE_INSTANCE_PROPERTY_RECEIVED_PROPERTY_IS, property); + + ServletContext context = request.getSession().getServletContext(); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either actionResponse = componentInstanceBusinessLogic.createOrUpdateGroupInstancePropertyValue(componentTypeEnum, componentId, componentInstanceId, groupInstanceId, property, userId); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value(); + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(resourceInstanceProperty); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + log.error("create and associate RI failed with exception: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @GET + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get group artifacts ", method = "GET", + summary = "Returns artifacts metadata according to groupInstId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "group found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Group not found")}) + public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("groupInstId") final String groupInstId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(GET_START_HANDLE_REQUEST_OF, url); + + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + Either actionResponse = groupBL + .getGroupInstWithArtifactsById(componentTypeEnum, componentId, componentInstanceId, + groupInstId, userId, false); + + if (actionResponse.isRight()) { + log.debug("failed to get all non abstract {}", containerComponentType); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); + log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + // US831698 + @GET + @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get component instance properties", method = "GET", + summary = "Returns component instance properties", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Properties found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component/Component Instance - not found")}) + public Response getInstancePropertiesById(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("containerComponentId") final String containerComponentId, + @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(GET_START_HANDLE_REQUEST_OF, url); + + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + + Either, ResponseFormat> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstancePropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, userId); + + if (componentInstancePropertiesById.isRight()) { + log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId); + return buildErrorResponse(componentInstancePropertiesById.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); + log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + // US330353 + @GET + @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get component instance capability properties", method = "GET", + summary = "Returns component instance capability properties", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Properties found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")}) + public Response getInstanceCapabilityPropertiesById( + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("containerComponentId") final String containerComponentId, + @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, + @PathParam("capabilityType") final String capabilityType, + @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(GET_START_HANDLE_REQUEST_OF, url); + + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + + Either, ResponseFormat> componentInstancePropertiesById = componentInstanceBusinessLogic.getComponentInstanceCapabilityPropertiesById(containerComponentType, containerComponentId, componentInstanceUniqueId, + capabilityType, capabilityName, ownerId, userId); + + if (componentInstancePropertiesById.isRight()) { + log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId); + return buildErrorResponse(componentInstancePropertiesById.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), componentInstancePropertiesById.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); + log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + //US 331281 + @PUT + @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/capability/{capabilityType}/capabilityName/{capabilityName}/ownerId/{ownerId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Instance Capabilty Property", method = "PUT", + summary = "Returns updated property", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "Resource instance capabilty property updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Component/Component Instance/Capability - not found")}) + public Response updateInstanceCapabilityProperty( + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("containerComponentId") final String containerComponentId, + @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, + @PathParam("capabilityType") final String capabilityType, + @PathParam("capabilityName") final String capabilityName, @PathParam("ownerId") final String ownerId, + @Parameter(description = "Instance capabilty property to update", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(PUT) Start handle request of {}", url); + try { + Wrapper errorWrapper = new Wrapper<>(); + List propertiesToUpdate = new ArrayList<>(); + if (errorWrapper.isEmpty()) { + Either, ResponseFormat> propertiesToUpdateEither = + convertMultipleProperties(data); + if (propertiesToUpdateEither.isRight()) { + errorWrapper.setInnerElement(propertiesToUpdateEither.right().value()); + } else { + propertiesToUpdate = propertiesToUpdateEither.left().value(); + } + } + + if (!errorWrapper.isEmpty()) { + return buildErrorResponse(errorWrapper.getInnerElement()); + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + + Either, ResponseFormat> updateCICapProperty = componentInstanceBusinessLogic.updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, propertiesToUpdate, userId); + + if (updateCICapProperty.isRight()) { + log.debug(FAILED_TO_GET_PROPERTIES_OF_COMPONENT_INSTANCE_ID_IN_WITH_ID, componentInstanceUniqueId, containerComponentType, containerComponentId); + return buildErrorResponse(updateCICapProperty.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateCICapProperty.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_GROUP_ARTIFACT_BY_ID); + log.debug(GET_GROUP_ARTIFACT_BY_ID_UNEXPECTED_EXCEPTION, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{containerComponentId}/serviceProxy") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create service proxy", method = "POST", summary = "Returns created service proxy", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service proxy created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service proxy already exist")}) + public Response createServiceProxy(@Parameter(description = "RI object to be created", required = true) String data, + @PathParam("containerComponentId") final String containerComponentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + try { + + ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); + componentInstance.setInvariantName(null); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentTypeEnum != ComponentTypeEnum.SERVICE) { + log.debug("Unsupported container component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + Either actionResponse = componentInstanceBusinessLogic.createServiceProxy(); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create service proxy"); + log.debug("Create service proxy failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete service proxy", method = "DELETE", summary = "Returns delete service proxy", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service proxy deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteServiceProxy(@PathParam("containerComponentId") final String containerComponentId, + @PathParam("serviceProxyId") final String serviceProxyId, + @Parameter(description = "valid values: resources / services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + Response response = null; + try { + log.debug(START_HANDLE_REQUEST_OF, url); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + String userId = request.getHeader(Constants.USER_ID_HEADER); + Either actionResponse = componentInstanceBusinessLogic.deleteServiceProxy(); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + } + return response; + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete service proxy"); + log.debug("Delete service proxy failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{containerComponentId}/serviceProxy/{serviceProxyId}/changeVersion/{newServiceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update service proxy with new version", method = "POST", + summary = "Returns updated service proxy", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service proxy created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response changeServiceProxyVersion(@PathParam("containerComponentId") final String containerComponentId, + @PathParam("serviceProxyId") final String serviceProxyId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + try { + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + Either actionResponse = componentInstanceBusinessLogic.changeServiceProxyVersion(); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update service proxy with new version"); + log.debug("Update service proxy with new version failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + /** + * REST API GET relation by Id + * Allows to get relation contained in specified component according to received Id + * @param containerComponentType + * @param componentId + * @param relationId + * @param request + * @param userId + * @return Response + */ + @GET + @Path("/{containerComponentType}/{componentId}/relationId/{relationId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get relation", method = "GET", + summary = "Returns relation metadata according to relationId",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "relation found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Relation not found")}) + public Response getRelationById(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("relationId") final String relationId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(GET_START_HANDLE_REQUEST_OF, url); + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentTypeEnum == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either actionResponse = componentInstanceBusinessLogic.getRelationById(componentId, relationId, userId, componentTypeEnum); + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getRelationById"); + log.debug("getRelationById unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Either convertToResourceInstance(String data) { + + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE); + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + ComponentInstance resourceInstanceInfo = convertStatus.left().value(); + + return Either.left(resourceInstanceInfo); + } + + private Either, ResponseFormat> convertToMultipleResourceInstance(String dataList) { + + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + + return Either.left(Arrays.asList(convertStatus.left().value())); + } + + private Either, ResponseFormat> convertMultipleProperties(String dataList) { + if (StringUtils.isEmpty(dataList)) { + return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceProperty[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + return Either.left(Arrays.asList(convertStatus.left().value())); + } + + private Either, ResponseFormat> convertMultipleInputs(String dataList) { + if (StringUtils.isEmpty(dataList)) { + return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstanceInput[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + return Either.left(Arrays.asList(convertStatus.left().value())); + } + + + private Either convertToRequirementCapabilityRelDef(String data) { + + Either convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class); + if (convertStatus.isRight()) { + return Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value())); + } + RequirementCapabilityRelDef requirementCapabilityRelDef = convertStatus.left().value(); + return Either.left(requirementCapabilityRelDef); + } + + public Either convertJsonToObject(String data, Class clazz) { + try { + log.trace("convert json to object. json=\n {}", data); + T t; + t = gsonDeserializer.fromJson(data, clazz); + if (t == null) { + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("object is null after converting from json"); + return Either.right(ActionStatus.INVALID_CONTENT); + } + return Either.left(t); + } catch (Exception e) { + // INVALID JSON + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json", e); + return Either.right(ActionStatus.INVALID_CONTENT); + } + } + + + @GET + @Path("/{containerComponentType}/{componentId}/paths-to-delete") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Check if forwarding path to delete on version change", method = "GET", summary = "Returns forwarding paths to delete", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + public Response changeResourceInstanceVersion( @PathParam("componentId") String componentId, + @QueryParam("componentInstanceId") final String oldComponentInstanceId, + @QueryParam("newComponentInstanceId") final String newComponentInstanceId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) + @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + if (oldComponentInstanceId == null){ + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_OLD_COMPONENT_INSTANCE)); + } + if (newComponentInstanceId == null){ + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_NEW_COMPONENT_INSTANCE)); + } + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + ComponentInstance newComponentInstance; + if(StringUtils.isNotEmpty(newComponentInstanceId)){ + newComponentInstance=new ComponentInstance(); + newComponentInstance.setToscaPresentationValue(JsonPresentationFields.CI_COMPONENT_UID,newComponentInstanceId); + }else{ + log.error("missing component id"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_DATA)); + } + Either,ResponseFormat> actionResponse= componentInstanceBusinessLogic.forwardingPathOnVersionChange( + containerComponentType,componentId,oldComponentInstanceId,newComponentInstance); + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + ForwardingPaths forwardingPaths=new ForwardingPaths(); + forwardingPaths.setForwardingPathToDelete(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), forwardingPaths); + + } + + @POST + @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces((MediaType.APPLICATION_JSON)) + @Operation(description = "Copy Component Instance", method = "POST", summary = "Returns updated service information",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Copy and Paste Success"), + @ApiResponse(responseCode = "403", description = "Restricted Operation"), + @ApiResponse(responseCode = "400", description = "Invalid Content / Missing content")}) + public Response copyComponentInstance( + @Parameter(description = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId, + @Parameter(description = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId, + @Context final HttpServletRequest request) { + log.info("Start to copy component instance"); + ServletContext context = request.getSession().getServletContext(); + String userId = request.getHeader(Constants.USER_ID_HEADER); + final String CNTAINER_CMPT_TYPE = "services"; + + try { + ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); + inputComponentInstance.setInvariantName(null); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "services")); + } + Either, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic.copyComponentInstance( + inputComponentInstance, containerComponentId, componentInstanceId, userId); + + if (copyComponentInstance.isRight()) { + log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value()); + return buildErrorResponse(copyComponentInstance.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + copyComponentInstance.left().value()); + } catch (Exception e) { + log.error("Failed to convert json to Map { }", data, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED, + "Failed to get the copied component instance information")); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Batch Delete ResourceInstances", method = "POST") + @ApiResponses(value = { + @ApiResponse(responseCode = "203", description = "ResourceInstances deleted"), + @ApiResponse(responseCode = "403", description = "Restricted Operation"), + @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content") + }) + public Response batchDeleteResourceInstances( + @Parameter(description = "valid values: resources / services / products", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME})) + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @Context final HttpServletRequest request, + @Parameter(description = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) { + try { + if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) { + log.error("Empty JSON List was sent",componentInstanceIdLisStr); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + + if (componentInstanceBusinessLogic == null) { + log.error("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr); + + if (convertResponse.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances"); + log.error("Failed to convert received data to BE format."); + return buildErrorResponse(convertResponse.right().value()); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + List componentInstanceIdList = convertResponse.left().value(); + log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList); + Map> deleteErrorMap = componentInstanceBusinessLogic.batchDeleteComponentInstance(containerComponentType, + componentId, componentInstanceIdList, userId); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances"); + log.error("batch delete resource instances with exception" , e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @PUT + @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Batch Dissociate RI from RI", method = "PUT", + summary = "Returns deleted RelationShip Info", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Relationship deleted"), + @ApiResponse(responseCode = "403", description = "Missing Information"), + @ApiResponse(responseCode = "400", description = "Invalid Content / Missing Content")}) + public Response batchDissociateRIFromRI( + @Parameter(description = "allowed values are resources/services/products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "unique id of the container component") @PathParam("componentId") final String componentId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "RelationshipInfo", required = true) String data, + @Context final HttpServletRequest request) { + + try { + if (data == null || data.length() == 0) { + log.info("Empty JSON list was sent"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + + if (componentInstanceBusinessLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data); + + if (regInfoWs.isRight()) { + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI"); + log.debug("Failed to convert received data to BE format"); + return buildErrorResponse(regInfoWs.right().value()); + } + + List requirementDefList = regInfoWs.left().value(); + List delOkResult = componentInstanceBusinessLogic.batchDissociateRIFromRI( + componentId, userId, requirementDefList, componentTypeEnum); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance"); + log.debug("batch dissociate resource instance from service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Either, ResponseFormat> convertToStringList(String datalist) { + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null); + + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + + return Either.left(Arrays.asList(convertStatus.left().value())); + } + + private Either, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) { + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null); + + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + + return Either.left(Arrays.asList(convertStatus.left().value())); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java index 688863784c..355c3e0bd2 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java @@ -1,408 +1,467 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * 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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.util.List; -import java.util.Map; -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.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.PropertyDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; -import org.openecomp.sdc.be.resources.data.EntryData; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.exception.ResponseFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Component Property Servlet", description = "Property Servlet - used to create properties in Service and Resource") -@Singleton -public class ComponentPropertyServlet extends BeGenericServlet { - - private final PropertyBusinessLogic propertyBusinessLogic; - private final ApplicationDataTypeCache applicationDataTypeCache; - - @Inject - public ComponentPropertyServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - ApplicationDataTypeCache applicationDataTypeCache, - PropertyBusinessLogic propertyBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.applicationDataTypeCache = applicationDataTypeCache; - this.propertyBusinessLogic = propertyBusinessLogic; - } - - private static final Logger log = LoggerFactory.getLogger(ComponentPropertyServlet.class); - private static final String CREATE_PROPERTY = "Create Property"; - private static final String DEBUG_MESSAGE = "Start handle request of {} modifier id is {}"; - - @POST - @Path("services/{serviceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Service Property", httpMethod = "POST", notes = "Returns created service property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service property created"), - @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Service property already exist") }) - public Response createPropertyInService(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "Service property to be created", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return createProperty(serviceId, data, request, userId); - } - - @POST - @Path("resources/{resourceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Resource Property", httpMethod = "POST", notes = "Returns created service property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"), - @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Resource property already exist") }) - public Response createPropertyInResource(@ApiParam(value = "Resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "Resource property to be created", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return createProperty(resourceId, data, request, userId); - } - - - @GET - @Path("services/{serviceId}/properties/{propertyId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Service Property", httpMethod = "GET", notes = "Returns property of service", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Service property not found") }) - public Response getPropertyInService(@ApiParam(value = "service id of property", required = true) - @PathParam("serviceId") final String serviceId, @ApiParam(value = "property id to get", required = true) @PathParam("propertyId") final String propertyId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getProperty(serviceId, propertyId, request, userId); - } - - @GET - @Path("resources/{resourceId}/properties/{propertyId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Resource Property", httpMethod = "GET", notes = "Returns property of resource", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Resource property not found") }) - public Response getPropertyInResource(@ApiParam(value = "resource id of property", required = true) - @PathParam("resourceId") final String resourceId, @ApiParam(value = "property id to get", required = true) @PathParam("propertyId") final String propertyId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getProperty(resourceId, propertyId, request, userId); - } - - @GET - @Path("services/{serviceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Service Property", httpMethod = "GET", notes = "Returns property list of service", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Service property not found") }) - public Response getPropertyListInService(@ApiParam(value = "service id of property", required = true) @PathParam("serviceId") final String serviceId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getPropertyList(serviceId, request, userId); - } - - @GET - @Path("resources/{resourceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Resource Property", httpMethod = "GET", notes = "Returns property list of resource", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Resource property not found") }) - public Response getPropertyListInResource(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return getPropertyList(resourceId, request, userId); - } - - @DELETE - @Path("services/{serviceId}/properties/{propertyId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete Service Property", httpMethod = "DELETE", notes = "Returns deleted property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Service property not found") }) - public Response deletePropertyInService(@ApiParam(value = "service id of property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "Property id to delete", required = true) @PathParam("propertyId") final String propertyId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return deleteProperty(serviceId, propertyId, request, userId); - } - - @DELETE - @Path("resources/{resourceId}/properties/{propertyId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete Resource Property", httpMethod = "DELETE", notes = "Returns deleted property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Resource property not found") }) - public Response deletePropertyInResource(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "Property id to delete", required = true) @PathParam("propertyId") final String propertyId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return deleteProperty(resourceId, propertyId, request, userId); - } - - @PUT - @Path("services/{serviceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Service Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service property updated"), - @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updatePropertyInService(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, - @ApiParam(value = "Service property to update", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return updateProperty(serviceId, data, request, userId); - } - - @PUT - @Path("resources/{resourceId}/properties") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource property updated"), - @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updatePropertyInResource(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "Resource property to update", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return updateProperty(resourceId, data, request, userId); - } - - private Response createProperty(String componentId, String data, HttpServletRequest request,String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data); - - try{ - Either, ActionStatus> propertyDefinition = - getPropertyModel(componentId, data); - if (propertyDefinition.isRight()) { - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(propertyDefinition.right().value()); - return buildErrorResponse(responseFormat); - } - - Map properties = propertyDefinition.left().value(); - if (properties == null || properties.size() != 1) { - log.info("Property content is invalid - {}", data); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - return buildErrorResponse(responseFormat); - } - - Map.Entry entry = properties.entrySet().iterator().next(); - PropertyDefinition newPropertyDefinition = entry.getValue(); - newPropertyDefinition.setParentUniqueId(componentId); - String propertyName = newPropertyDefinition.getName(); - - Either, ResponseFormat> addPropertyEither = - propertyBusinessLogic.addPropertyToComponent(componentId, propertyName, newPropertyDefinition, userId); - - if(addPropertyEither.isRight()) { - return buildErrorResponse(addPropertyEither.right().value()); - } - - return buildOkResponse(newPropertyDefinition); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE_PROPERTY); - log.debug("create property failed with exception", e); - ResponseFormat responseFormat = - getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - - - private Response updateProperty(String componentId, String data, HttpServletRequest request, String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); -// - try { - // convert json to PropertyDefinition - - Either, ActionStatus> propertiesListEither = - getPropertiesListForUpdate(data); - if (propertiesListEither.isRight()) { - ResponseFormat responseFormat = - getComponentsUtils().getResponseFormat(propertiesListEither.right().value()); - return buildErrorResponse(responseFormat); - } - Map properties = propertiesListEither.left().value(); - if (properties == null) { - log.info("Property content is invalid - {}", data); - ResponseFormat responseFormat = - getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); - return buildErrorResponse(responseFormat); - } - - //Validate value and Constraint of property - Either constraintValidatorResponse = - PropertyValueConstraintValidationUtil.getInstance(). - validatePropertyConstraints(properties.values(), applicationDataTypeCache); - if (constraintValidatorResponse.isRight()) { - log.error("Failed validation value and constraint of property: {}", - constraintValidatorResponse.right().value()); - return buildErrorResponse(constraintValidatorResponse.right().value()); - } - - // update property - - for(PropertyDefinition propertyDefinition : properties.values()) { - Either, ResponseFormat> status = - propertyBusinessLogic.updateComponentProperty( - componentId, propertyDefinition.getUniqueId(), propertyDefinition, userId); - if (status.isRight()) { - log.info("Failed to update Property. Reason - ", status.right().value()); - return buildErrorResponse(status.right().value()); - } - EntryData property = status.left().value(); - PropertyDefinition updatedPropertyDefinition = property.getValue(); - - log.debug("Property id {} updated successfully ", updatedPropertyDefinition.getUniqueId()); - } - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - return buildOkResponse(responseFormat, properties); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Property"); - log.debug("update property failed with exception", e); - ResponseFormat responseFormat = - getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - - } - } - - private Response getProperty(String componentId, String propertyId, HttpServletRequest request, String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(DEBUG_MESSAGE, url, userId); - - try { - Either, ResponseFormat> retrievedPropertyEither = - propertyBusinessLogic.getComponentProperty(componentId, propertyId, userId); - - if(retrievedPropertyEither.isRight()) { - return buildErrorResponse(retrievedPropertyEither.right().value()); - } - - return buildOkResponse(retrievedPropertyEither.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE_PROPERTY); - log.debug("get property failed with exception", e); - ResponseFormat responseFormat = - getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - private Response getPropertyList(String componentId, HttpServletRequest request, String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(DEBUG_MESSAGE, url, userId); - - try { - Either, ResponseFormat> propertiesListEither = - propertyBusinessLogic.getPropertiesList(componentId, userId); - - if(propertiesListEither.isRight()) { - return buildErrorResponse(propertiesListEither.right().value()); - } - - return buildOkResponse(propertiesListEither.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE_PROPERTY); - log.debug("get property failed with exception", e); - ResponseFormat responseFormat = - getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - private Response deleteProperty(String componentId, String propertyId, HttpServletRequest request, String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(DEBUG_MESSAGE, url, userId); - - try { - - // delete the property - Either, ResponseFormat> status = - propertyBusinessLogic.deletePropertyFromComponent(componentId, propertyId, userId); - if (status.isRight()) { - log.debug("Failed to delete Property. Reason - ", status.right().value()); - return buildErrorResponse(status.right().value()); - } - Map.Entry property = status.left().value(); - String name = property.getKey(); - PropertyDefinition propertyDefinition = property.getValue(); - - log.debug("Property {} deleted successfully with id {}", name, propertyDefinition.getUniqueId()); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); - return buildOkResponse(responseFormat, propertyToJson(property)); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Property"); - log.debug("delete property failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - - } - } - -} +/* + * Copyright © 2016-2018 European Support Limited + * + * 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.servlets; + +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.PropertyBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.resources.data.EntryData; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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 = "Component Property Servlet", description = "Component Property Servlet")) +@Singleton +public class ComponentPropertyServlet extends BeGenericServlet { + + private final PropertyBusinessLogic propertyBusinessLogic; + private final ApplicationDataTypeCache applicationDataTypeCache; + + @Inject + public ComponentPropertyServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + ApplicationDataTypeCache applicationDataTypeCache, + PropertyBusinessLogic propertyBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.applicationDataTypeCache = applicationDataTypeCache; + this.propertyBusinessLogic = propertyBusinessLogic; + } + + private static final Logger log = LoggerFactory.getLogger(ComponentPropertyServlet.class); + private static final String CREATE_PROPERTY = "Create Property"; + private static final String DEBUG_MESSAGE = "Start handle request of {} modifier id is {}"; + + @POST + @Path("services/{serviceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Service Property", method = "POST", summary = "Returns created service property", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service property created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service property already exist")}) + public Response createPropertyInService( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "Service property to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return createProperty(serviceId, data, request, userId); + } + + @POST + @Path("resources/{resourceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource Property", method = "POST", summary = "Returns created service property", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource property created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource property already exist")}) + public Response createPropertyInResource( + @Parameter(description = "Resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "Resource property to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return createProperty(resourceId, data, request, userId); + } + + + @GET + @Path("services/{serviceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Service Property", method = "GET", summary = "Returns property of service", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "property"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Service property not found")}) + public Response getPropertyInService( + @Parameter(description = "service id of property", required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "property id to get", required = true) @PathParam("propertyId") final String propertyId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getProperty(serviceId, propertyId, request, userId); + } + + @GET + @Path("resources/{resourceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Resource Property", method = "GET", summary = "Returns property of resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "property"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Resource property not found")}) + public Response getPropertyInResource( + @Parameter(description = "resource id of property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "property id to get", required = true) @PathParam("propertyId") final String propertyId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getProperty(resourceId, propertyId, request, userId); + } + + @GET + @Path("services/{serviceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Service Property", method = "GET", summary = "Returns property list of service", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "property"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Service property not found")}) + public Response getPropertyListInService( + @Parameter(description = "service id of property", + required = true) @PathParam("serviceId") final String serviceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getPropertyList(serviceId, request, userId); + } + + @GET + @Path("resources/{resourceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Resource Property", method = "GET", summary = "Returns property list of resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "property"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Resource property not found")}) + public Response getPropertyListInResource( + @Parameter(description = "resource id of property", + required = true) @PathParam("resourceId") final String resourceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getPropertyList(resourceId, request, userId); + } + + @DELETE + @Path("services/{serviceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete Service Property", method = "DELETE", summary = "Returns deleted property", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "deleted property"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Service property not found")}) + public Response deletePropertyInService( + @Parameter(description = "service id of property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "Property id to delete", + required = true) @PathParam("propertyId") final String propertyId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return deleteProperty(serviceId, propertyId, request, userId); + } + + @DELETE + @Path("resources/{resourceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete Resource Property", method = "DELETE", summary = "Returns deleted property", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "deleted property"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Resource property not found")}) + public Response deletePropertyInResource( + @Parameter(description = "resource id of property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "Property id to delete", + required = true) @PathParam("propertyId") final String propertyId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return deleteProperty(resourceId, propertyId, request, userId); + } + + @PUT + @Path("services/{serviceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Service Property", method = "PUT", summary = "Returns updated property", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service property updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updatePropertyInService( + @Parameter(description = "service id to update with new property", + required = true) @PathParam("serviceId") final String serviceId, + @Parameter(description = "Service property to update", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return updateProperty(serviceId, data, request, userId); + } + + @PUT + @Path("resources/{resourceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource Property", method = "PUT", summary = "Returns updated property", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource property updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updatePropertyInResource( + @Parameter(description = "resource id to update with new property", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "Resource property to update", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return updateProperty(resourceId, data, request, userId); + } + + private Response createProperty(String componentId, String data, HttpServletRequest request,String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data); + + try{ + Either, ActionStatus> propertyDefinition = + getPropertyModel(componentId, data); + if (propertyDefinition.isRight()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(propertyDefinition.right().value()); + return buildErrorResponse(responseFormat); + } + + Map properties = propertyDefinition.left().value(); + if (properties == null || properties.size() != 1) { + log.info("Property content is invalid - {}", data); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + return buildErrorResponse(responseFormat); + } + + Map.Entry entry = properties.entrySet().iterator().next(); + PropertyDefinition newPropertyDefinition = entry.getValue(); + newPropertyDefinition.setParentUniqueId(componentId); + String propertyName = newPropertyDefinition.getName(); + + Either, ResponseFormat> addPropertyEither = + propertyBusinessLogic.addPropertyToComponent(componentId, propertyName, newPropertyDefinition, userId); + + if(addPropertyEither.isRight()) { + return buildErrorResponse(addPropertyEither.right().value()); + } + + return buildOkResponse(newPropertyDefinition); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE_PROPERTY); + log.debug("create property failed with exception", e); + ResponseFormat responseFormat = + getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + + private Response updateProperty(String componentId, String data, HttpServletRequest request, String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); +// + try { + // convert json to PropertyDefinition + + Either, ActionStatus> propertiesListEither = + getPropertiesListForUpdate(data); + if (propertiesListEither.isRight()) { + ResponseFormat responseFormat = + getComponentsUtils().getResponseFormat(propertiesListEither.right().value()); + return buildErrorResponse(responseFormat); + } + Map properties = propertiesListEither.left().value(); + if (properties == null) { + log.info("Property content is invalid - {}", data); + ResponseFormat responseFormat = + getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + return buildErrorResponse(responseFormat); + } + + //Validate value and Constraint of property + Either constraintValidatorResponse = + PropertyValueConstraintValidationUtil.getInstance(). + validatePropertyConstraints(properties.values(), applicationDataTypeCache); + if (constraintValidatorResponse.isRight()) { + log.error("Failed validation value and constraint of property: {}", + constraintValidatorResponse.right().value()); + return buildErrorResponse(constraintValidatorResponse.right().value()); + } + + // update property + + for(PropertyDefinition propertyDefinition : properties.values()) { + Either, ResponseFormat> status = + propertyBusinessLogic.updateComponentProperty( + componentId, propertyDefinition.getUniqueId(), propertyDefinition, userId); + if (status.isRight()) { + log.info("Failed to update Property. Reason - ", status.right().value()); + return buildErrorResponse(status.right().value()); + } + EntryData property = status.left().value(); + PropertyDefinition updatedPropertyDefinition = property.getValue(); + + log.debug("Property id {} updated successfully ", updatedPropertyDefinition.getUniqueId()); + } + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Property"); + log.debug("update property failed with exception", e); + ResponseFormat responseFormat = + getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + private Response getProperty(String componentId, String propertyId, HttpServletRequest request, String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(DEBUG_MESSAGE, url, userId); + + try { + Either, ResponseFormat> retrievedPropertyEither = + propertyBusinessLogic.getComponentProperty(componentId, propertyId, userId); + + if(retrievedPropertyEither.isRight()) { + return buildErrorResponse(retrievedPropertyEither.right().value()); + } + + return buildOkResponse(retrievedPropertyEither.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE_PROPERTY); + log.debug("get property failed with exception", e); + ResponseFormat responseFormat = + getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + private Response getPropertyList(String componentId, HttpServletRequest request, String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(DEBUG_MESSAGE, url, userId); + + try { + Either, ResponseFormat> propertiesListEither = + propertyBusinessLogic.getPropertiesList(componentId, userId); + + if(propertiesListEither.isRight()) { + return buildErrorResponse(propertiesListEither.right().value()); + } + + return buildOkResponse(propertiesListEither.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE_PROPERTY); + log.debug("get property failed with exception", e); + ResponseFormat responseFormat = + getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + private Response deleteProperty(String componentId, String propertyId, HttpServletRequest request, String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(DEBUG_MESSAGE, url, userId); + + try { + + // delete the property + Either, ResponseFormat> status = + propertyBusinessLogic.deletePropertyFromComponent(componentId, propertyId, userId); + if (status.isRight()) { + log.debug("Failed to delete Property. Reason - ", status.right().value()); + return buildErrorResponse(status.right().value()); + } + Map.Entry property = status.left().value(); + String name = property.getKey(); + PropertyDefinition propertyDefinition = property.getValue(); + + log.debug("Property {} deleted successfully with id {}", name, propertyDefinition.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, propertyToJson(property)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Property"); + log.debug("delete property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java index 574359ee4c..98f75dfba3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java @@ -1,399 +1,466 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.apache.commons.collections.CollectionUtils; -import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentBusinessLogicProvider; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.mixin.GroupCompositionMixin; -import org.openecomp.sdc.be.mixin.PolicyCompositionMixin; -import org.openecomp.sdc.be.model.*; -import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.be.view.ResponseView; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Component Servlet", description = "Component Servlet") -@Controller -public class ComponentServlet extends BeGenericServlet { - private static final String GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION = "getCertifiedNotAbstractComponents failed with exception"; - - private static final String GET_CERTIFIED_NON_ABSTRACT = "Get Certified Non Abstract"; - - private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}"; - - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; - - private static final Logger log = Logger.getLogger(ComponentServlet.class); - - private final ComponentBusinessLogicProvider componentBusinessLogicProvider; - - @Inject - public ComponentServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - ComponentBusinessLogicProvider componentBusinessLogicProvider) { - super(userBusinessLogic, componentsUtils); - this.componentBusinessLogicProvider = componentBusinessLogicProvider; - } - - @GET - @Path("/{componentType}/{componentUuid}/conformanceLevelValidation") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Validate Component Conformance Level", httpMethod = "GET", notes = "Returns the result according to conformance level in BE config", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response conformanceLevelValidation(@PathParam("componentType") final String componentType, @PathParam("componentUuid") final String componentUuid, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - Response response; - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - if (componentTypeEnum != null) { - ComponentBusinessLogic compBL = componentBusinessLogicProvider.getInstance(componentTypeEnum); - Either eitherConformanceLevel = compBL.validateConformanceLevel(componentUuid, componentTypeEnum, userId); - if (eitherConformanceLevel.isRight()) { - response = buildErrorResponse(eitherConformanceLevel.right().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), gson.toJson(eitherConformanceLevel.left().value())); - } - } else { - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - return response; - } - - @GET - @Path("/{componentType}/{componentId}/requirmentsCapabilities") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Component Requirments And Capabilities", httpMethod = "GET", notes = "Returns Requirements And Capabilities according to componentId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getRequirementAndCapabilities(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - Response response; - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - if (componentTypeEnum != null) { - try { - ComponentBusinessLogic compBL = componentBusinessLogicProvider.getInstance(componentTypeEnum); - Either eitherRequirementsAndCapabilities = compBL.getRequirementsAndCapabilities(componentId, componentTypeEnum, userId); - if (eitherRequirementsAndCapabilities.isRight()) { - response = buildErrorResponse(eitherRequirementsAndCapabilities.right().value()); - } else { - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(eitherRequirementsAndCapabilities.left().value())); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Capabilities and requirements for " + componentId); - log.debug("getRequirementAndCapabilities failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } else { - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - return response; - } - - @GET - @Path("/{componentType}/latestversion/notabstract") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Component Requirments And Capabilities", httpMethod = "GET", notes = "Returns Requirments And Capabilities according to componentId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getLatestVersionNotAbstractCheckoutComponents(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @QueryParam("internalComponentType") String internalComponentType, - @QueryParam("componentUids") List componentUids, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response = null; - - try { - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); - - log.debug("Received componentUids size is {}", componentUids == null ? 0 : componentUids.size()); - - Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponents(false, componentTypeEnum, internalComponentType, componentUids, userId); - - if (actionResponse.isRight()) { - log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, componentType); - return buildErrorResponse(actionResponse.right().value()); - } - Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_CERTIFIED_NON_ABSTRACT + componentType); - log.debug(GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION, e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - - } - - @POST - @Path("/{componentType}/latestversion/notabstract") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Component Requirments And Capabilities", httpMethod = "GET", notes = "Returns Requirments And Capabilities according to componentId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getLatestVersionNotAbstractCheckoutComponentsByBody(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @QueryParam("internalComponentType") String internalComponentType, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "Consumer Object to be created", required = true) List data) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(GET) Start handle request of {}", url); - Response response = null; - - try { - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); - if (log.isDebugEnabled()) { - log.debug("Received componentUids size is {}", data == null ? 0 : data.size()); - } - - Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponents(false, componentTypeEnum, internalComponentType, data, userId); - - if (actionResponse.isRight()) { - log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, componentType); - return buildErrorResponse(actionResponse.right().value()); - - } - Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); - - - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_CERTIFIED_NON_ABSTRACT + componentType); - log.debug(GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION, e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - - } - - @GET - @Path("/{componentType}/latestversion/notabstract/metadata") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Component uid only", httpMethod = "GET", notes = "Returns componentId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getLatestVersionNotAbstractCheckoutComponentsIdesOnly(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @QueryParam("internalComponentType") String internalComponentType, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "uid list", required = true) String data) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response = null; - try { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); - - Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponentsMetadata(false, HighestFilterEnum.HIGHEST_ONLY, componentTypeEnum, internalComponentType, userId); - if (actionResponse.isRight()) { - log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, componentType); - return buildErrorResponse(actionResponse.right().value()); - } - Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_CERTIFIED_NON_ABSTRACT + componentType); - log.debug(GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION, e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - - } - - @GET - @Path("/{componentType}/{componentId}/componentInstances") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get Component instances", httpMethod = "GET", notes = "Returns component instances", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getComponentInstancesFilteredByPropertiesAndInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, - @QueryParam("searchText") String searchText, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "uid" + " " + "list", required = true) String data) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(GET) Start handle request of {}", url); - Response response = null; - try { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); - - Either, ResponseFormat> actionResponse = businessLogic.getComponentInstancesFilteredByPropertiesAndInputs(componentId, userId); - if (actionResponse.isRight()) { - log.debug("failed to get all component instances filtered by properties and inputs", componentType); - return buildErrorResponse(actionResponse.right().value()); - } - Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component Instances filtered by properties & inputs" + componentType); - log.debug("getComponentInstancesFilteredByPropertiesAndInputs failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - - - /** - * This API is a generic api for ui - the api get a list of strings and return the data on the component according to to list. - * for example: list of the string "properties, inputs" will return component with the list of properties and inputs. - * - * @param componentType - * @param componentId - * @param dataParamsToReturn - * @param request - * @param userId - * @return - */ - - @GET - @Path("/{componentType}/{componentId}/filteredDataByParams") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Resource", httpMethod = "GET", notes = "Returns resource according to resourceId", response = Resource.class) - @ResponseView(mixin = {GroupCompositionMixin.class, PolicyCompositionMixin.class}) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Resource not found") }) - public Response getComponentDataFilteredByParams(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @QueryParam("include") final List dataParamsToReturn, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - - try { - String resourceIdLower = componentId.toLowerCase(); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); - - log.trace("get component with id {} filtered by ui params", componentId); - Either actionResponse = businessLogic.getComponentDataFilteredByParams(resourceIdLower, modifier, dataParamsToReturn); - - if (actionResponse.isRight()) { - log.debug("failed to get component data filtered by ui params"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get component filtered by ui params"); - log.debug("get resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - - @GET - @Path("/{componentType}/{componentId}/filteredproperties/{propertyNameFragment}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve properties belonging to component instances of specific component by name and optionally resource type", httpMethod = "GET", notes = "Returns properties belonging to component instances of specific component by name and optionally resource type", response = Map.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getFilteredComponentInstanceProperties( - @PathParam("componentType") final String componentType, - @PathParam("componentId") final String componentId, - @PathParam("propertyNameFragment") final String propertyNameFragment, - @QueryParam("resourceType") List resourceTypes, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - User user = new User(); - user.setUserId(userId); - log.debug("User Id is {}" , userId); - Response response; - try { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); - Map> filters = new EnumMap<>(FilterKeyEnum.class); - List propertyNameFragments = new ArrayList<>(); - propertyNameFragments.add(propertyNameFragment); - filters.put(FilterKeyEnum.NAME_FRAGMENT, propertyNameFragments); - if(CollectionUtils.isNotEmpty(resourceTypes)){ - filters.put(FilterKeyEnum.RESOURCE_TYPE, resourceTypes); - } - Either>, ResponseFormat> actionResponse = businessLogic.getFilteredComponentInstanceProperties(componentId, filters, userId); - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Filtered Component Instance Properties"); - log.debug("Getting of filtered component instance properties failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } -} +/*- + * ============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.servlets; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +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.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.commons.collections.CollectionUtils; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogicProvider; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.mixin.GroupCompositionMixin; +import org.openecomp.sdc.be.mixin.PolicyCompositionMixin; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.be.view.ResponseView; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.stereotype.Controller; +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 = "Component Servlet",description = "Component Servlet")) +@Controller +public class ComponentServlet extends BeGenericServlet { + private static final String GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION = "getCertifiedNotAbstractComponents failed with exception"; + + private static final String GET_CERTIFIED_NON_ABSTRACT = "Get Certified Non Abstract"; + + private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}"; + + private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + + private static final Logger log = Logger.getLogger(ComponentServlet.class); + + private final ComponentBusinessLogicProvider componentBusinessLogicProvider; + + @Inject + public ComponentServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + ComponentBusinessLogicProvider componentBusinessLogicProvider) { + super(userBusinessLogic, componentsUtils); + this.componentBusinessLogicProvider = componentBusinessLogicProvider; + } + + @GET + @Path("/{componentType}/{componentUuid}/conformanceLevelValidation") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Validate Component Conformance Level", method = "GET", + summary = "Returns the result according to conformance level in BE config", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response conformanceLevelValidation(@PathParam("componentType") final String componentType, + @PathParam("componentUuid") final String componentUuid, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + Response response; + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum != null) { + ComponentBusinessLogic compBL = componentBusinessLogicProvider.getInstance(componentTypeEnum); + Either eitherConformanceLevel = compBL.validateConformanceLevel(componentUuid, componentTypeEnum, userId); + if (eitherConformanceLevel.isRight()) { + response = buildErrorResponse(eitherConformanceLevel.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), gson.toJson(eitherConformanceLevel.left().value())); + } + } else { + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + return response; + } + + @GET + @Path("/{componentType}/{componentId}/requirmentsCapabilities") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Component Requirments And Capabilities", method = "GET", + summary = "Returns Requirements And Capabilities according to componentId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getRequirementAndCapabilities(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + Response response; + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum != null) { + try { + ComponentBusinessLogic compBL = componentBusinessLogicProvider.getInstance(componentTypeEnum); + Either eitherRequirementsAndCapabilities = compBL.getRequirementsAndCapabilities(componentId, componentTypeEnum, userId); + if (eitherRequirementsAndCapabilities.isRight()) { + response = buildErrorResponse(eitherRequirementsAndCapabilities.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(eitherRequirementsAndCapabilities.left().value())); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Capabilities and requirements for " + componentId); + log.debug("getRequirementAndCapabilities failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } else { + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + return response; + } + + @GET + @Path("/{componentType}/latestversion/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Component Requirments And Capabilities", method = "GET", + summary = "Returns Requirments And Capabilities according to componentId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getLatestVersionNotAbstractCheckoutComponents( + @PathParam("componentType") final String componentType, @Context final HttpServletRequest request, + @QueryParam("internalComponentType") String internalComponentType, + @QueryParam("componentUids") List componentUids, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); + + log.debug("Received componentUids size is {}", componentUids == null ? 0 : componentUids.size()); + + Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponents(false, componentTypeEnum, internalComponentType, componentUids, userId); + + if (actionResponse.isRight()) { + log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, componentType); + return buildErrorResponse(actionResponse.right().value()); + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_CERTIFIED_NON_ABSTRACT + componentType); + log.debug(GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION, e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @POST + @Path("/{componentType}/latestversion/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Component Requirments And Capabilities", method = "GET", + summary = "Returns Requirments And Capabilities according to componentId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getLatestVersionNotAbstractCheckoutComponentsByBody( + @PathParam("componentType") final String componentType, @Context final HttpServletRequest request, + @QueryParam("internalComponentType") String internalComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "Consumer Object to be created", required = true) List data) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(GET) Start handle request of {}", url); + Response response = null; + + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); + if (log.isDebugEnabled()) { + log.debug("Received componentUids size is {}", data == null ? 0 : data.size()); + } + + Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponents(false, componentTypeEnum, internalComponentType, data, userId); + + if (actionResponse.isRight()) { + log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, componentType); + return buildErrorResponse(actionResponse.right().value()); + + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_CERTIFIED_NON_ABSTRACT + componentType); + log.debug(GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION, e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @GET + @Path("/{componentType}/latestversion/notabstract/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Component uid only", method = "GET", summary = "Returns componentId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getLatestVersionNotAbstractCheckoutComponentsIdesOnly( + @PathParam("componentType") final String componentType, @Context final HttpServletRequest request, + @QueryParam("internalComponentType") String internalComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "uid list", required = true) String data) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); + + Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponentsMetadata(false, HighestFilterEnum.HIGHEST_ONLY, componentTypeEnum, internalComponentType, userId); + if (actionResponse.isRight()) { + log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, componentType); + return buildErrorResponse(actionResponse.right().value()); + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(GET_CERTIFIED_NON_ABSTRACT + componentType); + log.debug(GET_CERTIFIED_NOT_ABSTRACT_COMPONENTS_FAILED_WITH_EXCEPTION, e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @GET + @Path("/{componentType}/{componentId}/componentInstances") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get Component instances", method = "GET", summary = "Returns component instances", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getComponentInstancesFilteredByPropertiesAndInputs( + @PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, + @Context final HttpServletRequest request, @QueryParam("searchText") String searchText, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "uid" + " " + "list", required = true) String data) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(GET) Start handle request of {}", url); + Response response = null; + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); + + Either, ResponseFormat> actionResponse = businessLogic.getComponentInstancesFilteredByPropertiesAndInputs(componentId, userId); + if (actionResponse.isRight()) { + log.debug("failed to get all component instances filtered by properties and inputs", componentType); + return buildErrorResponse(actionResponse.right().value()); + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component Instances filtered by properties & inputs" + componentType); + log.debug("getComponentInstancesFilteredByPropertiesAndInputs failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + + + /** + * This API is a generic api for ui - the api get a list of strings and return the data on the component according to to list. + * for example: list of the string "properties, inputs" will return component with the list of properties and inputs. + * + * @param componentType + * @param componentId + * @param dataParamsToReturn + * @param request + * @param userId + * @return + */ + + @GET + @Path("/{componentType}/{componentId}/filteredDataByParams") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ResponseView(mixin = {GroupCompositionMixin.class, PolicyCompositionMixin.class}) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response getComponentDataFilteredByParams(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @QueryParam("include") final List dataParamsToReturn, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + + try { + String resourceIdLower = componentId.toLowerCase(); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); + + log.trace("get component with id {} filtered by ui params", componentId); + Either actionResponse = businessLogic.getComponentDataFilteredByParams(resourceIdLower, modifier, dataParamsToReturn); + + if (actionResponse.isRight()) { + log.debug("failed to get component data filtered by ui params"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get component filtered by ui params"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + + @GET + @Path("/{componentType}/{componentId}/filteredproperties/{propertyNameFragment}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + description = "Retrieve properties belonging to component instances of specific component by name and optionally resource type", + method = "GET", + summary = "Returns properties belonging to component instances of specific component by name and optionally resource type", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Map.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getFilteredComponentInstanceProperties( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("propertyNameFragment") final String propertyNameFragment, + @QueryParam("resourceType") List resourceTypes, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + User user = new User(); + user.setUserId(userId); + log.debug("User Id is {}" , userId); + Response response; + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = componentBusinessLogicProvider.getInstance(componentTypeEnum); + Map> filters = new EnumMap<>(FilterKeyEnum.class); + List propertyNameFragments = new ArrayList<>(); + propertyNameFragments.add(propertyNameFragment); + filters.put(FilterKeyEnum.NAME_FRAGMENT, propertyNameFragments); + if(CollectionUtils.isNotEmpty(resourceTypes)){ + filters.put(FilterKeyEnum.RESOURCE_TYPE, resourceTypes); + } + Either>, ResponseFormat> actionResponse = businessLogic.getFilteredComponentInstanceProperties(componentId, filters, userId); + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Filtered Component Instance Properties"); + log.debug("Getting of filtered component instance properties failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java index e6553a2df1..2ecbab765e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java @@ -1,208 +1,233 @@ -/*- - * ============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.servlets; - -import com.google.gson.Gson; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ConsumerBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.ConsumerDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; -import org.springframework.beans.factory.annotation.Autowired; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/consumers") -@Api(value = "Consumer Servlet", description = "Consumer Servlet") -@Singleton -public class ConsumerServlet extends BeGenericServlet { - - private static final String MODIFIER_ID_IS = "modifier id is {}"; - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; - private static final Logger log = Logger.getLogger(ConsumerServlet.class); - private final ConsumerBusinessLogic businessLogic; - - @Inject - public ConsumerServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - ConsumerBusinessLogic businessLogic) { - super(userBusinessLogic, componentsUtils); - this.businessLogic = businessLogic; - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Consumer credentials", httpMethod = "POST", notes = "Returns created ECOMP consumer credentials", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Consumer credentials created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response createConsumer(@ApiParam(value = "Consumer Object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug(MODIFIER_ID_IS, userId); - - try { - Either convertionResponse = convertJsonToObject(data, modifier, AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS); - - if (convertionResponse.isRight()) { - log.debug("failed to create Consumer"); - return buildErrorResponse(convertionResponse.right().value()); - } - - ConsumerDefinition consumer = convertionResponse.left().value(); - - Either actionResult = businessLogic.createConsumer(modifier, consumer); - - if (actionResult.isRight()) { - log.debug("failed to create Consumer"); - return buildErrorResponse(actionResult.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResult.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create consumer"); - log.debug("create consumer failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - - } - } - - @GET - @Path("/{consumerId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Consumer", httpMethod = "GET", notes = "Returns consumer according to ConsumerID", response = ConsumerDefinition.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Consumer found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Consumer not found") }) - public Response getConsumer(@PathParam("consumerId") final String consumerId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug(MODIFIER_ID_IS, userId); - - Response response = null; - try { - Either actionResponse = businessLogic.getConsumer(consumerId, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to get consumer"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Consumer"); - log.debug("get consumer failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @DELETE - @Path("/{consumerId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Deletes Consumer", httpMethod = "DELETE", notes = "Returns deleted consumer according to ConsumerID", response = ConsumerDefinition.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "Consumer deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Consumer not found") }) - public Response deleteConsumer(@PathParam("consumerId") final String consumerId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug(MODIFIER_ID_IS, userId); - - Response response = null; - try { - Either actionResponse = businessLogic.deleteConsumer(consumerId, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to delete consumer"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Consumer"); - log.debug("delete consumer failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - public Either convertJsonToObject(String data, User user, AuditingActionEnum actionEnum) { - ConsumerDefinition consumer; - Gson gson = new Gson(); - try { - log.trace("convert json to object. json=\n {}", data); - consumer = gson.fromJson(data, ConsumerDefinition.class); - if (consumer == null) { - BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); - log.debug("object is null after converting from json"); - ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorForConsumerAndAudit(user, null, actionEnum); - return Either.right(responseFormat); - } - } catch (Exception e) { - // INVALID JSON - BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); - log.debug("failed to convert from json {}", data, e); - ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorForConsumerAndAudit(user, null, actionEnum); - return Either.right(responseFormat); - } - return Either.left(consumer); - } - -} +/*- + * ============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.servlets; + +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.DELETE; +import javax.ws.rs.GET; +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.openecomp.sdc.be.components.impl.ConsumerBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ConsumerDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import com.google.gson.Gson; +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/consumers") +@OpenAPIDefinition(info = @Info(title = "Consumer Servlet",description = "Consumer Servlet")) +@Singleton +public class ConsumerServlet extends BeGenericServlet { + + private static final String MODIFIER_ID_IS = "modifier id is {}"; + private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + private static final Logger log = Logger.getLogger(ConsumerServlet.class); + private final ConsumerBusinessLogic businessLogic; + + @Inject + public ConsumerServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + ConsumerBusinessLogic businessLogic) { + super(userBusinessLogic, componentsUtils); + this.businessLogic = businessLogic; + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Consumer credentials", method = "POST", + summary = "Returns created ECOMP consumer credentials",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Consumer credentials created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response createConsumer(@Parameter(description = "Consumer Object to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug(MODIFIER_ID_IS, userId); + + try { + Either convertionResponse = convertJsonToObject(data, modifier, AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS); + + if (convertionResponse.isRight()) { + log.debug("failed to create Consumer"); + return buildErrorResponse(convertionResponse.right().value()); + } + + ConsumerDefinition consumer = convertionResponse.left().value(); + + Either actionResult = businessLogic.createConsumer(modifier, consumer); + + if (actionResult.isRight()) { + log.debug("failed to create Consumer"); + return buildErrorResponse(actionResult.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResult.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create consumer"); + log.debug("create consumer failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + @GET + @Path("/{consumerId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Consumer", method = "GET", summary = "Returns consumer according to ConsumerID", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ConsumerDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Consumer found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Consumer not found")}) + public Response getConsumer(@PathParam("consumerId") final String consumerId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug(MODIFIER_ID_IS, userId); + + Response response = null; + try { + Either actionResponse = businessLogic.getConsumer(consumerId, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get consumer"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Consumer"); + log.debug("get consumer failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/{consumerId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Deletes Consumer", method = "DELETE", + summary = "Returns deleted consumer according to ConsumerID", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ConsumerDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Consumer deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Consumer not found")}) + public Response deleteConsumer(@PathParam("consumerId") final String consumerId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug(MODIFIER_ID_IS, userId); + + Response response = null; + try { + Either actionResponse = businessLogic.deleteConsumer(consumerId, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to delete consumer"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Consumer"); + log.debug("delete consumer failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + public Either convertJsonToObject(String data, User user, AuditingActionEnum actionEnum) { + ConsumerDefinition consumer; + Gson gson = new Gson(); + try { + log.trace("convert json to object. json=\n {}", data); + consumer = gson.fromJson(data, ConsumerDefinition.class); + if (consumer == null) { + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("object is null after converting from json"); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorForConsumerAndAudit(user, null, actionEnum); + return Either.right(responseFormat); + } + } catch (Exception e) { + // INVALID JSON + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", data, e); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorForConsumerAndAudit(user, null, actionEnum); + return Either.right(responseFormat); + } + return Either.left(consumer); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java index 26ff236dec..fc6c28c8cd 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java @@ -1,151 +1,169 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.DistributionMonitoringBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.info.DistributionStatusListResponse; -import org.openecomp.sdc.be.info.DistributionStatusOfServiceListResponce; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * Root resource (exposed at "/" path) - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Distribution Service Servlet", description = "Distribution Service Servlet") -@Singleton -public class DistributionServiceServlet extends BeGenericServlet { - private static final Logger log = Logger.getLogger(DistributionServiceServlet.class); - - @Inject - public DistributionServiceServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - DistributionMonitoringBusinessLogic distributionMonitoringLogic) { - super(userBusinessLogic, componentsUtils); - this.distributionMonitoringLogic = distributionMonitoringLogic; - } - - private DistributionMonitoringBusinessLogic distributionMonitoringLogic; - - @GET - @Path("/services/{serviceUUID}/distribution") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Distributions", httpMethod = "GET", notes = "Returns list bases on the information extracted from Auditing Records according to service uuid", response = DistributionStatusListResponse.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) - public Response getServiceById(@PathParam("serviceUUID") final String serviceUUID, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - Response response = null; - ResponseFormat responseFormat = null; - - try { - Either actionResponse = distributionMonitoringLogic.getListOfDistributionServiceStatus(serviceUUID, userId); - - if (actionResponse.isRight()) { - - responseFormat = actionResponse.right().value(); - response = buildErrorResponse(responseFormat); - } else { - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - response = buildOkResponse(responseFormat, actionResponse.left().value()); - - } - - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Distribution list for Service"); - log.debug("failed to get service distribution statuses", e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - - response = buildErrorResponse(responseFormat); - return response; - } - - } - - @GET - @Path("/services/distribution/{did}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Distributions", httpMethod = "GET", notes = "Return the list of distribution status objects", response = DistributionStatusListResponse.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Status not found") }) - public Response getListOfDistributionStatuses(@PathParam("did") final String did, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - Response response = null; - ResponseFormat responseFormat = null; - - try { - Either actionResponse = distributionMonitoringLogic.getListOfDistributionStatus(did, userId); - - if (actionResponse.isRight()) { - - responseFormat = actionResponse.right().value(); - log.debug("failed to fount statuses for did {} {}", did, responseFormat); - response = buildErrorResponse(responseFormat); - } else { - - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); - log.debug("success to fount statuses for did {} {}", did, actionResponse.left().value()); - response = buildOkResponse(responseFormat, actionResponse.left().value()); - - } - - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Distribution Status"); - log.debug("failed to get distribution status ", e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - - response = buildErrorResponse(responseFormat); - return response; - } - - } - -} +/*- + * ============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.servlets; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +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.openecomp.sdc.be.components.impl.DistributionMonitoringBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.info.DistributionStatusListResponse; +import org.openecomp.sdc.be.info.DistributionStatusOfServiceListResponce; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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.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; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Distribution Service Servlet",description = "Distribution Service Servlet")) +@Singleton +public class DistributionServiceServlet extends BeGenericServlet { + private static final Logger log = Logger.getLogger(DistributionServiceServlet.class); + + @Inject + public DistributionServiceServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + DistributionMonitoringBusinessLogic distributionMonitoringLogic) { + super(userBusinessLogic, componentsUtils); + this.distributionMonitoringLogic = distributionMonitoringLogic; + } + + private DistributionMonitoringBusinessLogic distributionMonitoringLogic; + + @GET + @Path("/services/{serviceUUID}/distribution") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Distributions", method = "GET", + summary = "Returns list bases on the information extracted from Auditing Records according to service uuid", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = DistributionStatusListResponse.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response getServiceById(@PathParam("serviceUUID") final String serviceUUID, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + ResponseFormat responseFormat = null; + + try { + Either actionResponse = distributionMonitoringLogic.getListOfDistributionServiceStatus(serviceUUID, userId); + + if (actionResponse.isRight()) { + + responseFormat = actionResponse.right().value(); + response = buildErrorResponse(responseFormat); + } else { + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, actionResponse.left().value()); + + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Distribution list for Service"); + log.debug("failed to get service distribution statuses", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + + response = buildErrorResponse(responseFormat); + return response; + } + + } + + @GET + @Path("/services/distribution/{did}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Distributions", method = "GET", + summary = "Return the list of distribution status objects", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = DistributionStatusListResponse.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Status not found")}) + public Response getListOfDistributionStatuses(@PathParam("did") final String did, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + ResponseFormat responseFormat = null; + + try { + Either actionResponse = distributionMonitoringLogic.getListOfDistributionStatus(did, userId); + + if (actionResponse.isRight()) { + + responseFormat = actionResponse.right().value(); + log.debug("failed to fount statuses for did {} {}", did, responseFormat); + response = buildErrorResponse(responseFormat); + } else { + + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + log.debug("success to fount statuses for did {} {}", did, actionResponse.left().value()); + response = buildOkResponse(responseFormat, actionResponse.left().value()); + + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Distribution Status"); + log.debug("failed to get distribution status ", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + + response = buildErrorResponse(responseFormat); + return response; + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java index e143203400..0c81ad3cab 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java @@ -1,616 +1,735 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.scheduledtasks.ComponentsCleanBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.info.ArtifactTypesInfo; -import org.openecomp.sdc.be.model.*; -import org.openecomp.sdc.be.model.Tag; -import org.openecomp.sdc.be.model.catalog.CatalogComponent; -import org.openecomp.sdc.be.model.category.CategoryDefinition; -import org.openecomp.sdc.be.model.category.GroupingDefinition; -import org.openecomp.sdc.be.model.category.SubCategoryDefinition; -import org.openecomp.sdc.be.ui.model.UiCategories; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Path("/v1/") - -/**** - * - * UI oriented servlet - to return elements in specific format UI needs - * - * - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Api(value = "Element Servlet", description = "Element Servlet") -@Singleton -public class ElementServlet extends BeGenericServlet { - - private static final Logger log = Logger.getLogger(ElementServlet.class); - private final ComponentsCleanBusinessLogic componentsCleanBusinessLogic; - private final ElementBusinessLogic elementBusinessLogic; - private final UserBusinessLogic userBusinessLogic; - - @Inject - public ElementServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - ComponentsCleanBusinessLogic componentsCleanBusinessLogic, - ElementBusinessLogic elementBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.componentsCleanBusinessLogic = componentsCleanBusinessLogic; - this.elementBusinessLogic = elementBusinessLogic; - this.userBusinessLogic = userBusinessLogic; - } - - /* - ****************************************************************************** - * NEW CATEGORIES category / \ subcategory subcategory / grouping - ******************************************************************************/ - - /* - * - * - * CATEGORIES - */ - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all component categories - @GET - @Path("/categories/{componentType}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve the list of all resource/service/product categories/sub-categories/groupings", httpMethod = "GET", notes = "Retrieve the list of all resource/service/product categories/sub-categories/groupings.", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns categories Ok"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid component type"), - @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getComponentCategories(@ApiParam(value = "allowed values are resources / services/ products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - - try { - Either, ResponseFormat> either = elementBusinessLogic.getAllCategories(componentType, userId); - if (either.isRight()) { - log.debug("No categories were found for type {}", componentType); - return buildErrorResponse(either.right().value()); - } else { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component Categories"); - log.debug("getComponentCategories failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/categories") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve the all resource, service and product categories", httpMethod = "GET", notes = "Retrieve the all resource, service and product categories", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns categories Ok"), @ApiResponse(code = 403, message = "Missing information"), - @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getAllCategories(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - try { - Either either = elementBusinessLogic - .getAllCategories(userId); - if (either.isRight()) { - log.debug("No categories were found"); - return buildErrorResponse(either.right().value()); - } else { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Categories"); - log.debug("getAllCategories failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - - @POST - @Path("/category/{componentType}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create new component category", httpMethod = "POST", notes = "Create new component category") - @ApiResponses(value = { @ApiResponse(code = 201, message = "Category created"), @ApiResponse(code = 400, message = "Invalid category data"), @ApiResponse(code = 403, message = "USER_ID header is missing"), - @ApiResponse(code = 409, message = "Category already exists / User not permitted to perform the action"), @ApiResponse(code = 500, message = "General Error") }) - public Response createComponentCategory( - @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, - @ApiParam(value = "Category to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - try { - CategoryDefinition category = RepresentationUtils.fromRepresentation(data, CategoryDefinition.class); - - Either createResourceCategory = - elementBusinessLogic.createCategory(category, componentType, userId); - if (createResourceCategory.isRight()) { - return buildErrorResponse(createResourceCategory.right().value()); - } - - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); - return buildOkResponse(responseFormat, createResourceCategory.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create resource category"); - log.debug("createResourceCategory failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @DELETE - @Path("/category/{componentType}/{categoryUniqueId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete component category", httpMethod = "DELETE", notes = "Delete component category", response = Category.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "Category deleted"), @ApiResponse(code = 403, message = "USER_ID header is missing"), @ApiResponse(code = 409, message = "User not permitted to perform the action"), - @ApiResponse(code = 404, message = "Category not found"), @ApiResponse(code = 500, message = "General Error") }) - public Response deleteComponentCategory(@PathParam(value = "categoryUniqueId") final String categoryUniqueId, @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - try { - Either createResourceCategory = - elementBusinessLogic.deleteCategory(categoryUniqueId, componentType, userId); - - if (createResourceCategory.isRight()) { - return buildErrorResponse(createResourceCategory.right().value()); - } - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); - return buildOkResponse(responseFormat, null); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create resource category"); - log.debug("createResourceCategory failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - /* - * - * - * SUBCATEGORIES - * - */ - - @POST - @Path("/category/{componentType}/{categoryId}/subCategory") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create new component sub-category", httpMethod = "POST", notes = "Create new component sub-category for existing category") - @ApiResponses(value = { @ApiResponse(code = 201, message = "Subcategory created"), @ApiResponse(code = 400, message = "Invalid subcategory data"), @ApiResponse(code = 403, message = "USER_ID header is missing"), - @ApiResponse(code = 404, message = "Parent category wasn't found"), @ApiResponse(code = 409, message = "Subcategory already exists / User not permitted to perform the action"), @ApiResponse(code = 500, message = "General Error") }) - public Response createComponentSubCategory( - @ApiParam(value = "allowed values are resources / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, - @ApiParam(value = "Parent category unique ID", required = true) @PathParam(value = "categoryId") final String categoryId, @ApiParam(value = "Subcategory to be created. \ne.g. {\"name\":\"Resource-subcat\"}", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - try { - SubCategoryDefinition subCategory = RepresentationUtils.fromRepresentation(data, SubCategoryDefinition.class); - - Either createSubcategory = elementBusinessLogic - .createSubCategory(subCategory, componentType, categoryId, userId); - if (createSubcategory.isRight()) { - return buildErrorResponse(createSubcategory.right().value()); - } - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); - return buildOkResponse(responseFormat, createSubcategory.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create sub-category"); - log.debug("createComponentSubCategory failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @DELETE - @Path("/category/{componentType}/{categoryUniqueId}/subCategory/{subCategoryUniqueId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete component category", httpMethod = "DELETE", notes = "Delete component category", response = Category.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "Category deleted"), @ApiResponse(code = 403, message = "USER_ID header is missing"), @ApiResponse(code = 409, message = "User not permitted to perform the action"), - @ApiResponse(code = 404, message = "Category not found"), @ApiResponse(code = 500, message = "General Error") }) - public Response deleteComponentSubCategory(@PathParam(value = "categoryUniqueId") final String categoryUniqueId, @PathParam(value = "subCategoryUniqueId") final String subCategoryUniqueId, - @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - try { - Either deleteSubResourceCategory = - elementBusinessLogic.deleteSubCategory(subCategoryUniqueId, componentType, userId); - if (deleteSubResourceCategory.isRight()) { - return buildErrorResponse(deleteSubResourceCategory.right().value()); - } - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); - return buildOkResponse(responseFormat, null); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete component category"); - log.debug("deleteComponentSubCategory failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - /* - * GROUPINGS - */ - @POST - @Path("/category/{componentType}/{categoryId}/subCategory/{subCategoryId}/grouping") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create new component grouping", httpMethod = "POST", notes = "Create new component grouping for existing sub-category") - @ApiResponses(value = { @ApiResponse(code = 201, message = "Grouping created"), @ApiResponse(code = 400, message = "Invalid grouping data"), @ApiResponse(code = 403, message = "USER_ID header is missing"), - @ApiResponse(code = 404, message = "Parent category or subcategory were not found"), @ApiResponse(code = 409, message = "Grouping already exists / User not permitted to perform the action"), - @ApiResponse(code = 500, message = "General Error") }) - public Response createComponentGrouping(@ApiParam(value = "allowed values are products", allowableValues = ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, - @ApiParam(value = "Parent category unique ID", required = true) @PathParam(value = "categoryId") final String grandParentCategoryId, - @ApiParam(value = "Parent sub-category unique ID", required = true) @PathParam(value = "subCategoryId") final String parentSubCategoryId, @ApiParam(value = "Subcategory to be created", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - try { - GroupingDefinition grouping = RepresentationUtils.fromRepresentation(data, GroupingDefinition.class); - - Either createGrouping = elementBusinessLogic - .createGrouping(grouping, componentType, grandParentCategoryId, parentSubCategoryId, userId); - if (createGrouping.isRight()) { - return buildErrorResponse(createGrouping.right().value()); - } - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); - return buildOkResponse(responseFormat, createGrouping.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create grouping"); - log.debug("createComponentGrouping failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @DELETE - @Path("/category/{componentType}/{categoryUniqueId}/subCategory/{subCategoryUniqueId}/grouping/{groupingUniqueId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Delete component category", httpMethod = "DELETE", notes = "Delete component category", response = Category.class) - @ApiResponses(value = { @ApiResponse(code = 204, message = "Category deleted"), @ApiResponse(code = 403, message = "USER_ID header is missing"), @ApiResponse(code = 409, message = "User not permitted to perform the action"), - @ApiResponse(code = 404, message = "Category not found"), @ApiResponse(code = 500, message = "General Error") }) - public Response deleteComponentGrouping(@PathParam(value = "categoryUniqueId") final String grandParentCategoryUniqueId, @PathParam(value = "subCategoryUniqueId") final String parentSubCategoryUniqueId, - @PathParam(value = "groupingUniqueId") final String groupingUniqueId, @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - try { - Either deleteGrouping = elementBusinessLogic - .deleteGrouping(groupingUniqueId, componentType, userId); - if (deleteGrouping.isRight()) { - return buildErrorResponse(deleteGrouping.right().value()); - } - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); - return buildOkResponse(responseFormat, null); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete component grouping"); - log.debug("deleteGrouping failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all tags - @GET - @Path("/tags") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve all tags", httpMethod = "GET", notes = "Retrieve all tags", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns tags Ok"), @ApiResponse(code = 404, message = "No tags were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getTags(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(getTags) Start handle request of {}", url); - - try { - Either, ActionStatus> either = elementBusinessLogic.getAllTags(userId); - if (either.isRight() || either.left().value() == null) { - log.debug("No tags were found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Tags"); - log.debug("getAllTags failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all property scopes - @GET - @Path("/propertyScopes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve all propertyScopes", httpMethod = "GET", notes = "Retrieve all propertyScopes", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns propertyScopes Ok"), @ApiResponse(code = 404, message = "No propertyScopes were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getPropertyScopes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(getPropertyScopes) Start handle request of {}", url); - - try { - Either, ActionStatus> either = elementBusinessLogic.getAllPropertyScopes(userId); - if (either.isRight() || either.left().value() == null) { - log.debug("No property scopes were found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property Scopes Categories"); - log.debug("getPropertyScopes failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all artifact types - @GET - @Path("/artifactTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve all artifactTypes", httpMethod = "GET", notes = "Retrieve all artifactTypes", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns artifactTypes Ok"), @ApiResponse(code = 404, message = "No artifactTypes were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getArtifactTypes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(GET - getArtifactTypes) Start handle request of {}", url); - - try { - Either, ActionStatus> either = elementBusinessLogic.getAllArtifactTypes(userId); - if (either.isRight() || either.left().value() == null) { - log.debug("No artifact types were found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else { - - Integer defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes(); - ArtifactTypesInfo typesResponse = new ArtifactTypesInfo(); - typesResponse.setArtifactTypes(either.left().value()); - typesResponse.setHeatDefaultTimeout(defaultHeatTimeout); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), typesResponse); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Artifact Types"); - log.debug("getArtifactTypes failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all artifact types - @GET - @Path("/configuration/ui") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve all artifactTypes", httpMethod = "GET", notes = "Retrieve all artifactTypes", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns artifactTypes Ok"), @ApiResponse(code = 404, message = "No artifactTypes were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getConfiguration(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(getConfiguration) Start handle request of {}", url); - - try { - Either, ActionStatus> otherEither = elementBusinessLogic.getAllArtifactTypes(userId); - Either defaultHeatTimeout = elementBusinessLogic.getDefaultHeatTimeout(); - Either, ActionStatus> deploymentEither = elementBusinessLogic.getAllDeploymentArtifactTypes(); - Either, ActionStatus> resourceTypesMap = elementBusinessLogic.getResourceTypesMap(); - - if (otherEither.isRight() || otherEither.left().value() == null) { - log.debug("No other artifact types were found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else if (deploymentEither.isRight() || deploymentEither.left().value() == null) { - log.debug("No deployment artifact types were found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else if (defaultHeatTimeout.isRight() || defaultHeatTimeout.left().value() == null) { - log.debug("heat default timeout was not found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else if (resourceTypesMap.isRight() || resourceTypesMap.left().value() == null) { - log.debug("No resource types were found"); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); - } else { - Map artifacts = new HashMap<>(); - Map configuration = new HashMap<>(); - - artifacts.put("other", otherEither.left().value()); - artifacts.put("deployment", deploymentEither.left().value()); - configuration.put("artifacts", artifacts); - configuration.put("defaultHeatTimeout", defaultHeatTimeout.left().value()); - configuration.put("componentTypes", elementBusinessLogic.getAllComponentTypesParamNames()); - configuration.put("roles", elementBusinessLogic.getAllSupportedRoles()); - configuration.put("resourceTypes", resourceTypesMap.left().value()); - configuration.put("environmentContext", ConfigurationManager.getConfigurationManager().getConfiguration().getEnvironmentContext()); - configuration.put("gab", ConfigurationManager.getConfigurationManager().getConfiguration().getGabConfig()); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), configuration); - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Artifact Types"); - log.debug("getArtifactTypes failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all followed resources and services - @GET - @Path("/followed") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve all followed", httpMethod = "GET", notes = "Retrieve all followed", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns followed Ok"), @ApiResponse(code = 404, message = "No followed were found"), @ApiResponse(code = 404, message = "User not found"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getFollowedResourcesServices(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - Response res = null; - User userData = null; - try { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // Getting the user - Either either = userBusinessLogic.getUser(userId, false); - if (either.isRight()) { - // Couldn't find or otherwise fetch the user - return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); - } - - if (either.left().value() != null) { - userData = either.left().value(); - Either>, ResponseFormat> followedResourcesServices = - elementBusinessLogic.getFollowed(userData); - if (followedResourcesServices.isRight()) { - log.debug("failed to get followed resources services "); - return buildErrorResponse(followedResourcesServices.right().value()); - } - Object data = RepresentationUtils.toRepresentation(followedResourcesServices.left().value()); - res = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), data); - } else { - res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Followed Resources / Services Categories"); - log.debug("Getting followed resources/services failed with exception", e); - res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - return res; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all certified resources and services and their last version - @GET - @Path("/screen") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve catalog resources and services", httpMethod = "GET", notes = "Retrieve catalog resources and services", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns resources and services Ok"), @ApiResponse(code = 404, message = "No resources and services were found"), @ApiResponse(code = 404, message = "User not found"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getCatalogComponents(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @QueryParam("excludeTypes") List excludeTypes) { - - Response res = null; - try { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - Either>, ResponseFormat> catalogData = elementBusinessLogic - .getCatalogComponents(userId, excludeTypes); - - if (catalogData.isRight()) { - log.debug("failed to get catalog data"); - return buildErrorResponse(catalogData.right().value()); - } - Object data = RepresentationUtils.toRepresentation(catalogData.left().value()); - res = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), data); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Catalog Components"); - log.debug("Getting catalog components failed with exception", e); - res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - return res; - } - - @DELETE - @Path("/inactiveComponents/{componentType}") - public Response deleteMarkedResources(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - NodeTypeEnum nodeType = NodeTypeEnum.getByNameIgnoreCase(componentType); - if (nodeType == null) { - log.info("componentType is not valid: {}", componentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - List componentsList = new ArrayList<>(); - componentsList.add(nodeType); - try { - Map, ResponseFormat>> cleanComponentsResult = componentsCleanBusinessLogic.cleanComponents(componentsList); - Either, ResponseFormat> cleanResult = cleanComponentsResult.get(nodeType); - - if (cleanResult.isRight()) { - log.debug("failed to delete marked components of type {}", nodeType); - response = buildErrorResponse(cleanResult.right().value()); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), cleanResult.left().value()); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Marked Components"); - log.debug("delete marked components failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Path("/ecompPortalMenu") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve ecomp portal menu - MOC", httpMethod = "GET", notes = "Retrieve ecomp portal menu", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Retrieve ecomp portal menu") }) - public Response getListOfCsars(@Context final HttpServletRequest request) { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - "[{\"menuId\":1,\"column\":2,\"text\":\"Design\",\"parentMenuId\":null,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":11,\"column\":1,\"text\":\"ProductDesign\",\"parentMenuId\":1,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":12,\"column\":2,\"text\":\"Service\",\"parentMenuId\":1,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":21,\"column\":1,\"text\":\"ViewPolicies\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":90,\"column\":1,\"text\":\"4thLevelApp1aR16\",\"parentMenuId\":21,\"url\":\"http://google.com\",\"appid\":null,\"roles\":null}]},{\"menuId\":22,\"column\":2,\"text\":\"UpdatePolicies\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":91,\"column\":1,\"text\":\"4thLevelApp1bR16\",\"parentMenuId\":22,\"url\":\"http://jsonlint.com/\",\"appid\":null,\"roles\":null}]},{\"menuId\":23,\"column\":3,\"text\":\"UpdateRules\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":24,\"column\":4,\"text\":\"CreateSignatures?\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":25,\"column\":5,\"text\":\"Definedata\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null}]}]}]"); - } - -} +/*- + * ============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.servlets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +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.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; +import org.openecomp.sdc.be.components.scheduledtasks.ComponentsCleanBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.info.ArtifactTypesInfo; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Category; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Tag; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.catalog.CatalogComponent; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.ui.model.UiCategories; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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; + +@Path("/v1/") + +/**** + * + * UI oriented servlet - to return elements in specific format UI needs + * + * + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@OpenAPIDefinition(info = @Info(title = "Element Servlet",description = "Element Servlet")) +@Singleton +public class ElementServlet extends BeGenericServlet { + + private static final Logger log = Logger.getLogger(ElementServlet.class); + private final ComponentsCleanBusinessLogic componentsCleanBusinessLogic; + private final ElementBusinessLogic elementBusinessLogic; + private final UserBusinessLogic userBusinessLogic; + + @Inject + public ElementServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + ComponentsCleanBusinessLogic componentsCleanBusinessLogic, + ElementBusinessLogic elementBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.componentsCleanBusinessLogic = componentsCleanBusinessLogic; + this.elementBusinessLogic = elementBusinessLogic; + this.userBusinessLogic = userBusinessLogic; + } + + /* + ****************************************************************************** + * NEW CATEGORIES category / \ subcategory subcategory / grouping + ******************************************************************************/ + + /* + * + * + * CATEGORIES + */ + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all component categories + @GET + @Path("/categories/{componentType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve the list of all resource/service/product categories/sub-categories/groupings", + method = "GET", + summary = "Retrieve the list of all resource/service/product categories/sub-categories/groupings.", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns categories Ok"), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "400", description = "Invalid component type"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getComponentCategories( + @Parameter(description = "allowed values are resources / services/ products", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME,ComponentTypeEnum.PRODUCT_PARAM_NAME}),required = true) + @PathParam(value = "componentType") final String componentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + + try { + Either, ResponseFormat> either = + elementBusinessLogic.getAllCategories(componentType, userId); + if (either.isRight()) { + log.debug("No categories were found for type {}", componentType); + return buildErrorResponse(either.right().value()); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component Categories"); + log.debug("getComponentCategories failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/categories") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve the all resource, service and product categories", method = "GET", + summary = "Retrieve the all resource, service and product categories", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns categories Ok"), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getAllCategories(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + Either either = elementBusinessLogic.getAllCategories(userId); + if (either.isRight()) { + log.debug("No categories were found"); + return buildErrorResponse(either.right().value()); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Categories"); + log.debug("getAllCategories failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + + @POST + @Path("/category/{componentType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create new component category", method = "POST", + summary = "Create new component category") + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Category created"), + @ApiResponse(responseCode = "400", description = "Invalid category data"), + @ApiResponse(responseCode = "403", description = "USER_ID header is missing"), + @ApiResponse(responseCode = "409", + description = "Category already exists / User not permitted to perform the action"), + @ApiResponse(responseCode = "500", description = "General Error")}) + public Response createComponentCategory( + @Parameter(description = "allowed values are resources /services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME,ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) @PathParam(value = "componentType") final String componentType, + @Parameter(description = "Category to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + try { + CategoryDefinition category = RepresentationUtils.fromRepresentation(data, CategoryDefinition.class); + + Either createResourceCategory = + elementBusinessLogic.createCategory(category, componentType, userId); + if (createResourceCategory.isRight()) { + return buildErrorResponse(createResourceCategory.right().value()); + } + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createResourceCategory.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create resource category"); + log.debug("createResourceCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/category/{componentType}/{categoryUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete component category", method = "DELETE", summary = "Delete component category", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Category.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Category deleted"), + @ApiResponse(responseCode = "403", description = "USER_ID header is missing"), + @ApiResponse(responseCode = "409", description = "User not permitted to perform the action"), + @ApiResponse(responseCode = "404", description = "Category not found"), + @ApiResponse(responseCode = "500", description = "General Error")}) + public Response deleteComponentCategory(@PathParam(value = "categoryUniqueId") final String categoryUniqueId, + @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + Either createResourceCategory = + elementBusinessLogic.deleteCategory(categoryUniqueId, componentType, userId); + + if (createResourceCategory.isRight()) { + return buildErrorResponse(createResourceCategory.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, null); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create resource category"); + log.debug("createResourceCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + /* + * + * + * SUBCATEGORIES + * + */ + + @POST + @Path("/category/{componentType}/{categoryId}/subCategory") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create new component sub-category", method = "POST", + summary = "Create new component sub-category for existing category") + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Subcategory created"), + @ApiResponse(responseCode = "400", description = "Invalid subcategory data"), + @ApiResponse(responseCode = "403", description = "USER_ID header is missing"), + @ApiResponse(responseCode = "404", description = "Parent category wasn't found"), + @ApiResponse(responseCode = "409", + description = "Subcategory already exists / User not permitted to perform the action"), + @ApiResponse(responseCode = "500", description = "General Error")}) + public Response createComponentSubCategory( + @Parameter(description = "allowed values are resources / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) @PathParam(value = "componentType") final String componentType, + @Parameter(description = "Parent category unique ID", + required = true) @PathParam(value = "categoryId") final String categoryId, + @Parameter(description = "Subcategory to be created. \ne.g. {\"name\":\"Resource-subcat\"}", + required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + SubCategoryDefinition subCategory = + RepresentationUtils.fromRepresentation(data, SubCategoryDefinition.class); + + Either createSubcategory = + elementBusinessLogic.createSubCategory(subCategory, componentType, categoryId, userId); + if (createSubcategory.isRight()) { + return buildErrorResponse(createSubcategory.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createSubcategory.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create sub-category"); + log.debug("createComponentSubCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/category/{componentType}/{categoryUniqueId}/subCategory/{subCategoryUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete component category", method = "DELETE", summary = "Delete component category", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Category.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Category deleted"), + @ApiResponse(responseCode = "403", description = "USER_ID header is missing"), + @ApiResponse(responseCode = "409", description = "User not permitted to perform the action"), + @ApiResponse(responseCode = "404", description = "Category not found"), + @ApiResponse(responseCode = "500", description = "General Error")}) + public Response deleteComponentSubCategory(@PathParam(value = "categoryUniqueId") final String categoryUniqueId, + @PathParam(value = "subCategoryUniqueId") final String subCategoryUniqueId, + @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + Either deleteSubResourceCategory = + elementBusinessLogic.deleteSubCategory(subCategoryUniqueId, componentType, userId); + if (deleteSubResourceCategory.isRight()) { + return buildErrorResponse(deleteSubResourceCategory.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, null); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete component category"); + log.debug("deleteComponentSubCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + /* + * GROUPINGS + */ + @POST + @Path("/category/{componentType}/{categoryId}/subCategory/{subCategoryId}/grouping") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create new component grouping", method = "POST", + summary = "Create new component grouping for existing sub-category") + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Grouping created"), + @ApiResponse(responseCode = "400", description = "Invalid grouping data"), + @ApiResponse(responseCode = "403", description = "USER_ID header is missing"), + @ApiResponse(responseCode = "404", description = "Parent category or subcategory were not found"), + @ApiResponse(responseCode = "409", + description = "Grouping already exists / User not permitted to perform the action"), + @ApiResponse(responseCode = "500", description = "General Error")}) + public Response createComponentGrouping( + @Parameter(description = "allowed values are products", + schema = @Schema(allowableValues = {ComponentTypeEnum.PRODUCT_PARAM_NAME}), + required = true) @PathParam(value = "componentType") final String componentType, + @Parameter(description = "Parent category unique ID", + required = true) @PathParam(value = "categoryId") final String grandParentCategoryId, + @Parameter(description = "Parent sub-category unique ID", + required = true) @PathParam(value = "subCategoryId") final String parentSubCategoryId, + @Parameter(description = "Subcategory to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + try { + GroupingDefinition grouping = RepresentationUtils.fromRepresentation(data, GroupingDefinition.class); + + Either createGrouping = elementBusinessLogic.createGrouping(grouping, + componentType, grandParentCategoryId, parentSubCategoryId, userId); + if (createGrouping.isRight()) { + return buildErrorResponse(createGrouping.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createGrouping.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create grouping"); + log.debug("createComponentGrouping failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/category/{componentType}/{categoryUniqueId}/subCategory/{subCategoryUniqueId}/grouping/{groupingUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Delete component category", method = "DELETE", summary = "Delete component category", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Category.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Category deleted"), + @ApiResponse(responseCode = "403", description = "USER_ID header is missing"), + @ApiResponse(responseCode = "409", description = "User not permitted to perform the action"), + @ApiResponse(responseCode = "404", description = "Category not found"), + @ApiResponse(responseCode = "500", description = "General Error")}) + public Response deleteComponentGrouping( + @PathParam(value = "categoryUniqueId") final String grandParentCategoryUniqueId, + @PathParam(value = "subCategoryUniqueId") final String parentSubCategoryUniqueId, + @PathParam(value = "groupingUniqueId") final String groupingUniqueId, + @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + Either deleteGrouping = + elementBusinessLogic.deleteGrouping(groupingUniqueId, componentType, userId); + if (deleteGrouping.isRight()) { + return buildErrorResponse(deleteGrouping.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, null); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete component grouping"); + log.debug("deleteGrouping failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all tags + @GET + @Path("/tags") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve all tags", method = "GET", summary = "Retrieve all tags",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns tags Ok"), + @ApiResponse(responseCode = "404", description = "No tags were found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getTags(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getTags) Start handle request of {}", url); + + try { + Either, ActionStatus> either = elementBusinessLogic.getAllTags(userId); + if (either.isRight() || either.left().value() == null) { + log.debug("No tags were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Tags"); + log.debug("getAllTags failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all property scopes + @GET + @Path("/propertyScopes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve all propertyScopes", method = "GET", summary = "Retrieve all propertyScopes", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns propertyScopes Ok"), + @ApiResponse(responseCode = "404", description = "No propertyScopes were found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getPropertyScopes(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getPropertyScopes) Start handle request of {}", url); + + try { + Either, ActionStatus> either = elementBusinessLogic.getAllPropertyScopes(userId); + if (either.isRight() || either.left().value() == null) { + log.debug("No property scopes were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property Scopes Categories"); + log.debug("getPropertyScopes failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all artifact types + @GET + @Path("/artifactTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve all artifactTypes", method = "GET", summary = "Retrieve all artifactTypes", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns artifactTypes Ok"), + @ApiResponse(responseCode = "404", description = "No artifactTypes were found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getArtifactTypes(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(GET - getArtifactTypes) Start handle request of {}", url); + + try { + Either, ActionStatus> either = elementBusinessLogic.getAllArtifactTypes(userId); + if (either.isRight() || either.left().value() == null) { + log.debug("No artifact types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + + Integer defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration() + .getDefaultHeatArtifactTimeoutMinutes(); + ArtifactTypesInfo typesResponse = new ArtifactTypesInfo(); + typesResponse.setArtifactTypes(either.left().value()); + typesResponse.setHeatDefaultTimeout(defaultHeatTimeout); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), typesResponse); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Artifact Types"); + log.debug("getArtifactTypes failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all artifact types + @GET + @Path("/configuration/ui") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve all artifactTypes", method = "GET", summary = "Retrieve all artifactTypes", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns artifactTypes Ok"), + @ApiResponse(responseCode = "404", description = "No artifactTypes were found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getConfiguration(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getConfiguration) Start handle request of {}", url); + + try { + Either, ActionStatus> otherEither = elementBusinessLogic.getAllArtifactTypes(userId); + Either defaultHeatTimeout = elementBusinessLogic.getDefaultHeatTimeout(); + Either, ActionStatus> deploymentEither = + elementBusinessLogic.getAllDeploymentArtifactTypes(); + Either, ActionStatus> resourceTypesMap = elementBusinessLogic.getResourceTypesMap(); + + if (otherEither.isRight() || otherEither.left().value() == null) { + log.debug("No other artifact types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else if (deploymentEither.isRight() || deploymentEither.left().value() == null) { + log.debug("No deployment artifact types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else if (defaultHeatTimeout.isRight() || defaultHeatTimeout.left().value() == null) { + log.debug("heat default timeout was not found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else if (resourceTypesMap.isRight() || resourceTypesMap.left().value() == null) { + log.debug("No resource types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + Map artifacts = new HashMap<>(); + Map configuration = new HashMap<>(); + + artifacts.put("other", otherEither.left().value()); + artifacts.put("deployment", deploymentEither.left().value()); + configuration.put("artifacts", artifacts); + configuration.put("defaultHeatTimeout", defaultHeatTimeout.left().value()); + configuration.put("componentTypes", elementBusinessLogic.getAllComponentTypesParamNames()); + configuration.put("roles", elementBusinessLogic.getAllSupportedRoles()); + configuration.put("resourceTypes", resourceTypesMap.left().value()); + configuration.put("environmentContext", + ConfigurationManager.getConfigurationManager().getConfiguration().getEnvironmentContext()); + configuration.put("gab", + ConfigurationManager.getConfigurationManager().getConfiguration().getGabConfig()); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), configuration); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Artifact Types"); + log.debug("getArtifactTypes failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all followed resources and services + @GET + @Path("/followed") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve all followed", method = "GET", summary = "Retrieve all followed", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns followed Ok"), + @ApiResponse(responseCode = "404", description = "No followed were found"), + @ApiResponse(responseCode = "404", description = "User not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getFollowedResourcesServices(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Response res = null; + User userData = null; + try { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // Getting the user + Either either = userBusinessLogic.getUser(userId, false); + if (either.isRight()) { + // Couldn't find or otherwise fetch the user + return buildErrorResponse( + getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); + } + + if (either.left().value() != null) { + userData = either.left().value(); + Either>, ResponseFormat> followedResourcesServices = + elementBusinessLogic.getFollowed(userData); + if (followedResourcesServices.isRight()) { + log.debug("failed to get followed resources services "); + return buildErrorResponse(followedResourcesServices.right().value()); + } + Object data = RepresentationUtils.toRepresentation(followedResourcesServices.left().value()); + res = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), data); + } else { + res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Followed Resources / Services Categories"); + log.debug("Getting followed resources/services failed with exception", e); + res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return res; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all certified resources and services and their last version + @GET + @Path("/screen") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve catalog resources and services", method = "GET", + summary = "Retrieve catalog resources and services", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns resources and services Ok"), + @ApiResponse(responseCode = "404", description = "No resources and services were found"), + @ApiResponse(responseCode = "404", description = "User not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getCatalogComponents(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @QueryParam("excludeTypes") List excludeTypes) { + + Response res = null; + try { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + Either>, ResponseFormat> catalogData = + elementBusinessLogic.getCatalogComponents(userId, excludeTypes); + + if (catalogData.isRight()) { + log.debug("failed to get catalog data"); + return buildErrorResponse(catalogData.right().value()); + } + Object data = RepresentationUtils.toRepresentation(catalogData.left().value()); + res = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), data); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Catalog Components"); + log.debug("Getting catalog components failed with exception", e); + res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return res; + } + + @DELETE + @Path("/inactiveComponents/{componentType}") + public Response deleteMarkedResources(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + NodeTypeEnum nodeType = NodeTypeEnum.getByNameIgnoreCase(componentType); + if (nodeType == null) { + log.info("componentType is not valid: {}", componentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + List componentsList = new ArrayList<>(); + componentsList.add(nodeType); + try { + Map, ResponseFormat>> cleanComponentsResult = componentsCleanBusinessLogic.cleanComponents(componentsList); + Either, ResponseFormat> cleanResult = cleanComponentsResult.get(nodeType); + + if (cleanResult.isRight()) { + log.debug("failed to delete marked components of type {}", nodeType); + response = buildErrorResponse(cleanResult.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), cleanResult.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Marked Components"); + log.debug("delete marked components failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/ecompPortalMenu") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve ecomp portal menu - MOC", method = "GET", summary = "Retrieve ecomp portal menu", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Retrieve ecomp portal menu") }) + public Response getListOfCsars(@Context final HttpServletRequest request) { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + "[{\"menuId\":1,\"column\":2,\"text\":\"Design\",\"parentMenuId\":null,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":11,\"column\":1,\"text\":\"ProductDesign\",\"parentMenuId\":1,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":12,\"column\":2,\"text\":\"Service\",\"parentMenuId\":1,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":21,\"column\":1,\"text\":\"ViewPolicies\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":90,\"column\":1,\"text\":\"4thLevelApp1aR16\",\"parentMenuId\":21,\"url\":\"http://google.com\",\"appid\":null,\"roles\":null}]},{\"menuId\":22,\"column\":2,\"text\":\"UpdatePolicies\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":91,\"column\":1,\"text\":\"4thLevelApp1bR16\",\"parentMenuId\":22,\"url\":\"http://jsonlint.com/\",\"appid\":null,\"roles\":null}]},{\"menuId\":23,\"column\":3,\"text\":\"UpdateRules\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":24,\"column\":4,\"text\":\"CreateSignatures?\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":25,\"column\":5,\"text\":\"Definedata\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null}]}]}]"); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GenericArtifactBrowserServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GenericArtifactBrowserServlet.java index afa57f7957..580362c00d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GenericArtifactBrowserServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GenericArtifactBrowserServlet.java @@ -1,110 +1,112 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 Nokia 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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.io.IOException; -import java.util.Set; -import java.util.stream.Collectors; -import javax.inject.Inject; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -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.tuple.ImmutablePair; -import org.onap.sdc.gab.model.GABQuery; -import org.onap.sdc.gab.model.GABQuery.GABQueryType; -import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GenericArtifactBrowserBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.info.GenericArtifactQueryInfo; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; -import org.owasp.esapi.ESAPI; -import org.springframework.stereotype.Controller; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/gab") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Generic Artifact Browser") -@Controller -public class GenericArtifactBrowserServlet extends BeGenericServlet { - - private static final Logger LOGGER = Logger.getLogger(GenericArtifactBrowserServlet.class); - private final GenericArtifactBrowserBusinessLogic gabLogic; - private final ArtifactsBusinessLogic artifactsBusinessLogic; - - @Inject - public GenericArtifactBrowserServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - ArtifactsBusinessLogic artifactsBusinessLogic, - GenericArtifactBrowserBusinessLogic gabLogic) { - super(userBusinessLogic, componentsUtils); - this.artifactsBusinessLogic = artifactsBusinessLogic; - this.gabLogic = gabLogic; - } - - @POST - @Path("/searchFor") - @ApiOperation(value = "Search json paths inside the yaml", httpMethod = "POST", notes = "Returns found entries of json paths", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Returned yaml entries"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response searchFor( - @ApiParam(value = "Generic Artifact search model", required = true) GenericArtifactQueryInfo query, - @Context final HttpServletRequest request) { - try { - Either, ResponseFormat> immutablePairResponseFormatEither = artifactsBusinessLogic - .downloadArtifact(ESAPI.encoder().canonicalize(query.getParentId()), ESAPI.encoder().canonicalize(query.getArtifactUniqueId())); - if (immutablePairResponseFormatEither.isLeft()){ - GABQuery gabQuery = prepareGabQuery(query, immutablePairResponseFormatEither); - return buildOkResponse(gabLogic.searchFor(gabQuery)); - }else{ - throw new IOException(immutablePairResponseFormatEither.right().value().getFormattedMessage()); - } - } catch (IOException e) { - LOGGER.error("Cannot search for a given queries in the yaml file", e); - return buildGeneralErrorResponse(); - } - } - - private GABQuery prepareGabQuery(GenericArtifactQueryInfo query, - Either, ResponseFormat> immutablePairResponseFormatEither) { - byte[] content = immutablePairResponseFormatEither.left().value().getRight(); - Set queryFields = query.getFields().stream().map(ESAPI.encoder()::canonicalize).collect(Collectors.toSet()); - return new GABQuery(queryFields, new String(content), GABQueryType.CONTENT); - } -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Nokia 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.servlets; + +import java.io.IOException; +import java.util.Set; +import java.util.stream.Collectors; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +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.tuple.ImmutablePair; +import org.onap.sdc.gab.model.GABQuery; +import org.onap.sdc.gab.model.GABQuery.GABQueryType; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.GenericArtifactBrowserBusinessLogic; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.info.GenericArtifactQueryInfo; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import org.owasp.esapi.ESAPI; +import org.springframework.stereotype.Controller; +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/gab") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Generic Artifact Browser")) +@Controller +public class GenericArtifactBrowserServlet extends BeGenericServlet { + + private static final Logger LOGGER = Logger.getLogger(GenericArtifactBrowserServlet.class); + private final GenericArtifactBrowserBusinessLogic gabLogic; + private final ArtifactsBusinessLogic artifactsBusinessLogic; + + @Inject + public GenericArtifactBrowserServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + ArtifactsBusinessLogic artifactsBusinessLogic, + GenericArtifactBrowserBusinessLogic gabLogic) { + super(userBusinessLogic, componentsUtils); + this.artifactsBusinessLogic = artifactsBusinessLogic; + this.gabLogic = gabLogic; + } + + @POST + @Path("/searchFor") + @Operation(description = "Search json paths inside the yaml", method = "POST", summary = "Returns found entries of json paths",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Returned yaml entries"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response searchFor( + @Parameter(description = "Generic Artifact search model", required = true) GenericArtifactQueryInfo query, + @Context final HttpServletRequest request) { + try { + Either, ResponseFormat> immutablePairResponseFormatEither = artifactsBusinessLogic + .downloadArtifact(ESAPI.encoder().canonicalize(query.getParentId()), ESAPI.encoder().canonicalize(query.getArtifactUniqueId())); + if (immutablePairResponseFormatEither.isLeft()){ + GABQuery gabQuery = prepareGabQuery(query, immutablePairResponseFormatEither); + return buildOkResponse(gabLogic.searchFor(gabQuery)); + }else{ + throw new IOException(immutablePairResponseFormatEither.right().value().getFormattedMessage()); + } + } catch (IOException e) { + LOGGER.error("Cannot search for a given queries in the yaml file", e); + return buildGeneralErrorResponse(); + } + } + + private GABQuery prepareGabQuery(GenericArtifactQueryInfo query, + Either, ResponseFormat> immutablePairResponseFormatEither) { + byte[] content = immutablePairResponseFormatEither.left().value().getRight(); + Set queryFields = query.getFields().stream().map(ESAPI.encoder()::canonicalize).collect(Collectors.toSet()); + return new GABQuery(queryFields, new String(content), GABQueryType.CONTENT); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupEndpoint.java index eb61e8992a..387faae3ab 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupEndpoint.java @@ -1,105 +1,120 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogicNew; -import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.model.GroupProperty; -import org.openecomp.sdc.common.api.Constants; -import org.springframework.stereotype.Controller; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.List; - -/** - * Here new APIs for group will be written in an attempt to gradually clean BL code - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Group Servlet") -@Controller -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class GroupEndpoint { - - private final GroupBusinessLogicNew groupBusinessLogic; - - @Inject - public GroupEndpoint(GroupBusinessLogicNew groupBusinessLogic) { - this.groupBusinessLogic = groupBusinessLogic; - } - - @POST - @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/members") - @ApiOperation(value = "Update group members ", httpMethod = "POST", notes = "Updates list of members and returns it", response = String.class, responseContainer = "List") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Group members updated"), - @ApiResponse(code = 400, message = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Component not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public List updateGroupMembers( - @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @PathParam("groupUniqueId") final String groupUniqueId, - @ApiParam(value = "List of members unique ids", required = true) List members, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - return groupBusinessLogic.updateMembers(componentId, componentTypeEnum, userId, groupUniqueId, members); - } - - @GET - @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/properties") - @ApiOperation(value = "Get List of properties on a group", httpMethod = "GET", notes = "Returns list of properties", response = GroupProperty.class, responseContainer="List") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Group Updated"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public List getGroupProperties(@PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @PathParam("groupUniqueId") final String groupUniqueId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return groupBusinessLogic.getProperties(containerComponentType, userId, componentId, groupUniqueId); - } - - @PUT - @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/properties") - @ApiOperation(value = "Updates List of properties on a group (only values)", httpMethod = "PUT", notes = "Returns updated list of properties", response = GroupProperty.class, responseContainer="List") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Group Updated"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public List updateGroupProperties(@PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @PathParam("groupUniqueId") final String groupUniqueId, - @ApiParam(value = "Group Properties to be Updated", required = true) List properties, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - return groupBusinessLogic.updateProperties(componentId, componentTypeEnum, userId, groupUniqueId, properties); - } - -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.util.List; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.openecomp.sdc.be.components.impl.GroupBusinessLogicNew; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.common.api.Constants; +import org.springframework.stereotype.Controller; +import com.jcabi.aspects.Loggable; +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; + +/** + * Here new APIs for group will be written in an attempt to gradually clean BL code + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Group Servlet")) +@Controller +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class GroupEndpoint { + + private final GroupBusinessLogicNew groupBusinessLogic; + + @Inject + public GroupEndpoint(GroupBusinessLogicNew groupBusinessLogic) { + this.groupBusinessLogic = groupBusinessLogic; + } + + @POST + @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/members") + @Operation(description = "Update group members ", method = "POST", + summary = "Updates list of members and returns it", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Group members updated"), @ApiResponse( + responseCode = "400", + description = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found"), + @ApiResponse(responseCode = "500", description = "Internal Error")}) + public List updateGroupMembers(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupUniqueId, + @Parameter(description = "List of members unique ids", required = true) List members, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + return groupBusinessLogic.updateMembers(componentId, componentTypeEnum, userId, groupUniqueId, members); + } + + @GET + @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/properties") + @Operation(description = "Get List of properties on a group", method = "GET", + summary = "Returns list of properties", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GroupProperty.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Group Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public List getGroupProperties( + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupUniqueId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return groupBusinessLogic.getProperties(containerComponentType, userId, componentId, groupUniqueId); + } + + @PUT + @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/properties") + @Operation(description = "Updates List of properties on a group (only values)", method = "PUT", + summary = "Returns updated list of properties", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GroupProperty.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Group Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public List updateGroupProperties( + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupUniqueId, + @Parameter(description = "Group Properties to be Updated", required = true) List properties, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + return groupBusinessLogic.updateProperties(componentId, componentTypeEnum, userId, groupUniqueId, properties); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java index 557304f903..bbc41f2ffb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java @@ -1,237 +1,247 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.info.GroupDefinitionInfo; -import org.openecomp.sdc.be.model.GroupDefinition; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -/** - * Root resource (exposed at "/" path) - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Path("/v1/catalog") -@Api(value = "Group Servlet") -@Singleton -public class GroupServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(GroupServlet.class); - public static final String START_HANDLE_REQUEST = "Start handle request of {}"; - private final GroupBusinessLogic groupBL; - - @Inject - public GroupServlet(UserBusinessLogic userBusinessLogic, - GroupBusinessLogic groupBL, ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.groupBL = groupBL; - } - - @POST - @Path("/{containerComponentType}/{componentId}/groups/{groupType}") - @ApiOperation(value = "Create group ", httpMethod = "POST", notes = "Creates new group in component and returns it", response = GroupDefinition.class) - @ApiResponses(value = { - @ApiResponse(code = 201, message = "Group created"), - @ApiResponse(code = 400, message = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Component not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Response createGroup(@PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @PathParam("groupType") final String type, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(post) Start handle request of {}", url); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - GroupDefinition groupDefinition = groupBL - .createGroup(componentId, componentTypeEnum, type, userId); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), - groupDefinition); - } - - @GET - @Path("/{containerComponentType}/{componentId}/groups/{groupId}") - @ApiOperation(value = "Get group artifacts ", httpMethod = "GET", notes = "Returns artifacts metadata according to groupId", response = Resource.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "group found"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Group not found")}) - public Response getGroupById(@PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("groupId") final String groupId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - - try { - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - Either actionResponse = groupBL - .getGroupWithArtifactsById(componentTypeEnum, componentId, groupId, userId, false); - - if (actionResponse.isRight()) { - log.debug("failed to get all non abstract {}", containerComponentType); - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - actionResponse.left().value()); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getGroupArtifactById"); - log.debug("getGroupArtifactById unexpected exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @DELETE - @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}") - @ApiOperation(value = "Delete Group", httpMethod = "DELETE", notes = "Returns deleted group id", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 201, message = "ResourceInstance deleted"), - @ApiResponse(code = 400, message = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Component not found"), - @ApiResponse(code = 500, message = "Internal Error") - }) - public Response deleteGroup(@PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @PathParam("groupUniqueId") final String groupId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST, url); - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - GroupDefinition groupDefinition = groupBL - .deleteGroup(componentId, componentTypeEnum, groupId, userId); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), groupDefinition.getUniqueId()); - } - - @PUT - @Path("/{containerComponentType}/{componentId}/groups/{groupId}") - @ApiOperation(value = "Update Group metadata", httpMethod = "PUT", notes = "Returns updated Group", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Group updated"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "component / group Not found")}) - public Response updateGroup(@PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @PathParam("groupId") final String groupId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "GroupDefinition", required = true) GroupDefinition groupData, - @Context final HttpServletRequest request) { - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - GroupDefinition updatedGroup = groupBL.updateGroup(componentId, componentTypeEnum, groupId, userId, groupData); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updatedGroup); - } - - @PUT - @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/metadata") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Group Metadata", httpMethod = "PUT", notes = "Returns updated group definition", response = GroupDefinition.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Group Updated"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateGroupMetadata( - @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupUniqueId, - @ApiParam(value = "Service object to be Updated", required = true) String data, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST, url); - - User user = new User(); - user.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - try { - Either convertResponse = parseToObject(data, () -> GroupDefinition.class); - if (convertResponse.isRight()) { - log.debug("failed to parse group"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - GroupDefinition updatedGroup = convertResponse.left().value(); - - // Update GroupDefinition - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - Either actionResponse = groupBL - .validateAndUpdateGroupMetadata(componentId, user, componentTypeEnum, updatedGroup, true ,true); - - if (actionResponse.isRight()) { - log.debug("failed to update GroupDefinition"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - GroupDefinition group = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(group); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Group Metadata"); - log.debug("update group metadata failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - -} +/*- + * ============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.servlets; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.info.GroupDefinitionInfo; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Group Servlet")) +@Singleton +public class GroupServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(GroupServlet.class); + public static final String START_HANDLE_REQUEST = "Start handle request of {}"; + private final GroupBusinessLogic groupBL; + + @Inject + public GroupServlet(UserBusinessLogic userBusinessLogic, GroupBusinessLogic groupBL, + ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, + ServletUtils servletUtils, ResourceImportManager resourceImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.groupBL = groupBL; + } + + @POST + @Path("/{containerComponentType}/{componentId}/groups/{groupType}") + @Operation(description = "Create group ", method = "POST", + summary = "Creates new group in component and returns it", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GroupDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Group created"), @ApiResponse( + responseCode = "400", + description = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found"), + @ApiResponse(responseCode = "500", description = "Internal Error")}) + public Response createGroup(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupType") final String type, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(post) Start handle request of {}", url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + GroupDefinition groupDefinition = groupBL.createGroup(componentId, componentTypeEnum, type, userId); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), groupDefinition); + } + + @GET + @Path("/{containerComponentType}/{componentId}/groups/{groupId}") + @Operation(description = "Get group artifacts ", method = "GET", + summary = "Returns artifacts metadata according to groupId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "group found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Group not found")}) + public Response getGroupById(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupId") final String groupId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + Either actionResponse = + groupBL.getGroupWithArtifactsById(componentTypeEnum, componentId, groupId, userId, false); + + if (actionResponse.isRight()) { + log.debug("failed to get all non abstract {}", containerComponentType); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getGroupArtifactById"); + log.debug("getGroupArtifactById unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}") + @Operation(description = "Delete Group", method = "DELETE", summary = "Returns deleted group id", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "ResourceInstance deleted"), @ApiResponse( + responseCode = "400", + description = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found"), + @ApiResponse(responseCode = "500", description = "Internal Error")}) + public Response deleteGroup(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST, url); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + GroupDefinition groupDefinition = groupBL.deleteGroup(componentId, componentTypeEnum, groupId, userId); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), + groupDefinition.getUniqueId()); + } + + @PUT + @Path("/{containerComponentType}/{componentId}/groups/{groupId}") + @Operation(description = "Update Group metadata", method = "PUT", summary = "Returns updated Group", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Group updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "component / group Not found")}) + public Response updateGroup(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupId") final String groupId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "GroupDefinition", required = true) GroupDefinition groupData, + @Context final HttpServletRequest request) { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + GroupDefinition updatedGroup = groupBL.updateGroup(componentId, componentTypeEnum, groupId, userId, groupData); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updatedGroup); + } + + @PUT + @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Group Metadata", method = "PUT", summary = "Returns updated group definition", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = GroupDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Group Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateGroupMetadata(@PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupUniqueId, + @Parameter(description = "Service object to be Updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST, url); + + User user = new User(); + user.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + Either convertResponse = parseToObject(data, () -> GroupDefinition.class); + if (convertResponse.isRight()) { + log.debug("failed to parse group"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + GroupDefinition updatedGroup = convertResponse.left().value(); + + // Update GroupDefinition + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + Either actionResponse = groupBL.validateAndUpdateGroupMetadata(componentId, + user, componentTypeEnum, updatedGroup, true, true); + + if (actionResponse.isRight()) { + log.debug("failed to update GroupDefinition"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + GroupDefinition group = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(group); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Group Metadata"); + log.debug("update group metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupTypesEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupTypesEndpoint.java index ffbf0e7cb0..79a8208978 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupTypesEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupTypesEndpoint.java @@ -1,66 +1,79 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.*; -import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic; -import org.openecomp.sdc.be.mixin.GroupTypeMixin; -import org.openecomp.sdc.be.model.GroupTypeDefinition; -import org.openecomp.sdc.be.view.ResponseView; -import org.openecomp.sdc.common.api.Constants; -import org.springframework.stereotype.Controller; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.List; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "group types resource") -@Controller -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class GroupTypesEndpoint { - - private final GroupTypeBusinessLogic groupTypeBusinessLogic; - - public GroupTypesEndpoint(GroupTypeBusinessLogic groupTypeBusinessLogic) { - this.groupTypeBusinessLogic = groupTypeBusinessLogic; - } - - @GET - @Path("/groupTypes") - @ApiOperation(value = "Get group types ", httpMethod = "GET", notes = "Returns group types", response = GroupTypeDefinition.class, responseContainer = "List") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "group types found"), - @ApiResponse(code = 400, message = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 500, message = "Internal Error") - }) - @ResponseView(mixin = {GroupTypeMixin.class}) - public List getGroupTypes(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "An optional parameter to indicate the type of the container from where this call is executed") - @QueryParam("internalComponentType") String internalComponentType) { - return groupTypeBusinessLogic.getAllGroupTypes(userId, internalComponentType); - } - -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic; +import org.openecomp.sdc.be.mixin.GroupTypeMixin; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.view.ResponseView; +import org.openecomp.sdc.common.api.Constants; +import org.springframework.stereotype.Controller; +import com.jcabi.aspects.Loggable; +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 = "group types resource")) +@Controller +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class GroupTypesEndpoint { + + private final GroupTypeBusinessLogic groupTypeBusinessLogic; + + public GroupTypesEndpoint(GroupTypeBusinessLogic groupTypeBusinessLogic) { + this.groupTypeBusinessLogic = groupTypeBusinessLogic; + } + + @GET + @Path("/groupTypes") + @Operation(description = "Get group types ", method = "GET", summary = "Returns group types", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = GroupTypeDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "group types found"), @ApiResponse( + responseCode = "400", + description = "field name invalid type/length, characters; mandatory field is absent, already exists (name)"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Error")}) + @ResponseView(mixin = {GroupTypeMixin.class}) + public List getGroupTypes(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter( + description = "An optional parameter to indicate the type of the container from where this call is executed") @QueryParam("internalComponentType") String internalComponentType) { + return groupTypeBusinessLogic.getAllGroupTypes(userId, internalComponentType); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java index 4f97eaf198..df061ad3b1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java @@ -1,523 +1,580 @@ -/*- - * ============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.servlets; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.util.Arrays; -import java.util.List; -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.DELETE; -import javax.ws.rs.GET; -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.builder.ReflectionToStringBuilder; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.DataTypeBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; -import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; -import org.openecomp.sdc.be.model.ComponentInstInputsMap; -import org.openecomp.sdc.be.model.ComponentInstanceInput; -import org.openecomp.sdc.be.model.ComponentInstanceProperty; -import org.openecomp.sdc.be.model.InputDefinition; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.model.ComponentInstListInput; -import org.openecomp.sdc.be.model.DataTypeDefinition; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Api(value = "Input Catalog", description = "Input Servlet") -@Path("/v1/catalog") -@Singleton -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class InputsServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(InputsServlet.class); - - private final DataTypeBusinessLogic businessLogic; - private final InputsBusinessLogic inputsBusinessLogic; - - @Inject - public InputsServlet(UserBusinessLogic userBusinessLogic, - InputsBusinessLogic inputsBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - DataTypeBusinessLogic dataTypeBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.inputsBusinessLogic = inputsBusinessLogic; - this.businessLogic = dataTypeBusinessLogic; - } - - @POST - @Path("/{containerComponentType}/{componentId}/update/inputs") - @ApiOperation(value = "Update resource inputs", httpMethod = "POST", notes = "Returns updated input", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Input updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateComponentInputs( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("componentId") final String componentId, - @ApiParam(value = "json describe the input", required = true) String data, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - String userId = request.getHeader(Constants.USER_ID_HEADER); - - try { - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Either inputsEither = getComponentsUtils() - .convertJsonToObjectUsingObjectMapper(data, modifier, InputDefinition[].class, - AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.SERVICE); - if(inputsEither.isRight()){ - log.debug("Failed to convert data to input definition. Status is {}", inputsEither.right().value()); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - List inputsToUpdate = Arrays.asList(inputsEither.left().value()); - - log.debug("Start handle request of updateComponentInputs. Received inputs are {}", inputsToUpdate); - - ServletContext context = request.getSession().getServletContext(); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(containerComponentType); - - if (businessLogic == null) { - log.debug("Unsupported component type {}", containerComponentType); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR)); - } - - Either, ResponseFormat> actionResponse = inputsBusinessLogic.updateInputsValue(componentType, componentId, inputsToUpdate, userId, true, false); - - if (actionResponse.isRight()) { - return buildErrorResponse(actionResponse.right().value()); - } - - List componentInputs = actionResponse.left().value(); - ObjectMapper mapper = new ObjectMapper(); - String result = mapper.writeValueAsString(componentInputs); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } - catch (Exception e) { - log.error("create and associate RI failed with exception: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - - @GET - @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{originComponentUid}/inputs") - @ApiOperation(value = "Get Inputs only", httpMethod = "GET", notes = "Returns Inputs list", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getComponentInstanceInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("instanceId") final String instanceId, - @PathParam("originComponentUid") final String originComponentUid, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response; - - try { - Either, ResponseFormat> inputsResponse = inputsBusinessLogic.getComponentInstanceInputs(userId, componentId, instanceId); - if (inputsResponse.isRight()) { - log.debug("failed to get component instance inputs {}", componentType); - return buildErrorResponse(inputsResponse.right().value()); - } - Object inputs = RepresentationUtils.toRepresentation(inputsResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), inputs); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Inputs " + componentType); - log.debug("getInputs failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{inputId}/properties") - @ApiOperation(value = "Get properties", httpMethod = "GET", notes = "Returns properties list", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getInputPropertiesForComponentInstance(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("instanceId") final String instanceId, - @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(GET) Start handle request of {}", url); - Response response = null; - - try { - Either, ResponseFormat> inputPropertiesRes = inputsBusinessLogic.getComponentInstancePropertiesByInputId(userId, componentId, instanceId, inputId); - if (inputPropertiesRes.isRight()) { - log.debug("failed to get properties of input: {}, with instance id: {}", inputId, instanceId); - return buildErrorResponse(inputPropertiesRes.right().value()); - } - Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Properites by input id: " + inputId + " for instance with id: " + instanceId); - log.debug("getInputPropertiesForComponentInstance failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Path("/{componentType}/{componentId}/inputs/{inputId}/inputs") - @ApiOperation(value = "Get inputs", httpMethod = "GET", notes = "Returns inputs list", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getInputsForComponentInput(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response; - try { - Either, ResponseFormat> inputsRes = inputsBusinessLogic.getInputsForComponentInput(userId, componentId, inputId); - - if (inputsRes.isRight()) { - log.debug("failed to get inputs of input: {}, with instance id: {}", inputId, componentId); - return buildErrorResponse(inputsRes.right().value()); - } - Object properties = RepresentationUtils.toRepresentation(inputsRes.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get inputs by input id: " + inputId + " for component with id: " + componentId); - log.debug("getInputsForComponentInput failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Path("/{componentType}/{componentId}/inputs/{inputId}") - @ApiOperation(value = "Get inputs", httpMethod = "GET", notes = "Returns inputs list", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response getInputsAndPropertiesForComponentInput(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response; - - try { - Either inputsRes = inputsBusinessLogic.getInputsAndPropertiesForComponentInput(userId, componentId, inputId, false); - - if (inputsRes.isRight()) { - log.debug("failed to get inputs of input: {}, with instance id: {}", inputId, componentId); - return buildErrorResponse(inputsRes.right().value()); - } - Object properties = RepresentationUtils.toRepresentation(inputsRes.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get inputs by input id: " + inputId + " for component with id: " + componentId); - log.debug("getInputsForComponentInput failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - private Either parseToComponentInstanceMap(String serviceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ComponentInstInputsMap.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - } - - private Either parseToComponentInstListInput(String json, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(json, user, ComponentInstListInput.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - } - - @POST - @Path("/{componentType}/{componentId}/create/inputs") - @ApiOperation(value = "Create inputs on service", httpMethod = "POST", notes = "Return inputs list", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response createMultipleInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "ComponentIns Inputs Object to be created", required = true) String componentInstInputsMapObj) { - - return super.declareProperties(userId, componentId, componentType, componentInstInputsMapObj, - DeclarationTypeEnum.INPUT, request); - } - - - /** - * Creates a "list input" and updates given list of properties to get value from the input. - * also a data type which has same properties is created. - * the data type will be the entry_schema of the list input. - * @param componentType the container type (service, resource, ...) - * @param componentId the container ID - * @param request HttpServletRequest object - * @param userId the User ID - * @param componentInstInputsMapObj the list of properties to be declared and the "list input" to be created. - * the type of the input must be "list". - * schema.type of the input will be the name of new data type. - * @return the created input - */ - @POST - @Path("/{componentType}/{componentId}/create/listInput") - @ApiOperation(value = "Create a list input on service", httpMethod = "POST", notes = "Return input", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response createListInput(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "ComponentIns Inputs Object to be created", required = true) String componentInstInputsMapObj) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("#createListInput: Start handle request of {}", url); - Response response = null; - - try { - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Either componentInstInputsMapRes = - parseToComponentInstListInput(componentInstInputsMapObj, modifier); - if (componentInstInputsMapRes.isRight()) { - log.debug("failed to parse componentInstInputsMap"); - response = buildErrorResponse(componentInstInputsMapRes.right().value()); - return response; - } - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - ComponentInstListInput componentInstInputsMap = componentInstInputsMapRes.left().value(); - if (log.isDebugEnabled()) { - // for inspection on debug - log.debug("parsed componentInstInputsMap={}", ReflectionToStringBuilder.toString(componentInstInputsMap)); - } - - Either, ResponseFormat> inputPropertiesRes = inputsBusinessLogic.createListInput( - userId, componentId, componentTypeEnum, componentInstInputsMap, true, false); - if (inputPropertiesRes.isRight()) { - log.debug("failed to create list input for service: {}", componentId); - return buildErrorResponse(inputPropertiesRes.right().value()); - } - Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create list input for service with id: " + componentId); - log.debug("createListInput failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - - @DELETE - @Path("/{componentType}/{componentId}/delete/{inputId}/input") - @ApiOperation(value = "Delete input from service", httpMethod = "DELETE", notes = "Delete service input", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Input deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Input not found") }) - public Response deleteInput ( - @PathParam("componentType") final String componentType, - @PathParam("componentId") final String componentId, - @PathParam("inputId") final String inputId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @ApiParam(value = "Service Input to be deleted", required = true) String componentInstInputsMapObj) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response = null; - - try { - Either deleteInput = inputsBusinessLogic.deleteInput(componentId, userId, inputId); - if (deleteInput.isRight()){ - ResponseFormat deleteResponseFormat = deleteInput.right().value(); - response = buildErrorResponse(deleteResponseFormat); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteInput.left().value()); - } catch (Exception e){ - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete input for service + " + componentId + " + with id: " + inputId); - log.debug("Delete input failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - /** - * Gets a specific data type associated with a component. - * @param componentType the container type (service, resource, ...) - * @param componentId the container ID - * @param dataTypeName the data type name - * @param request HttpServletRequest object - * @return the data type info - */ - @GET - @Path("/{componentType}/{componentId}/dataType/{dataTypeName}") - @ApiOperation(value = "Get data type in service", httpMethod = "GET", notes = "Get data type in service", - response = DataTypeDefinition.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Data type found"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Data type not found")}) - public Response getDataType( - @PathParam("componentType") final String componentType, - @PathParam("componentId") final String componentId, - @PathParam("dataTypeName") final String dataTypeName, - @Context final HttpServletRequest request - ) { - ComponentsUtils componentsUtils = getComponentsUtils(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(getDataType) Start handle request of {}", url); - Response response; - - try { - Either getResult = businessLogic.getPrivateDataType(componentId, dataTypeName); - if (getResult.isRight()) { - ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResult.right().value()); - return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); - } - Object json = RepresentationUtils.toRepresentation(getResult.left().value()); - return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get data type from service + " + componentId + " + with name: " + dataTypeName); - log.debug("Get data type failed with exception", e); - response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - /** - * Gets a list of data types which a component has. - * @param componentType the container type (service, resource, ...) - * @param componentId the container ID - * @param request HttpServletRequest object - * @return the list of data types in the component - */ - @GET - @Path("/{componentType}/{componentId}/dataTypes") - @ApiOperation(value = "Get data types that service has", httpMethod = "GET", notes = "Get data types in service", - response = Resource.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Data type found"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Component not found")}) - public Response getDataTypes( - @PathParam("componentType") final String componentType, - @PathParam("componentId") final String componentId, - @Context final HttpServletRequest request - ) { - ServletContext context = request.getSession().getServletContext(); - ComponentsUtils componentsUtils = getComponentsUtils(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(getDataType) Start handle request of {}", url); - Response response; - - try { - Either, StorageOperationStatus> getResult = businessLogic.getPrivateDataTypes(componentId); - if (getResult.isRight()) { - ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResult.right().value()); - return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); - } - Object json = RepresentationUtils.toRepresentation(getResult.left().value()); - return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get data type from service + " + componentId); - log.debug("Get data type failed with exception", e); - response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - /** - * Deletes a data type from a component. - * @param componentType the container type (service, resource, ...) - * @param componentId the container ID - * @param dataTypeName the data type name to be deleted - * @param request HttpServletRequest object - * @return operation result - */ - @DELETE - @Path("/{componentType}/{componentId}/dataType/{dataTypeName}") - @ApiOperation(value = "Delete data type from service", httpMethod = "DELETE", notes = "Delete service input", - response = Resource.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Data type deleted"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Data type not found")}) - public Response deleteDataType( - @PathParam("componentType") final String componentType, - @PathParam("componentId") final String componentId, - @PathParam("dataTypeName") final String dataTypeName, - @Context final HttpServletRequest request - ) { - ServletContext context = request.getSession().getServletContext(); - ComponentsUtils componentsUtils = getComponentsUtils(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - Response response; - - try { - Either deleteResult = businessLogic.deletePrivateDataType(componentId, dataTypeName); - if (deleteResult.isRight()) { - ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteResult.right().value()); - return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); - } - Object json = RepresentationUtils.toRepresentation(deleteResult.left().value()); - return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete data type for service + " + componentId + " + with name: " + dataTypeName); - log.debug("Delete data type failed with exception", e); - response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } -} +/*- + * ============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.servlets; + +import java.util.Arrays; +import java.util.List; +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.DELETE; +import javax.ws.rs.GET; +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.builder.ReflectionToStringBuilder; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.DataTypeBusinessLogic; +import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstListInput; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +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) +@OpenAPIDefinition(info = @Info(title = "Input Catalog", description = "Input Servlet")) +@Path("/v1/catalog") +@Singleton +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class InputsServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(InputsServlet.class); + + private final DataTypeBusinessLogic businessLogic; + private final InputsBusinessLogic inputsBusinessLogic; + + @Inject + public InputsServlet(UserBusinessLogic userBusinessLogic, + InputsBusinessLogic inputsBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + DataTypeBusinessLogic dataTypeBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.inputsBusinessLogic = inputsBusinessLogic; + this.businessLogic = dataTypeBusinessLogic; + } + + @POST + @Path("/{containerComponentType}/{componentId}/update/inputs") + @Operation(description = "Update resource inputs", method = "POST", summary = "Returns updated input", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Input updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateComponentInputs(@Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, + @Parameter(description = "json describe the input", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + try { + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Either inputsEither = getComponentsUtils() + .convertJsonToObjectUsingObjectMapper(data, modifier, InputDefinition[].class, + AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.SERVICE); + if(inputsEither.isRight()){ + log.debug("Failed to convert data to input definition. Status is {}", inputsEither.right().value()); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + List inputsToUpdate = Arrays.asList(inputsEither.left().value()); + + log.debug("Start handle request of updateComponentInputs. Received inputs are {}", inputsToUpdate); + + ServletContext context = request.getSession().getServletContext(); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(containerComponentType); + + if (businessLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR)); + } + + Either, ResponseFormat> actionResponse = inputsBusinessLogic.updateInputsValue(componentType, componentId, inputsToUpdate, userId, true, false); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + List componentInputs = actionResponse.left().value(); + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(componentInputs); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } + catch (Exception e) { + log.error("create and associate RI failed with exception: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + + @GET + @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{originComponentUid}/inputs") + @Operation(description = "Get Inputs only", method = "GET", summary = "Returns Inputs list", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getComponentInstanceInputs(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @PathParam("instanceId") final String instanceId, + @PathParam("originComponentUid") final String originComponentUid, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response; + + try { + Either, ResponseFormat> inputsResponse = inputsBusinessLogic.getComponentInstanceInputs(userId, componentId, instanceId); + if (inputsResponse.isRight()) { + log.debug("failed to get component instance inputs {}", componentType); + return buildErrorResponse(inputsResponse.right().value()); + } + Object inputs = RepresentationUtils.toRepresentation(inputsResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), inputs); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Inputs " + componentType); + log.debug("getInputs failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{inputId}/properties") + @Operation(description = "Get properties", method = "GET", summary = "Returns properties list", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class)))) ) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getInputPropertiesForComponentInstance(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @PathParam("instanceId") final String instanceId, + @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(GET) Start handle request of {}", url); + Response response = null; + + try { + Either, ResponseFormat> inputPropertiesRes = inputsBusinessLogic + .getComponentInstancePropertiesByInputId(userId, componentId, instanceId, inputId); + if (inputPropertiesRes.isRight()) { + log.debug("failed to get properties of input: {}, with instance id: {}", inputId, instanceId); + return buildErrorResponse(inputPropertiesRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError( + "Get Properites by input id: " + inputId + " for instance with id: " + instanceId); + log.debug("getInputPropertiesForComponentInstance failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/{componentType}/{componentId}/inputs/{inputId}/inputs") + @Operation(description = "Get inputs", method = "GET", summary = "Returns inputs list", responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class)))) ) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getInputsForComponentInput(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response; + try { + Either, ResponseFormat> inputsRes = + inputsBusinessLogic.getInputsForComponentInput(userId, componentId, inputId); + + if (inputsRes.isRight()) { + log.debug("failed to get inputs of input: {}, with instance id: {}", inputId, componentId); + return buildErrorResponse(inputsRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputsRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError( + "Get inputs by input id: " + inputId + " for component with id: " + componentId); + log.debug("getInputsForComponentInput failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/{componentType}/{componentId}/inputs/{inputId}") + @Operation(description = "Get inputs", method = "GET", summary = "Returns inputs list", responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class)))) ) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getInputsAndPropertiesForComponentInput(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response; + + try { + Either inputsRes = + inputsBusinessLogic.getInputsAndPropertiesForComponentInput(userId, componentId, inputId, false); + + if (inputsRes.isRight()) { + log.debug("failed to get inputs of input: {}, with instance id: {}", inputId, componentId); + return buildErrorResponse(inputsRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputsRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError( + "Get inputs by input id: " + inputId + " for component with id: " + componentId); + log.debug("getInputsForComponentInput failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private Either parseToComponentInstanceMap(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ComponentInstInputsMap.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + private Either parseToComponentInstListInput(String json, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(json, user, ComponentInstListInput.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + @POST + @Path("/{componentType}/{componentId}/create/inputs") + @Operation(description = "Create inputs on service", method = "POST", summary = "Return inputs list", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response createMultipleInputs(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "ComponentIns Inputs Object to be created", + required = true) String componentInstInputsMapObj) { + + return super.declareProperties(userId, componentId, componentType, componentInstInputsMapObj, + DeclarationTypeEnum.INPUT, request); + } + + + /** + * Creates a "list input" and updates given list of properties to get value from the input. + * also a data type which has same properties is created. + * the data type will be the entry_schema of the list input. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param request HttpServletRequest object + * @param userId the User ID + * @param componentInstInputsMapObj the list of properties to be declared and the "list input" to be created. + * the type of the input must be "list". + * schema.type of the input will be the name of new data type. + * @return the created input + */ + @POST + @Path("/{componentType}/{componentId}/create/listInput") + @Operation(description = "Create a list input on service", method = "POST", summary = "Return input", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class)))) ) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response createListInput(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "ComponentIns Inputs Object to be created", + required = true) String componentInstInputsMapObj) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("#createListInput: Start handle request of {}", url); + Response response = null; + + try { + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Either componentInstInputsMapRes = + parseToComponentInstListInput(componentInstInputsMapObj, modifier); + if (componentInstInputsMapRes.isRight()) { + log.debug("failed to parse componentInstInputsMap"); + response = buildErrorResponse(componentInstInputsMapRes.right().value()); + return response; + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentInstListInput componentInstInputsMap = componentInstInputsMapRes.left().value(); + if (log.isDebugEnabled()) { + // for inspection on debug + log.debug("parsed componentInstInputsMap={}", + ReflectionToStringBuilder.toString(componentInstInputsMap)); + } + + Either, ResponseFormat> inputPropertiesRes = inputsBusinessLogic + .createListInput(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false); + if (inputPropertiesRes.isRight()) { + log.debug("failed to create list input for service: {}", componentId); + return buildErrorResponse(inputPropertiesRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance() + .logBeRestApiGeneralError("Create list input for service with id: " + componentId); + log.debug("createListInput failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + + @DELETE + @Path("/{componentType}/{componentId}/delete/{inputId}/input") + @Operation(description = "Delete input from service", method = "DELETE", summary = "Delete service input", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class)))) ) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Input deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Input not found")}) + public Response deleteInput(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "Service Input to be deleted", required = true) String componentInstInputsMapObj) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + Either deleteInput = + inputsBusinessLogic.deleteInput(componentId, userId, inputId); + if (deleteInput.isRight()) { + ResponseFormat deleteResponseFormat = deleteInput.right().value(); + response = buildErrorResponse(deleteResponseFormat); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteInput.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance() + .logBeRestApiGeneralError("Delete input for service + " + componentId + " + with id: " + inputId); + log.debug("Delete input failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /** + * Gets a specific data type associated with a component. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param dataTypeName the data type name + * @param request HttpServletRequest object + * @return the data type info + */ + @GET + @Path("/{componentType}/{componentId}/dataType/{dataTypeName}") + @Operation(description = "Get data type in service", method = "GET", summary = "Get data type in service", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = DataTypeDefinition.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Data type found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Data type not found")}) + public Response getDataType( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("dataTypeName") final String dataTypeName, + @Context final HttpServletRequest request + ) { + ComponentsUtils componentsUtils = getComponentsUtils(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getDataType) Start handle request of {}", url); + Response response; + + try { + Either getResult = businessLogic.getPrivateDataType(componentId, dataTypeName); + if (getResult.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResult.right().value()); + return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); + } + Object json = RepresentationUtils.toRepresentation(getResult.left().value()); + return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get data type from service + " + componentId + " + with name: " + dataTypeName); + log.debug("Get data type failed with exception", e); + response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + /** + * Gets a list of data types which a component has. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param request HttpServletRequest object + * @return the list of data types in the component + */ + @GET + @Path("/{componentType}/{componentId}/dataTypes") + @Operation(description = "Get data types that service has", method = "GET", summary = "Get data types in service", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class)))) ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Data type found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response getDataTypes( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @Context final HttpServletRequest request + ) { + ServletContext context = request.getSession().getServletContext(); + ComponentsUtils componentsUtils = getComponentsUtils(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getDataType) Start handle request of {}", url); + Response response; + + try { + Either, StorageOperationStatus> getResult = businessLogic.getPrivateDataTypes(componentId); + if (getResult.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResult.right().value()); + return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); + } + Object json = RepresentationUtils.toRepresentation(getResult.left().value()); + return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get data type from service + " + componentId); + log.debug("Get data type failed with exception", e); + response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + /** + * Deletes a data type from a component. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param dataTypeName the data type name to be deleted + * @param request HttpServletRequest object + * @return operation result + */ + @DELETE + @Path("/{componentType}/{componentId}/dataType/{dataTypeName}") + @Operation(description = "Delete data type from service", method = "DELETE", summary = "Delete service input", + responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Data type deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Data type not found")}) + public Response deleteDataType( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("dataTypeName") final String dataTypeName, + @Context final HttpServletRequest request + ) { + ServletContext context = request.getSession().getServletContext(); + ComponentsUtils componentsUtils = getComponentsUtils(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response; + + try { + Either deleteResult = businessLogic.deletePrivateDataType(componentId, dataTypeName); + if (deleteResult.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteResult.right().value()); + return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); + } + Object json = RepresentationUtils.toRepresentation(deleteResult.left().value()); + return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete data type for service + " + componentId + " + with name: " + dataTypeName); + log.debug("Delete data type failed with exception", e); + response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java index 66b465d40f..f6531f7873 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java @@ -1,339 +1,348 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * 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.servlets; - -import com.google.common.collect.ImmutableMap; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -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.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.InterfaceDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.exception.ResponseFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Interface Operation Servlet", description = "Interface Operation Servlet") -@Singleton -public class InterfaceOperationServlet extends AbstractValidationsServlet { - - private static final Logger log = LoggerFactory.getLogger(InterfaceOperationServlet.class); - private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; - - @Inject - public InterfaceOperationServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/interfaceOperations") - @ApiOperation(value = "Create Interface Operations on Resource", httpMethod = "POST", - notes = "Create Interface Operations on Resource", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Interface Operations on Resource"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Resource not found"), - @ApiResponse(code = 409, message = "Interface Operation already exist")}) - public Response createInterfaceOperationsOnResource( - @ApiParam(value = "Interface Operations to create", required = true) String data, - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, false); - } - - private Response createOrUpdate(String data, ComponentTypeEnum componentType, String componentId, - HttpServletRequest request, String userId, boolean isUpdate) { - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("Start create or update request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - - List mappedInterfaceData = getMappedInterfaceData(data, modifier, componentType); - Either, ResponseFormat> actionResponse; - if (isUpdate) { - actionResponse = - interfaceOperationBusinessLogic - .updateInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true); - } else { - actionResponse = - interfaceOperationBusinessLogic - .createInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true); - } - - if (actionResponse.isRight()) { - log.error("failed to create or update interface operation"); - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - getFormattedResponse(actionResponse.left().value())); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update"); - log.error("create or update interface Operation with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private List getMappedInterfaceData(String inputJson, User user, - ComponentTypeEnum componentTypeEnum) { - Either uiComponentEither = - getComponentsUtils().convertJsonToObjectUsingObjectMapper(inputJson, user, - UiComponentDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); - return new ArrayList<>(uiComponentEither.left().value().getInterfaces().values()); - } - - private Object getFormattedResponse(List interfaceDefinitions) throws IOException { - Map> allInterfaces = - ImmutableMap.of(JsonPresentationFields.INTERFACES.getPresentation(), interfaceDefinitions); - return RepresentationUtils.toFilteredRepresentation(allInterfaces); - } - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/interfaceOperations") - @ApiOperation(value = "Update Interface Operations on Resource", httpMethod = "PUT", - notes = "Update Interface Operations on Resource", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Interface Operations on Resource"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Resource not found")}) - public Response updateInterfaceOperationsOnResource( - @ApiParam(value = "Interface Operations to update", required = true) String data, - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, true); - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationId}") - @ApiOperation(value = "Delete Interface Operation from Resource", httpMethod = "DELETE", - notes = "Delete Interface Operation from Resource", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation from Resource"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Resource not found")}) - public Response deleteInterfaceOperationsFromResource( - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, - @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return delete(interfaceId, operationId, resourceId, request, userId); - } - - private Response delete(String interfaceId, String operationId, String componentId, HttpServletRequest request, - String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("Start delete request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - Either, ResponseFormat> actionResponse = - interfaceOperationBusinessLogic.deleteInterfaceOperation( - componentIdLower, interfaceId, Collections.singletonList(operationId), modifier, true); - if (actionResponse.isRight()) { - log.error("failed to delete interface operation"); - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - getFormattedResponse(actionResponse.left().value())); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation"); - log.error("Delete interface operation with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationId}") - @ApiOperation(value = "Get Interface Operation from Resource", httpMethod = "GET", - notes = "GET Interface Operation from Resource", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation from Resource"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Resource not found")}) - public Response getInterfaceOperationsFromResource( - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, - @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return get(interfaceId, operationId, resourceId, request, userId); - } - - private Response get(String interfaceId, String operationId, String componentId, HttpServletRequest request, - String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("Start get request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - Either, ResponseFormat> actionResponse = - interfaceOperationBusinessLogic.getInterfaceOperation( - componentIdLower, interfaceId, Collections.singletonList(operationId), modifier, true); - if (actionResponse.isRight()) { - log.error("failed to get interface operation"); - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - getFormattedResponse(actionResponse.left().value())); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component interface operations"); - log.error("get component interface operations failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/interfaceOperations") - @ApiOperation(value = "Create Interface Operations on Service", httpMethod = "POST", - notes = "Create Interface Operations on Service", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Interface Operations on Service"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Service not found"), - @ApiResponse(code = 409, message = "Interface Operation already exist")}) - public Response createInterfaceOperationsOnService( - @ApiParam(value = "Interface Operations to create", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, false); - } - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/interfaceOperations") - @ApiOperation(value = "Update Interface Operations on Service", httpMethod = "PUT", - notes = "Update Interface Operations on Service", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Interface Operations on Service"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Service not found")}) - public Response updateInterfaceOperationsOnService( - @ApiParam(value = "Interface Operations to update", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, true); - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationId}") - @ApiOperation(value = "Delete Interface Operation from Service", httpMethod = "DELETE", - notes = "Delete Interface Operation from Service", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation from Service"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Service not found")}) - public Response deleteInterfaceOperationsFromService( - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, - @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return delete(interfaceId, operationId, serviceId, request, userId); - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationId}") - @ApiOperation(value = "Get Interface Operation from Service", httpMethod = "GET", - notes = "GET Interface Operation from Service", response = InterfaceDefinition.class, responseContainer = "List") - @ApiResponses(value = {@ApiResponse(code = 201, message = "Get Interface Operation from Service"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Service not found")}) - public Response getInterfaceOperationsFromService( - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, - @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { - return get(interfaceId, operationId, serviceId, request, userId); - } - -} - +/* + * Copyright © 2016-2018 European Support Limited + * + * 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.servlets; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableMap; +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") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Interface Operation Servlet", description = "Interface Operation Servlet")) +@Singleton +public class InterfaceOperationServlet extends AbstractValidationsServlet { + + private static final Logger log = LoggerFactory.getLogger(InterfaceOperationServlet.class); + private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; + + @Inject + public InterfaceOperationServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaceOperations") + @Operation(description = "Create Interface Operations on Resource", method = "POST", + summary = "Create Interface Operations on Resource",responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Interface Operations on Resource"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found"), + @ApiResponse(responseCode = "409", description = "Interface Operation already exist")}) + public Response createInterfaceOperationsOnResource( + @Parameter(description = "Interface Operations to create", required = true) String data, + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, false); + } + + private Response createOrUpdate(String data, ComponentTypeEnum componentType, String componentId, + HttpServletRequest request, String userId, boolean isUpdate) { + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("Start create or update request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + + List mappedInterfaceData = getMappedInterfaceData(data, modifier, componentType); + Either, ResponseFormat> actionResponse; + if (isUpdate) { + actionResponse = + interfaceOperationBusinessLogic + .updateInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true); + } else { + actionResponse = + interfaceOperationBusinessLogic + .createInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true); + } + + if (actionResponse.isRight()) { + log.error("failed to create or update interface operation"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + getFormattedResponse(actionResponse.left().value())); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update"); + log.error("create or update interface Operation with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private List getMappedInterfaceData(String inputJson, User user, + ComponentTypeEnum componentTypeEnum) { + Either uiComponentEither = + getComponentsUtils().convertJsonToObjectUsingObjectMapper(inputJson, user, + UiComponentDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); + return new ArrayList<>(uiComponentEither.left().value().getInterfaces().values()); + } + + private Object getFormattedResponse(List interfaceDefinitions) throws IOException { + Map> allInterfaces = + ImmutableMap.of(JsonPresentationFields.INTERFACES.getPresentation(), interfaceDefinitions); + return RepresentationUtils.toFilteredRepresentation(allInterfaces); + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaceOperations") + @Operation(description = "Update Interface Operations on Resource", method = "PUT", + summary = "Update Interface Operations on Resource",responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Interface Operations on Resource"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response updateInterfaceOperationsOnResource( + @Parameter(description = "Interface Operations to update", required = true) String data, + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, true); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationId}") + @Operation(description = "Delete Interface Operation from Resource", method = "DELETE", + summary = "Delete Interface Operation from Resource", responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Interface Operation from Resource"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response deleteInterfaceOperationsFromResource( + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Parameter(description = "Interface Id") @PathParam("interfaceId") String interfaceId, + @Parameter(description = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return delete(interfaceId, operationId, resourceId, request, userId); + } + + private Response delete(String interfaceId, String operationId, String componentId, HttpServletRequest request, + String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("Start delete request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + Either, ResponseFormat> actionResponse = + interfaceOperationBusinessLogic.deleteInterfaceOperation( + componentIdLower, interfaceId, Collections.singletonList(operationId), modifier, true); + if (actionResponse.isRight()) { + log.error("failed to delete interface operation"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + getFormattedResponse(actionResponse.left().value())); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation"); + log.error("Delete interface operation with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationId}") + @Operation(description = "Get Interface Operation from Resource", method = "GET", + summary = "GET Interface Operation from Resource",responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Interface Operation from Resource"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response getInterfaceOperationsFromResource( + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Parameter(description = "Interface Id") @PathParam("interfaceId") String interfaceId, + @Parameter(description = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return get(interfaceId, operationId, resourceId, request, userId); + } + + private Response get(String interfaceId, String operationId, String componentId, HttpServletRequest request, + String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("Start get request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + Either, ResponseFormat> actionResponse = + interfaceOperationBusinessLogic.getInterfaceOperation( + componentIdLower, interfaceId, Collections.singletonList(operationId), modifier, true); + if (actionResponse.isRight()) { + log.error("failed to get interface operation"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + getFormattedResponse(actionResponse.left().value())); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component interface operations"); + log.error("get component interface operations failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaceOperations") + @Operation(description = "Create Interface Operations on Service", method = "POST", + summary = "Create Interface Operations on Service", responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Interface Operations on Service"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found"), + @ApiResponse(responseCode = "409", description = "Interface Operation already exist")}) + public Response createInterfaceOperationsOnService( + @Parameter(description = "Interface Operations to create", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, false); + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaceOperations") + @Operation(description = "Update Interface Operations on Service", method = "PUT", + summary = "Update Interface Operations on Service",responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Interface Operations on Service"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response updateInterfaceOperationsOnService( + @Parameter(description = "Interface Operations to update", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, true); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationId}") + @Operation(description = "Delete Interface Operation from Service", method = "DELETE", + summary = "Delete Interface Operation from Service",responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Interface Operation from Service"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response deleteInterfaceOperationsFromService( + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Interface Id") @PathParam("interfaceId") String interfaceId, + @Parameter(description = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return delete(interfaceId, operationId, serviceId, request, userId); + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationId}") + @Operation(description = "Get Interface Operation from Service", method = "GET", + summary = "GET Interface Operation from Service",responses = @ApiResponse(content = @Content( + array = @ArraySchema(schema = @Schema(implementation = InterfaceDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Get Interface Operation from Service"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response getInterfaceOperationsFromService( + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Interface Id") @PathParam("interfaceId") String interfaceId, + @Parameter(description = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return get(interfaceId, operationId, serviceId, request, userId); + } + +} + diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java index 60e8f3c0fa..753ae13873 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java @@ -1,169 +1,197 @@ -/*- - * ============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.servlets; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -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.utils.UiComponentDataConverter; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.ui.model.UiComponentMetadata; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.springframework.beans.factory.annotation.Autowired; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Lifecycle Actions Servlet", description = "Lifecycle Actions Servlet") -@Singleton -public class LifecycleServlet extends BeGenericServlet { - - private static final Logger log = Logger.getLogger(LifecycleServlet.class); - private final LifecycleBusinessLogic lifecycleBusinessLogic; - - @Inject - public LifecycleServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - LifecycleBusinessLogic lifecycleBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.lifecycleBusinessLogic = lifecycleBusinessLogic; - } - - - @POST - @Path("/{componentCollection}/{componentId}/lifecycleState/{lifecycleOperation}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Change Resource lifecycle State", httpMethod = "POST", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource state changed"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 409, message = "Resource already exist") }) - public Response changeResourceState(@ApiParam(value = "LifecycleChangeInfo - relevant for checkin, failCertification, cancelCertification", required = false) String jsonChangeInfo, - @ApiParam(value = "validValues: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," - + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam(value = "componentCollection") final String componentCollection, - @ApiParam(allowableValues = "checkout, undoCheckout, checkin, certificationRequest, startCertification, failCertification, cancelCertification, certify", required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition, - @ApiParam(value = "id of component to be changed") @PathParam(value = "componentId") final String componentId, @Context final HttpServletRequest request, - @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - Response response = null; - - // get modifier from graph - log.debug("get modifier properties"); - Either eitherGetUser = getUser(request, userId); - if (eitherGetUser.isRight()) { - return buildErrorResponse(eitherGetUser.right().value()); - } - User user = eitherGetUser.left().value(); - - String resourceIdLower = componentId.toLowerCase(); - log.debug("perform {} operation to resource with id {} ", lifecycleTransition, resourceIdLower); - Either validateEnum = validateTransitionEnum(lifecycleTransition, user); - if (validateEnum.isRight()) { - return validateEnum.right().value(); - } - - LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction(); - - try { - if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) { - ObjectMapper mapper = new ObjectMapper(); - changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks()); - } - } - - catch (Exception e) { - BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); - log.debug("failed to convert from json {}", jsonChangeInfo, e); - ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(user, componentId, AuditingActionEnum.CHECKOUT_RESOURCE); - return buildErrorResponse(responseFormat); - } - - try { - LifeCycleTransitionEnum transitionEnum = validateEnum.left().value(); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(componentCollection); - if (componentType != null) { - Either actionResponse = lifecycleBusinessLogic - .changeComponentState(componentType, componentId, user, transitionEnum, changeInfo, false, true); - - if (actionResponse.isRight()) { - log.info("failed to change resource state"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - log.debug("change state successful !!!"); - UiComponentMetadata componentMetatdata = UiComponentDataConverter.convertToUiComponentMetadata(actionResponse.left().value()); - Object value = RepresentationUtils.toRepresentation(componentMetatdata); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), value); - return response; - } else { - log.info("componentCollection \"{}\" is not valid. Supported componentCollection values are \"{}\", \"{}\" or \"{}\"", componentCollection, ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME, - ComponentTypeEnum.PRODUCT_PARAM_NAME); - ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, componentId, AuditingActionEnum.CHECKOUT_RESOURCE); - return buildErrorResponse(error); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State"); - log.debug("change lifecycle state failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - private Either 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(buildErrorResponse(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.servlets; + +import javax.inject.Inject; +import javax.inject.Singleton; +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.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.utils.UiComponentDataConverter; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.ui.model.UiComponentMetadata; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +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 = "Lifecycle Actions Servlet", description = "Lifecycle Actions Servlet")) +@Singleton +public class LifecycleServlet extends BeGenericServlet { + + private static final Logger log = Logger.getLogger(LifecycleServlet.class); + private final LifecycleBusinessLogic lifecycleBusinessLogic; + + @Inject + public LifecycleServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils, + LifecycleBusinessLogic lifecycleBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.lifecycleBusinessLogic = lifecycleBusinessLogic; + } + + + @POST + @Path("/{componentCollection}/{componentId}/lifecycleState/{lifecycleOperation}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Change Resource lifecycle State", method = "POST", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource state changed"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response changeResourceState( + @Parameter( + description = "LifecycleChangeInfo - relevant for checkin, failCertification, cancelCertification", + required = false) String jsonChangeInfo, + @Parameter(description = "validValues: resources / services / products", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME})) @PathParam( + value = "componentCollection") final String componentCollection, + @Parameter(schema = @Schema(allowableValues = { + "checkout, undoCheckout, checkin, certificationRequest, startCertification, failCertification, cancelCertification, certify"}), + required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition, + @Parameter(description = "id of component to be changed") @PathParam( + value = "componentId") final String componentId, + @Context final HttpServletRequest request, + @Parameter(description = "id of user initiating the operation") @HeaderParam( + value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + Response response = null; + + // get modifier from graph + log.debug("get modifier properties"); + Either eitherGetUser = getUser(request, userId); + if (eitherGetUser.isRight()) { + return buildErrorResponse(eitherGetUser.right().value()); + } + User user = eitherGetUser.left().value(); + + String resourceIdLower = componentId.toLowerCase(); + log.debug("perform {} operation to resource with id {} ", lifecycleTransition, resourceIdLower); + Either validateEnum = validateTransitionEnum(lifecycleTransition, user); + if (validateEnum.isRight()) { + return validateEnum.right().value(); + } + + LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction(); + + try { + if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) { + ObjectMapper mapper = new ObjectMapper(); + changeInfo = new LifecycleChangeInfoWithAction( + mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks()); + } + } + + catch (Exception e) { + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", jsonChangeInfo, e); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(user, componentId, + AuditingActionEnum.CHECKOUT_RESOURCE); + return buildErrorResponse(responseFormat); + } + + try { + LifeCycleTransitionEnum transitionEnum = validateEnum.left().value(); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(componentCollection); + if (componentType != null) { + Either actionResponse = + lifecycleBusinessLogic.changeComponentState(componentType, componentId, user, transitionEnum, + changeInfo, false, true); + + if (actionResponse.isRight()) { + log.info("failed to change resource state"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + log.debug("change state successful !!!"); + UiComponentMetadata componentMetatdata = + UiComponentDataConverter.convertToUiComponentMetadata(actionResponse.left().value()); + Object value = RepresentationUtils.toRepresentation(componentMetatdata); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), value); + return response; + } else { + log.info( + "componentCollection \"{}\" is not valid. Supported componentCollection values are \"{}\", \"{}\" or \"{}\"", + componentCollection, ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.PRODUCT_PARAM_NAME); + ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, componentId, + AuditingActionEnum.CHECKOUT_RESOURCE); + return buildErrorResponse(error); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State"); + log.debug("change lifecycle state failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private Either 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(buildErrorResponse(error)); + } + return Either.left(transitionEnum); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyServlet.java index 38f38787a6..1ab061fa27 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyServlet.java @@ -1,381 +1,480 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; -import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.PolicyDefinition; -import org.openecomp.sdc.be.model.PolicyTargetDTO; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.user.UserBusinessLogic; -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.exception.ResponseFormat; -import org.springframework.stereotype.Controller; - -/** - * Provides REST API to create, retrieve, update, delete a policy - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Policy Servlet") -@Controller -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class PolicyServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(PolicyServlet.class); - private final PolicyBusinessLogic policyBusinessLogic; - - @Inject - public PolicyServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - PolicyBusinessLogic policyBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.policyBusinessLogic = policyBusinessLogic; - } - - @POST - @Path("/{containerComponentType}/{componentId}/policies/{policyTypeName}") - @ApiOperation(value = "Create Policy", httpMethod = "POST", notes = "Returns created Policy", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Policy created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Policy already exist"), @ApiResponse(code = 404, message = "Component not found")}) - public Response createPolicy(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyTypeName") final String policyTypeName, - @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @Context final HttpServletRequest request) { - init(); - - Wrapper responseWrapper = new Wrapper<>(); - try { - Wrapper componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); - if (responseWrapper.isEmpty()) { - responseWrapper.setInnerElement(policyBusinessLogic.createPolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyTypeName, userId, true) - .either(l -> buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), l), - this::buildErrorResponse)); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Policy"); - log.error("Failed to create policy. The exception {} occurred. ", e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } - return responseWrapper.getInnerElement(); - } - - @PUT - @Path("/{containerComponentType}/{componentId}/policies/{policyId}") - @ApiOperation(value = "Update Policy metadata", httpMethod = "PUT", notes = "Returns updated Policy", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "component / policy Not found")}) - public Response updatePolicy(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @ApiParam(value = "PolicyDefinition", required = true) String policyData, @Context final HttpServletRequest request) { - init(); - - Wrapper responseWrapper = new Wrapper<>(); - try { - Wrapper componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); - Wrapper policyWrapper = new Wrapper<>(); - if (responseWrapper.isEmpty()) { - convertJsonToObjectOfClass(policyData, policyWrapper, PolicyDefinition.class, responseWrapper); - if (policyWrapper.isEmpty()) { - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT))); - } - } - if (!policyWrapper.isEmpty()) { - policyWrapper.getInnerElement().setUniqueId(policyId); - responseWrapper.setInnerElement(policyBusinessLogic.updatePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyWrapper.getInnerElement(), userId, true) - .either(this::buildOkResponse, - this::buildErrorResponse)); - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Policy"); - log.error("Failed to update policy. The exception {} occurred. ", e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } - return responseWrapper.getInnerElement(); - } - - @GET - @Path("/{containerComponentType}/{componentId}/policies/{policyId}") - @ApiOperation(value = "Get Policy", httpMethod = "GET", notes = "Returns Policy", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy was found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "component / policy Not found")}) - public Response getPolicy(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @Context final HttpServletRequest request) { - init(); - - Wrapper responseWrapper = new Wrapper<>(); - try { - Wrapper componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); - if (responseWrapper.isEmpty()) { - responseWrapper.setInnerElement(policyBusinessLogic.getPolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, userId) - .either(this::buildOkResponse, - this::buildErrorResponse)); - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Policy"); - log.error("Failed to retrieve policy. The exception {} occurred. ", e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } - return responseWrapper.getInnerElement(); - } - - @DELETE - @Path("/{containerComponentType}/{componentId}/policies/{policyId}") - @ApiOperation(value = "Delete Policy", httpMethod = "DELETE", notes = "No body", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 204, message = "Policy was deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "component / policy Not found")}) - public Response deletePolicy(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @Context final HttpServletRequest request) { - init(); - - Wrapper responseWrapper = new Wrapper<>(); - try { - Wrapper componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); - if (responseWrapper.isEmpty()) { - responseWrapper.setInnerElement(policyBusinessLogic.deletePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, userId, true) - .either(this::buildOkResponse, - this::buildErrorResponse)); - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Policy"); - log.error("Failed to delete policy. The exception {} occurred. ", e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } - return responseWrapper.getInnerElement(); - } - - @PUT - @Path("/{containerComponentType}/{componentId}/policies/{policyId}/undeclare") - @ApiOperation(value = "undeclare Policy", httpMethod = "PUT", notes = "No body", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 204, message = "Policy was undeclared"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "component / policy Not found")}) - public Response undeclarePolicy(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @Context final HttpServletRequest request) { - init(); - - Wrapper responseWrapper = new Wrapper<>(); - try { - Wrapper componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); - if (responseWrapper.isEmpty()) { - responseWrapper.setInnerElement(policyBusinessLogic.undeclarePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, userId, true) - .either(this::buildOkResponse, - this::buildErrorResponse)); - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Undeclare Policy"); - log.error("Failed to undeclare policy. The exception {} occurred. ", e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } - return responseWrapper.getInnerElement(); - } - - @GET - @Path("/{containerComponentType}/{componentId}/policies/{policyId}/properties") - @ApiOperation(value = "Get component policy properties", httpMethod = "GET", notes = "Returns component policy properties", response = PropertyDataDefinition.class, responseContainer="List") - @ApiResponses(value = {@ApiResponse(code = 200, message = "Properties found"),@ApiResponse(code = 400, message = "invalid content - Error: containerComponentType is invalid"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Componentorpolicy not found"), - @ApiResponse(code = 500, message = "The GET request failed due to internal SDC problem.") })public Response getPolicyProperties(@ApiParam(value = "the id of the component which is the container of the policy") @PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @ApiParam(value = "the id of the policy which its properties are to return") @PathParam("policyId") final String policyId, - @ApiParam(value = "the userid", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Context final HttpServletRequest request) { - init(); - try { - return convertToComponentType(containerComponentType) - .left() - .bind(cmptType -> policyBusinessLogic.getPolicyProperties(cmptType, containerComponentId, policyId, userId)) - .either(this::buildOkResponse, - this::buildErrorResponse); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("get Policy properties"); - log.debug("#getPolicyProperties - get Policy properties has failed.", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - - } - - @PUT - @Path("/{containerComponentType}/{componentId}/policies/{policyId}/properties") - @ApiOperation(value = "Update Policy properties", httpMethod = "PUT", notes = "Returns updated Policy", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy properties updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "component / policy Not found")}) - public Response updatePolicyProperties(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyId") final String policyId, @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @ApiParam(value = "PolicyDefinition", required = true) String policyData, @Context final HttpServletRequest request) { - init(); - Wrapper responseWrapper = new Wrapper<>(); - try { - Wrapper componentTypeWrapper = validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); - Wrapper propertiesWrapper = new Wrapper<>(); - if (responseWrapper.isEmpty()) { - convertJsonToObjectOfClass(policyData, propertiesWrapper, PropertyDataDefinition[].class, responseWrapper); - if (propertiesWrapper.isEmpty()) { - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT))); - } - } - if (!propertiesWrapper.isEmpty()) { - responseWrapper.setInnerElement( - policyBusinessLogic.updatePolicyProperties(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, propertiesWrapper.getInnerElement(), userId, true) - .either(this::buildOkResponse, this::buildErrorResponse)); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Policy"); - log.error("Failed to update policy. The exception {} occurred. ", e); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); - } - return responseWrapper.getInnerElement(); - } - - private Wrapper validateComponentTypeAndUserId(final String containerComponentType, String userId, Wrapper responseWrapper) { - Wrapper componentTypeWrapper = new Wrapper<>(); - if (StringUtils.isEmpty(userId)) { - log.error("Missing userId HTTP header. "); - responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID))); - } - if (responseWrapper.isEmpty()) { - validateComponentType(responseWrapper, componentTypeWrapper, containerComponentType); - } - return componentTypeWrapper; - } - - @POST - @Path("/{containerComponentType}/{componentId}/policies/{policyId}/targets") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "update policy targets", httpMethod = "POST", notes = "Returns updated Policy", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Policy target updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updatePolicyTargets(@PathParam("componentId") final String containerComponentId, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, - @PathParam("policyId") final String policyId, - @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, - @Context final HttpServletRequest request, - List requestJson) { - try { - - return updatePolicyTargetsFromDTO(requestJson) - .left() - .bind(policyTarget -> updatePolicyTargetsFromMap(policyTarget, containerComponentType, containerComponentId, policyId, userId)) - .either(this::buildOkResponse, this::buildErrorResponse); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Policy"); - log.debug("Policy target update has been failed with the exception{}. ", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @POST - @Path("/{componentType}/{componentId}/create/policies") - @ApiOperation(value = "Create policies on service", httpMethod = "POST", notes = "Return policies list", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) - public Response declareProperties(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "ComponentIns policies Object to be created", required = true) String componentInstPoliciesMapObj) { - - return super.declareProperties(userId, componentId, componentType, componentInstPoliciesMapObj, - DeclarationTypeEnum.POLICY, request); - } - - private Either updatePolicyTargetsFromMap(Map> policyTarget, String containerComponentType, String containerComponentId, String policyId, String userId) { - return convertToComponentType(containerComponentType) - .left() - .bind(cmptType -> policyBusinessLogic.updatePolicyTargets(cmptType, containerComponentId, policyId, policyTarget, userId)); - } - - private Either>, ResponseFormat> updatePolicyTargetsFromDTO(List targetDTOList) { - Map> policyTarget = new HashMap<>(); - for (PolicyTargetDTO currentTarget : targetDTOList) { - if(!addTargetsByType(policyTarget, currentTarget.getType(), currentTarget.getUniqueIds())){ - return Either.right(componentsUtils.getResponseFormat(ActionStatus.POLICY_TARGET_TYPE_DOES_NOT_EXIST, currentTarget.getType())); - } - } - return Either.left(policyTarget); - } - - - public boolean addTargetsByType(Map> policyTarget, String type, List uniqueIds) { - PolicyTargetType targetTypeEnum = PolicyTargetType.getByNameIgnoreCase(type); - if(targetTypeEnum != null){ - policyTarget.put(targetTypeEnum, validateUniquenessOfIds(uniqueIds)); - return true; - } - else{ - return false; - } - } - - private List validateUniquenessOfIds(List uniqueIds) { - return uniqueIds.stream().distinct().collect(Collectors.toList()); - } -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.PolicyDefinition; +import org.openecomp.sdc.be.model.PolicyTargetDTO; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.exception.ResponseFormat; +import org.springframework.stereotype.Controller; +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; +/** + * Provides REST API to create, retrieve, update, delete a policy + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Policy Servlet")) +@Controller +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class PolicyServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(PolicyServlet.class); + private final PolicyBusinessLogic policyBusinessLogic; + + @Inject + public PolicyServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + PolicyBusinessLogic policyBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.policyBusinessLogic = policyBusinessLogic; + } + + @POST + @Path("/{containerComponentType}/{componentId}/policies/{policyTypeName}") + @Operation(description = "Create Policy", method = "POST", summary = "Returns created Policy", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Policy created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Policy already exist"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response createPolicy(@PathParam("componentId") final String containerComponentId, @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyTypeName") final String policyTypeName, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request) { + init(); + + Wrapper responseWrapper = new Wrapper<>(); + try { + Wrapper componentTypeWrapper = + validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); + if (responseWrapper.isEmpty()) { + responseWrapper.setInnerElement(policyBusinessLogic + .createPolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyTypeName, + userId, true) + .either(l -> buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), l), + this::buildErrorResponse)); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Policy"); + log.error("Failed to create policy. The exception {} occurred. ", e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + return responseWrapper.getInnerElement(); + } + + @PUT + @Path("/{containerComponentType}/{componentId}/policies/{policyId}") + @Operation(description = "Update Policy metadata", method = "PUT", summary = "Returns updated Policy", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Policy updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "component / policy Not found")}) + public Response updatePolicy(@PathParam("componentId") final String containerComponentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyId") final String policyId, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Parameter(description = "PolicyDefinition", required = true) String policyData, + @Context final HttpServletRequest request) { + init(); + + Wrapper responseWrapper = new Wrapper<>(); + try { + Wrapper componentTypeWrapper = + validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); + Wrapper policyWrapper = new Wrapper<>(); + if (responseWrapper.isEmpty()) { + convertJsonToObjectOfClass(policyData, policyWrapper, PolicyDefinition.class, responseWrapper); + if (policyWrapper.isEmpty()) { + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT))); + } + } + if (!policyWrapper.isEmpty()) { + policyWrapper.getInnerElement().setUniqueId(policyId); + responseWrapper.setInnerElement(policyBusinessLogic + .updatePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, + policyWrapper.getInnerElement(), userId, true) + .either(this::buildOkResponse, this::buildErrorResponse)); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Policy"); + log.error("Failed to update policy. The exception {} occurred. ", e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + return responseWrapper.getInnerElement(); + } + + @GET + @Path("/{containerComponentType}/{componentId}/policies/{policyId}") + @Operation(description = "Get Policy", method = "GET", summary = "Returns Policy", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Policy was found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "component / policy Not found")}) + public Response getPolicy(@PathParam("componentId") final String containerComponentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyId") final String policyId, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request) { + init(); + + Wrapper responseWrapper = new Wrapper<>(); + try { + Wrapper componentTypeWrapper = + validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); + if (responseWrapper.isEmpty()) { + responseWrapper.setInnerElement(policyBusinessLogic + .getPolicy(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, userId) + .either(this::buildOkResponse, this::buildErrorResponse)); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Policy"); + log.error("Failed to retrieve policy. The exception {} occurred. ", e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + return responseWrapper.getInnerElement(); + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/policies/{policyId}") + @Operation(description = "Delete Policy", method = "DELETE", summary = "No body", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Policy was deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "component / policy Not found")}) + public Response deletePolicy(@PathParam("componentId") final String containerComponentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyId") final String policyId, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request) { + init(); + + Wrapper responseWrapper = new Wrapper<>(); + try { + Wrapper componentTypeWrapper = + validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); + if (responseWrapper.isEmpty()) { + responseWrapper + .setInnerElement( + policyBusinessLogic + .deletePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, + policyId, userId, true) + .either(this::buildOkResponse, this::buildErrorResponse)); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Policy"); + log.error("Failed to delete policy. The exception {} occurred. ", e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + return responseWrapper.getInnerElement(); + } + + @PUT + @Path("/{containerComponentType}/{componentId}/policies/{policyId}/undeclare") + @Operation(description = "undeclare Policy", method = "PUT", summary = "No body",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Policy was undeclared"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "component / policy Not found")}) + public Response undeclarePolicy(@PathParam("componentId") final String containerComponentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyId") final String policyId, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request) { + init(); + + Wrapper responseWrapper = new Wrapper<>(); + try { + Wrapper componentTypeWrapper = + validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); + if (responseWrapper.isEmpty()) { + responseWrapper + .setInnerElement( + policyBusinessLogic + .undeclarePolicy(componentTypeWrapper.getInnerElement(), containerComponentId, + policyId, userId, true) + .either(this::buildOkResponse, this::buildErrorResponse)); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Undeclare Policy"); + log.error("Failed to undeclare policy. The exception {} occurred. ", e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + return responseWrapper.getInnerElement(); + } + + @GET + @Path("/{containerComponentType}/{componentId}/policies/{policyId}/properties") + @Operation(description = "Get component policy properties", method = "GET", + summary = "Returns component policy properties",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = PropertyDataDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Properties found"), + @ApiResponse(responseCode = "400", + description = "invalid content - Error: containerComponentType is invalid"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Componentorpolicy not found"), + @ApiResponse(responseCode = "500", description = "The GET request failed due to internal SDC problem.")}) + public Response getPolicyProperties(@Parameter( + description = "the id of the component which is the container of the policy") @PathParam("componentId") final String containerComponentId, + @Parameter(description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @Parameter( + description = "the id of the policy which its properties are to return") @PathParam("policyId") final String policyId, + @Parameter(description = "the userid", + required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request) { + init(); + try { + return convertToComponentType(containerComponentType).left().bind(cmptType -> policyBusinessLogic + .getPolicyProperties(cmptType, containerComponentId, policyId, userId)) + .either(this::buildOkResponse, this::buildErrorResponse); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("get Policy properties"); + log.debug("#getPolicyProperties - get Policy properties has failed.", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + + } + + @PUT + @Path("/{containerComponentType}/{componentId}/policies/{policyId}/properties") + @Operation(description = "Update Policy properties", method = "PUT", summary = "Returns updated Policy", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Policy properties updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "component / policy Not found")}) + public Response updatePolicyProperties(@PathParam("componentId") final String containerComponentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyId") final String policyId, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Parameter(description = "PolicyDefinition", required = true) String policyData, + @Context final HttpServletRequest request) { + init(); + Wrapper responseWrapper = new Wrapper<>(); + try { + Wrapper componentTypeWrapper = + validateComponentTypeAndUserId(containerComponentType, userId, responseWrapper); + Wrapper propertiesWrapper = new Wrapper<>(); + if (responseWrapper.isEmpty()) { + convertJsonToObjectOfClass(policyData, propertiesWrapper, PropertyDataDefinition[].class, + responseWrapper); + if (propertiesWrapper.isEmpty()) { + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT))); + } + } + if (!propertiesWrapper.isEmpty()) { + responseWrapper.setInnerElement(policyBusinessLogic + .updatePolicyProperties(componentTypeWrapper.getInnerElement(), containerComponentId, policyId, + propertiesWrapper.getInnerElement(), userId, true) + .either(this::buildOkResponse, this::buildErrorResponse)); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Policy"); + log.error("Failed to update policy. The exception {} occurred. ", e); + responseWrapper.setInnerElement( + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + return responseWrapper.getInnerElement(); + } + + private Wrapper validateComponentTypeAndUserId(final String containerComponentType, String userId, Wrapper responseWrapper) { + Wrapper componentTypeWrapper = new Wrapper<>(); + if (StringUtils.isEmpty(userId)) { + log.error("Missing userId HTTP header. "); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID))); + } + if (responseWrapper.isEmpty()) { + validateComponentType(responseWrapper, componentTypeWrapper, containerComponentType); + } + return componentTypeWrapper; + } + + @POST + @Path("/{containerComponentType}/{componentId}/policies/{policyId}/targets") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "update policy targets", method = "POST", summary = "Returns updated Policy", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Policy target updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updatePolicyTargets(@PathParam("componentId") final String containerComponentId, @Parameter( + description = "valid values: resources / services", + schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME , + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("policyId") final String policyId, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of modifier user", + required = true) String userId, + @Context final HttpServletRequest request, List requestJson) { + try { + + return updatePolicyTargetsFromDTO(requestJson).left() + .bind(policyTarget -> updatePolicyTargetsFromMap(policyTarget, containerComponentType, + containerComponentId, policyId, userId)) + .either(this::buildOkResponse, this::buildErrorResponse); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Policy"); + log.debug("Policy target update has been failed with the exception{}. ", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{componentType}/{componentId}/create/policies") + @Operation(description = "Create policies on service", method = "POST", summary = "Return policies list", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response declareProperties(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "ComponentIns policies Object to be created", + required = true) String componentInstPoliciesMapObj) { + + return super.declareProperties(userId, componentId, componentType, componentInstPoliciesMapObj, + DeclarationTypeEnum.POLICY, request); + } + + private Either updatePolicyTargetsFromMap( + Map> policyTarget, String containerComponentType, + String containerComponentId, String policyId, String userId) { + return convertToComponentType(containerComponentType).left().bind(cmptType -> policyBusinessLogic + .updatePolicyTargets(cmptType, containerComponentId, policyId, policyTarget, userId)); + } + + private Either>, ResponseFormat> updatePolicyTargetsFromDTO( + List targetDTOList) { + Map> policyTarget = new HashMap<>(); + for (PolicyTargetDTO currentTarget : targetDTOList) { + if (!addTargetsByType(policyTarget, currentTarget.getType(), currentTarget.getUniqueIds())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.POLICY_TARGET_TYPE_DOES_NOT_EXIST, + currentTarget.getType())); + } + } + return Either.left(policyTarget); + } + + + public boolean addTargetsByType(Map> policyTarget, String type, List uniqueIds) { + PolicyTargetType targetTypeEnum = PolicyTargetType.getByNameIgnoreCase(type); + if(targetTypeEnum != null){ + policyTarget.put(targetTypeEnum, validateUniquenessOfIds(uniqueIds)); + return true; + } + else{ + return false; + } + } + + private List validateUniquenessOfIds(List uniqueIds) { + return uniqueIds.stream().distinct().collect(Collectors.toList()); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyTypesEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyTypesEndpoint.java index dc4bb95611..8030ef4184 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyTypesEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PolicyTypesEndpoint.java @@ -1,67 +1,80 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.*; -import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic; -import org.openecomp.sdc.be.mixin.PolicyTypeMixin; -import org.openecomp.sdc.be.model.PolicyTypeDefinition; -import org.openecomp.sdc.be.view.ResponseView; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.stereotype.Controller; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.util.List; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "policy types resource") -@Controller -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class PolicyTypesEndpoint { - - private static final Logger log = Logger.getLogger(PolicyTypesEndpoint.class); - - private final PolicyTypeBusinessLogic policyTypeBusinessLogic; - - public PolicyTypesEndpoint(PolicyTypeBusinessLogic policyTypeBusinessLogic) { - this.policyTypeBusinessLogic = policyTypeBusinessLogic; - } - - @GET - @Path("/policyTypes") - @ApiOperation(value = "Get policy types ", httpMethod = "GET", notes = "Returns policy types", response = PolicyTypeDefinition.class, responseContainer="List") - @ApiResponses(value = { @ApiResponse(code = 200, message = "policy types found"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 500, message = "The GET request failed due to internal SDC problem.")}) - @ResponseView(mixin = {PolicyTypeMixin.class}) - public List getPolicyTypes(@ApiParam(value = "An optional parameter to indicate the type of the container from where this call is executed") - @QueryParam("internalComponentType") String internalComponentType, - @ApiParam(value = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - log.debug("(get) Start handle request of GET policyTypes"); - return policyTypeBusinessLogic.getAllPolicyTypes(userId, internalComponentType); - } - -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic; +import org.openecomp.sdc.be.mixin.PolicyTypeMixin; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.view.ResponseView; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.springframework.stereotype.Controller; +import com.jcabi.aspects.Loggable; +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 = "policy types resource")) +@Controller +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class PolicyTypesEndpoint { + + private static final Logger log = Logger.getLogger(PolicyTypesEndpoint.class); + + private final PolicyTypeBusinessLogic policyTypeBusinessLogic; + + public PolicyTypesEndpoint(PolicyTypeBusinessLogic policyTypeBusinessLogic) { + this.policyTypeBusinessLogic = policyTypeBusinessLogic; + } + + @GET + @Path("/policyTypes") + @Operation(description = "Get policy types ", method = "GET", summary = "Returns policy types",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = PolicyTypeDefinition.class))))) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "policy types found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "The GET request failed due to internal SDC problem.")}) + @ResponseView(mixin = {PolicyTypeMixin.class}) + public List getPolicyTypes(@Parameter(description = "An optional parameter to indicate the type of the container from where this call is executed") + @QueryParam("internalComponentType") String internalComponentType, + @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + log.debug("(get) Start handle request of GET policyTypes"); + return policyTypeBusinessLogic.getAllPolicyTypes(userId, internalComponentType); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java index 922db5adac..c6a6571687 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java @@ -1,287 +1,329 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ProductBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.Product; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.Map; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Product Catalog", description = "Product Servlet") -@Singleton -public class ProductServlet extends BeGenericServlet { - private static final Logger log = Logger.getLogger(ProductServlet.class); - private final ProductBusinessLogic productBusinessLogic; - - @Inject - public ProductServlet(UserBusinessLogic userBusinessLogic, - ProductBusinessLogic productBusinessLogic, - ComponentsUtils componentsUtils) { - super(userBusinessLogic, componentsUtils); - this.productBusinessLogic = productBusinessLogic; - } - - @POST - @Path("/products") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create product", httpMethod = "POST", notes = "Returns created product", response = Product.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Product created"), @ApiResponse(code = 403, message = "Restricted operation / Empty USER_ID header"), @ApiResponse(code = 400, message = "Invalid/missing content"), - @ApiResponse(code = 409, message = "Product already exists / User not found / Wrong user role") }) - public Response createProduct(@ApiParam(value = "Product object to be created", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of product strategist user", required = true) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Product product = RepresentationUtils.fromRepresentation(data, Product.class); - Either actionResponse = productBusinessLogic.createProduct(product, modifier); - - if (actionResponse.isRight()) { - log.debug("Failed to create product"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Product"); - log.debug("create product failed with error ", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - @GET - @Path("/products/{productId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve product", httpMethod = "GET", notes = "Returns product according to productId", response = Product.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Product found"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 409, message = "Restricted operation"), - @ApiResponse(code = 500, message = "Internal Server Error"), @ApiResponse(code = 404, message = "Product not found"), }) - public Response getProductById(@PathParam("productId") final String productId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - try { - log.trace("get product with id {}", productId); - Either actionResponse = productBusinessLogic.getProduct(productId, modifier); - - if (actionResponse.isRight()) { - log.debug("Failed to get product"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Object product = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Product"); - log.debug("get product failed with error ", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - @GET - @Path("/products/productName/{productName}/productVersion/{productVersion}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns product according to name and version", response = Product.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Product found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Product not found") }) - public Response getServiceByNameAndVersion(@PathParam("productName") final String productName, @PathParam("productVersion") final String productVersion, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Either actionResponse = productBusinessLogic.getProductByNameAndVersion(productName, productVersion, userId); - - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Product product = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(product); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get product by name and version"); - log.debug("get product failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @DELETE - @Path("/products/{productId}") - public Response deleteProduct(@PathParam("productId") final String productId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - try { - log.trace("delete product with id {}", productId); - Either actionResponse = productBusinessLogic.deleteProduct(productId, modifier); - - if (actionResponse.isRight()) { - log.debug("Failed to delete product"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Object product = RepresentationUtils.toRepresentation(actionResponse.left().value()); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); - log.debug("delete resource failed with error ", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @PUT - @Path("/products/{productId}/metadata") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Product Metadata", httpMethod = "PUT", notes = "Returns updated product", response = Product.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Product Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateProductMetadata(@PathParam("productId") final String productId, @ApiParam(value = "Product object to be Updated", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response = null; - - try { - String productIdLower = productId.toLowerCase(); - Product updatedProduct = RepresentationUtils.fromRepresentation(data, Product.class); - Either actionResponse = productBusinessLogic.updateProductMetadata(productIdLower, updatedProduct, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to update product"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Product product = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(product); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - log.debug("update product metadata failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - @GET - @Path("/products/validate-name/{productName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "validate product name", httpMethod = "GET", notes = "checks if the chosen product name is available ", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") }) - public Response validateServiceName(@PathParam("productName") final String productName, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response = null; - try { - Either, ResponseFormat> actionResponse = productBusinessLogic.validateProductNameExists(productName, userId); - - if (actionResponse.isRight()) { - log.debug("failed to get validate service name"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Product Name"); - log.debug("validate product name failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - -} +/*- + * ============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.servlets; + +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.ProductBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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 = "Product Catalog", description = "Product Catalog")) +@Singleton +public class ProductServlet extends BeGenericServlet { + private static final Logger log = Logger.getLogger(ProductServlet.class); + private final ProductBusinessLogic productBusinessLogic; + + @Inject + public ProductServlet(UserBusinessLogic userBusinessLogic, + ProductBusinessLogic productBusinessLogic, + ComponentsUtils componentsUtils) { + super(userBusinessLogic, componentsUtils); + this.productBusinessLogic = productBusinessLogic; + } + + @POST + @Path("/products") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create product", method = "POST", summary = "Returns created product", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Product created"), + @ApiResponse(responseCode = "403", description = "Restricted operation / Empty USER_ID header"), + @ApiResponse(responseCode = "400", description = "Invalid/missing content"), + @ApiResponse(responseCode = "409", description = "Product already exists / User not found / Wrong user role")}) + public Response createProduct(@Parameter(description = "Product object to be created", required = true) String data, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of product strategist user", + required = true) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Product product = RepresentationUtils.fromRepresentation(data, Product.class); + Either actionResponse = productBusinessLogic.createProduct(product, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to create product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Product"); + log.debug("create product failed with error ", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/products/{productId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve product", method = "GET", summary = "Returns product according to productId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Product found"), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Server Error"), + @ApiResponse(responseCode = "404", description = "Product not found"),}) + public Response getProductById(@PathParam("productId") final String productId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + log.trace("get product with id {}", productId); + Either actionResponse = productBusinessLogic.getProduct(productId, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to get product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object product = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Product"); + log.debug("get product failed with error ", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/products/productName/{productName}/productVersion/{productVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Service", method = "GET", + summary = "Returns product according to name and version",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Product found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Product not found")}) + public Response getServiceByNameAndVersion(@PathParam("productName") final String productName, + @PathParam("productVersion") final String productVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Either actionResponse = + productBusinessLogic.getProductByNameAndVersion(productName, productVersion, userId); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Product product = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(product); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get product by name and version"); + log.debug("get product failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/products/{productId}") + public Response deleteProduct(@PathParam("productId") final String productId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + log.trace("delete product with id {}", productId); + Either actionResponse = productBusinessLogic.deleteProduct(productId, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to delete product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object product = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); + log.debug("delete resource failed with error ", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/products/{productId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Product Metadata", method = "PUT", summary = "Returns updated product", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Product Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateProductMetadata(@PathParam("productId") final String productId, + @Parameter(description = "Product object to be Updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + + try { + String productIdLower = productId.toLowerCase(); + Product updatedProduct = RepresentationUtils.fromRepresentation(data, Product.class); + Either actionResponse = + productBusinessLogic.updateProductMetadata(productIdLower, updatedProduct, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to update product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Product product = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(product); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + log.debug("update product metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/products/validate-name/{productName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "validate product name", method = "GET", + summary = "checks if the chosen product name is available ",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation")}) + public Response validateServiceName(@PathParam("productName") final String productName, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + try { + Either, ResponseFormat> actionResponse = + productBusinessLogic.validateProductNameExists(productName, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get validate service name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Product Name"); + log.debug("validate product name failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java index 1abc69bf42..5df3404b24 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java @@ -1,335 +1,344 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * 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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.RequirementBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.RequirementDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -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 java.util.List; -import java.util.Optional; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Requirement Servlet", description = "Requirement Servlet") -@Singleton -public class RequirementServlet extends AbstractValidationsServlet { - private static final Logger LOGGER = Logger.getLogger(RequirementServlet.class); - private final RequirementBusinessLogic requirementBusinessLogic; - - @Inject - public RequirementServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - RequirementBusinessLogic requirementBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.requirementBusinessLogic = requirementBusinessLogic; - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/requirements") - @ApiOperation(value = "Create requirements on resource", httpMethod = "POST", - notes = "Create requirements on resource", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create requirements"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "requirement already exist")}) - public Response createRequirementsOnResource( - @ApiParam(value = "Requirement to create", required = true) String data, - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "resources" , resourceId, request, - userId, false, "createRequirements"); - } - - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/requirements") - @ApiOperation(value = "Update Requirements on resource", httpMethod = "PUT", - notes = "Update Requirements on resource", response = RequirementDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Requirements"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updateRequirementsOnResource( - @ApiParam(value = "Requirements to update", required = true) String data, - @ApiParam(value = "Component Id") @PathParam("resourceId") String resourceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "resources", resourceId, request, - userId, true, "updateRequirements"); - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/requirements/{requirementId}") - @ApiOperation(value = "Get Requirement from resource", httpMethod = "GET", - notes = "GET Requirement from resource", response = RequirementDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "GET requirement"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response getRequirementsFromResource( - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @ApiParam(value = "Requirement Id") @PathParam("requirementId") String requirementId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return get(requirementId, resourceId, request, userId); - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/resources/{resourceId}/requirements/{requirementId}") - @ApiOperation(value = "Delete requirements from resource", httpMethod = "DELETE", - notes = "Delete requirements from resource", response = RequirementDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete requirement"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response deleteRequirementsFromResource( - @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, - @ApiParam(value = "requirement Id") @PathParam("requirementId") String requirementId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return delete(requirementId, resourceId, request, userId); - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/requirements") - @ApiOperation(value = "Create requirements on service", httpMethod = "POST", - notes = "Create requirements on service", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Requirements"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Requirement already exist")}) - public Response createRequirementsOnService( - @ApiParam(value = "Requirements to create", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "services" , serviceId, request, userId, - false , "createRequirements"); - } - - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/requirements") - @ApiOperation(value = "Update requirements on service", httpMethod = "PUT", - notes = "Update requirements on service", response = RequirementDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update requirements"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updateRequirementsOnService( - @ApiParam(value = "Requirements to update", required = true) String data, - @ApiParam(value = "Component Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, "services", serviceId, request, userId, - true, "updateRequirements"); - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/requirements/{requirementId}") - @ApiOperation(value = "Get requirement from service", httpMethod = "GET", - notes = "GET requirement from service", response = RequirementDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Requirements"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response getRequirementsOnService( - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Requirement Id") @PathParam("requirementId") String requirementId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return get(requirementId, serviceId, request, userId); - } - - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/services/{serviceId}/requirements/{requirementId}") - @ApiOperation(value = "Delete requirement from service", httpMethod = "DELETE", - notes = "Delete requirement from service", response = RequirementDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Requirements"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response deleteRequirementsOnService( - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Requirement Id") @PathParam("requirementId") String requirementId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return delete(requirementId, serviceId, request, userId); - } - - - private Response createOrUpdate (String data, String componentType, String componentId, - HttpServletRequest request, String userId, - boolean isUpdate, String errorContext) { - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - - Either, ResponseFormat> mappedRequirementDataEither = - getMappedRequirementData(data, modifier, ComponentTypeEnum.findByParamName(componentType)); - if(mappedRequirementDataEither.isRight()) { - LOGGER.error("Failed to create or update requirements"); - return buildErrorResponse(mappedRequirementDataEither.right().value()); - } - List mappedRequirementData = mappedRequirementDataEither.left().value(); - Either, ResponseFormat> actionResponse; - if(isUpdate) { - actionResponse = requirementBusinessLogic.updateRequirements(componentIdLower, mappedRequirementData, modifier, - errorContext, true); - } else { - actionResponse = requirementBusinessLogic.createRequirements(componentIdLower, mappedRequirementData, modifier, - errorContext, true); - } - - if (actionResponse.isRight()) { - LOGGER.error("Failed to create or update requirements"); - return buildErrorResponse(actionResponse.right().value()); - } - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - actionResponse.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("requirements create or update"); - LOGGER.error("Failed to create or update requirements with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Response get (String requirementIdToGet, String componentId, - HttpServletRequest request, String userId){ - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - LOGGER.debug("Start get request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - Either actionResponse = requirementBusinessLogic - .getRequirement(componentIdLower, requirementIdToGet, modifier, true); - if (actionResponse.isRight()) { - LOGGER.error("failed to get requirements"); - return buildErrorResponse(actionResponse.right().value()); - } - Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get requirements"); - LOGGER.error("get requirements failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Response delete (String requirementId, String componentId, HttpServletRequest - request, String userId){ - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - LOGGER.debug("Start delete request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - - Either actionResponse = requirementBusinessLogic - .deleteRequirement(componentIdLower, requirementId, modifier, true); - if (actionResponse.isRight()) { - LOGGER.error("failed to delete requirements"); - return buildErrorResponse(actionResponse.right().value()); - } - Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete requirements"); - LOGGER.error("Delete requirements failed with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Either, ResponseFormat> getMappedRequirementData(String inputJson, User user, - ComponentTypeEnum componentTypeEnum){ - Either mappedData = getComponentsUtils() - .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, - AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); - Optional> requirementDefinitionList = mappedData.left().value() - .getRequirements().values().stream().findFirst(); - return requirementDefinitionList., ResponseFormat>> - map(Either::left).orElseGet(() -> Either.right(getComponentsUtils() - .getResponseFormat(ActionStatus.GENERAL_ERROR))); - } -} +/* + * Copyright © 2016-2018 European Support Limited + * + * 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.servlets; + +import java.util.List; +import java.util.Optional; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.RequirementBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Requirement Servlet", description = "Requirement Servlet")) +@Singleton +public class RequirementServlet extends AbstractValidationsServlet { + private static final Logger LOGGER = Logger.getLogger(RequirementServlet.class); + private final RequirementBusinessLogic requirementBusinessLogic; + + @Inject + public RequirementServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + RequirementBusinessLogic requirementBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.requirementBusinessLogic = requirementBusinessLogic; + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/requirements") + @Operation(description = "Create requirements on resource", method = "POST", + summary = "Create requirements on resource",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create requirements"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "requirement already exist")}) + public Response createRequirementsOnResource( + @Parameter(description = "Requirement to create", required = true) String data, + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "resources" , resourceId, request, + userId, false, "createRequirements"); + } + + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/requirements") + @Operation(description = "Update Requirements on resource", method = "PUT", + summary = "Update Requirements on resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Requirements"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateRequirementsOnResource( + @Parameter(description = "Requirements to update", required = true) String data, + @Parameter(description = "Component Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "resources", resourceId, request, + userId, true, "updateRequirements"); + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/requirements/{requirementId}") + @Operation(description = "Get Requirement from resource", method = "GET", + summary = "GET Requirement from resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET requirement"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response getRequirementsFromResource( + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return get(requirementId, resourceId, request, userId); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/requirements/{requirementId}") + @Operation(description = "Delete requirements from resource", method = "DELETE", + summary = "Delete requirements from resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete requirement"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteRequirementsFromResource( + @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId, + @Parameter(description = "requirement Id") @PathParam("requirementId") String requirementId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return delete(requirementId, resourceId, request, userId); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/requirements") + @Operation(description = "Create requirements on service", method = "POST", + summary = "Create requirements on service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Requirements"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Requirement already exist")}) + public Response createRequirementsOnService( + @Parameter(description = "Requirements to create", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "services" , serviceId, request, userId, + false , "createRequirements"); + } + + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/requirements") + @Operation(description = "Update requirements on service", method = "PUT", + summary = "Update requirements on service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update requirements"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateRequirementsOnService( + @Parameter(description = "Requirements to update", required = true) String data, + @Parameter(description = "Component Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, "services", serviceId, request, userId, + true, "updateRequirements"); + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/requirements/{requirementId}") + @Operation(description = "Get requirement from service", method = "GET", + summary = "GET requirement from service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET Requirements"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response getRequirementsOnService( + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return get(requirementId, serviceId, request, userId); + } + + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/requirements/{requirementId}") + @Operation(description = "Delete requirement from service", method = "DELETE", + summary = "Delete requirement from service", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Requirements"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteRequirementsOnService( + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return delete(requirementId, serviceId, request, userId); + } + + + private Response createOrUpdate (String data, String componentType, String componentId, + HttpServletRequest request, String userId, + boolean isUpdate, String errorContext) { + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + + Either, ResponseFormat> mappedRequirementDataEither = + getMappedRequirementData(data, modifier, ComponentTypeEnum.findByParamName(componentType)); + if(mappedRequirementDataEither.isRight()) { + LOGGER.error("Failed to create or update requirements"); + return buildErrorResponse(mappedRequirementDataEither.right().value()); + } + List mappedRequirementData = mappedRequirementDataEither.left().value(); + Either, ResponseFormat> actionResponse; + if(isUpdate) { + actionResponse = requirementBusinessLogic.updateRequirements(componentIdLower, mappedRequirementData, modifier, + errorContext, true); + } else { + actionResponse = requirementBusinessLogic.createRequirements(componentIdLower, mappedRequirementData, modifier, + errorContext, true); + } + + if (actionResponse.isRight()) { + LOGGER.error("Failed to create or update requirements"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("requirements create or update"); + LOGGER.error("Failed to create or update requirements with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Response get (String requirementIdToGet, String componentId, + HttpServletRequest request, String userId){ + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + LOGGER.debug("Start get request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + Either actionResponse = requirementBusinessLogic + .getRequirement(componentIdLower, requirementIdToGet, modifier, true); + if (actionResponse.isRight()) { + LOGGER.error("failed to get requirements"); + return buildErrorResponse(actionResponse.right().value()); + } + Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get requirements"); + LOGGER.error("get requirements failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Response delete (String requirementId, String componentId, HttpServletRequest + request, String userId){ + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + LOGGER.debug("Start delete request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + + Either actionResponse = requirementBusinessLogic + .deleteRequirement(componentIdLower, requirementId, modifier, true); + if (actionResponse.isRight()) { + LOGGER.error("failed to delete requirements"); + return buildErrorResponse(actionResponse.right().value()); + } + Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete requirements"); + LOGGER.error("Delete requirements failed with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Either, ResponseFormat> getMappedRequirementData(String inputJson, User user, + ComponentTypeEnum componentTypeEnum){ + Either mappedData = getComponentsUtils() + .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, + AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); + Optional> requirementDefinitionList = mappedData.left().value() + .getRequirements().values().stream().findFirst(); + return requirementDefinitionList., ResponseFormat>> + map(Either::left).orElseGet(() -> Either.right(getComponentsUtils() + .getResponseFormat(ActionStatus.GENERAL_ERROR))); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java index d1f50c9361..efbf730d3a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java @@ -1,79 +1,91 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -public class RequirementsServlet extends BeGenericServlet { - - private static final Logger log = Logger.getLogger(RequirementsServlet.class); - - @Inject - public RequirementsServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils) { - super(userBusinessLogic, componentsUtils); - } - - @PUT - @Path("resources/{resourceId}/requirements/{requirementId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource Requirement", httpMethod = "PUT", notes = "Returns updated requirement", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource requirement updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateRequirement(@ApiParam(value = "resource id to update with new requirement", required = true) @PathParam("resourceId") final String resourceId, - @ApiParam(value = "requirement id to update", required = true) @PathParam("requirementId") final String requirementId, @ApiParam(value = "Resource property to update", required = true) String requirementData, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - // Convert RequirementDefinition from JSON - // TODO: it's going to be another object, probably. This is placeholder - // for sake of JSON validation - // RequirementDefinition requirementDefinition; - ResponseFormat responseFormat; - try { - // TODO pass real entity - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); - } catch (Exception e) { - log.debug("Unexpected error: ", e); - responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } -} +/*- + * ============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.servlets; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +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.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import com.jcabi.aspects.Loggable; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +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) +public class RequirementsServlet extends BeGenericServlet { + + private static final Logger log = Logger.getLogger(RequirementsServlet.class); + + @Inject + public RequirementsServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils) { + super(userBusinessLogic, componentsUtils); + } + + @PUT + @Path("resources/{resourceId}/requirements/{requirementId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource Requirement", method = "PUT", summary = "Returns updated requirement", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource requirement updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateRequirement( + @Parameter(description = "resource id to update with new requirement", + required = true) @PathParam("resourceId") final String resourceId, + @Parameter(description = "requirement id to update", + required = true) @PathParam("requirementId") final String requirementId, + @Parameter(description = "Resource property to update", required = true) String requirementData, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + // Convert RequirementDefinition from JSON + // TODO: it's going to be another object, probably. This is placeholder + // for sake of JSON validation + // RequirementDefinition requirementDefinition; + ResponseFormat responseFormat; + try { + // TODO pass real entity + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); + } catch (Exception e) { + log.debug("Unexpected error: ", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java index 6e78b503d3..3d7471ebc3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java @@ -1,165 +1,187 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.UploadResourceInfo; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; - -import javax.inject.Singleton; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.File; - -/** - * Root resource (exposed at "/" path) - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/upload") -@Api(value = "Resources Catalog Upload", description = "Upload resource yaml") -@Singleton -public class ResourceUploadServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(ResourceUploadServlet.class); - public static final String NORMATIVE_TYPE_RESOURCE = "multipart"; - public static final String CSAR_TYPE_RESOURCE = "csar"; - public static final String USER_TYPE_RESOURCE = "user-resource"; - public static final String USER_TYPE_RESOURCE_UI_IMPORT = "user-resource-ui-import"; - - @Inject - public ResourceUploadServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - } - - public enum ResourceAuthorityTypeEnum { - NORMATIVE_TYPE_BE(NORMATIVE_TYPE_RESOURCE, true, false), USER_TYPE_BE(USER_TYPE_RESOURCE, true, true), USER_TYPE_UI(USER_TYPE_RESOURCE_UI_IMPORT, false, true), CSAR_TYPE_BE(CSAR_TYPE_RESOURCE, true, true); - - private String urlPath; - private boolean isBackEndImport, isUserTypeResource; - - public static ResourceAuthorityTypeEnum findByUrlPath(String urlPath) { - ResourceAuthorityTypeEnum found = null; - for (ResourceAuthorityTypeEnum curr : ResourceAuthorityTypeEnum.values()) { - if (curr.getUrlPath().equals(urlPath)) { - found = curr; - break; - } - } - return found; - } - - private ResourceAuthorityTypeEnum(String urlPath, boolean isBackEndImport, boolean isUserTypeResource) { - this.urlPath = urlPath; - this.isBackEndImport = isBackEndImport; - this.isUserTypeResource = isUserTypeResource; - } - - public String getUrlPath() { - return urlPath; - } - - public boolean isBackEndImport() { - return isBackEndImport; - } - - public boolean isUserTypeResource() { - return isUserTypeResource; - } - } - - @POST - @Path("/{resourceAuthority}") - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Resource from yaml", httpMethod = "POST", notes = "Returns created resource", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Resource already exist") }) - public Response uploadMultipart( - @ApiParam(value = "validValues: normative-resource / user-resource", allowableValues = NORMATIVE_TYPE_RESOURCE + "," + USER_TYPE_RESOURCE + "," - + USER_TYPE_RESOURCE_UI_IMPORT) @PathParam(value = "resourceAuthority") final String resourceAuthority, - @ApiParam("FileInputStream") @FormDataParam("resourceZip") File file, @ApiParam("ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader, - @ApiParam("resourceMetadata") @FormDataParam("resourceMetadata") String resourceInfoJsonString, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - // updateResourse Query Parameter if false checks if already exist - @DefaultValue("true") @QueryParam("createNewVersion") boolean createNewVersion) { - - try { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - Wrapper uploadResourceInfoWrapper = new Wrapper<>(); - Wrapper yamlStringWrapper = new Wrapper<>(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // When we get an errorResponse it will be filled into the - // responseWrapper - validateAuthorityType(responseWrapper, resourceAuthority); - - ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.findByUrlPath(resourceAuthority); - - commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString); - - fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString, resourceAuthorityEnum, file); - - // PayLoad Validations - if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){ - commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); - - specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, resourceAuthorityEnum); - } - - if (responseWrapper.isEmpty()) { - handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, createNewVersion, null); - } - - return responseWrapper.getInnerElement(); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Upload Resource"); - log.debug("upload resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /********************************************************************************************************************/ -} +/*- + * ============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.servlets; + +import java.io.File; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +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.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +import com.jcabi.aspects.Loggable; +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; +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/upload") +@OpenAPIDefinition(info = @Info(title = "Resources Catalog Upload", description = "Upload resource yaml")) +@Singleton +public class ResourceUploadServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(ResourceUploadServlet.class); + public static final String NORMATIVE_TYPE_RESOURCE = "multipart"; + public static final String CSAR_TYPE_RESOURCE = "csar"; + public static final String USER_TYPE_RESOURCE = "user-resource"; + public static final String USER_TYPE_RESOURCE_UI_IMPORT = "user-resource-ui-import"; + + @Inject + public ResourceUploadServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + } + + public enum ResourceAuthorityTypeEnum { + NORMATIVE_TYPE_BE(NORMATIVE_TYPE_RESOURCE, true, false), USER_TYPE_BE(USER_TYPE_RESOURCE, true, + true), USER_TYPE_UI(USER_TYPE_RESOURCE_UI_IMPORT, false, + true), CSAR_TYPE_BE(CSAR_TYPE_RESOURCE, true, true); + + private String urlPath; + private boolean isBackEndImport, isUserTypeResource; + + public static ResourceAuthorityTypeEnum findByUrlPath(String urlPath) { + ResourceAuthorityTypeEnum found = null; + for (ResourceAuthorityTypeEnum curr : ResourceAuthorityTypeEnum.values()) { + if (curr.getUrlPath().equals(urlPath)) { + found = curr; + break; + } + } + return found; + } + + private ResourceAuthorityTypeEnum(String urlPath, boolean isBackEndImport, boolean isUserTypeResource) { + this.urlPath = urlPath; + this.isBackEndImport = isBackEndImport; + this.isUserTypeResource = isUserTypeResource; + } + + public String getUrlPath() { + return urlPath; + } + + public boolean isBackEndImport() { + return isBackEndImport; + } + + public boolean isUserTypeResource() { + return isUserTypeResource; + } + } + + @POST + @Path("/{resourceAuthority}") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource from yaml", method = "POST", summary = "Returns created resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response uploadMultipart( + @Parameter(description = "validValues: normative-resource / user-resource", + schema = @Schema(allowableValues = {NORMATIVE_TYPE_RESOURCE , + USER_TYPE_RESOURCE,USER_TYPE_RESOURCE_UI_IMPORT})) @PathParam( + value = "resourceAuthority") final String resourceAuthority, + @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file, + @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader, + @Parameter(description = "resourceMetadata") @FormDataParam("resourceMetadata") String resourceInfoJsonString, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + // updateResourse Query Parameter if false checks if already exist + @DefaultValue("true") @QueryParam("createNewVersion") boolean createNewVersion) { + + try { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + Wrapper uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // When we get an errorResponse it will be filled into the + // responseWrapper + validateAuthorityType(responseWrapper, resourceAuthority); + + ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.findByUrlPath(resourceAuthority); + + commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString); + + fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString, resourceAuthorityEnum, file); + + // PayLoad Validations + if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){ + commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); + + specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, resourceAuthorityEnum); + } + + if (responseWrapper.isEmpty()) { + handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, createNewVersion, null); + } + + return responseWrapper.getInnerElement(); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Upload Resource"); + log.debug("upload resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /********************************************************************************************************************/ +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java index e18cbfc1af..415fdcf562 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java @@ -1,526 +1,574 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.apache.http.HttpStatus; -import org.json.JSONException; -import org.json.JSONObject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.CsarValidationUtils; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ImportUtils; -import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -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.UploadResourceInfo; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum; -import org.openecomp.sdc.be.user.UserBusinessLogic; -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.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Resources Catalog", description = "Resources Servlet") -@Singleton -public class ResourcesServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(ResourcesServlet.class); - private final ResourceBusinessLogic resourceBusinessLogic; - - @Inject - public ResourcesServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ResourceBusinessLogic resourceBusinessLogic, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.resourceBusinessLogic = resourceBusinessLogic; - } - - @POST - @Path("/resources") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Resource", httpMethod = "POST", notes = "Returns created resource", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Resource already exist") }) - public Response createResource(@ApiParam(value = "Resource object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); - init(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response; - try { - - Wrapper responseWrapper = new Wrapper<>(); - // UI Import - if (isUIImport(data)) { - performUIImport(responseWrapper, data, request, userId, null); - } - // UI Create - else { - - Either convertResponse = parseToResource(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse resource"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - - Resource resource = convertResponse.left().value(); - Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null); - Object representation = RepresentationUtils.toRepresentation(createdResource); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); - responseWrapper.setInnerElement(response); - } - return responseWrapper.getInnerElement(); - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource"); - log.debug("create resource failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - private boolean isUIImport(String data) { - boolean isUIImport; - try { - JSONObject json = new JSONObject(data); - String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME); - isUIImport = payloadName != null && !payloadName.isEmpty(); - } catch (JSONException e) { - log.debug("failed to parse json sent from client, json:{}", data, e); - isUIImport = false; - } - return isUIImport; - } - - private void performUIImport(Wrapper responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException { - - Wrapper userWrapper = new Wrapper<>(); - Wrapper uploadResourceInfoWrapper = new Wrapper<>(); - Wrapper yamlStringWrapper = new Wrapper<>(); - - ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI; - - commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data); - - if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) { - fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null); - - // PayLoad Validations - commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); - } - specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum); - - if (responseWrapper.isEmpty()) { - handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId); - } - } - - private Either parseToResource(String resourceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); - } - - private Either parseToLightResource(String resourceJson, User user) { - Either ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); - if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow) - ret.left().value().setRequirements(null); - ret.left().value().setCapabilities(null); - } - return ret; - } - - @DELETE - @Path("/resources/{resourceId}") - public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - - try { - String resourceIdLower = resourceId.toLowerCase(); - ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier); - - if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { - log.debug("failed to delete resource"); - response = buildErrorResponse(actionResponse); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - return response; - - } catch (JSONException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); - log.debug("delete resource failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @DELETE - @Path("/resources/{resourceName}/{version}") - public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - ResponseFormat actionResponse = resourceBusinessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier); - - if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { - log.debug("failed to delete resource"); - response = buildErrorResponse(actionResponse); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - return response; - } - - @GET - @Path("/resources/{resourceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Resource", httpMethod = "GET", notes = "Returns resource according to resourceId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Resource not found") }) - public Response getResourceById(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - - try { - String resourceIdLower = resourceId.toLowerCase(); - log.trace("get resource with id {}", resourceId); - Either actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to get resource"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource"); - log.debug("get resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @GET - @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Resource by name and version", httpMethod = "GET", notes = "Returns resource according to resourceId", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Resource not found") }) - public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - Response response; - try { - Either actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId); - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version"); - log.debug("get resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @GET - @Path("/resources/validate-name/{resourceName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "validate resource name", httpMethod = "GET", notes = "checks if the chosen resource name is available ", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation") }) - public Response validateResourceName(@PathParam("resourceName") final String resourceName, @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - Response response; - - if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) { - log.debug("invalid resource type received"); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - return response; - - } - ResourceTypeEnum typeEnum = null; - if (resourceType != null) { - typeEnum = ResourceTypeEnum.valueOf(resourceType); - } - Either, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId); - - if (actionResponse.isRight()) { - log.debug("failed to validate resource name"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - } - - @GET - @Path("/resources/certified/abstract") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}" , url); - try { - List resources = resourceBusinessLogic - .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources)); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources"); - log.debug("getCertifiedAbstractResources failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/resources/certified/notabstract") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}" , url); - try { - List resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces)); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources"); - log.debug("getCertifiedNotAbstractResources failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @PUT - @Path("/resources/{resourceId}/metadata") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource Metadata", httpMethod = "PUT", notes = "Returns updated resource metadata", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource metadata updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content") }) - public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource metadata to be updated", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response; - try { - String resourceIdLower = resourceId.toLowerCase(); - Either updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); - if (updateInfoResource.isRight()) { - log.debug("failed to parse resource metadata"); - response = buildErrorResponse(updateInfoResource.right().value()); - return response; - } - Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false); - Object resource = RepresentationUtils.toRepresentation(updatedResource); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata"); - log.debug("Update Resource Metadata failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @PUT - @Path("/resources/{resourceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Resource", httpMethod = "PUT", notes = "Returns updated resource", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Resource already exist") }) - public Response updateResource(@ApiParam(value = "Resource object to be updated", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @PathParam(value = "resourceId") String resourceId) { - - userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); - init(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response; - try { - Wrapper responseWrapper = new Wrapper<>(); - // UI Import - if (isUIImport(data)) { - performUIImport(responseWrapper, data, request, userId, resourceId); - } else { - Either convertResponse = parseToLightResource(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse resource"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId); - Object representation = RepresentationUtils.toRepresentation(updatedResource); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); - responseWrapper.setInnerElement(response); - } - return responseWrapper.getInnerElement(); - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource"); - log.debug("update resource failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Path("/resources/csar/{csaruuid}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Resource", httpMethod = "POST", notes = "Returns resource created from csar uuid", response = Resource.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource retrieced"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response getResourceFromCsar(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @PathParam(value = "csaruuid") String csarUUID) { - - init(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // retrieve user details - userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); - User user = new User(); - user.setUserId(userId); - - log.debug("user id is {}", userId); - - Response response; - - try { - - Either eitherResource = resourceBusinessLogic.getLatestResourceFromCsarUuid(csarUUID, user); - - // validate response - if (eitherResource.isRight()) { - log.debug("failed to get resource from csarUuid : {}", csarUUID); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), eitherResource.right().value()); - } else { - Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value()); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); - } - - return response; - - } catch (IOException e) { - log.debug("get resource by csar failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } -} +/*- + * ============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.servlets; + +import com.jcabi.aspects.Loggable; +import fj.data.Either; +import javax.inject.Inject; +import org.apache.http.HttpStatus; +import org.json.JSONException; +import org.json.JSONObject; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.CsarValidationUtils; +import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.components.impl.ImportUtils; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.exception.ResponseFormat; +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 javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Resources Catalog", description = "Resources Servlet")) +@Singleton +public class ResourcesServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(ResourcesServlet.class); + private final ResourceBusinessLogic resourceBusinessLogic; + + @Inject + public ResourcesServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ResourceBusinessLogic resourceBusinessLogic, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.resourceBusinessLogic = resourceBusinessLogic; + } + + @POST + @Path("/resources") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + init(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response; + try { + + Wrapper responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, null); + } + // UI Create + else { + + Either convertResponse = parseToResource(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Resource resource = convertResponse.left().value(); + Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null); + Object representation = RepresentationUtils.toRepresentation(createdResource); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); + responseWrapper.setInnerElement(response); + } + return responseWrapper.getInnerElement(); + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource"); + log.debug("create resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + private boolean isUIImport(String data) { + boolean isUIImport; + try { + JSONObject json = new JSONObject(data); + String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME); + isUIImport = payloadName != null && !payloadName.isEmpty(); + } catch (JSONException e) { + log.debug("failed to parse json sent from client, json:{}", data, e); + isUIImport = false; + } + return isUIImport; + } + + private void performUIImport(Wrapper responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException { + + Wrapper userWrapper = new Wrapper<>(); + Wrapper uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + + ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI; + + commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data); + + if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) { + fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null); + + // PayLoad Validations + commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); + } + specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum); + + if (responseWrapper.isEmpty()) { + handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId); + } + } + + private Either parseToResource(String resourceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); + } + + private Either parseToLightResource(String resourceJson, User user) { + Either ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); + if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow) + ret.left().value().setRequirements(null); + ret.left().value().setCapabilities(null); + } + return ret; + } + + @DELETE + @Path("/resources/{resourceId}") + public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + + try { + String resourceIdLower = resourceId.toLowerCase(); + ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete resource"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (JSONException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); + log.debug("delete resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Path("/resources/{resourceName}/{version}") + public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + ResponseFormat actionResponse = resourceBusinessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete resource"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + } + + @GET + @Path("/resources/{resourceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response getResourceById(@PathParam("resourceId") final String resourceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + + try { + String resourceIdLower = resourceId.toLowerCase(); + log.trace("get resource with id {}", resourceId); + Either actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get resource"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Resource by name and version", method = "GET", + summary = "Returns resource according to resourceId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, + @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + Response response; + try { + Either actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId); + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/resources/validate-name/{resourceName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "validate resource name", method = "GET", + summary = "checks if the chosen resource name is available ", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation")}) + public Response validateResourceName(@PathParam("resourceName") final String resourceName, + @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + Response response; + + if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) { + log.debug("invalid resource type received"); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + return response; + + } + ResourceTypeEnum typeEnum = null; + if (resourceType != null) { + typeEnum = ResourceTypeEnum.valueOf(resourceType); + } + Either, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId); + + if (actionResponse.isRight()) { + log.debug("failed to validate resource name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } + + @GET + @Path("/resources/certified/abstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}" , url); + try { + List resources = resourceBusinessLogic + .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources)); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources"); + log.debug("getCertifiedAbstractResources failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/resources/certified/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}" , url); + try { + List resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces)); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources"); + log.debug("getCertifiedNotAbstractResources failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @PUT + @Path("/resources/{resourceId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource metadata updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content")}) + public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId, + @Parameter(description = "Resource metadata to be updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response; + try { + String resourceIdLower = resourceId.toLowerCase(); + Either updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); + if (updateInfoResource.isRight()) { + log.debug("failed to parse resource metadata"); + response = buildErrorResponse(updateInfoResource.right().value()); + return response; + } + Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false); + Object resource = RepresentationUtils.toRepresentation(updatedResource); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata"); + log.debug("Update Resource Metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/resources/{resourceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response updateResource( + @Parameter(description = "Resource object to be updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @PathParam(value = "resourceId") String resourceId) { + + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + init(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response; + try { + Wrapper responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, resourceId); + } else { + Either convertResponse = parseToLightResource(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar( + convertResponse.left().value(), modifier, null, null, resourceId); + Object representation = RepresentationUtils.toRepresentation(updatedResource); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); + responseWrapper.setInnerElement(response); + } + return responseWrapper.getInnerElement(); + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource"); + log.debug("update resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/resources/csar/{csaruuid}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource retrieced"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response getResourceFromCsar(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @PathParam(value = "csaruuid") String csarUUID) { + + init(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // retrieve user details + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + User user = new User(); + user.setUserId(userId); + + log.debug("user id is {}", userId); + + Response response; + + try { + + Either eitherResource = + resourceBusinessLogic.getLatestResourceFromCsarUuid(csarUUID, user); + + // validate response + if (eitherResource.isRight()) { + log.debug("failed to get resource from csarUuid : {}", csarUUID); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + eitherResource.right().value()); + } else { + Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); + } + + return response; + + } catch (IOException e) { + log.debug("get resource by csar failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java index f87d7347b0..3ffef17fbb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java @@ -1,274 +1,261 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * 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.servlets; - -import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF; - -import com.google.gson.Gson; -import com.google.gson.JsonParseException; -import com.jcabi.aspects.Loggable; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.apache.commons.lang3.StringUtils; -import org.json.simple.JSONArray; -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.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; -import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.Operation; -import org.openecomp.sdc.be.model.OperationInput; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.model.tosca.ToscaFunctions; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.types.ServiceConsumptionData; -import org.openecomp.sdc.be.types.ServiceConsumptionSource; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.exception.ResponseFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -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; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Service Consumption Servlet", description = "Service Consumption Servlet") -@Singleton -public class ServiceConsumptionServlet extends BeGenericServlet { - - private static final Logger log = LoggerFactory.getLogger(ServiceConsumptionServlet.class); - private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; - private final ServiceBusinessLogic serviceBusinessLogic; - - @Inject - public ServiceConsumptionServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils, - InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, - ServiceBusinessLogic serviceBusinessLogic) { - super(userBusinessLogic, componentsUtils); - this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; - this.serviceBusinessLogic = serviceBusinessLogic; - } - - @POST - @Path("/services/{serviceId}/consumption/{serviceInstanceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Service consumption on operation", httpMethod = "POST", - notes = "Returns consumption data", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service property created"), - @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Service property already exist") }) - public Response addInputToServiceOperation(@PathParam("serviceId")final String serviceId, - @PathParam("serviceInstanceId")final String serviceInstanceId, - @ApiParam(value = "Service Consumption Data", required = true) String data, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data); - User modifier = new User(); - modifier.setUserId(userId); - - try { - - Either>, ResponseFormat> dataFromJson = - getServiceConsumptionData(data, modifier); - if(dataFromJson.isRight()) { - return buildErrorResponse(dataFromJson.right().value()); - } - - Map> serviceConsumptionDataMap = dataFromJson.left().value(); - - for(Entry> consumptionEntry : serviceConsumptionDataMap.entrySet()) { - List consumptionList = consumptionEntry.getValue(); - Either, ResponseFormat> operationEither = - serviceBusinessLogic.addServiceConsumptionData(serviceId, serviceInstanceId, - consumptionEntry.getKey(), consumptionList, userId); - if (operationEither.isRight()) { - return buildErrorResponse(operationEither.right().value()); - } - } - - return buildOkResponse(serviceConsumptionDataMap); - - } - catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Operation Inputs"); - log.debug("Create Operation Inputs failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - - } - - @GET - @Path("/services/{serviceId}/consumption/{serviceInstanceId}/interfaces/{interfaceId}/operations/{operationId}/inputs") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response getInputsListOfOperation(@PathParam("serviceId")final String serviceId, - @PathParam("serviceInstanceId")final String serviceInstanceId, - @PathParam("interfaceId")final String interfaceId, - @PathParam("operationId")final String operationId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} modifier id is {}", url, userId); - User user = new User(); - user.setUserId(userId); - - try { - Either, ResponseFormat> inputsEither = - interfaceOperationBusinessLogic.getInputsListForOperation(serviceId, serviceInstanceId, interfaceId, operationId, user); - - if(inputsEither.isRight()) { - return buildErrorResponse(inputsEither.right().value()); - } - - List inputs = inputsEither.left().value(); - return buildOkResponse(updateOperationInputListForUi(inputs, interfaceOperationBusinessLogic)); - } - catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Operation Inputs"); - log.debug("Get Operation Inputs failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - - private List updateOperationInputListForUi(List inputsList, - InterfaceOperationBusinessLogic interfaceOperationBL) { - List operationInputs = new ArrayList<>(); - for(OperationInputDefinition input : inputsList) { - - String value = input.getValue(); - - // Additional UI mapping needed for other sources - if (StringUtils.isNotBlank(value) - && !ServiceConsumptionSource.STATIC.getSource().equals(input.getSource())) { - uiMappingForOtherSources(value, input); - } - - // Add Constraint for UI - OperationInput operationInput = new OperationInput(input); - operationInput.setConstraints(interfaceOperationBL.setInputConstraint(input)); - operationInputs.add(operationInput); - } - - return operationInputs; - } - - private void uiMappingForOtherSources(String value, OperationInputDefinition input) { - try { - Map valueAsMap = (new Gson()).fromJson(value, Map.class); - String toscaFunction = valueAsMap.keySet().iterator().next(); - Object consumptionValueName = valueAsMap.values().iterator().next(); - if(consumptionValueName instanceof List) { - List toscaFunctionList = (List) consumptionValueName; - String consumptionInputValue = null; - if (ToscaFunctions.GET_PROPERTY.getFunctionName().equals(toscaFunction)) { - String propertyValue = toscaFunctionList.stream() - .map(Object::toString) - .filter(val -> !val.equals(SELF)) - .collect(Collectors.joining("_")); - consumptionInputValue = String.valueOf(propertyValue); - } else if (ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName().equals(toscaFunction)) { - //Return full output name - consumptionInputValue = - toscaFunctionList.get(1) + "." + toscaFunctionList.get(2) + "." +toscaFunctionList.get(3); - } - input.setValue(consumptionInputValue); - } else { - input.setValue(String.valueOf(consumptionValueName)); - } - } - catch(JsonParseException ex){ - log.info("This means it is static value for which no changes are needed"); - } - } - - private Either>, ResponseFormat> getServiceConsumptionData(String data, - User user) { - JSONParser parser = new JSONParser(); - Map> serviceConsumptionDataMap = new HashMap<>(); - - try { - JSONArray operationsArray = (JSONArray) parser.parse(data); - Iterator iterator = operationsArray.iterator(); - while (iterator.hasNext()) { - Map next = (Map) iterator.next(); - Entry consumptionEntry = (Entry) next.entrySet().iterator().next(); - String operationId = (String) consumptionEntry.getKey(); - Object value = consumptionEntry.getValue(); - - JSONArray inputsArray = (JSONArray) parser.parse(value.toString()); - serviceConsumptionDataMap.putIfAbsent(operationId, new ArrayList<>()); - for(Object consumptionObject : inputsArray) { - Either serviceDataEither = - getComponentsUtils() - .convertJsonToObjectUsingObjectMapper(consumptionObject.toString(), user, ServiceConsumptionData - .class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - if(serviceDataEither.isRight()) { - return Either.right(serviceDataEither.right().value()); - } - - serviceConsumptionDataMap.get(operationId).add(serviceDataEither.left().value()); - } - } - } - catch (ParseException e) { - log.info("Conetnt is invalid - {}", data); - return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - return Either.left(serviceConsumptionDataMap); - } -} +/* + * Copyright © 2016-2018 European Support Limited + * + * 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.servlets; + +import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +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.GET; +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.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.OperationInput; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.tosca.ToscaFunctions; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.types.ServiceConsumptionData; +import org.openecomp.sdc.be.types.ServiceConsumptionSource; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.gson.Gson; +import com.google.gson.JsonParseException; +import com.jcabi.aspects.Loggable; +import fj.data.Either; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +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 = "Service Consumption Servlet", description = "Service Consumption Servlet")) +@Singleton +public class ServiceConsumptionServlet extends BeGenericServlet { + + private static final Logger log = LoggerFactory.getLogger(ServiceConsumptionServlet.class); + private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; + private final ServiceBusinessLogic serviceBusinessLogic; + + @Inject + public ServiceConsumptionServlet(UserBusinessLogic userBusinessLogic, ComponentsUtils componentsUtils, + InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, + ServiceBusinessLogic serviceBusinessLogic) { + super(userBusinessLogic, componentsUtils); + this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; + this.serviceBusinessLogic = serviceBusinessLogic; + } + + @POST + @Path("/services/{serviceId}/consumption/{serviceInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @io.swagger.v3.oas.annotations.Operation(description = "Service consumption on operation", method = "POST", + summary = "Returns consumption data", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service property created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service property already exist")}) + public Response addInputToServiceOperation(@PathParam("serviceId") final String serviceId, + @PathParam("serviceInstanceId") final String serviceInstanceId, + @Parameter(description = "Service Consumption Data", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data); + User modifier = new User(); + modifier.setUserId(userId); + + try { + + Either>, ResponseFormat> dataFromJson = + getServiceConsumptionData(data, modifier); + if (dataFromJson.isRight()) { + return buildErrorResponse(dataFromJson.right().value()); + } + + Map> serviceConsumptionDataMap = dataFromJson.left().value(); + + for (Entry> consumptionEntry : serviceConsumptionDataMap.entrySet()) { + List consumptionList = consumptionEntry.getValue(); + Either, ResponseFormat> operationEither = + serviceBusinessLogic.addServiceConsumptionData(serviceId, serviceInstanceId, + consumptionEntry.getKey(), consumptionList, userId); + if (operationEither.isRight()) { + return buildErrorResponse(operationEither.right().value()); + } + } + + return buildOkResponse(serviceConsumptionDataMap); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Operation Inputs"); + log.debug("Create Operation Inputs failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + @GET + @Path("/services/{serviceId}/consumption/{serviceInstanceId}/interfaces/{interfaceId}/operations/{operationId}/inputs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getInputsListOfOperation(@PathParam("serviceId") final String serviceId, + @PathParam("serviceInstanceId") final String serviceInstanceId, + @PathParam("interfaceId") final String interfaceId, @PathParam("operationId") final String operationId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} modifier id is {}", url, userId); + User user = new User(); + user.setUserId(userId); + + try { + Either, ResponseFormat> inputsEither = interfaceOperationBusinessLogic + .getInputsListForOperation(serviceId, serviceInstanceId, interfaceId, operationId, user); + + if (inputsEither.isRight()) { + return buildErrorResponse(inputsEither.right().value()); + } + + List inputs = inputsEither.left().value(); + return buildOkResponse(updateOperationInputListForUi(inputs, interfaceOperationBusinessLogic)); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Operation Inputs"); + log.debug("Get Operation Inputs failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + private List updateOperationInputListForUi(List inputsList, + InterfaceOperationBusinessLogic interfaceOperationBL) { + List operationInputs = new ArrayList<>(); + for (OperationInputDefinition input : inputsList) { + + String value = input.getValue(); + + // Additional UI mapping needed for other sources + if (StringUtils.isNotBlank(value) + && !ServiceConsumptionSource.STATIC.getSource().equals(input.getSource())) { + uiMappingForOtherSources(value, input); + } + + // Add Constraint for UI + OperationInput operationInput = new OperationInput(input); + operationInput.setConstraints(interfaceOperationBL.setInputConstraint(input)); + operationInputs.add(operationInput); + } + + return operationInputs; + } + + private void uiMappingForOtherSources(String value, OperationInputDefinition input) { + try { + Map valueAsMap = (new Gson()).fromJson(value, Map.class); + String toscaFunction = valueAsMap.keySet().iterator().next(); + Object consumptionValueName = valueAsMap.values().iterator().next(); + if (consumptionValueName instanceof List) { + List toscaFunctionList = (List) consumptionValueName; + String consumptionInputValue = null; + if (ToscaFunctions.GET_PROPERTY.getFunctionName().equals(toscaFunction)) { + String propertyValue = toscaFunctionList.stream().map(Object::toString) + .filter(val -> !val.equals(SELF)).collect(Collectors.joining("_")); + consumptionInputValue = String.valueOf(propertyValue); + } else if (ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName().equals(toscaFunction)) { + // Return full output name + consumptionInputValue = + toscaFunctionList.get(1) + "." + toscaFunctionList.get(2) + "." + toscaFunctionList.get(3); + } + input.setValue(consumptionInputValue); + } else { + input.setValue(String.valueOf(consumptionValueName)); + } + } catch (JsonParseException ex) { + log.info("This means it is static value for which no changes are needed"); + } + } + + private Either>, ResponseFormat> getServiceConsumptionData(String data, + User user) { + JSONParser parser = new JSONParser(); + Map> serviceConsumptionDataMap = new HashMap<>(); + + try { + JSONArray operationsArray = (JSONArray) parser.parse(data); + Iterator iterator = operationsArray.iterator(); + while (iterator.hasNext()) { + Map next = (Map) iterator.next(); + Entry consumptionEntry = (Entry) next.entrySet().iterator().next(); + String operationId = (String) consumptionEntry.getKey(); + Object value = consumptionEntry.getValue(); + + JSONArray inputsArray = (JSONArray) parser.parse(value.toString()); + serviceConsumptionDataMap.putIfAbsent(operationId, new ArrayList<>()); + for (Object consumptionObject : inputsArray) { + Either serviceDataEither = + getComponentsUtils().convertJsonToObjectUsingObjectMapper(consumptionObject.toString(), + user, ServiceConsumptionData.class, AuditingActionEnum.CREATE_RESOURCE, + ComponentTypeEnum.SERVICE); + if (serviceDataEither.isRight()) { + return Either.right(serviceDataEither.right().value()); + } + + serviceConsumptionDataMap.get(operationId).add(serviceDataEither.left().value()); + } + } + } catch (ParseException e) { + log.info("Conetnt is invalid - {}", data); + return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(serviceConsumptionDataMap); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java index 08485a2894..7c22d62742 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java @@ -1,292 +1,298 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -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.codehaus.jackson.map.ObjectMapper; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; -import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter; -import org.openecomp.sdc.be.ui.model.UIConstraint; -import org.openecomp.sdc.be.ui.model.UINodeFilter; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.exception.ResponseFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Path("/v1/catalog/services/{serviceId}/resourceInstances/{resourceInstanceId}/nodeFilter") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Service Filter", description = "Service Filter Servlet") -@Singleton -public class ServiceFilterServlet extends AbstractValidationsServlet { - - private static final Logger log = LoggerFactory.getLogger(ServiceFilterServlet.class); - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; - private static final String MODIFIER_ID_IS = "modifier id is {}"; - private static final String FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER = "failed to update or create node filter"; - private static final String FAILED_TO_PARSE_SERVICE = "failed to parse service"; - private static final String NODE_FILTER_CREATION_OR_UPDATE = "Node Filter Creation or update"; - private static final String CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR = - "create or update node filter with an error"; - private final ServiceBusinessLogic serviceBusinessLogic; - - @Inject - public ServiceFilterServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ServiceBusinessLogic serviceBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.serviceBusinessLogic = serviceBusinessLogic; - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/") - @ApiOperation(value = "Add Service Filter Constraint", httpMethod = "POST", notes = "Add Service Filter Constraint", - response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response addServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - final HttpSession session = request.getSession(); - ServletContext context = session.getServletContext(); - User modifier = new User(); - modifier.setUserId(userId); - log.debug(MODIFIER_ID_IS, userId); - - Response response; - - try { - String serviceIdLower = serviceId.toLowerCase(); - - Either convertResponse = parseToConstraint(data, modifier); - if (convertResponse.isRight()) { - log.debug(FAILED_TO_PARSE_SERVICE); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - UIConstraint uiConstraint = convertResponse.left().value(); - if (uiConstraint == null) { - log.debug(FAILED_TO_PARSE_SERVICE); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - Either actionResponse; - String constraint = new ConstraintConvertor().convert(uiConstraint); - actionResponse = serviceBusinessLogic - .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), - constraint, -1, modifier, true); - - if (actionResponse.isRight()) { - log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - CINodeFilterDataDefinition value = actionResponse.left().value(); - UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(value); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE); - log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/") - @ApiOperation(value = "Update Service Filter Constraint", httpMethod = "PUT", - notes = "Update Service Filter Constraint", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updateServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug(MODIFIER_ID_IS, userId); - - Response response; - - try { - String serviceIdLower = serviceId.toLowerCase(); - - Either convertResponse = parseToConstraints(data, modifier); - if (convertResponse.isRight()) { - log.debug(FAILED_TO_PARSE_SERVICE); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - List> uiConstraintsMaps = (List>) convertResponse.left().value(); - if (uiConstraintsMaps == null) { - log.debug("failed to parse data"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - final ObjectMapper objectMapper = new ObjectMapper(); - List uiConstraints = uiConstraintsMaps.stream().map(dataMap -> objectMapper.convertValue(dataMap, UIConstraint.class)).collect( - Collectors.toList()); - if (uiConstraints == null) { - log.debug("failed to parse data"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - Either actionResponse; - List constraints = new ConstraintConvertor().convertToList(uiConstraints); - actionResponse = serviceBusinessLogic.updateServiceFilter(serviceIdLower, ciId, constraints, modifier, true); - - if (actionResponse.isRight()) { - log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - CINodeFilterDataDefinition value = actionResponse.left().value(); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - new NodeFilterConverter().convertToUi(value)); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE); - log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/{constraintIndex}") - @ApiOperation(value = "Delete Service Filter Constraint", httpMethod = "Delete", - notes = "Delete Service Filter Constraint", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Service Filter Constraint"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response deleteServiceFilterConstraint( - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId, - @ApiParam(value = "Constraint Index") @PathParam("constraintIndex") int index, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug(MODIFIER_ID_IS, userId); - - Response response; - - try { - String serviceIdLower = serviceId.toLowerCase(); - - Either actionResponse; - actionResponse = serviceBusinessLogic - .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.DELETE, - null, null, index, modifier, true); - - if (actionResponse.isRight()) { - - log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - final CINodeFilterDataDefinition value = actionResponse.left().value(); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - new NodeFilterConverter().convertToUi(value)); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE); - log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - private Either parseToConstraint(String serviceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, UIConstraint.class, - AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - } - - private Either parseToConstraints(String serviceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, List.class, - AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - } -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; +import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter; +import org.openecomp.sdc.be.ui.model.UIConstraint; +import org.openecomp.sdc.be.ui.model.UINodeFilter; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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; + +@Path("/v1/catalog/services/{serviceId}/resourceInstances/{resourceInstanceId}/nodeFilter") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Service Filter", description = "Service Filter Servlet")) +@Singleton +public class ServiceFilterServlet extends AbstractValidationsServlet { + + private static final Logger log = LoggerFactory.getLogger(ServiceFilterServlet.class); + private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + private static final String MODIFIER_ID_IS = "modifier id is {}"; + private static final String FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER = "failed to update or create node filter"; + private static final String FAILED_TO_PARSE_SERVICE = "failed to parse service"; + private static final String NODE_FILTER_CREATION_OR_UPDATE = "Node Filter Creation or update"; + private static final String CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR = + "create or update node filter with an error"; + private final ServiceBusinessLogic serviceBusinessLogic; + + @Inject + public ServiceFilterServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + ServiceBusinessLogic serviceBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.serviceBusinessLogic = serviceBusinessLogic; + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/") + @Operation(description = "Add Service Filter Constraint", method = "POST", summary = "Add Service Filter Constraint", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Service Filter"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response addServiceFilterConstraint(@Parameter(description = "Service data", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + final HttpSession session = request.getSession(); + ServletContext context = session.getServletContext(); + User modifier = new User(); + modifier.setUserId(userId); + log.debug(MODIFIER_ID_IS, userId); + + Response response; + + try { + String serviceIdLower = serviceId.toLowerCase(); + + Either convertResponse = parseToConstraint(data, modifier); + if (convertResponse.isRight()) { + log.debug(FAILED_TO_PARSE_SERVICE); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + UIConstraint uiConstraint = convertResponse.left().value(); + if (uiConstraint == null) { + log.debug(FAILED_TO_PARSE_SERVICE); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Either actionResponse; + String constraint = new ConstraintConvertor().convert(uiConstraint); + actionResponse = serviceBusinessLogic + .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), + constraint, -1, modifier, true); + + if (actionResponse.isRight()) { + log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + CINodeFilterDataDefinition value = actionResponse.left().value(); + UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(value); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE); + log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/") + @Operation(description = "Update Service Filter Constraint", method = "PUT", + summary = "Update Service Filter Constraint", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Service Filter"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateServiceFilterConstraint(@Parameter(description = "Service data", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug(MODIFIER_ID_IS, userId); + + Response response; + + try { + String serviceIdLower = serviceId.toLowerCase(); + + Either convertResponse = parseToConstraints(data, modifier); + if (convertResponse.isRight()) { + log.debug(FAILED_TO_PARSE_SERVICE); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + List> uiConstraintsMaps = (List>) convertResponse.left().value(); + if (uiConstraintsMaps == null) { + log.debug("failed to parse data"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + final ObjectMapper objectMapper = new ObjectMapper(); + List uiConstraints = uiConstraintsMaps.stream().map(dataMap -> objectMapper.convertValue(dataMap, UIConstraint.class)).collect( + Collectors.toList()); + if (uiConstraints == null) { + log.debug("failed to parse data"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Either actionResponse; + List constraints = new ConstraintConvertor().convertToList(uiConstraints); + actionResponse = serviceBusinessLogic.updateServiceFilter(serviceIdLower, ciId, constraints, modifier, true); + + if (actionResponse.isRight()) { + log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + CINodeFilterDataDefinition value = actionResponse.left().value(); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + new NodeFilterConverter().convertToUi(value)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE); + log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/{constraintIndex}") + @Operation(description = "Delete Service Filter Constraint", method = "Delete", + summary = "Delete Service Filter Constraint", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Service Filter Constraint"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response deleteServiceFilterConstraint( + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId, + @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug(MODIFIER_ID_IS, userId); + + Response response; + + try { + String serviceIdLower = serviceId.toLowerCase(); + + Either actionResponse; + actionResponse = serviceBusinessLogic + .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.DELETE, + null, null, index, modifier, true); + + if (actionResponse.isRight()) { + + log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + final CINodeFilterDataDefinition value = actionResponse.left().value(); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + new NodeFilterConverter().convertToUi(value)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE); + log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private Either parseToConstraint(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, UIConstraint.class, + AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + private Either parseToConstraints(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, List.class, + AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceForwardingPathServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceForwardingPathServlet.java index a9c257f6d1..22054f6791 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceForwardingPathServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceForwardingPathServlet.java @@ -1,264 +1,280 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - - -import com.google.common.collect.Sets; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.apache.commons.collections.MapUtils; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.Service; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; -import org.openecomp.sdc.be.ui.model.UiServiceDataTransfer; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.Collections; -import java.util.Set; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/services/{serviceId}/paths") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Service Forwarding Path", description = "Service Forwarding Path Servlet") -@Singleton -public class ServiceForwardingPathServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(ServiceForwardingPathServlet.class); - private final ServiceBusinessLogic serviceBusinessLogic; - - @Inject - public ServiceForwardingPathServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ServiceBusinessLogic serviceBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.serviceBusinessLogic = serviceBusinessLogic; - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/") - @ApiOperation(value = "Create Forwarding Path", httpMethod = "POST", notes = "Create Forwarding Path", response = Service.class) - @ApiResponses(value = - {@ApiResponse(code = 201, message = "Create Forwarding Path"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Forwarding Path already exist")}) - public Response createForwardingPath( - @ApiParam(value = "Forwarding Path to create", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, serviceId, request, userId, false); - } - - - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/") - @ApiOperation(value = "Update Forwarding Path", httpMethod = "PUT", notes = "Update Forwarding Path", response = Service.class) - @ApiResponses(value = - {@ApiResponse(code = 201, message = "Update Forwarding Path"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Forwarding Path already exist")}) - public Response updateForwardingPath( - @ApiParam(value = "Update Path to create", required = true) String data, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, serviceId, request, userId, true); - } - - private Response createOrUpdate( String data, String serviceId, HttpServletRequest request, String userId, boolean isUpdate) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response; - - try { - String serviceIdLower = serviceId.toLowerCase(); - - Either convertResponse = parseToService(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse service"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - Service updatedService = convertResponse.left().value(); - Either actionResponse ; - if (isUpdate) { - actionResponse = serviceBusinessLogic.updateForwardingPath(serviceIdLower, updatedService, modifier, true); - } else { - actionResponse = serviceBusinessLogic.createForwardingPath(serviceIdLower, updatedService, modifier, true); - } - - if (actionResponse.isRight()) { - log.debug("failed to update or create paths"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Service service = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Forward Path Creation or update"); - log.debug("create or update forwarding path with an error", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/{forwardingPathId}") - @ApiOperation(value = "Get Forwarding Path", httpMethod = "GET", notes = "GET Forwarding Path", response = ForwardingPathDataDefinition.class) - @ApiResponses(value = - {@ApiResponse(code = 201, message = "Get Forwarding Path"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Forwarding Path already exist")}) - public Response getForwardingPath( - @ApiParam(value = "Forwarding Path to create", required = true) String datax, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @ApiParam(value = "Forwarding Path Id") @PathParam("forwardingPathId") String forwardingPathId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - - try { - Either serviceResponse = serviceBusinessLogic.getComponentDataFilteredByParams(serviceId, modifier, Collections.singletonList(ComponentFieldsEnum.FORWARDING_PATHS.getValue())); - if (serviceResponse.isRight()) { - return buildErrorResponse(serviceResponse.right().value()); - } - - UiServiceDataTransfer uiServiceDataTransfer = (UiServiceDataTransfer) serviceResponse.left().value(); - - ForwardingPathDataDefinition forwardingPathDataDefinition = new ForwardingPathDataDefinition(); - if (!MapUtils.isEmpty(uiServiceDataTransfer.getForwardingPaths())) { - forwardingPathDataDefinition = uiServiceDataTransfer.getForwardingPaths().get(forwardingPathId); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(forwardingPathDataDefinition)); - - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); - log.debug("update service metadata failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/{forwardingPathId}") - @ApiOperation(value = "Delete Forwarding Path", httpMethod = "DELETE", notes = "Delete Forwarding Path", response = Service.class) - @ApiResponses(value = - {@ApiResponse(code = 201, message = "Delete Forwarding Path"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Forwarding Path already exist")}) - public Response deleteForwardingPath( - @ApiParam(value = "Forwarding Path Id") @PathParam("forwardingPathId") String forwardingPathId, - @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response; - - try { - String serviceIdLower = serviceId.toLowerCase(); - - Either, ResponseFormat> actionResponse = serviceBusinessLogic.deleteForwardingPaths(serviceIdLower, Sets.newHashSet(forwardingPathId), modifier, true); - - if (actionResponse.isRight()) { - log.debug("failed to delete paths"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Set deletedPaths = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(deletedPaths); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete forward paths"); - log.debug("Delete service paths with an error", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - - private Either parseToService(String serviceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);//TODO: change sSERVICE constant - } -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + + +import java.util.Collections; +import java.util.Set; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.collections.MapUtils; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.ui.model.UiServiceDataTransfer; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import com.google.common.collect.Sets; +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/services/{serviceId}/paths") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Service Forwarding Path", description = "Service Forwarding Path Servlet")) +@Singleton +public class ServiceForwardingPathServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(ServiceForwardingPathServlet.class); + private final ServiceBusinessLogic serviceBusinessLogic; + + @Inject + public ServiceForwardingPathServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + ServiceBusinessLogic serviceBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.serviceBusinessLogic = serviceBusinessLogic; + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/") + @Operation(description = "Create Forwarding Path", method = "POST", summary = "Create Forwarding Path",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = + {@ApiResponse(responseCode = "201", description = "Create Forwarding Path"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) + public Response createForwardingPath( + @Parameter(description = "Forwarding Path to create", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, serviceId, request, userId, false); + } + + + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/") + @Operation(description = "Update Forwarding Path", method = "PUT", summary = "Update Forwarding Path",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = + {@ApiResponse(responseCode = "201", description = "Update Forwarding Path"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) + public Response updateForwardingPath( + @Parameter(description = "Update Path to create", required = true) String data, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, serviceId, request, userId, true); + } + + private Response createOrUpdate( String data, String serviceId, HttpServletRequest request, String userId, boolean isUpdate) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response; + + try { + String serviceIdLower = serviceId.toLowerCase(); + + Either convertResponse = parseToService(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse service"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Service updatedService = convertResponse.left().value(); + Either actionResponse ; + if (isUpdate) { + actionResponse = serviceBusinessLogic.updateForwardingPath(serviceIdLower, updatedService, modifier, true); + } else { + actionResponse = serviceBusinessLogic.createForwardingPath(serviceIdLower, updatedService, modifier, true); + } + + if (actionResponse.isRight()) { + log.debug("failed to update or create paths"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Forward Path Creation or update"); + log.debug("create or update forwarding path with an error", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/{forwardingPathId}") + @Operation(description = "Get Forwarding Path", method = "GET", summary = "GET Forwarding Path",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ForwardingPathDataDefinition.class))))) + @ApiResponses(value = + {@ApiResponse(responseCode = "201", description = "Get Forwarding Path"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) + public Response getForwardingPath( + @Parameter(description = "Forwarding Path to create", required = true) String datax, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Parameter(description = "Forwarding Path Id") @PathParam("forwardingPathId") String forwardingPathId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + + try { + Either serviceResponse = serviceBusinessLogic.getComponentDataFilteredByParams(serviceId, modifier, Collections.singletonList(ComponentFieldsEnum.FORWARDING_PATHS.getValue())); + if (serviceResponse.isRight()) { + return buildErrorResponse(serviceResponse.right().value()); + } + + UiServiceDataTransfer uiServiceDataTransfer = (UiServiceDataTransfer) serviceResponse.left().value(); + + ForwardingPathDataDefinition forwardingPathDataDefinition = new ForwardingPathDataDefinition(); + if (!MapUtils.isEmpty(uiServiceDataTransfer.getForwardingPaths())) { + forwardingPathDataDefinition = uiServiceDataTransfer.getForwardingPaths().get(forwardingPathId); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(forwardingPathDataDefinition)); + + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); + log.debug("update service metadata failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/{forwardingPathId}") + @Operation(description = "Delete Forwarding Path", method = "DELETE", summary = "Delete Forwarding Path",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = + {@ApiResponse(responseCode = "201", description = "Delete Forwarding Path"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) + public Response deleteForwardingPath( + @Parameter(description = "Forwarding Path Id") @PathParam("forwardingPathId") String forwardingPathId, + @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response; + + try { + String serviceIdLower = serviceId.toLowerCase(); + + Either, ResponseFormat> actionResponse = serviceBusinessLogic.deleteForwardingPaths(serviceIdLower, Sets.newHashSet(forwardingPathId), modifier, true); + + if (actionResponse.isRight()) { + log.debug("failed to delete paths"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Set deletedPaths = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(deletedPaths); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete forward paths"); + log.debug("Delete service paths with an error", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + + private Either parseToService(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);//TODO: change sSERVICE constant + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java index 9e960b0d97..8e71775e14 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java @@ -1,696 +1,770 @@ -/*- - * ============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.servlets; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.reflect.TypeToken; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import org.apache.http.HttpStatus; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -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.LifecycleChangeInfoWithAction; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.ServiceRelations; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.DistributionStatusEnum; -import org.openecomp.sdc.be.model.GroupInstanceProperty; -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.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.user.UserBusinessLogic; -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.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Service Catalog", description = "Service Servlet") -@Singleton -public class ServiceServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(ServiceServlet.class); - private final ServiceBusinessLogic serviceBusinessLogic; - private final ResourceBusinessLogic resourceBusinessLogic; - - @Inject - public ServiceServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - ServiceBusinessLogic serviceBusinessLogic, - ResourceBusinessLogic resourceBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.serviceBusinessLogic = serviceBusinessLogic; - this.resourceBusinessLogic = resourceBusinessLogic; - } - - @POST - @Path("/services") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create Service", httpMethod = "POST", notes = "Returns created service", response = Service.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Service created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Service already exist") }) - public Response createService(@ApiParam(value = "Service object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Either convertResponse = parseToService(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse service"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - - Service service = convertResponse.left().value(); - Either actionResponse = serviceBusinessLogic.createService(service, modifier); - - if (actionResponse.isRight()) { - log.debug("Failed to create service"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Service"); - log.debug("create service failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - public Either parseToService(String serviceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - } - - @GET - @Path("/services/validate-name/{serviceName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "validate service name", httpMethod = "GET", notes = "checks if the chosen service name is available ", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") }) - public Response validateServiceName(@PathParam("serviceName") final String serviceName, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response = null; - try { - Either, ResponseFormat> actionResponse = serviceBusinessLogic.validateServiceNameExists(serviceName, userId); - - if (actionResponse.isRight()) { - log.debug("failed to get validate service name"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name"); - log.debug("validate service name failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/audit-records/{componentType}/{componentUniqueId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "get component audit records", httpMethod = "GET", notes = "get audit records for a service or a resource", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") }) - public Response getComponentAuditRecords(@PathParam("componentType") final String componentType, @PathParam("componentUniqueId") final String componentUniqueId, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - init(); - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Wrapper responseWrapper = new Wrapper<>(); - Wrapper uuidWrapper = new Wrapper<>(); - Wrapper versionWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - Wrapper componentWrapper = new Wrapper<>(); - try { - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - validateComponentType(responseWrapper, componentWrapper, componentType); - } - - if (responseWrapper.isEmpty()) { - fillUUIDAndVersion(responseWrapper, uuidWrapper, versionWrapper, userWrapper.getInnerElement(), componentWrapper.getInnerElement(), componentUniqueId, context); - } - - if (responseWrapper.isEmpty()) { - Either>, ResponseFormat> eitherServiceAudit = serviceBusinessLogic.getComponentAuditRecords(versionWrapper.getInnerElement(), uuidWrapper.getInnerElement(), userId); - - if (eitherServiceAudit.isRight()) { - Response errorResponse = buildErrorResponse(eitherServiceAudit.right().value()); - responseWrapper.setInnerElement(errorResponse); - } else { - List> auditRecords = eitherServiceAudit.left().value(); - Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), auditRecords); - responseWrapper.setInnerElement(okResponse); - - } - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name"); - log.debug("get Service Audit Records failed with exception", e); - Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - responseWrapper.setInnerElement(errorResponse); - } - return responseWrapper.getInnerElement(); - } - - private void fillUUIDAndVersion(Wrapper responseWrapper, Wrapper uuidWrapper, Wrapper versionWrapper, User user, final ComponentTypeEnum componentTypeEnum, final String componentUniqueId, ServletContext context) { - - if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { - Either eitherResource = resourceBusinessLogic.getResource(componentUniqueId, user); - if (eitherResource.isLeft()) { - uuidWrapper.setInnerElement(eitherResource.left().value().getUUID()); - versionWrapper.setInnerElement(eitherResource.left().value().getVersion()); - } else { - responseWrapper.setInnerElement(buildErrorResponse(eitherResource.right().value())); - } - - } else { - Either eitherService = serviceBusinessLogic.getService(componentUniqueId, user); - if (eitherService.isLeft()) { - uuidWrapper.setInnerElement(eitherService.left().value().getUUID()); - versionWrapper.setInnerElement(eitherService.left().value().getVersion()); - } else { - responseWrapper.setInnerElement(buildErrorResponse(eitherService.right().value())); - - } - } - } - - @DELETE - @Path("/services/{serviceId}") - public Response deleteService(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - try { - String serviceIdLower = serviceId.toLowerCase(); - ResponseFormat actionResponse = serviceBusinessLogic.deleteService(serviceIdLower, modifier); - - if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { - log.debug("failed to delete service"); - response = buildErrorResponse(actionResponse); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); - log.debug("delete service failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @DELETE - @Path("/services/{serviceName}/{version}") - public Response deleteServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - try { - ResponseFormat actionResponse = serviceBusinessLogic.deleteServiceByNameAndVersion(serviceName, version, modifier); - - if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { - log.debug("failed to delete service"); - response = buildErrorResponse(actionResponse); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); - log.debug("delete service failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @PUT - @Path("/services/{serviceId}/metadata") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Service Metadata", httpMethod = "PUT", notes = "Returns updated service", response = Service.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateServiceMetadata(@PathParam("serviceId") final String serviceId, @ApiParam(value = "Service object to be Updated", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - - try { - String serviceIdLower = serviceId.toLowerCase(); - - Either convertResponse = parseToService(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse service"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - Service updatedService = convertResponse.left().value(); - Either actionResponse = serviceBusinessLogic.updateServiceMetadata(serviceIdLower, updatedService, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to update service"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Service service = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); - log.debug("update service metadata failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - /** - * updates group instance property values - * Note, than in case of group instance updated successfully, related resourceInstance and containing component modification time will be updated - * @param serviceId - * @param componentInstanceId - * @param groupInstanceId - * @param data - * @param request - * @param userId - * @return - */ - @PUT - @Path("/{containerComponentType}/{serviceId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Group Instance Property Values", httpMethod = "PUT", notes = "Returns updated group instance", response = Service.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Group Instance Property Values Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) - public Response updateGroupInstancePropertyValues(@PathParam("serviceId") final String serviceId,@PathParam("componentInstanceId") final String componentInstanceId, @PathParam("groupInstanceId") final String groupInstanceId, @ApiParam(value = "Group instance object to be Updated", required = true) String data, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - Response response = null; - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}",userId); - - Either, ResponseFormat> actionResponse = null; - try { - List updatedProperties; - Type listType = new TypeToken>(){}.getType(); - ArrayList newProperties = gson.fromJson(data, listType); - if (newProperties == null) { - actionResponse = Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - if(actionResponse == null){ - log.debug("Start handle update group instance property values request. Received group instance is {}", groupInstanceId); - actionResponse = serviceBusinessLogic.updateGroupInstancePropertyValues(modifier, serviceId, componentInstanceId, groupInstanceId, newProperties); - if(actionResponse.isRight()){ - actionResponse = Either.right(actionResponse.right().value()); - } - } - if(actionResponse.isLeft()){ - updatedProperties = actionResponse.left().value(); - ObjectMapper mapper = new ObjectMapper(); - String result = mapper.writeValueAsString(updatedProperties); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } - else{ - response = buildErrorResponse(actionResponse.right().value()); - } - } catch (Exception e) { - log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - return response; - } - - @GET - @Path("/services/{serviceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns service according to serviceId", response = Service.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) - public Response getServiceById(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - String serviceIdLower = serviceId.toLowerCase(); - log.debug("get service with id {}", serviceId); - Either actionResponse = serviceBusinessLogic.getService(serviceIdLower, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to get service"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Service service = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service"); - log.debug("get service failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @GET - @Path("/services/serviceName/{serviceName}/serviceVersion/{serviceVersion}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns service according to name and version", response = Service.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) - public Response getServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Either actionResponse = serviceBusinessLogic.getServiceByNameAndVersion(serviceName, serviceVersion, userId); - - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - Service service = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service by name and version"); - log.debug("get service failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @POST - @Path("/services/{serviceId}/distribution-state/{state}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Update Service Distribution State", httpMethod = "POST", notes = "service with the changed distribution status") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service distribution state changed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 403, message = "Service is not available for distribution"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 404, message = "Requested service was not found"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) - public Response updateServiceDistributionState(@ApiParam(value = "DistributionChangeInfo - get comment out of body", required = true) LifecycleChangeInfoWithAction jsonChangeInfo, @PathParam("serviceId") final String serviceId, - @ApiParam(allowableValues = "approve, reject", required = true) @PathParam("state") final String state, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Either actionResponse = serviceBusinessLogic.changeServiceDistributionState(serviceId, state, jsonChangeInfo, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to Update Service Distribution State"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - Service service = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Distribution State"); - log.debug("updateServiceDistributionState failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - @POST - @Path("/services/{serviceId}/distribution/{env}/activate") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Activate distribution", httpMethod = "POST", notes = "activate distribution") - @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 409, message = "Service cannot be distributed due to missing deployment artifacts"), @ApiResponse(code = 404, message = "Requested service was not found"), - @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) - public Response activateDistribution(@PathParam("serviceId") final String serviceId, @PathParam("env") final String env, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Either distResponse = serviceBusinessLogic.activateDistribution(serviceId, env, modifier, request); - - if (distResponse.isRight()) { - log.debug("failed to activate service distribution"); - response = buildErrorResponse(distResponse.right().value()); - return response; - } - Service service = distResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Activate Distribution"); - log.debug("activate distribution failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - @POST - @Path("/services/{serviceId}/distribution/{did}/markDeployed") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Mark distribution as deployed", httpMethod = "POST", notes = "relevant audit record will be created") - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service was marked as deployed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 403, message = "Service is not available"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 404, message = "Requested service was not found"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) - public Response markDistributionAsDeployed(@PathParam("serviceId") final String serviceId, @PathParam("did") final String did, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - Either distResponse = serviceBusinessLogic.markDistributionAsDeployed(serviceId, did, modifier); - - if (distResponse.isRight()) { - log.debug("failed to mark distribution as deployed"); - response = buildErrorResponse(distResponse.right().value()); - return response; - } - Service service = distResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(service); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Mark Distribution As Deployed"); - log.debug("mark distribution as deployed failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - @POST - @Path("/services/{serviceId}/tempUrlToBeDeleted") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) - public Response tempUrlToBeDeleted(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response; - try { - Service service = (serviceBusinessLogic.getService(serviceId, modifier)).left().value(); - Either res = serviceBusinessLogic.updateDistributionStatusForActivation(service, modifier, DistributionStatusEnum.DISTRIBUTED); - - if (res.isRight()) { - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("tempUrlToBeDeleted"); - log.debug("failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - - @GET - @Path("/services/{serviceId}/linksMap") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve Service component relations map", httpMethod = "GET", notes = "Returns service components relations", response = ServiceRelations.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) - public Response getServiceComponentRelationMap(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response = null; - try { - String serviceIdLower = serviceId.toLowerCase(); - log.debug("get service components relations with id {}", serviceId); - Either actionResponse = serviceBusinessLogic.getServiceComponentsRelations(serviceIdLower, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to get service relations data"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - - ServiceRelations serviceRelations = actionResponse.left().value(); - Object result = RepresentationUtils.toRepresentation(serviceRelations); - - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service"); - log.debug("get service relations data failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - -} +/*- + * ============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.servlets; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.reflect.TypeToken; +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 javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +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.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.ServiceRelations; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.GroupInstanceProperty; +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.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.exception.ResponseFormat; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Service Catalog", description = "Service Servlet")) +@Singleton +public class ServiceServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(ServiceServlet.class); + private final ServiceBusinessLogic serviceBusinessLogic; + private final ResourceBusinessLogic resourceBusinessLogic; + + @Inject + public ServiceServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + ServiceBusinessLogic serviceBusinessLogic, + ResourceBusinessLogic resourceBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.serviceBusinessLogic = serviceBusinessLogic; + this.resourceBusinessLogic = resourceBusinessLogic; + } + + @POST + @Path("/services") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Service", method = "POST", summary = "Returns created service", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Service created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service already exist")}) + public Response createService(@Parameter(description = "Service object to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Either convertResponse = parseToService(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse service"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Service service = convertResponse.left().value(); + Either actionResponse = serviceBusinessLogic.createService(service, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to create service"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Service"); + log.debug("create service failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + public Either parseToService(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + @GET + @Path("/services/validate-name/{serviceName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "validate service name", method = "GET", + summary = "checks if the chosen service name is available ", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation")}) + public Response validateServiceName(@PathParam("serviceName") final String serviceName, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + try { + Either, ResponseFormat> actionResponse = + serviceBusinessLogic.validateServiceNameExists(serviceName, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get validate service name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name"); + log.debug("validate service name failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/audit-records/{componentType}/{componentUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "get component audit records", method = "GET", + summary = "get audit records for a service or a resource", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation")}) + public Response getComponentAuditRecords(@PathParam("componentType") final String componentType, + @PathParam("componentUniqueId") final String componentUniqueId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + init(); + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Wrapper responseWrapper = new Wrapper<>(); + Wrapper uuidWrapper = new Wrapper<>(); + Wrapper versionWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + Wrapper componentWrapper = new Wrapper<>(); + try { + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + validateComponentType(responseWrapper, componentWrapper, componentType); + } + + if (responseWrapper.isEmpty()) { + fillUUIDAndVersion(responseWrapper, uuidWrapper, versionWrapper, userWrapper.getInnerElement(), + componentWrapper.getInnerElement(), componentUniqueId, context); + } + + if (responseWrapper.isEmpty()) { + Either>, ResponseFormat> eitherServiceAudit = + serviceBusinessLogic.getComponentAuditRecords(versionWrapper.getInnerElement(), + uuidWrapper.getInnerElement(), userId); + + if (eitherServiceAudit.isRight()) { + Response errorResponse = buildErrorResponse(eitherServiceAudit.right().value()); + responseWrapper.setInnerElement(errorResponse); + } else { + List> auditRecords = eitherServiceAudit.left().value(); + Response okResponse = + buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), auditRecords); + responseWrapper.setInnerElement(okResponse); + + } + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name"); + log.debug("get Service Audit Records failed with exception", e); + Response errorResponse = + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(errorResponse); + } + return responseWrapper.getInnerElement(); + } + + private void fillUUIDAndVersion(Wrapper responseWrapper, Wrapper uuidWrapper, Wrapper versionWrapper, User user, final ComponentTypeEnum componentTypeEnum, final String componentUniqueId, ServletContext context) { + + if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { + Either eitherResource = resourceBusinessLogic.getResource(componentUniqueId, user); + if (eitherResource.isLeft()) { + uuidWrapper.setInnerElement(eitherResource.left().value().getUUID()); + versionWrapper.setInnerElement(eitherResource.left().value().getVersion()); + } else { + responseWrapper.setInnerElement(buildErrorResponse(eitherResource.right().value())); + } + + } else { + Either eitherService = serviceBusinessLogic.getService(componentUniqueId, user); + if (eitherService.isLeft()) { + uuidWrapper.setInnerElement(eitherService.left().value().getUUID()); + versionWrapper.setInnerElement(eitherService.left().value().getVersion()); + } else { + responseWrapper.setInnerElement(buildErrorResponse(eitherService.right().value())); + + } + } + } + + @DELETE + @Path("/services/{serviceId}") + public Response deleteService(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + String serviceIdLower = serviceId.toLowerCase(); + ResponseFormat actionResponse = serviceBusinessLogic.deleteService(serviceIdLower, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete service"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); + log.debug("delete service failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Path("/services/{serviceName}/{version}") + public Response deleteServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + ResponseFormat actionResponse = serviceBusinessLogic.deleteServiceByNameAndVersion(serviceName, version, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete service"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); + log.debug("delete service failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/services/{serviceId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Service Metadata", method = "PUT", summary = "Returns updated service", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateServiceMetadata(@PathParam("serviceId") final String serviceId, + @Parameter(description = "Service object to be Updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + String serviceIdLower = serviceId.toLowerCase(); + + Either convertResponse = parseToService(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse service"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Service updatedService = convertResponse.left().value(); + Either actionResponse = + serviceBusinessLogic.updateServiceMetadata(serviceIdLower, updatedService, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to update service"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); + log.debug("update service metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + /** + * updates group instance property values + * Note, than in case of group instance updated successfully, related resourceInstance and containing component modification time will be updated + * @param serviceId + * @param componentInstanceId + * @param groupInstanceId + * @param data + * @param request + * @param userId + * @return + */ + @PUT + @Path("/{containerComponentType}/{serviceId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Group Instance Property Values", method = "PUT", + summary = "Returns updated group instance", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Group Instance Property Values Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response updateGroupInstancePropertyValues(@PathParam("serviceId") final String serviceId, + @PathParam("componentInstanceId") final String componentInstanceId, + @PathParam("groupInstanceId") final String groupInstanceId, + @Parameter(description = "Group instance object to be Updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Response response = null; + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}",userId); + + Either, ResponseFormat> actionResponse = null; + try { + List updatedProperties; + Type listType = new TypeToken>(){}.getType(); + ArrayList newProperties = gson.fromJson(data, listType); + if (newProperties == null) { + actionResponse = Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + if(actionResponse == null){ + log.debug("Start handle update group instance property values request. Received group instance is {}", groupInstanceId); + actionResponse = serviceBusinessLogic.updateGroupInstancePropertyValues(modifier, serviceId, componentInstanceId, groupInstanceId, newProperties); + if(actionResponse.isRight()){ + actionResponse = Either.right(actionResponse.right().value()); + } + } + if(actionResponse.isLeft()){ + updatedProperties = actionResponse.left().value(); + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(updatedProperties); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } + else{ + response = buildErrorResponse(actionResponse.right().value()); + } + } catch (Exception e) { + log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return response; + } + + @GET + @Path("/services/{serviceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Service", method = "GET", summary = "Returns service according to serviceId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response getServiceById(@PathParam("serviceId") final String serviceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + String serviceIdLower = serviceId.toLowerCase(); + log.debug("get service with id {}", serviceId); + Either actionResponse = serviceBusinessLogic.getService(serviceIdLower, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get service"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service"); + log.debug("get service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/services/serviceName/{serviceName}/serviceVersion/{serviceVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Service", method = "GET", + summary = "Returns service according to name and version", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response getServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, + @PathParam("serviceVersion") final String serviceVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Either actionResponse = serviceBusinessLogic.getServiceByNameAndVersion(serviceName, serviceVersion, userId); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service by name and version"); + log.debug("get service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @POST + @Path("/services/{serviceId}/distribution-state/{state}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Service Distribution State", method = "POST", + summary = "service with the changed distribution status") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service distribution state changed"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "403", description = "Service is not available for distribution"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Requested service was not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) + public Response updateServiceDistributionState( + @Parameter(description = "DistributionChangeInfo - get comment out of body", + required = true) LifecycleChangeInfoWithAction jsonChangeInfo, + @PathParam("serviceId") final String serviceId, + @Parameter(schema = @Schema(allowableValues = {"approve", "reject"}), + required = true) @PathParam("state") final String state, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Either actionResponse = serviceBusinessLogic.changeServiceDistributionState(serviceId, state, jsonChangeInfo, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to Update Service Distribution State"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Distribution State"); + log.debug("updateServiceDistributionState failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @POST + @Path("/services/{serviceId}/distribution/{env}/activate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Activate distribution", method = "POST", summary = "activate distribution") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "409", + description = "Service cannot be distributed due to missing deployment artifacts"), + @ApiResponse(responseCode = "404", description = "Requested service was not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) + public Response activateDistribution(@PathParam("serviceId") final String serviceId, + @PathParam("env") final String env, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Either distResponse = serviceBusinessLogic.activateDistribution(serviceId, env, modifier, request); + + if (distResponse.isRight()) { + log.debug("failed to activate service distribution"); + response = buildErrorResponse(distResponse.right().value()); + return response; + } + Service service = distResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Activate Distribution"); + log.debug("activate distribution failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @POST + @Path("/services/{serviceId}/distribution/{did}/markDeployed") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Mark distribution as deployed", method = "POST", + summary = "relevant audit record will be created") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service was marked as deployed"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "403", description = "Service is not available"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Requested service was not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) + public Response markDistributionAsDeployed(@PathParam("serviceId") final String serviceId, + @PathParam("did") final String did, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + Either distResponse = serviceBusinessLogic.markDistributionAsDeployed(serviceId, did, modifier); + + if (distResponse.isRight()) { + log.debug("failed to mark distribution as deployed"); + response = buildErrorResponse(distResponse.right().value()); + return response; + } + Service service = distResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Mark Distribution As Deployed"); + log.debug("mark distribution as deployed failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @POST + @Path("/services/{serviceId}/tempUrlToBeDeleted") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.") }) + public Response tempUrlToBeDeleted(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response; + try { + Service service = (serviceBusinessLogic.getService(serviceId, modifier)).left().value(); + Either res = serviceBusinessLogic.updateDistributionStatusForActivation(service, modifier, DistributionStatusEnum.DISTRIBUTED); + + if (res.isRight()) { + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("tempUrlToBeDeleted"); + log.debug("failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + + @GET + @Path("/services/{serviceId}/linksMap") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Service component relations map", method = "GET", + summary = "Returns service components relations",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ServiceRelations.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) + public Response getServiceComponentRelationMap(@PathParam("serviceId") final String serviceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + String serviceIdLower = serviceId.toLowerCase(); + log.debug("get service components relations with id {}", serviceId); + Either actionResponse = serviceBusinessLogic.getServiceComponentsRelations(serviceIdLower, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get service relations data"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + ServiceRelations serviceRelations = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(serviceRelations); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service"); + log.debug("get service relations data failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java index 33df8bc4b6..a3e47a0b23 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java @@ -1,380 +1,387 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import javax.inject.Inject; -import org.apache.commons.collections4.ListUtils; -import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; -import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; -import org.openecomp.sdc.be.components.impl.RelationshipTypeBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; -import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.CapabilityTypeDefinition; -import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.DataTypeDefinition; -import org.openecomp.sdc.be.model.InterfaceDefinition; -import org.openecomp.sdc.be.model.RelationshipTypeDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.user.UserBusinessLogic; -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.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@Api(value = "Types Fetch Servlet", description = "Types Fetch Servlet") -@Singleton -public class TypesFetchServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(TypesFetchServlet.class); - private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}"; - private final PropertyBusinessLogic propertyBusinessLogic; - private final RelationshipTypeBusinessLogic relationshipTypeBusinessLogic; - private final CapabilitiesBusinessLogic capabilitiesBusinessLogic; - private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; - private final ResourceBusinessLogic resourceBusinessLogic; - - @Inject - public TypesFetchServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - PropertyBusinessLogic propertyBusinessLogic, - RelationshipTypeBusinessLogic relationshipTypeBusinessLogic, - CapabilitiesBusinessLogic capabilitiesBusinessLogic, - InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, - ResourceBusinessLogic resourceBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.propertyBusinessLogic = propertyBusinessLogic; - this.relationshipTypeBusinessLogic = relationshipTypeBusinessLogic; - this.capabilitiesBusinessLogic = capabilitiesBusinessLogic; - this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; - this.resourceBusinessLogic = resourceBusinessLogic; - } - - @GET - @Path("dataTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get data types", httpMethod = "GET", notes = "Returns data types", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "datatypes"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Data types not found") }) - public Response getAllDataTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - try { - init(); - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); - - Either, ResponseFormat> allDataTypes = - propertyBusinessLogic.getAllDataTypes(); - - if (allDataTypes.isRight()) { - log.info("Failed to get all dara types. Reason - {}", allDataTypes.right().value()); - Response errorResponse = buildErrorResponse(allDataTypes.right().value()); - responseWrapper.setInnerElement(errorResponse); - - } else { - - Map dataTypes = allDataTypes.left().value(); - String dataTypeJson = gson.toJson(dataTypes); - Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson); - responseWrapper.setInnerElement(okResponse); - - } - } - - return responseWrapper.getInnerElement(); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property"); - log.debug("get all data types failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - - @GET - @Path("interfaceLifecycleTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get interface lifecycle types", httpMethod = "GET", notes = "Returns interface lifecycle types", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Interface lifecycle types"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Interface lifecycle types not found") - }) - public Response getInterfaceLifecycleTypes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - - try { - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.info("Start handle request of {} | modifier id is {}", url, userId); - - Either, ResponseFormat> allInterfaceLifecycleTypes = - interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes(); - - if (allInterfaceLifecycleTypes.isRight()) { - log.info("Failed to get all interface lifecycle types. Reason - {}", - allInterfaceLifecycleTypes.right().value()); - Response errorResponse = buildErrorResponse(allInterfaceLifecycleTypes.right().value()); - responseWrapper.setInnerElement(errorResponse); - - } else { - String interfaceLifecycleTypeJson = gson.toJson(allInterfaceLifecycleTypes.left().value()); - Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), interfaceLifecycleTypeJson); - responseWrapper.setInnerElement(okResponse); - - } - } - - return responseWrapper.getInnerElement(); - } catch (Exception e) { - log.debug("get all interface lifecycle types failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - @GET - @Path("capabilityTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get capability types", httpMethod = "GET", notes = "Returns capability types", response = - Response.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "capabilityTypes"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Capability types not found")}) - public Response getAllCapabilityTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = - Constants.USER_ID_HEADER) String userId) { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - - try { - init(); - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); - - Either, ResponseFormat> allDataTypes = - capabilitiesBusinessLogic.getAllCapabilityTypes(); - - if (allDataTypes.isRight()) { - log.info("Failed to get all capability types. Reason - {}", allDataTypes.right().value()); - Response errorResponse = buildErrorResponse(allDataTypes.right().value()); - responseWrapper.setInnerElement(errorResponse); - - } else { - - Map dataTypes = allDataTypes.left().value(); - String dataTypeJson = gson.toJson(dataTypes); - Response okResponse = - buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson); - responseWrapper.setInnerElement(okResponse); - - } - } - - return responseWrapper.getInnerElement(); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Capability Types"); - log.debug("get all capability types failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - - @GET - @Path("relationshipTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get relationship types", httpMethod = "GET", notes = "Returns relationship types", response = - Response.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "relationshipTypes"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Relationship types not found")}) - public Response getAllRelationshipTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = - Constants.USER_ID_HEADER) String userId) { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - - try { - init(); - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); - - Either, ResponseFormat> allDataTypes = - relationshipTypeBusinessLogic.getAllRelationshipTypes(); - - if (allDataTypes.isRight()) { - log.info("Failed to get all relationship types. Reason - {}", allDataTypes.right().value()); - Response errorResponse = buildErrorResponse(allDataTypes.right().value()); - responseWrapper.setInnerElement(errorResponse); - - } else { - - Map dataTypes = allDataTypes.left().value(); - String dataTypeJson = gson.toJson(dataTypes); - Response okResponse = - buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson); - responseWrapper.setInnerElement(okResponse); - - } - } - - return responseWrapper.getInnerElement(); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Relationship Types"); - log.debug("get all relationship types failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - - @GET - @Path("nodeTypes") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Get node types", httpMethod = "GET", notes = "Returns node types", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 200, message = "nodeTypes"), @ApiResponse(code = 403, message = - "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 404, message = "Node types not found")}) - public Response getAllNodeTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = - Constants.USER_ID_HEADER) String userId) { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - ServletContext context = request.getSession().getServletContext(); - Either, Response> response; - Map componentMap; - - try { - init(); - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} | modifier id is {}", url, userId); - - response = getComponent(resourceBusinessLogic, true, userId); - if (response.isRight()) { - return response.right().value(); - } - componentMap = new HashMap<>(response.left().value()); - - response = getComponent(resourceBusinessLogic, false, userId); - if (response.isRight()) { - return response.right().value(); - } - componentMap.putAll(response.left().value()); - - String nodeTypesJson = gson.toJson(componentMap); - Response okResponse = - buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeTypesJson); - responseWrapper.setInnerElement(okResponse); - } - - return responseWrapper.getInnerElement(); - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Node Types"); - log.debug("get all node types failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - return buildErrorResponse(responseFormat); - } - } - - private Either, Response> getComponent(ComponentBusinessLogic resourceBL, boolean isAbstract, - String userId) { - Either, ResponseFormat> actionResponse; - List componentList; - - actionResponse = - resourceBL.getLatestVersionNotAbstractComponentsMetadata(isAbstract, HighestFilterEnum.HIGHEST_ONLY - , ComponentTypeEnum.RESOURCE, null, userId); - if (actionResponse.isRight()) { - log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, ComponentTypeEnum.RESOURCE.getValue()); - return Either.right(buildErrorResponse(actionResponse.right().value())); - } - - componentList = actionResponse.left().value(); - - return Either.left(ListUtils.emptyIfNull(componentList).stream() - .filter(component -> ((ResourceMetadataDataDefinition) component - .getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName() != null) - .collect(Collectors.toMap( - component -> ((ResourceMetadataDataDefinition) component - .getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName(), - component -> component, (component1, component2) -> component1))); - } -} +/*- + * ============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.servlets; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +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.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +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.collections4.ListUtils; +import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; +import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; +import org.openecomp.sdc.be.components.impl.RelationshipTypeBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.RelationshipTypeDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.exception.ResponseFormat; +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.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 = "Types Fetch Servlet",description = "Types Fetch Servlet")) +@Singleton +public class TypesFetchServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(TypesFetchServlet.class); + private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}"; + private final PropertyBusinessLogic propertyBusinessLogic; + private final RelationshipTypeBusinessLogic relationshipTypeBusinessLogic; + private final CapabilitiesBusinessLogic capabilitiesBusinessLogic; + private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; + private final ResourceBusinessLogic resourceBusinessLogic; + + @Inject + public TypesFetchServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + PropertyBusinessLogic propertyBusinessLogic, + RelationshipTypeBusinessLogic relationshipTypeBusinessLogic, + CapabilitiesBusinessLogic capabilitiesBusinessLogic, + InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, + ResourceBusinessLogic resourceBusinessLogic) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.propertyBusinessLogic = propertyBusinessLogic; + this.relationshipTypeBusinessLogic = relationshipTypeBusinessLogic; + this.capabilitiesBusinessLogic = capabilitiesBusinessLogic; + this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; + this.resourceBusinessLogic = resourceBusinessLogic; + } + + @GET + @Path("dataTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get data types", method = "GET", summary = "Returns data types", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "datatypes"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Data types not found")}) + public Response getAllDataTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + try { + init(); + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} | modifier id is {}", url, userId); + + Either, ResponseFormat> allDataTypes = + propertyBusinessLogic.getAllDataTypes(); + + if (allDataTypes.isRight()) { + log.info("Failed to get all dara types. Reason - {}", allDataTypes.right().value()); + Response errorResponse = buildErrorResponse(allDataTypes.right().value()); + responseWrapper.setInnerElement(errorResponse); + + } else { + + Map dataTypes = allDataTypes.left().value(); + String dataTypeJson = gson.toJson(dataTypes); + Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson); + responseWrapper.setInnerElement(okResponse); + + } + } + + return responseWrapper.getInnerElement(); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property"); + log.debug("get all data types failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + @GET + @Path("interfaceLifecycleTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get interface lifecycle types", method = "GET", summary = "Returns interface lifecycle types", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Interface lifecycle types"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Interface lifecycle types not found") + }) + public Response getInterfaceLifecycleTypes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + + try { + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.info("Start handle request of {} | modifier id is {}", url, userId); + + Either, ResponseFormat> allInterfaceLifecycleTypes = + interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes(); + + if (allInterfaceLifecycleTypes.isRight()) { + log.info("Failed to get all interface lifecycle types. Reason - {}", + allInterfaceLifecycleTypes.right().value()); + Response errorResponse = buildErrorResponse(allInterfaceLifecycleTypes.right().value()); + responseWrapper.setInnerElement(errorResponse); + + } else { + String interfaceLifecycleTypeJson = gson.toJson(allInterfaceLifecycleTypes.left().value()); + Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), interfaceLifecycleTypeJson); + responseWrapper.setInnerElement(okResponse); + + } + } + + return responseWrapper.getInnerElement(); + } catch (Exception e) { + log.debug("get all interface lifecycle types failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + @GET + @Path("capabilityTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get capability types", method = "GET", summary = "Returns capability types", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "capabilityTypes"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Capability types not found")}) + public Response getAllCapabilityTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = + Constants.USER_ID_HEADER) String userId) { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + + try { + init(); + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} | modifier id is {}", url, userId); + + Either, ResponseFormat> allDataTypes = + capabilitiesBusinessLogic.getAllCapabilityTypes(); + + if (allDataTypes.isRight()) { + log.info("Failed to get all capability types. Reason - {}", allDataTypes.right().value()); + Response errorResponse = buildErrorResponse(allDataTypes.right().value()); + responseWrapper.setInnerElement(errorResponse); + + } else { + + Map dataTypes = allDataTypes.left().value(); + String dataTypeJson = gson.toJson(dataTypes); + Response okResponse = + buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson); + responseWrapper.setInnerElement(okResponse); + + } + } + + return responseWrapper.getInnerElement(); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Capability Types"); + log.debug("get all capability types failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + @GET + @Path("relationshipTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get relationship types", method = "GET", summary = "Returns relationship types", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "relationshipTypes"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Relationship types not found")}) + public Response getAllRelationshipTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = + Constants.USER_ID_HEADER) String userId) { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + + try { + init(); + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} | modifier id is {}", url, userId); + + Either, ResponseFormat> allDataTypes = + relationshipTypeBusinessLogic.getAllRelationshipTypes(); + + if (allDataTypes.isRight()) { + log.info("Failed to get all relationship types. Reason - {}", allDataTypes.right().value()); + Response errorResponse = buildErrorResponse(allDataTypes.right().value()); + responseWrapper.setInnerElement(errorResponse); + + } else { + + Map dataTypes = allDataTypes.left().value(); + String dataTypeJson = gson.toJson(dataTypes); + Response okResponse = + buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson); + responseWrapper.setInnerElement(okResponse); + + } + } + + return responseWrapper.getInnerElement(); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Relationship Types"); + log.debug("get all relationship types failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + @GET + @Path("nodeTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Get node types", method = "GET", summary = "Returns node types", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "nodeTypes"), @ApiResponse(responseCode = "403", description = + "Restricted operation"), @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Node types not found")}) + public Response getAllNodeTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = + Constants.USER_ID_HEADER) String userId) { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + ServletContext context = request.getSession().getServletContext(); + Either, Response> response; + Map componentMap; + + try { + init(); + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} | modifier id is {}", url, userId); + + response = getComponent(resourceBusinessLogic, true, userId); + if (response.isRight()) { + return response.right().value(); + } + componentMap = new HashMap<>(response.left().value()); + + response = getComponent(resourceBusinessLogic, false, userId); + if (response.isRight()) { + return response.right().value(); + } + componentMap.putAll(response.left().value()); + + String nodeTypesJson = gson.toJson(componentMap); + Response okResponse = + buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeTypesJson); + responseWrapper.setInnerElement(okResponse); + } + + return responseWrapper.getInnerElement(); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Node Types"); + log.debug("get all node types failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + private Either, Response> getComponent(ComponentBusinessLogic resourceBL, boolean isAbstract, + String userId) { + Either, ResponseFormat> actionResponse; + List componentList; + + actionResponse = + resourceBL.getLatestVersionNotAbstractComponentsMetadata(isAbstract, HighestFilterEnum.HIGHEST_ONLY + , ComponentTypeEnum.RESOURCE, null, userId); + if (actionResponse.isRight()) { + log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, ComponentTypeEnum.RESOURCE.getValue()); + return Either.right(buildErrorResponse(actionResponse.right().value())); + } + + componentList = actionResponse.left().value(); + + return Either.left(ListUtils.emptyIfNull(componentList).stream() + .filter(component -> ((ResourceMetadataDataDefinition) component + .getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName() != null) + .collect(Collectors.toMap( + component -> ((ResourceMetadataDataDefinition) component + .getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName(), + component -> component, (component1, component2) -> component1))); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java index 0d0aa4e72d..5847a06e2b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java @@ -1,125 +1,136 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.servlets; - -import com.google.common.annotations.VisibleForTesting; -import com.jcabi.aspects.Loggable; -import io.swagger.annotations.*; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.openecomp.sdc.be.components.impl.CommonImportManager; -import org.openecomp.sdc.be.components.validation.AccessValidations; -import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -import org.openecomp.sdc.be.model.AnnotationTypeDefinition; -import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; -import org.openecomp.sdc.be.utils.TypeUtils; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; - -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * Here new APIs for types upload written in an attempt to gradually servlet code - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/uploadType") -@Consumes(MediaType.MULTIPART_FORM_DATA) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Catalog Types Upload") -@Controller -public class TypesUploadEndpoint { - - private final CommonImportManager commonImportManager; - private final AnnotationTypeOperations annotationTypeOperations; - private final AccessValidations accessValidations; - - public TypesUploadEndpoint(CommonImportManager commonImportManager, AnnotationTypeOperations annotationTypeOperations, AccessValidations accessValidations) { - this.commonImportManager = commonImportManager; - this.annotationTypeOperations = annotationTypeOperations; - this.accessValidations = accessValidations; - } - - @POST - @Path("/annotationtypes") - @ApiOperation(value = "Create AnnotationTypes from yaml", httpMethod = "POST", notes = "Returns created annotation types", response = Response.class) - @ApiResponses(value = { - @ApiResponse(code = 201, message = "annotation types created"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "annotation types already exist")}) - public Response uploadAnnotationTypes( - @ApiParam("FileInputStream") @FormDataParam("annotationTypesZip") File file, - @HeaderParam("USER_ID") String userId) throws IOException { - accessValidations.validateUserExists(userId, "Annotation Types Creation"); - Wrapper yamlStringWrapper = new Wrapper<>(); - AbstractValidationsServlet.extractZipContents(yamlStringWrapper, file); - List> typesResults = commonImportManager.createElementTypes(yamlStringWrapper.getInnerElement(), TypesUploadEndpoint::buildAnnotationFromFieldMap, annotationTypeOperations); - HttpStatus status = getHttpStatus(typesResults); - return Response.status(status.value()) - .entity(typesResults) - .build(); - } - - @VisibleForTesting - static HttpStatus getHttpStatus(List> typesResults) { - boolean typeActionFailed = false; - boolean typeExists = false; - boolean typeActionSucceeded = false; - for (ImmutablePair typeResult : typesResults) { - Boolean result = typeResult.getRight(); - if (result==null) { - typeExists = true; - } else if (result) { - typeActionSucceeded = true; - } else { - typeActionFailed = true; - } - } - HttpStatus status = HttpStatus.OK; - if (typeActionFailed) { - status = HttpStatus.BAD_REQUEST; - } else if (typeActionSucceeded) { - status = HttpStatus.CREATED; - } else if (typeExists) { - status = HttpStatus.CONFLICT; - } - return status; - } - - private static T buildAnnotationFromFieldMap(String typeName, Map toscaJson) { - AnnotationTypeDefinition annotationType = new AnnotationTypeDefinition(); - annotationType.setVersion(TypeUtils.getFirstCertifiedVersionVersion()); - annotationType.setHighestVersion(true); - annotationType.setType(typeName); - TypeUtils.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, annotationType::setDescription); - CommonImportManager.setProperties(toscaJson, annotationType::setProperties); - return (T) annotationType; - } - - -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 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.servlets; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.CommonImportManager; +import org.openecomp.sdc.be.components.validation.AccessValidations; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; +import org.openecomp.sdc.be.model.AnnotationTypeDefinition; +import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; +import org.openecomp.sdc.be.utils.TypeUtils; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import com.google.common.annotations.VisibleForTesting; +import com.jcabi.aspects.Loggable; +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; +/** + * Here new APIs for types upload written in an attempt to gradually servlet responseCode + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/uploadType") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Catalog Types Upload")) +@Controller +public class TypesUploadEndpoint { + + private final CommonImportManager commonImportManager; + private final AnnotationTypeOperations annotationTypeOperations; + private final AccessValidations accessValidations; + + public TypesUploadEndpoint(CommonImportManager commonImportManager, AnnotationTypeOperations annotationTypeOperations, AccessValidations accessValidations) { + this.commonImportManager = commonImportManager; + this.annotationTypeOperations = annotationTypeOperations; + this.accessValidations = accessValidations; + } + + @POST + @Path("/annotationtypes") + @Operation(description = "Create AnnotationTypes from yaml", method = "POST", + summary = "Returns created annotation types",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "annotation types created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "annotation types already exist")}) + + public Response uploadAnnotationTypes(@Parameter(description = "FileInputStream") @FormDataParam("annotationTypesZip") File file, + @HeaderParam("USER_ID") String userId) throws IOException { + accessValidations.validateUserExists(userId, "Annotation Types Creation"); + Wrapper yamlStringWrapper = new Wrapper<>(); + AbstractValidationsServlet.extractZipContents(yamlStringWrapper, file); + List> typesResults = + commonImportManager.createElementTypes(yamlStringWrapper.getInnerElement(), + TypesUploadEndpoint::buildAnnotationFromFieldMap, annotationTypeOperations); + HttpStatus status = getHttpStatus(typesResults); + return Response.status(status.value()).entity(typesResults).build(); + } + + @VisibleForTesting + static HttpStatus getHttpStatus(List> typesResults) { + boolean typeActionFailed = false; + boolean typeExists = false; + boolean typeActionSucceeded = false; + for (ImmutablePair typeResult : typesResults) { + Boolean result = typeResult.getRight(); + if (result==null) { + typeExists = true; + } else if (result) { + typeActionSucceeded = true; + } else { + typeActionFailed = true; + } + } + HttpStatus status = HttpStatus.OK; + if (typeActionFailed) { + status = HttpStatus.BAD_REQUEST; + } else if (typeActionSucceeded) { + status = HttpStatus.CREATED; + } else if (typeExists) { + status = HttpStatus.CONFLICT; + } + return status; + } + + private static T buildAnnotationFromFieldMap(String typeName, Map toscaJson) { + AnnotationTypeDefinition annotationType = new AnnotationTypeDefinition(); + annotationType.setVersion(TypeUtils.getFirstCertifiedVersionVersion()); + annotationType.setHighestVersion(true); + annotationType.setType(typeName); + TypeUtils.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, annotationType::setDescription); + CommonImportManager.setProperties(toscaJson, annotationType::setProperties); + return (T) annotationType; + } + + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java index e838dc9a93..d1eef493bb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java @@ -1,344 +1,407 @@ -/*- - * ============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.servlets; - -import com.google.gson.reflect.TypeToken; -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.openecomp.sdc.be.components.impl.*; -import org.openecomp.sdc.be.components.impl.model.ToscaTypeImportData; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.DataTypeDefinition; -import org.openecomp.sdc.be.model.GroupTypeDefinition; -import org.openecomp.sdc.be.model.PolicyTypeDefinition; -import org.openecomp.sdc.be.model.RelationshipTypeDefinition; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerTwoParam; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; -import org.springframework.stereotype.Controller; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/uploadType") -@Consumes(MediaType.MULTIPART_FORM_DATA) -@Produces(MediaType.APPLICATION_JSON) -@Api(value = "Catalog Types Upload") -@Controller -public class TypesUploadServlet extends AbstractValidationsServlet { - private static final Logger log = Logger.getLogger(TypesUploadServlet.class); - public static final String CREATE = "Create "; - - private final CapabilityTypeImportManager capabilityTypeImportManager; - private final InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager; - private final CategoriesImportManager categoriesImportManager; - private final DataTypeImportManager dataTypeImportManager; - private final GroupTypeImportManager groupTypeImportManager; - private final PolicyTypeImportManager policyTypeImportManager; - private final RelationshipTypeImportManager relationshipTypeImportManager; - - @Inject - public TypesUploadServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager, - CapabilityTypeImportManager capabilityTypeImportManager, - InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager, - CategoriesImportManager categoriesImportManager, - DataTypeImportManager dataTypeImportManager, - GroupTypeImportManager groupTypeImportManager, - PolicyTypeImportManager policyTypeImportManager, - RelationshipTypeImportManager relationshipTypeImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.capabilityTypeImportManager = capabilityTypeImportManager; - this.interfaceLifecycleTypeImportManager = interfaceLifecycleTypeImportManager; - this.categoriesImportManager = categoriesImportManager; - this.dataTypeImportManager = dataTypeImportManager; - this.groupTypeImportManager = groupTypeImportManager; - this.policyTypeImportManager = policyTypeImportManager; - this.relationshipTypeImportManager = relationshipTypeImportManager; - } - - @POST - @Path("/capability") - @ApiOperation(value = "Create Capability Type from yaml", httpMethod = "POST", notes = "Returns created Capability Type", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Capability Type created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Capability Type already exist") }) - public Response uploadCapabilityType(@ApiParam("FileInputStream") @FormDataParam("capabilityTypeZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { - ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload)); - return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.CapabilityType.name()); - } - - @POST - @Path("/relationship") - @ApiOperation(value = "Create Relationship Type from yaml", httpMethod = "POST", - notes = "Returns created Relationship Type", response = Response.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Relationship Type created"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Relationship Type already exist")}) - public Response uploadRelationshipType(@ApiParam("FileInputStream") @FormDataParam("relationshipTypeZip") File file, - @Context final HttpServletRequest request, - @HeaderParam("USER_ID") String creator) { - return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator, - NodeTypeEnum.RelationshipType.getName()); - } - - @POST - @Path("/interfaceLifecycle") - @ApiOperation(value = "Create Interface Lyfecycle Type from yaml", httpMethod = "POST", notes = "Returns created Interface Lifecycle Type", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Interface Lifecycle Type created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Interface Lifecycle Type already exist") }) - public Response uploadInterfaceLifecycleType(@ApiParam("FileInputStream") @FormDataParam("interfaceLifecycleTypeZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { - ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, () -> interfaceLifecycleTypeImportManager.createLifecycleTypes(ymlPayload)); - return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "Interface Types"); - } - - @POST - @Path("/categories") - @ApiOperation(value = "Create Categories from yaml", httpMethod = "POST", notes = "Returns created categories", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Categories created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Category already exist") }) - public Response uploadCategories(@ApiParam("FileInputStream") @FormDataParam("categoriesZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { - ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, () -> categoriesImportManager.createCategories(ymlPayload)); - return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "categories"); - } - - @POST - @Path("/datatypes") - @ApiOperation(value = "Create Categories from yaml", httpMethod = "POST", notes = "Returns created data types", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "Data types created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Data types already exist") }) - public Response uploadDataTypes(@ApiParam("FileInputStream") @FormDataParam("dataTypesZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { - ConsumerTwoParam, String> createElementsMethod = this::createDataTypes; - return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.DataType.getName()); - } - - @POST - @Path("/grouptypes") - @ApiOperation(value = "Create GroupTypes from yaml", httpMethod = "POST", notes = "Returns created group types", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "group types created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "group types already exist") }) - public Response uploadGroupTypes(@ApiParam("toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData, - @ApiParam("FileInputStream") @FormDataParam("groupTypesZip") File file, - @Context final HttpServletRequest request, - @HeaderParam("USER_ID") String creator) { - Map typesMetadata = getTypesMetadata(toscaTypesMetaData); - return uploadTypesWithMetaData(this::createGroupTypes, typesMetadata, file, request, creator, NodeTypeEnum.GroupType.getName()); - } - - @POST - @Path("/policytypes") - @ApiOperation(value = "Create PolicyTypes from yaml", httpMethod = "POST", notes = "Returns created policy types", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "policy types created"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "policy types already exist") }) - public Response uploadPolicyTypes( - @ApiParam("toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData, - @ApiParam("FileInputStream") @FormDataParam("policyTypesZip") File file, - @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { - Map typesMetadata = getTypesMetadata(toscaTypesMetaData); - return uploadTypesWithMetaData(this::createPolicyTypes, typesMetadata, file, request, creator, NodeTypeEnum.PolicyType.getName()); - } - - private Map getTypesMetadata(String toscaTypesMetaData) { - return gson.fromJson(toscaTypesMetaData, new TypeToken>(){}.getType()); - } - - private Response uploadElementTypeServletLogic(ConsumerTwoParam, String> createElementsMethod, File file, final HttpServletRequest request, String creator, String elementTypeName) { - init(); - String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER); - try { - Wrapper yamlStringWrapper = new Wrapper<>(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - Wrapper responseWrapper = doUploadTypeValidations(request, userId, file); - if (responseWrapper.isEmpty()) { - fillZipContents(yamlStringWrapper, file); - } - if (responseWrapper.isEmpty()) { - createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement()); - } - return responseWrapper.getInnerElement(); - } catch (Exception e) { - log.debug("create {} failed with exception:", elementTypeName, e); - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private Wrapper doUploadTypeValidations(final HttpServletRequest request, String userId, File file) { - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - validateUserExist(responseWrapper, userWrapper, userId); - - if (responseWrapper.isEmpty()) { - validateUserRole(responseWrapper, userWrapper.getInnerElement()); - } - - if (responseWrapper.isEmpty()) { - validateDataNotNull(responseWrapper, file); - } - return responseWrapper; - } - - private Response uploadTypesWithMetaData(ConsumerTwoParam, ToscaTypeImportData> createElementsMethod, Map typesMetaData, File file, final HttpServletRequest request, String creator, String elementTypeName) { - init(); - String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER); - Wrapper yamlStringWrapper = new Wrapper<>(); - try { - Wrapper responseWrapper = doUploadTypeValidations(request, userId, file); - if (responseWrapper.isEmpty()) { - fillZipContents(yamlStringWrapper, file); - } - if (responseWrapper.isEmpty()) { - ToscaTypeImportData toscaTypeImportData = new ToscaTypeImportData(yamlStringWrapper.getInnerElement(), typesMetaData); - createElementsMethod.accept(responseWrapper, toscaTypeImportData); - } - return responseWrapper.getInnerElement(); - } catch (Exception e) { - log.debug("create {} failed with exception:", elementTypeName, e); - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - private void createElementsType(Wrapper responseWrapper, Supplier> elementsCreater) { - Either eitherResult = elementsCreater.get(); - if (eitherResult.isRight()) { - Response response = buildErrorResponse(eitherResult.right().value()); - responseWrapper.setInnerElement(response); - } else { - try { - Response response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), RepresentationUtils.toRepresentation(eitherResult.left().value())); - responseWrapper.setInnerElement(response); - } catch (Exception e) { - Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - responseWrapper.setInnerElement(response); - log.error("#createElementsType - json serialization failed with error: ", e); - } - } - } - - // data types - private void createDataTypes(Wrapper responseWrapper, String dataTypesYml) { - final Supplier>, ResponseFormat>> generateElementTypeFromYml = () -> dataTypeImportManager.createDataTypes(dataTypesYml); - buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.DATA_TYPE_ALREADY_EXIST, NodeTypeEnum.DataType.name()); - } - - // group types - private void createGroupTypes(Wrapper responseWrapper, ToscaTypeImportData toscaTypeImportData) { - final Supplier>, ResponseFormat>> generateElementTypeFromYml = () -> groupTypeImportManager.createGroupTypes(toscaTypeImportData); - buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.GROUP_TYPE_ALREADY_EXIST, NodeTypeEnum.GroupType.name()); - } - - // policy types - private void createPolicyTypes(Wrapper responseWrapper, ToscaTypeImportData toscaTypeImportData) { - final Supplier>, ResponseFormat>> generateElementTypeFromYml = () -> policyTypeImportManager.createPolicyTypes(toscaTypeImportData); - buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.POLICY_TYPE_ALREADY_EXIST, NodeTypeEnum.PolicyType.name()); - } - - // data types - private void buildStatusForElementTypeCreate(Wrapper responseWrapper, Supplier>, ResponseFormat>> generateElementTypeFromYml, ActionStatus alreadyExistStatus, String elementTypeName) { - Either>, ResponseFormat> eitherResult = generateElementTypeFromYml.get(); - - if (eitherResult.isRight()) { - Response response = buildErrorResponse(eitherResult.right().value()); - responseWrapper.setInnerElement(response); - } else { - Object representation; - try { - List> list = eitherResult.left().value(); - ActionStatus status = ActionStatus.OK; - if (list != null) { - - // Group result by the right value - true or false. - // I.e., get the number of data types which are new and - // which are old. - Map>> collect = list.stream().collect(Collectors.groupingBy(ImmutablePair::getRight)); - if (collect != null) { - Set keySet = collect.keySet(); - if (keySet.size() == 1) { - Boolean isNew = keySet.iterator().next(); - if (isNew.booleanValue()) { - // all data types created at the first time - status = ActionStatus.CREATED; - } else { - // All data types already exists - - status = alreadyExistStatus; - } - } - } - } - representation = RepresentationUtils.toRepresentation(eitherResult.left().value()); - - Response response = buildOkResponse(getComponentsUtils().getResponseFormat(status), representation); - responseWrapper.setInnerElement(response); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName); - log.debug("failed to convert {} to json", elementTypeName, e); - Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - responseWrapper.setInnerElement(response); - } - } - } - // relationship types - private void createRelationshipTypes(Wrapper responseWrapper, String relationshipTypesYml) { - final Supplier>, ResponseFormat>> - generateElementTypeFromYml = - () -> relationshipTypeImportManager.createRelationshipTypes(relationshipTypesYml); - buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, - ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST, NodeTypeEnum.RelationshipType.name()); - } - -} +/*- + * ============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.servlets; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import javax.inject.Inject; +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.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.CapabilityTypeImportManager; +import org.openecomp.sdc.be.components.impl.CategoriesImportManager; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.DataTypeImportManager; +import org.openecomp.sdc.be.components.impl.GroupTypeImportManager; +import org.openecomp.sdc.be.components.impl.InterfaceLifecycleTypeImportManager; +import org.openecomp.sdc.be.components.impl.PolicyTypeImportManager; +import org.openecomp.sdc.be.components.impl.RelationshipTypeImportManager; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.model.ToscaTypeImportData; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.RelationshipTypeDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerTwoParam; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.stereotype.Controller; +import com.google.gson.reflect.TypeToken; +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/uploadType") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Catalog Types Upload")) +@Controller +public class TypesUploadServlet extends AbstractValidationsServlet { + private static final Logger log = Logger.getLogger(TypesUploadServlet.class); + public static final String CREATE = "Create "; + + private final CapabilityTypeImportManager capabilityTypeImportManager; + private final InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager; + private final CategoriesImportManager categoriesImportManager; + private final DataTypeImportManager dataTypeImportManager; + private final GroupTypeImportManager groupTypeImportManager; + private final PolicyTypeImportManager policyTypeImportManager; + private final RelationshipTypeImportManager relationshipTypeImportManager; + + @Inject + public TypesUploadServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager, + CapabilityTypeImportManager capabilityTypeImportManager, + InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager, + CategoriesImportManager categoriesImportManager, + DataTypeImportManager dataTypeImportManager, + GroupTypeImportManager groupTypeImportManager, + PolicyTypeImportManager policyTypeImportManager, + RelationshipTypeImportManager relationshipTypeImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.capabilityTypeImportManager = capabilityTypeImportManager; + this.interfaceLifecycleTypeImportManager = interfaceLifecycleTypeImportManager; + this.categoriesImportManager = categoriesImportManager; + this.dataTypeImportManager = dataTypeImportManager; + this.groupTypeImportManager = groupTypeImportManager; + this.policyTypeImportManager = policyTypeImportManager; + this.relationshipTypeImportManager = relationshipTypeImportManager; + } + + @POST + @Path("/capability") + @Operation(description = "Create Capability Type from yaml", method = "POST", + summary = "Returns created Capability Type", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Capability Type created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Capability Type already exist")}) + public Response uploadCapabilityType(@Parameter(description = "FileInputStream") @FormDataParam("capabilityTypeZip") File file, + @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + ConsumerTwoParam, String> createElementsMethod = + (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, + () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload)); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, + NodeTypeEnum.CapabilityType.name()); + } + + @POST + @Path("/relationship") + @Operation(description = "Create Relationship Type from yaml", method = "POST", + summary = "Returns created Relationship Type", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Relationship Type created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Relationship Type already exist")}) + public Response uploadRelationshipType(@Parameter(description = "FileInputStream") @FormDataParam("relationshipTypeZip") File file, + @Context final HttpServletRequest request, + @HeaderParam("USER_ID") String creator) { + return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator, + NodeTypeEnum.RelationshipType.getName()); + } + + @POST + @Path("/interfaceLifecycle") + @Operation(description = "Create Interface Lyfecycle Type from yaml", method = "POST", + summary = "Returns created Interface Lifecycle Type", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Interface Lifecycle Type created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Interface Lifecycle Type already exist")}) + public Response uploadInterfaceLifecycleType( + @Parameter(description = "FileInputStream") @FormDataParam("interfaceLifecycleTypeZip") File file, + @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + ConsumerTwoParam, String> createElementsMethod = + (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, + () -> interfaceLifecycleTypeImportManager.createLifecycleTypes(ymlPayload)); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "Interface Types"); + } + + @POST + @Path("/categories") + @Operation(description = "Create Categories from yaml", method = "POST", summary = "Returns created categories", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Categories created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Category already exist")}) + public Response uploadCategories(@Parameter(description = "FileInputStream") @FormDataParam("categoriesZip") File file, + @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + ConsumerTwoParam, String> createElementsMethod = + (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, + () -> categoriesImportManager.createCategories(ymlPayload)); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "categories"); + } + + @POST + @Path("/datatypes") + @Operation(description = "Create Categories from yaml", method = "POST", summary = "Returns created data types", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Data types created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Data types already exist")}) + public Response uploadDataTypes(@Parameter(description = "FileInputStream") @FormDataParam("dataTypesZip") File file, + @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + ConsumerTwoParam, String> createElementsMethod = this::createDataTypes; + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, + NodeTypeEnum.DataType.getName()); + } + + @POST + @Path("/grouptypes") + @Operation(description = "Create GroupTypes from yaml", method = "POST", summary = "Returns created group types", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "group types created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "group types already exist")}) + public Response uploadGroupTypes( + @Parameter(description = "toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData, + @Parameter(description = "FileInputStream") @FormDataParam("groupTypesZip") File file, + @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + Map typesMetadata = getTypesMetadata(toscaTypesMetaData); + return uploadTypesWithMetaData(this::createGroupTypes, typesMetadata, file, request, creator, + NodeTypeEnum.GroupType.getName()); + } + + @POST + @Path("/policytypes") + @Operation(description = "Create PolicyTypes from yaml", method = "POST", summary = "Returns created policy types", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "policy types created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "policy types already exist")}) + public Response uploadPolicyTypes( + @Parameter(description = "toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData, + @Parameter(description = "FileInputStream") @FormDataParam("policyTypesZip") File file, + @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + Map typesMetadata = getTypesMetadata(toscaTypesMetaData); + return uploadTypesWithMetaData(this::createPolicyTypes, typesMetadata, file, request, creator, + NodeTypeEnum.PolicyType.getName()); + } + + private Map getTypesMetadata(String toscaTypesMetaData) { + return gson.fromJson(toscaTypesMetaData, new TypeToken>(){}.getType()); + } + + private Response uploadElementTypeServletLogic(ConsumerTwoParam, String> createElementsMethod, File file, final HttpServletRequest request, String creator, String elementTypeName) { + init(); + String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER); + try { + Wrapper yamlStringWrapper = new Wrapper<>(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Wrapper responseWrapper = doUploadTypeValidations(request, userId, file); + if (responseWrapper.isEmpty()) { + fillZipContents(yamlStringWrapper, file); + } + if (responseWrapper.isEmpty()) { + createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement()); + } + return responseWrapper.getInnerElement(); + } catch (Exception e) { + log.debug("create {} failed with exception:", elementTypeName, e); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Wrapper doUploadTypeValidations(final HttpServletRequest request, String userId, File file) { + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + validateUserRole(responseWrapper, userWrapper.getInnerElement()); + } + + if (responseWrapper.isEmpty()) { + validateDataNotNull(responseWrapper, file); + } + return responseWrapper; + } + + private Response uploadTypesWithMetaData(ConsumerTwoParam, ToscaTypeImportData> createElementsMethod, Map typesMetaData, File file, final HttpServletRequest request, String creator, String elementTypeName) { + init(); + String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER); + Wrapper yamlStringWrapper = new Wrapper<>(); + try { + Wrapper responseWrapper = doUploadTypeValidations(request, userId, file); + if (responseWrapper.isEmpty()) { + fillZipContents(yamlStringWrapper, file); + } + if (responseWrapper.isEmpty()) { + ToscaTypeImportData toscaTypeImportData = new ToscaTypeImportData(yamlStringWrapper.getInnerElement(), typesMetaData); + createElementsMethod.accept(responseWrapper, toscaTypeImportData); + } + return responseWrapper.getInnerElement(); + } catch (Exception e) { + log.debug("create {} failed with exception:", elementTypeName, e); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private void createElementsType(Wrapper responseWrapper, Supplier> elementsCreater) { + Either eitherResult = elementsCreater.get(); + if (eitherResult.isRight()) { + Response response = buildErrorResponse(eitherResult.right().value()); + responseWrapper.setInnerElement(response); + } else { + try { + Response response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), RepresentationUtils.toRepresentation(eitherResult.left().value())); + responseWrapper.setInnerElement(response); + } catch (Exception e) { + Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(response); + log.error("#createElementsType - json serialization failed with error: ", e); + } + } + } + + // data types + private void createDataTypes(Wrapper responseWrapper, String dataTypesYml) { + final Supplier>, ResponseFormat>> generateElementTypeFromYml = + () -> dataTypeImportManager.createDataTypes(dataTypesYml); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, + ActionStatus.DATA_TYPE_ALREADY_EXIST, NodeTypeEnum.DataType.name()); + } + + // group types + private void createGroupTypes(Wrapper responseWrapper, ToscaTypeImportData toscaTypeImportData) { + final Supplier>, ResponseFormat>> generateElementTypeFromYml = + () -> groupTypeImportManager.createGroupTypes(toscaTypeImportData); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, + ActionStatus.GROUP_TYPE_ALREADY_EXIST, NodeTypeEnum.GroupType.name()); + } + + // policy types + private void createPolicyTypes(Wrapper responseWrapper, ToscaTypeImportData toscaTypeImportData) { + final Supplier>, ResponseFormat>> generateElementTypeFromYml = + () -> policyTypeImportManager.createPolicyTypes(toscaTypeImportData); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, + ActionStatus.POLICY_TYPE_ALREADY_EXIST, NodeTypeEnum.PolicyType.name()); + } + + // data types + private void buildStatusForElementTypeCreate(Wrapper responseWrapper, Supplier>, ResponseFormat>> generateElementTypeFromYml, ActionStatus alreadyExistStatus, String elementTypeName) { + Either>, ResponseFormat> eitherResult = generateElementTypeFromYml.get(); + + if (eitherResult.isRight()) { + Response response = buildErrorResponse(eitherResult.right().value()); + responseWrapper.setInnerElement(response); + } else { + Object representation; + try { + List> list = eitherResult.left().value(); + ActionStatus status = ActionStatus.OK; + if (list != null) { + + // Group result by the right value - true or false. + // I.e., get the number of data types which are new and + // which are old. + Map>> collect = list.stream().collect(Collectors.groupingBy(ImmutablePair::getRight)); + if (collect != null) { + Set keySet = collect.keySet(); + if (keySet.size() == 1) { + Boolean isNew = keySet.iterator().next(); + if (isNew.booleanValue()) { + // all data types created at the first time + status = ActionStatus.CREATED; + } else { + // All data types already exists + + status = alreadyExistStatus; + } + } + } + } + representation = RepresentationUtils.toRepresentation(eitherResult.left().value()); + + Response response = buildOkResponse(getComponentsUtils().getResponseFormat(status), representation); + responseWrapper.setInnerElement(response); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName); + log.debug("failed to convert {} to json", elementTypeName, e); + Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(response); + } + } + } + // relationship types + private void createRelationshipTypes(Wrapper responseWrapper, String relationshipTypesYml) { + final Supplier>, ResponseFormat>> + generateElementTypeFromYml = + () -> relationshipTypeImportManager.createRelationshipTypes(relationshipTypesYml); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, + ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST, NodeTypeEnum.RelationshipType.name()); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java index 328b4a9874..15646c26c0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java @@ -1,387 +1,455 @@ -/*- - * ============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.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import io.swagger.annotations.*; -import javax.inject.Inject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; - -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.List; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/user") -@Api(value = "User Administration", description = "User admininstarator operations") -@Singleton -public class UserAdminServlet extends BeGenericServlet { - - private static final String UTF_8 = "UTF-8"; - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; - private static final String ROLE_DELIMITER = ","; - private static final Logger log = Logger.getLogger(UserAdminServlet.class); - private final UserBusinessLogic userBusinessLogic; - - @Inject - public UserAdminServlet(UserBusinessLogic userBusinessLogic, - ComponentsUtils componentsUtils) { - super(userBusinessLogic, componentsUtils); - this.userBusinessLogic = userBusinessLogic; - } - - /*************************************** - * API start - *************************************************************/ - - /* User by userId CRUD start */ - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // retrieve all user details - @GET - @Path("/{userId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "retrieve user details", httpMethod = "GET", notes = "Returns user details according to userId", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response get(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - - try { - Either either = userBusinessLogic.getUser(userId, false); - - if (either.isRight()) { - return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); - } else { - if (either.left().value() != null) { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } else { - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User"); - log.debug("get user failed with unexpected error: {}", e.getMessage(), e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/{userId}/role") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "retrieve user role", notes = "Returns user role according to userId", response = String.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user role Ok"), @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), - @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getRole(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(getRole) Start handle request of {}", url); - - try { - Either either = userBusinessLogic.getUser(userId, false); - if (either.isRight()) { - return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); - } else { - if (either.left().value() != null) { - String roleJson = "{ \"role\" : \"" + either.left().value().getRole() + "\" }"; - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), roleJson); - } else { - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User Role"); - log.debug("Get user role failed with unexpected error: {}", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // update user role - @POST - @Path("/{userId}/role") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "update user role", notes = "Update user role", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Update user OK"), @ApiResponse(code = 400, message = "Invalid Content."), @ApiResponse(code = 403, message = "Missing information/Restricted operation"), - @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 409, message = "User already exists"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response updateUserRole(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userIdUpdateUser, @Context final HttpServletRequest request, - @ApiParam(value = "json describe the update role", required = true) String data, @HeaderParam(value = Constants.USER_ID_HEADER) String modifierUserId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(modifierUserId); - log.debug("modifier id is {}", modifierUserId); - - Response response = null; - - try { - User updateInfoUser = getComponentsUtils().convertJsonToObject(data, modifier, User.class, AuditingActionEnum.UPDATE_USER).left().value(); - Either updateUserResponse = userBusinessLogic.updateUserRole(modifier, userIdUpdateUser, updateInfoUser.getRole()); - - if (updateUserResponse.isRight()) { - log.debug("failed to update user role"); - response = buildErrorResponse(updateUserResponse.right().value()); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateUserResponse.left().value()); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update User Metadata"); - log.debug("Update User Role failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - /* User role CRUD end */ - - /* New user CRUD start */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "add user", httpMethod = "POST", notes = "Provision new user", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 201, message = "New user created"), @ApiResponse(code = 400, message = "Invalid Content."), @ApiResponse(code = 403, message = "Missing information"), - @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 409, message = "User already exists"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response createUser(@Context final HttpServletRequest request, @ApiParam(value = "json describe the user", required = true) String newUserData, @HeaderParam(value = Constants.USER_ID_HEADER) String modifierAttId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(modifierAttId); - log.debug("modifier id is {}", modifierAttId); - - Response response = null; - - try { - User newUserInfo = getComponentsUtils().convertJsonToObject(newUserData, modifier, User.class, AuditingActionEnum.ADD_USER).left().value(); - Either createUserResponse = userBusinessLogic.createUser(modifier, newUserInfo); - - if (createUserResponse.isRight()) { - log.debug("failed to create user"); - response = buildErrorResponse(createUserResponse.right().value()); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), createUserResponse.left().value()); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update User Metadata"); - log.debug("Create User failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - /* New user CRUD end */ - - /* User authorization start */ - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // User Authorization - @GET - @Path("/authorize") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - - @ApiOperation(value = "authorize", notes = "authorize user", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 403, message = "Restricted Access"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response authorize(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam("HTTP_CSP_FIRSTNAME") String firstName, @HeaderParam("HTTP_CSP_LASTNAME") String lastName, - @HeaderParam("HTTP_CSP_EMAIL") String email) { - - try { - userId = userId != null ? URLDecoder.decode(userId, UTF_8) : null; - firstName = firstName != null ? URLDecoder.decode(firstName, UTF_8) : null; - lastName = lastName != null ? URLDecoder.decode(lastName, UTF_8) : null; - email = email != null ? URLDecoder.decode(email, UTF_8) : null; - } catch (UnsupportedEncodingException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Authorize User - decode headers"); - ResponseFormat errorResponseWrapper = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - log.error("#authorize - authorization decoding failed with error: ", e); - return buildErrorResponse(errorResponseWrapper); - } - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug(START_HANDLE_REQUEST_OF, url); - - User authUser = new User(); - authUser.setUserId(userId); - authUser.setFirstName(firstName); - authUser.setLastName(lastName); - authUser.setEmail(email); - log.debug("auth user id is {}", userId); - - Response response = null; - try { - Either authorize = userBusinessLogic.authorize(authUser); - - if (authorize.isRight()) { - log.debug("authorize user failed"); - response = buildErrorResponse(authorize.right().value()); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), authorize.left().value()); - return response; - - } catch (Exception e) { - log.debug("authorize user failed with unexpected error: {}", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /* User authorization end */ - - @GET - @Path("/admins") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "retrieve all administrators", httpMethod = "GET", notes = "Returns all administrators", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getAdminsUser(@Context final HttpServletRequest request) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); - - try { - Either, ResponseFormat> either = userBusinessLogic.getAllAdminUsers(); - - if (either.isRight()) { - log.debug("Failed to get all admin users"); - return buildErrorResponse(either.right().value()); - } else { - if (either.left().value() != null) { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } else { - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Administrators"); - log.debug("get all admins failed with unexpected error: {}", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/users") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve the list of all active ASDC users or only group of users having specific roles.", httpMethod = "GET", notes = "Returns list of users with the specified roles, or all of users in the case of empty 'roles' header", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns users Ok"), @ApiResponse(code = 204, message = "No provisioned ASDC users of requested role"), @ApiResponse(code = 403, message = "Restricted Access"), - @ApiResponse(code = 400, message = "Missing content"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response getUsersList(@Context final HttpServletRequest request, @ApiParam(value = "Any active user's USER_ID ") @HeaderParam(Constants.USER_ID_HEADER) final String userId, - @ApiParam(value = "TESTER,DESIGNER,PRODUCT_STRATEGIST,OPS,PRODUCT_MANAGER,GOVERNOR, ADMIN OR all users by not typing anything") @QueryParam("roles") final String roles) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} modifier id is {}", url, userId); - - List rolesList = new ArrayList<>(); - if (roles != null && !roles.trim().isEmpty()) { - String[] rolesArr = roles.split(ROLE_DELIMITER); - for (String role : rolesArr) { - rolesList.add(role.trim()); - } - } - - try { - Either, ResponseFormat> either = userBusinessLogic.getUsersList(userId, rolesList, roles); - - if (either.isRight()) { - log.debug("Failed to get ASDC users"); - return buildErrorResponse(either.right().value()); - } else { - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); - } - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get ASDC users"); - log.debug("get users failed with unexpected error: {}", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // delete user - @DELETE - @Path("/{userId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "delete user", notes = "Delete user", response = User.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Update deleted OK"), @ApiResponse(code = 400, message = "Invalid Content."), @ApiResponse(code = 403, message = "Missing information"), - @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 500, message = "Internal Server Error") }) - public Response deActivateUser(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userIdHeader) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {} modifier id is {}", url, userIdHeader); - - User modifier = new User(); - modifier.setUserId(userIdHeader); - - Response response = null; - try { - Either deactiveUserResponse = userBusinessLogic.deActivateUser(modifier, userId); - - if (deactiveUserResponse.isRight()) { - log.debug("Failed to deactivate user"); - response = buildErrorResponse(deactiveUserResponse.right().value()); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deactiveUserResponse.left().value()); - return response; - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get ASDC users"); - log.debug("deactivate user failed with unexpected error: {}", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } -} +/*- + * ============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.servlets; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +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.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +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/user") +@OpenAPIDefinition(info = @Info(title = "User Administration", description = "User admininstarator operations")) +@Singleton +public class UserAdminServlet extends BeGenericServlet { + + private static final String UTF_8 = "UTF-8"; + private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + private static final String ROLE_DELIMITER = ","; + private static final Logger log = Logger.getLogger(UserAdminServlet.class); + private final UserBusinessLogic userBusinessLogic; + + @Inject + public UserAdminServlet(UserBusinessLogic userBusinessLogic, + ComponentsUtils componentsUtils) { + super(userBusinessLogic, componentsUtils); + this.userBusinessLogic = userBusinessLogic; + } + + /*************************************** + * API start + *************************************************************/ + + /* User by userId CRUD start */ + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all user details + @GET + @Path("/{userId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "retrieve user details", method = "GET", + summary = "Returns user details according to userId",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns user Ok"), + @ApiResponse(responseCode = "404", description = "User not found"), + @ApiResponse(responseCode = "405", description = "Method Not Allowed"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response get( + @Parameter(description = "userId of user to get", required = true) @PathParam("userId") final String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + + try { + Either either = userBusinessLogic.getUser(userId, false); + + if (either.isRight()) { + return buildErrorResponse( + getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); + } else { + if (either.left().value() != null) { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + either.left().value()); + } else { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User"); + log.debug("get user failed with unexpected error: {}", e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/{userId}/role") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "retrieve user role", summary = "Returns user role according to userId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns user role Ok"), + @ApiResponse(responseCode = "404", description = "User not found"), + @ApiResponse(responseCode = "405", description = "Method Not Allowed"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getRole( + @Parameter(description = "userId of user to get", required = true) @PathParam("userId") final String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getRole) Start handle request of {}", url); + + try { + Either either = userBusinessLogic.getUser(userId, false); + if (either.isRight()) { + return buildErrorResponse( + getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); + } else { + if (either.left().value() != null) { + String roleJson = "{ \"role\" : \"" + either.left().value().getRole() + "\" }"; + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), roleJson); + } else { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User Role"); + log.debug("Get user role failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // update user role + @POST + @Path("/{userId}/role") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "update user role", summary = "Update user role", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Update user OK"), + @ApiResponse(responseCode = "400", description = "Invalid Content."), + @ApiResponse(responseCode = "403", description = "Missing information/Restricted operation"), + @ApiResponse(responseCode = "404", description = "User not found"), + @ApiResponse(responseCode = "405", description = "Method Not Allowed"), + @ApiResponse(responseCode = "409", description = "User already exists"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response updateUserRole( + @Parameter(description = "userId of user to get", + required = true) @PathParam("userId") final String userIdUpdateUser, + @Context final HttpServletRequest request, + @Parameter(description = "json describe the update role", required = true) String data, + @HeaderParam(value = Constants.USER_ID_HEADER) String modifierUserId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(modifierUserId); + log.debug("modifier id is {}", modifierUserId); + + Response response = null; + + try { + User updateInfoUser = getComponentsUtils().convertJsonToObject(data, modifier, User.class, AuditingActionEnum.UPDATE_USER).left().value(); + Either updateUserResponse = userBusinessLogic.updateUserRole(modifier, userIdUpdateUser, updateInfoUser.getRole()); + + if (updateUserResponse.isRight()) { + log.debug("failed to update user role"); + response = buildErrorResponse(updateUserResponse.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateUserResponse.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update User Metadata"); + log.debug("Update User Role failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /* User role CRUD end */ + + /* New user CRUD start */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "add user", method = "POST", summary = "Provision new user", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "New user created"), + @ApiResponse(responseCode = "400", description = "Invalid Content."), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "405", description = "Method Not Allowed"), + @ApiResponse(responseCode = "409", description = "User already exists"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response createUser(@Context final HttpServletRequest request, + @Parameter(description = "json describe the user", required = true) String newUserData, + @HeaderParam(value = Constants.USER_ID_HEADER) String modifierAttId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(modifierAttId); + log.debug("modifier id is {}", modifierAttId); + + Response response = null; + + try { + User newUserInfo = getComponentsUtils().convertJsonToObject(newUserData, modifier, User.class, AuditingActionEnum.ADD_USER).left().value(); + Either createUserResponse = userBusinessLogic.createUser(modifier, newUserInfo); + + if (createUserResponse.isRight()) { + log.debug("failed to create user"); + response = buildErrorResponse(createUserResponse.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), createUserResponse.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update User Metadata"); + log.debug("Create User failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /* New user CRUD end */ + + /* User authorization start */ + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // User Authorization + @GET + @Path("/authorize") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + + @Operation(description = "authorize", summary = "authorize user", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returns user Ok"), @ApiResponse(responseCode = "403", description = "Restricted Access"), @ApiResponse(responseCode = "500", description = "Internal Server Error") }) + public Response authorize(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam("HTTP_CSP_FIRSTNAME") String firstName, @HeaderParam("HTTP_CSP_LASTNAME") String lastName, + @HeaderParam("HTTP_CSP_EMAIL") String email) { + + try { + userId = userId != null ? URLDecoder.decode(userId, UTF_8) : null; + firstName = firstName != null ? URLDecoder.decode(firstName, UTF_8) : null; + lastName = lastName != null ? URLDecoder.decode(lastName, UTF_8) : null; + email = email != null ? URLDecoder.decode(email, UTF_8) : null; + } catch (UnsupportedEncodingException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Authorize User - decode headers"); + ResponseFormat errorResponseWrapper = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + log.error("#authorize - authorization decoding failed with error: ", e); + return buildErrorResponse(errorResponseWrapper); + } + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + User authUser = new User(); + authUser.setUserId(userId); + authUser.setFirstName(firstName); + authUser.setLastName(lastName); + authUser.setEmail(email); + log.debug("auth user id is {}", userId); + + Response response = null; + try { + Either authorize = userBusinessLogic.authorize(authUser); + + if (authorize.isRight()) { + log.debug("authorize user failed"); + response = buildErrorResponse(authorize.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), authorize.left().value()); + return response; + + } catch (Exception e) { + log.debug("authorize user failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /* User authorization end */ + + @GET + @Path("/admins") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "retrieve all administrators", method = "GET", summary = "Returns all administrators", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns user Ok"), + @ApiResponse(responseCode = "405", description = "Method Not Allowed"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getAdminsUser(@Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + + try { + Either, ResponseFormat> either = userBusinessLogic.getAllAdminUsers(); + + if (either.isRight()) { + log.debug("Failed to get all admin users"); + return buildErrorResponse(either.right().value()); + } else { + if (either.left().value() != null) { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + either.left().value()); + } else { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Administrators"); + log.debug("get all admins failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/users") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve the list of all active ASDC users or only group of users having specific roles.", + method = "GET", + summary = "Returns list of users with the specified roles, or all of users in the case of empty 'roles' header", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Returns users Ok"), + @ApiResponse(responseCode = "204", description = "No provisioned ASDC users of requested role"), + @ApiResponse(responseCode = "403", description = "Restricted Access"), + @ApiResponse(responseCode = "400", description = "Missing content"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response getUsersList(@Context final HttpServletRequest request, @Parameter( + description = "Any active user's USER_ID ") @HeaderParam(Constants.USER_ID_HEADER) final String userId, + @Parameter( + description = "TESTER,DESIGNER,PRODUCT_STRATEGIST,OPS,PRODUCT_MANAGER,GOVERNOR, ADMIN OR all users by not typing anything") @QueryParam("roles") final String roles) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} modifier id is {}", url, userId); + + List rolesList = new ArrayList<>(); + if (roles != null && !roles.trim().isEmpty()) { + String[] rolesArr = roles.split(ROLE_DELIMITER); + for (String role : rolesArr) { + rolesList.add(role.trim()); + } + } + + try { + Either, ResponseFormat> either = userBusinessLogic.getUsersList(userId, rolesList, roles); + + if (either.isRight()) { + log.debug("Failed to get ASDC users"); + return buildErrorResponse(either.right().value()); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get ASDC users"); + log.debug("get users failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // delete user + @DELETE + @Path("/{userId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "delete user", summary = "Delete user", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Update deleted OK"), + @ApiResponse(responseCode = "400", description = "Invalid Content."), + @ApiResponse(responseCode = "403", description = "Missing information"), + @ApiResponse(responseCode = "404", description = "User not found"), + @ApiResponse(responseCode = "405", description = "Method Not Allowed"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "500", description = "Internal Server Error")}) + public Response deActivateUser( + @Parameter(description = "userId of user to get", required = true) @PathParam("userId") final String userId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userIdHeader) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {} modifier id is {}", url, userIdHeader); + + User modifier = new User(); + modifier.setUserId(userIdHeader); + + Response response = null; + try { + Either deactiveUserResponse = userBusinessLogic.deActivateUser(modifier, userId); + + if (deactiveUserResponse.isRight()) { + log.debug("Failed to deactivate user"); + response = buildErrorResponse(deactiveUserResponse.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deactiveUserResponse.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get ASDC users"); + log.debug("deactivate user failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } +} -- cgit 1.2.3-korg