diff options
Diffstat (limited to 'vid-app-common/src/main/java')
39 files changed, 835 insertions, 358 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/OperationalEnvironment.java b/vid-app-common/src/main/java/org/onap/vid/aai/OperationalEnvironment.java index be6c6e51f..71ed1713a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/OperationalEnvironment.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/OperationalEnvironment.java @@ -3,13 +3,14 @@ * VID * ================================================================================ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Nokia. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,37 +21,83 @@ package org.onap.vid.aai; -import org.onap.vid.aai.model.RelationshipList; +import static com.fasterxml.jackson.annotation.JsonProperty.Access.WRITE_ONLY; + +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import org.onap.vid.aai.model.RelationshipList; @JsonIgnoreProperties(ignoreUnknown = true) -public class OperationalEnvironment { - - private String operationalEnvironmentId; - private String operationalEnvironmentName; - private String operationalEnvironmentType; - private String operationalEnvironmentStatus; - private String tenantContext; - private String workloadContext; - private String resourceVersion; - private RelationshipList relationshipList; - - public OperationalEnvironment() { +public final class OperationalEnvironment { + + private final String operationalEnvironmentId; + private final String operationalEnvironmentName; + private final String operationalEnvironmentType; + private final String operationalEnvironmentStatus; + private final String tenantContext; + private final String workloadContext; + private final String resourceVersion; + private final RelationshipList relationshipList; + + public static OperationalEnvironmentBuilder builder() { + return new OperationalEnvironmentBuilder(); + } + + @JsonCreator + OperationalEnvironment( + @JsonProperty(value = "operational-environment-id", access = WRITE_ONLY) String operationalEnvironmentId, + @JsonProperty(value = "operational-environment-name", access = WRITE_ONLY) String operationalEnvironmentName, + @JsonProperty(value = "operational-environment-type", access = WRITE_ONLY) String operationalEnvironmentType, + @JsonProperty(value = "operational-environment-status", access = WRITE_ONLY) String operationalEnvironmentStatus, + @JsonProperty(value = "tenant-context", access = WRITE_ONLY) String tenantContext, + @JsonProperty(value = "workload-context", access = WRITE_ONLY) String workloadContext, + @JsonProperty(value = "resource-version", access = WRITE_ONLY) String resourceVersion, + @JsonProperty(value = "relationship-list", access = WRITE_ONLY) RelationshipList relationshipList) { + this.operationalEnvironmentId = operationalEnvironmentId; + this.operationalEnvironmentName = operationalEnvironmentName; + this.operationalEnvironmentType = operationalEnvironmentType; + this.operationalEnvironmentStatus = operationalEnvironmentStatus; + this.tenantContext = tenantContext; + this.workloadContext = workloadContext; + this.resourceVersion = resourceVersion; + this.relationshipList = relationshipList; } - public OperationalEnvironment(OperationalEnvironmentBuilder builder) { - this.operationalEnvironmentId = builder.operationalEnvironmentId; - this.operationalEnvironmentName = builder.operationalEnvironmentName; - this.operationalEnvironmentType = builder.operationalEnvironmentType; - this.operationalEnvironmentStatus = builder.operationalEnvironmentStatus; - this.tenantContext = builder.tenantContext; - this.workloadContext = builder.workloadContext; - this.resourceVersion = builder.resourceVersion; - this.relationshipList = builder.relationshipList; + public String getOperationalEnvironmentId() { + return operationalEnvironmentId; + } + + public String getOperationalEnvironmentName() { + return operationalEnvironmentName; + } + + public String getOperationalEnvironmentType() { + return operationalEnvironmentType; + } + + public String getOperationalEnvironmentStatus() { + return operationalEnvironmentStatus; + } + + public String getTenantContext() { + return tenantContext; + } + + public String getWorkloadContext() { + return workloadContext; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public RelationshipList getRelationshipList() { + return relationshipList; } public static class OperationalEnvironmentBuilder { + private String operationalEnvironmentId; private String operationalEnvironmentName; private String operationalEnvironmentType; @@ -58,127 +105,65 @@ public class OperationalEnvironment { private String tenantContext; private String workloadContext; private String resourceVersion; + private RelationshipList relationshipList; - public OperationalEnvironmentBuilder setOperationalEnvironmentId( - String operationalEnvironmentId) { + public OperationalEnvironmentBuilder withOperationalEnvironmentId( + String operationalEnvironmentId) { this.operationalEnvironmentId = operationalEnvironmentId; return this; } - public OperationalEnvironmentBuilder setOperationalEnvironmentName( - String operationalEnvironmentName) { + public OperationalEnvironmentBuilder withOperationalEnvironmentName( + String operationalEnvironmentName) { this.operationalEnvironmentName = operationalEnvironmentName; return this; } - public OperationalEnvironmentBuilder setOperationalEnvironmentType( - String operationalEnvironmentType) { + public OperationalEnvironmentBuilder withOperationalEnvironmentType( + String operationalEnvironmentType) { this.operationalEnvironmentType = operationalEnvironmentType; return this; } - public OperationalEnvironmentBuilder setOperationalEnvironmentStatus( - String operationalEnvironmentStatus) { + public OperationalEnvironmentBuilder withOperationalEnvironmentStatus( + String operationalEnvironmentStatus) { this.operationalEnvironmentStatus = operationalEnvironmentStatus; return this; } - public OperationalEnvironmentBuilder setTenantContext(String tenantContext) { + public OperationalEnvironmentBuilder withTenantContext(String tenantContext) { this.tenantContext = tenantContext; return this; } - public OperationalEnvironmentBuilder setWorkloadContext(String workloadContext) { + public OperationalEnvironmentBuilder withWorkloadContext(String workloadContext) { this.workloadContext = workloadContext; return this; } - public OperationalEnvironmentBuilder setResourceVersion(String resourceVersion) { + public OperationalEnvironmentBuilder withResourceVersion(String resourceVersion) { this.resourceVersion = resourceVersion; return this; } - public OperationalEnvironmentBuilder setRelationshipList( - RelationshipList relationshipList) { + public OperationalEnvironmentBuilder withRelationshipList( + RelationshipList relationshipList) { this.relationshipList = relationshipList; return this; } - public OperationalEnvironment createOperationalEnvironment() { - return new OperationalEnvironment(this); + public OperationalEnvironment build() { + return new OperationalEnvironment(operationalEnvironmentId, + operationalEnvironmentName, + operationalEnvironmentType, + operationalEnvironmentStatus, + tenantContext, + workloadContext, + resourceVersion, + relationshipList); } - } - - public String getOperationalEnvironmentId() { - return operationalEnvironmentId; - } - @JsonProperty("operational-environment-id") - public void setJsonOperationalEnvironmentId(String operationalEnvironmentId) { - this.operationalEnvironmentId = operationalEnvironmentId; } - public String getOperationalEnvironmentName() { - return operationalEnvironmentName; - } - - @JsonProperty("operational-environment-name") - public void setJsonOperationalEnvironmentName(String operationalEnvironmentName) { - this.operationalEnvironmentName = operationalEnvironmentName; - } - - public String getOperationalEnvironmentType() { - return operationalEnvironmentType; - } - - @JsonProperty("operational-environment-type") - public void setJsonOperationalEnvironmentType(String operationalEnvironmentType) { - this.operationalEnvironmentType = operationalEnvironmentType; - } - - public String getOperationalEnvironmentStatus() { - return operationalEnvironmentStatus; - } - - @JsonProperty("operational-environment-status") - public void setJsonOperationalEnvironmentStatus(String operationalEnvironmentStatus) { - this.operationalEnvironmentStatus = operationalEnvironmentStatus; - } - - public String getTenantContext() { - return tenantContext; - } - - @JsonProperty("tenant-context") - public void setJsonTenantContext(String tenantContext) { - this.tenantContext = tenantContext; - } - - public String getWorkloadContext() { - return workloadContext; - } - - @JsonProperty("workload-context") - public void setJsonWorkloadContext(String workloadContext) { - this.workloadContext = workloadContext; - } - - public String getResourceVersion() { - return resourceVersion; - } - - @JsonProperty("resource-version") - public void setJsonResourceVersion(String resourceVersion) { - this.resourceVersion = resourceVersion; - } - - public RelationshipList getRelationshipList() { - return relationshipList; - } - - @JsonProperty("relationship-list") - public void setJsonRelationshipList(RelationshipList relationshipList) { - this.relationshipList = relationshipList; - } } diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/model/AaiGetOperationalEnvironments/OperationalEnvironmentList.java b/vid-app-common/src/main/java/org/onap/vid/aai/model/AaiGetOperationalEnvironments/OperationalEnvironmentList.java index 13c6ada2d..6b3fbbd64 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/model/AaiGetOperationalEnvironments/OperationalEnvironmentList.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/model/AaiGetOperationalEnvironments/OperationalEnvironmentList.java @@ -3,13 +3,14 @@ * VID * ================================================================================ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Nokia. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,30 +21,27 @@ package org.onap.vid.aai.model.AaiGetOperationalEnvironments; -import com.fasterxml.jackson.annotation.JsonAlias; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.onap.vid.aai.OperationalEnvironment; +import static com.fasterxml.jackson.annotation.JsonProperty.Access.WRITE_ONLY; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Collections; import java.util.List; +import org.onap.vid.aai.OperationalEnvironment; @JsonIgnoreProperties(ignoreUnknown = true) -public class OperationalEnvironmentList { - - public List<OperationalEnvironment> getOperationalEnvironment() { - return operationalEnvironment; - } +public final class OperationalEnvironmentList { - @JsonAlias("operational-environment") - public void setOperationalEnvironment(List<OperationalEnvironment> operationalEnvironment) { - this.operationalEnvironment = operationalEnvironment; - } + private final List<OperationalEnvironment> operationalEnvironment; - public OperationalEnvironmentList() { + @JsonCreator + public OperationalEnvironmentList( + @JsonProperty(value = "operational-environment", access = WRITE_ONLY) List<OperationalEnvironment> operationalEnvironment) { + this.operationalEnvironment = Collections.unmodifiableList(operationalEnvironment); } - public OperationalEnvironmentList(List<OperationalEnvironment> operationalEnvironment) { - this.operationalEnvironment = operationalEnvironment; + public List<OperationalEnvironment> getOperationalEnvironment() { + return operationalEnvironment; } - - private List<OperationalEnvironment> operationalEnvironment; } diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/util/AAITreeConverter.java b/vid-app-common/src/main/java/org/onap/vid/aai/util/AAITreeConverter.java index 48736bc01..111a260e1 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/util/AAITreeConverter.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/util/AAITreeConverter.java @@ -20,14 +20,12 @@ package org.onap.vid.aai.util; -import static java.util.function.Function.identity; -import static java.util.stream.Collectors.counting; -import static java.util.stream.Collectors.groupingBy; import static org.onap.vid.asdc.parser.ToscaParserImpl2.Constants.A_LA_CARTE; import java.util.Map; -import java.util.Objects; +import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; +import org.onap.vid.model.ModelUtil; import org.onap.vid.model.aaiTree.AAITreeNode; import org.onap.vid.model.aaiTree.CollectionResource; import org.onap.vid.model.aaiTree.Network; @@ -56,6 +54,13 @@ public class AAITreeConverter { public static final String SERVICE_INSTANCE_SERVICE_INSTANCE_ID = "service-instance.service-instance-id"; public static final String TENANT_TENANT_NAME = "tenant.tenant-name"; + private final ModelUtil modelUtil; + + @Inject + public AAITreeConverter(ModelUtil modelUtil) { + this.modelUtil = modelUtil; + } + public ServiceInstance convertTreeToUIModel(AAITreeNode rootNode, String globalCustomerId, String serviceType, String instantiationType, String instanceRole, String instanceType) { ServiceInstance serviceInstance = new ServiceInstance(); serviceInstance.setInstanceId(rootNode.getId()); @@ -107,13 +112,7 @@ public class AAITreeConverter { } private <T extends Node> Map<String, Long> getExistingCounterMap(Map<String, T> nodeList) { - return nodeList.entrySet().stream() - .map(k -> { - ModelInfo modelInfo = k.getValue().getModelInfo(); - return StringUtils.defaultIfEmpty(modelInfo.getModelCustomizationId(), modelInfo.getModelVersionId()); - }) - .filter(Objects::nonNull) - .collect(groupingBy(identity(), counting())); + return modelUtil.getExistingCounterMap(nodeList, Node::getModelInfo); } private static ModelInfo createModelInfo(AAITreeNode aaiNode) { diff --git a/vid-app-common/src/main/java/org/onap/vid/asdc/parser/VidNotionsBuilder.java b/vid-app-common/src/main/java/org/onap/vid/asdc/parser/VidNotionsBuilder.java index d35c8df9c..760eb4251 100644 --- a/vid-app-common/src/main/java/org/onap/vid/asdc/parser/VidNotionsBuilder.java +++ b/vid-app-common/src/main/java/org/onap/vid/asdc/parser/VidNotionsBuilder.java @@ -20,26 +20,39 @@ package org.onap.vid.asdc.parser; +import static java.util.stream.Collectors.toSet; import static org.apache.commons.lang3.StringUtils.equalsAnyIgnoreCase; import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.hibernate.annotations.common.util.StringHelper.isNotEmpty; +import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; import com.google.common.collect.ImmutableMap; +import java.io.IOException; import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Stream; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.onap.sdc.tosca.parser.api.ISdcCsarHelper; import org.onap.sdc.toscaparser.api.NodeTemplate; import org.onap.sdc.toscaparser.api.elements.Metadata; +import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.vid.model.ServiceModel; import org.onap.vid.model.VidNotions; +import org.onap.vid.model.VidNotions.InstantiationType; +import org.onap.vid.model.VidNotions.InstantiationUI; +import org.onap.vid.model.VidNotions.ModelCategory; import org.onap.vid.properties.Features; import org.togglz.core.manager.FeatureManager; public class VidNotionsBuilder { private final FeatureManager featureManager; + private final Set<UUID> invariantToMacro; //map of service type that are always macro services, and their relevant featureFlag private static final Map<VidNotions.ModelCategory, Features> macroServicesByModelCategory = ImmutableMap.of( @@ -50,15 +63,30 @@ public class VidNotionsBuilder { public VidNotionsBuilder(FeatureManager featureManager) { this.featureManager = featureManager; + invariantToMacro = loadInvariantMacroUUIDsFromFile(); + } + + @NotNull + private Set<UUID> loadInvariantMacroUUIDsFromFile() { + try { + return Stream.of(JACKSON_OBJECT_MAPPER.readValue( + VidNotionsBuilder.class.getResource("/macro_services_by_invariant_uuid.json"), + String[].class + )).map(UUID::fromString).collect(toSet()); + } catch (IOException e) { + throw new GenericUncheckedException(e); + } } VidNotions buildVidNotions(ISdcCsarHelper csarHelper, ServiceModel serviceModel) { VidNotions.ModelCategory modelCategory = suggestModelCategory(csarHelper, serviceModel); + final InstantiationType instantiationType = suggestInstantiationType(serviceModel, modelCategory); return new VidNotions( - suggestInstantiationUI(csarHelper, serviceModel), + suggestInstantiationUI(csarHelper, serviceModel, modelCategory, instantiationType), modelCategory, - suggestViewEditUI(csarHelper, serviceModel), - suggestInstantiationType(serviceModel, modelCategory)); + suggestViewEditUI(csarHelper, serviceModel, modelCategory, instantiationType), + instantiationType + ); } private boolean isMacroTypeByModelCategory(VidNotions.ModelCategory modelCategory) { @@ -67,31 +95,51 @@ public class VidNotionsBuilder { return (featureOfMacroType!=null && featureManager.isActive(featureOfMacroType)); } - VidNotions.InstantiationType suggestInstantiationType(ServiceModel serviceModel, VidNotions.ModelCategory modelCategory) { + InstantiationType suggestInstantiationType(ServiceModel serviceModel, VidNotions.ModelCategory modelCategory) { if (isMacroTypeByModelCategory(modelCategory)) { - return VidNotions.InstantiationType.Macro; + return InstantiationType.Macro; } - if (serviceModel==null || serviceModel.getService()==null || isEmpty(serviceModel.getService().getInstantiationType())) { - return VidNotions.InstantiationType.ClientConfig; + if (serviceModel==null || serviceModel.getService()==null) { + return defaultInstantiationType(); } - String instantiationType = serviceModel.getService().getInstantiationType(); - if (instantiationType.equals(ToscaParserImpl2.Constants.MACRO)) { - return VidNotions.InstantiationType.Macro; + + if (StringUtils.equals(serviceModel.getService().getInstantiationType(), ToscaParserImpl2.Constants.MACRO)) { + return InstantiationType.Macro; } - if (instantiationType.equals(ToscaParserImpl2.Constants.A_LA_CARTE)) { - return VidNotions.InstantiationType.ALaCarte; + + if (StringUtils.equals(serviceModel.getService().getInstantiationType(), ToscaParserImpl2.Constants.A_LA_CARTE)) { + return InstantiationType.ALaCarte; } - return VidNotions.InstantiationType.ClientConfig; + if (!featureManager.isActive(Features.FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND)) + return InstantiationType.ClientConfig; + + return isMacroByInvariantUuid(serviceModel.getService().getInvariantUuid()) ? + InstantiationType.Macro : + InstantiationType.ALaCarte; + } + + @NotNull + private InstantiationType defaultInstantiationType() { + return featureManager.isActive(Features.FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND) ? + InstantiationType.ALaCarte : + InstantiationType.ClientConfig; } //UI route a-la-carte services to old UI only if InstantiationUI is LEGACY //So any other value for InstantiationUI other than LEGACY make UI to route //a-la-carte services to new UI - VidNotions.InstantiationUI suggestInstantiationUI(ISdcCsarHelper csarHelper, ServiceModel serviceModel) { + VidNotions.InstantiationUI suggestInstantiationUI(ISdcCsarHelper csarHelper, ServiceModel serviceModel, ModelCategory modelCategory, InstantiationType instantiationType) { if(featureManager.isActive(Features.FLAG_EXP_ANY_ALACARTE_NEW_INSTANTIATION_UI) && isALaCarte(csarHelper)) { return VidNotions.InstantiationUI.ANY_ALACARTE_NEW_UI; } + + if (featureManager.isActive(Features.FLAG_2002_ANY_ALACARTE_BESIDES_EXCLUDED_NEW_INSTANTIATION_UI) && + !isMacro(instantiationType) && + !isAlacarteExcludedByCategory(modelCategory)) { + return InstantiationUI.ANY_ALACARTE_WHICH_NOT_EXCLUDED; + } + if (featureManager.isActive(Features.FLAG_1902_VNF_GROUPING) && isGrouping(csarHelper)) { return VidNotions.InstantiationUI.SERVICE_WITH_VNF_GROUPING; } @@ -115,6 +163,10 @@ public class VidNotionsBuilder { } + private boolean isAlacarteExcludedByCategory(ModelCategory modelCategory) { + return modelCategory==ModelCategory.PORT_MIRRORING || modelCategory==ModelCategory.VLAN_TAGGING ; + } + private boolean isVnfServiceRole(ISdcCsarHelper csarHelper) { final String serviceRole = csarHelper.getServiceMetadata().getValue(ToscaParserImpl2.Constants.SERVICE_ROLE ); return StringUtils.equalsIgnoreCase("VNF" , serviceRole); @@ -153,6 +205,12 @@ public class VidNotionsBuilder { if(isALaCarte(csarHelper) && hasFabricConfiguration(csarHelper)) { return VidNotions.ModelCategory.IS_5G_FABRIC_CONFIGURATION_MODEL; } + if (isPortMirroringService(serviceModel)) { + return ModelCategory.PORT_MIRRORING; + } + if (isVlanTaggingService(serviceModel)) { + return ModelCategory.VLAN_TAGGING; + } if (isInfraStructureVpn(csarHelper)) { return VidNotions.ModelCategory.INFRASTRUCTURE_VPN; } @@ -165,13 +223,13 @@ public class VidNotionsBuilder { return VidNotions.ModelCategory.OTHER; } - VidNotions.InstantiationUI suggestViewEditUI(ISdcCsarHelper csarHelper, ServiceModel serviceModel) { + VidNotions.InstantiationUI suggestViewEditUI(ISdcCsarHelper csarHelper, ServiceModel serviceModel, ModelCategory modelCategory, InstantiationType instantiationType) { if (featureManager.isActive(Features.FLAG_1902_VNF_GROUPING) && isGrouping(csarHelper)) { return VidNotions.InstantiationUI.SERVICE_WITH_VNF_GROUPING; } if (featureManager.isActive(Features.FLAG_1908_MACRO_NOT_TRANSPORT_NEW_VIEW_EDIT) && - isMacro(serviceModel) && + isMacro(instantiationType) && !isTransportService(csarHelper) && //till new view/edit would support fabric service activation !hasFabricConfiguration(csarHelper)) { @@ -179,7 +237,7 @@ public class VidNotionsBuilder { } if (featureManager.isActive(Features.FLAG_1902_NEW_VIEW_EDIT)) { - VidNotions.InstantiationUI instantiationUISuggestion = suggestInstantiationUI(csarHelper, serviceModel); + VidNotions.InstantiationUI instantiationUISuggestion = suggestInstantiationUI(csarHelper, serviceModel, modelCategory, instantiationType); if (instantiationUISuggestion!=VidNotions.InstantiationUI.LEGACY) { return instantiationUISuggestion; } @@ -188,8 +246,8 @@ public class VidNotionsBuilder { return VidNotions.InstantiationUI.LEGACY; } - private boolean isMacro(ServiceModel serviceModel) { - return ToscaParserImpl2.Constants.MACRO.equals(serviceModel.getService().getInstantiationType()); + private boolean isMacro(InstantiationType instantiationType) { + return instantiationType==InstantiationType.Macro; } private boolean isUuidExactlyHardCoded1ffce89fef3f(ISdcCsarHelper csarHelper) { @@ -232,4 +290,29 @@ public class VidNotionsBuilder { final String serviceRole = csarHelper.getServiceMetadata().getValue(ToscaParserImpl2.Constants.SERVICE_ROLE); return StringUtils.equalsIgnoreCase(serviceRole, ToscaParserImpl2.Constants.GROUPING); } + + private boolean isPortMirroringService(ServiceModel serviceModel) { + return (serviceModel.getService()!=null && + StringUtils.equals(serviceModel.getService().getServiceType(), "PORT-MIRROR")); + } + + private boolean isVlanTaggingService(ServiceModel serviceModel) { + if (serviceModel==null || serviceModel.getVnfs()==null) { + return false; + } + + return serviceModel.getVnfs().values().stream().anyMatch( + vnf-> MapUtils.isNotEmpty(vnf.getVfcInstanceGroups()) + ); + + } + + protected boolean isMacroByInvariantUuid(String uuid) { + try { + return invariantToMacro.contains(UUID.fromString(uuid)); + } + catch (IllegalArgumentException | NullPointerException e) { //not a uuid + return false; + } + } } diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java b/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java index 6bd98fff6..96e777a13 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.vid.dal.AsyncInstantiationRepository; import org.onap.vid.exceptions.AccessDeniedException; import org.onap.vid.model.JobAuditStatus; import org.onap.vid.model.ServiceInfo; @@ -35,8 +36,10 @@ import org.onap.vid.properties.Features; import org.onap.vid.roles.RoleProvider; import org.onap.vid.services.AsyncInstantiationBusinessLogic; import org.onap.vid.services.AuditService; +import org.onap.vid.services.InstantiationTemplatesService; import org.onap.vid.utils.SystemPropertiesWrapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -53,21 +56,29 @@ public class AsyncInstantiationController extends VidRestrictedBaseController { public static final String ASYNC_INSTANTIATION = "asyncInstantiation"; protected final AsyncInstantiationBusinessLogic asyncInstantiationBL; + protected final InstantiationTemplatesService instantiationTemplates; + protected final AsyncInstantiationRepository asyncInstantiationRepository; private final SystemPropertiesWrapper systemPropertiesWrapper; private final RoleProvider roleProvider; private final FeatureManager featureManager; - @Autowired - protected AuditService auditService; + protected final AuditService auditService; @Autowired - public AsyncInstantiationController(AsyncInstantiationBusinessLogic asyncInstantiationBL, RoleProvider roleProvider, FeatureManager featureManager, SystemPropertiesWrapper systemPropertiesWrapper) { + public AsyncInstantiationController(AsyncInstantiationBusinessLogic asyncInstantiationBL, + InstantiationTemplatesService instantiationTemplates, + AsyncInstantiationRepository asyncInstantiationRepository, RoleProvider roleProvider, + FeatureManager featureManager, SystemPropertiesWrapper systemPropertiesWrapper, + AuditService auditService) { this.asyncInstantiationBL = asyncInstantiationBL; + this.instantiationTemplates = instantiationTemplates; + this.asyncInstantiationRepository = asyncInstantiationRepository; this.roleProvider = roleProvider; this.featureManager = featureManager; this.systemPropertiesWrapper = systemPropertiesWrapper; + this.auditService = auditService; } /** @@ -76,8 +87,13 @@ public class AsyncInstantiationController extends VidRestrictedBaseController { * @return the services list */ @RequestMapping(method = RequestMethod.GET) - public List<ServiceInfo> getServicesInfo(HttpServletRequest request) { - return asyncInstantiationBL.getAllServicesInfo(); + public List<ServiceInfo> getServicesInfo(HttpServletRequest request, + @RequestParam(value = "serviceModelId", required = false) UUID serviceModelId) { + if (serviceModelId == null) { + return asyncInstantiationBL.getAllServicesInfo(); + } else { + return asyncInstantiationRepository.listServicesByServiceModelId(serviceModelId); + } } @RequestMapping(value = "bulk", method = RequestMethod.POST) @@ -158,6 +174,11 @@ public class AsyncInstantiationController extends VidRestrictedBaseController { return new MsoResponseWrapper2(200, uuids); } + @GetMapping("templateTopology/{jobId}") + public ServiceInstantiation getTemplateTopology(HttpServletRequest request, @PathVariable(value="jobId") UUID jobId) { + return instantiationTemplates.getJobRequestAsTemplate(jobId); + } + @RequestMapping(value = "/auditStatusForRetry/{trackById}", method = RequestMethod.GET) public JobAuditStatus getResourceAuditStatus(HttpServletRequest request, @PathVariable(value="trackById") String trackById) { return auditService.getResourceAuditStatus(trackById); diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java b/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java index 7233a67e3..f5b325b4a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/LoggerController.java @@ -66,7 +66,7 @@ public class LoggerController extends RestrictedBaseController { this.logfilePathCreator = logfilePathCreator; } - @GetMapping(value = "/{loggerName:audit|audit2019|error|metrics|metrics2019}") + @GetMapping(value = "/{loggerName:audit|audit2019|error|metrics|metrics2019|debug}") public String getLog(@PathVariable String loggerName, HttpServletRequest request, @RequestParam(value="limit", defaultValue = "5000") Integer limit) throws IOException { diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/OperationalEnvironmentController.java b/vid-app-common/src/main/java/org/onap/vid/controller/OperationalEnvironmentController.java index 44bdc813b..d291f9925 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/OperationalEnvironmentController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/OperationalEnvironmentController.java @@ -20,10 +20,21 @@ */ package org.onap.vid.controller; +import static org.onap.vid.utils.Logging.getMethodCallerName; +import static org.onap.vid.utils.Logging.getMethodName; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.MoreObjects; import io.joshworks.restclient.http.HttpResponse; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; @@ -42,19 +53,13 @@ import org.onap.vid.utils.SystemPropertiesWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.MissingServletRequestParameterException; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.onap.vid.utils.Logging.getMethodCallerName; -import static org.onap.vid.utils.Logging.getMethodName; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("operationalEnvironment") @@ -64,7 +69,7 @@ public class OperationalEnvironmentController extends VidRestrictedBaseControlle private final MsoBusinessLogic msoBusinessLogic; private final SystemPropertiesWrapper systemPropertiesWrapper; - private static final Pattern RECOVERY_ACTION_MESSAGE_PATTERN = Pattern.compile("from String \"(.*)\": value not"); + private static final Pattern RECOVERY_ACTION_MESSAGE_PATTERN = Pattern.compile("from String \"(.*)\": not one"); @Autowired diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java b/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java index 91fb94231..cfb848007 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java @@ -58,7 +58,6 @@ import org.onap.vid.properties.VidProperties; import org.onap.vid.scheduler.SchedulerService; import org.onap.vid.scheduler.SchedulerServiceImpl; import org.onap.vid.services.AAIServiceTree; -import org.onap.vid.services.AAITreeNodeBuilder; import org.onap.vid.services.AaiService; import org.onap.vid.services.AaiServiceImpl; import org.onap.vid.services.ChangeManagementService; @@ -66,9 +65,11 @@ import org.onap.vid.services.PombaService; import org.onap.vid.services.PombaServiceImpl; import org.onap.vid.utils.JoshworksJacksonObjectMapper; import org.onap.vid.utils.Logging; +import org.onap.vid.utils.SystemPropertiesWrapper; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.togglz.core.manager.FeatureManager; @@ -100,8 +101,8 @@ public class WebConfig implements WebMvcConfigurer { @Bean public AaiService getAaiService(AaiClientInterface aaiClient, AaiResponseTranslator aaiResponseTranslator, - AAITreeNodeBuilder aaiTreeNode, AAIServiceTree aaiServiceTree, ExecutorService executorService) { - return new AaiServiceImpl(aaiClient, aaiResponseTranslator, aaiServiceTree, executorService); + AAIServiceTree aaiServiceTree, Logging logging, ExecutorService executorService) { + return new AaiServiceImpl(aaiClient, aaiResponseTranslator, aaiServiceTree, executorService, logging); } @Bean @@ -222,6 +223,8 @@ public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new VidLoggingInterceptor()); + registry.addInterceptor( + new VidLoggingInterceptor(new ControllersUtils(new SystemPropertiesWrapper())) + ).order(Ordered.HIGHEST_PRECEDENCE); } } diff --git a/vid-app-common/src/main/java/org/onap/vid/dal/AsyncInstantiationRepository.kt b/vid-app-common/src/main/java/org/onap/vid/dal/AsyncInstantiationRepository.kt index 79c7297a3..c26b88a5e 100644 --- a/vid-app-common/src/main/java/org/onap/vid/dal/AsyncInstantiationRepository.kt +++ b/vid-app-common/src/main/java/org/onap/vid/dal/AsyncInstantiationRepository.kt @@ -86,13 +86,22 @@ class AsyncInstantiationRepository @Autowired constructor(val dataAccessService: private fun filterByCreationDateAndNotDeleted(): String { val minus3Months = LocalDateTime.now().minusMonths(3) val filterDate = Timestamp.valueOf(minus3Months) + return filterServicesByNotHiddenAndNotDeleted() + + " and created >= '" + filterDate + "' " + } + + private fun filterByServiceModelId(serviceModelUuid: UUID): String { + return filterServicesByNotHiddenAndNotDeleted() + + " and SERVICE_MODEL_ID = '$serviceModelUuid'" + } + + private fun filterServicesByNotHiddenAndNotDeleted(): String { return " WHERE" + " hidden = false" + - " and deleted_at is null" + // don't fetch deleted - - " and created >= '" + filterDate + "' " + " and deleted_at is null" // don't fetch deleted } + private fun orderByCreatedDateAndStatus(): String { return " createdBulkDate DESC ,\n" + " (CASE jobStatus\n" + @@ -144,4 +153,7 @@ class AsyncInstantiationRepository @Autowired constructor(val dataAccessService: .joinToString(" $conditionType ") return dataAccessService.getList(className, " WHERE $condition", orderBy, null) as List<T> } + + fun listServicesByServiceModelId(serviceModelId: UUID): List<ServiceInfo> = + dataAccessService.getList(ServiceInfo::class.java, filterByServiceModelId(serviceModelId), orderByCreatedDateAndStatus(), null) as List<ServiceInfo>; } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceCommand.kt index 8ce73d713..2fdd19100 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceCommand.kt @@ -62,13 +62,13 @@ class MacroServiceCommand @Autowired constructor( //Aai return bad response while checking names uniqueness catch (exception : ExceptionWithRequestInfo) { - Logger.error("Failed to check name uniqueness in AAI. VID will try again later", exception) + Logger.error(EELFLoggerDelegate.errorLogger, "Failed to check name uniqueness in AAI. VID will try again later", exception) throw TryAgainException(exception); } //Vid reached to max retries while trying to find unique name in AAI catch (exception : MaxRetriesException) { - Logger.error("Failed to find unused name in AAI", exception) + Logger.error(EELFLoggerDelegate.errorLogger, "Failed to find unused name in AAI", exception) throw AbortingException(exception); } } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt index b35deb892..e46a24f78 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt @@ -11,7 +11,6 @@ import org.onap.vid.changeManagement.RequestDetailsWrapper import org.onap.vid.model.serviceInstantiation.* import org.onap.vid.mso.model.* import org.onap.vid.mso.model.BaseResourceInstantiationRequestDetails.* -import org.onap.vid.mso.model.VfModuleInstantiationRequestDetails.UserParamMap import org.onap.vid.mso.rest.SubscriberInfo import org.onap.vid.properties.Features import org.onap.vid.services.AsyncInstantiationBusinessLogic @@ -99,15 +98,17 @@ class MsoRequestBuilder return RequestDetailsWrapper(VnfInstantiationRequestDetails(vnfDetails.modelInfo, cloudConfiguration, requestInfo, null, null, null, null)) } - fun generateVfModuleInstantiationRequest(vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, vgInstanceId: String?, userId: String, testApi: String?): RequestDetailsWrapper<VfModuleInstantiationRequestDetails> { + protected fun generateVfModuleRequestWithRequestParams( + vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, + serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, vgInstanceId: String?, userId: String, + requestParameters: (userParams: List<UserParamTypes>) -> RequestParametersVfModuleOrVolumeGroup + ): RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> { val requestInfo = generateRequestInfo(vfModuleDetails.instanceName, ResourceType.VF_MODULE, vfModuleDetails.isRollbackOnFailure, null, userId) //cloud configuration val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId) - //request parameters val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams) - val requestParameters = VfModuleInstantiationRequestDetails.RequestParametersVfModule(userParams, vfModuleDetails.isUsePreload, testApi) //related instance list val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo)) @@ -116,14 +117,44 @@ class MsoRequestBuilder volumeGroupModel.modelType = "volumeGroup" relatedInstanceList.add(RelatedInstance(volumeGroupModel, vgInstanceId, vfModuleDetails.volumeGroupInstanceName)) } - return RequestDetailsWrapper(VfModuleInstantiationRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters)) + + return RequestDetailsWrapper(VfModuleOrVolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters(userParams))) + } + + fun generateVfModuleInstantiationRequest( + vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, + serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, + vgInstanceId: String?, userId: String, testApi: String? + ): RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> { + val requestParameters = { userParams: List<UserParamTypes> -> + RequestParametersVfModuleOrVolumeGroupInstantiation(userParams, vfModuleDetails.isUsePreload, testApi) + } + + return generateVfModuleRequestWithRequestParams(vfModuleDetails, serviceModelInfo, serviceInstanceId, + vnfModelInfo, vnfInstanceId, vgInstanceId, userId, requestParameters) } + fun generateVfModuleReplaceRequest( + vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, + serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, + vgInstanceId: String?, userId: String, testApi: String? + ): RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> { + val requestParameters = { userParams: List<UserParamTypes> -> + RequestParametersVfModuleUpgrade(userParams, vfModuleDetails.isUsePreload, testApi, + vfModuleDetails.isRetainAssignments, nullSafeNegate(vfModuleDetails.isRetainVolumeGroups)) + } + + return generateVfModuleRequestWithRequestParams(vfModuleDetails, serviceModelInfo, serviceInstanceId, + vnfModelInfo, vnfInstanceId, vgInstanceId, userId, requestParameters) + } + + private fun nullSafeNegate(booleanValue: Boolean?): Boolean? = booleanValue?.not() + fun generateVolumeGroupInstantiationRequest(vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<VolumeGroupRequestDetails> { val requestInfo = generateRequestInfo(vfModuleDetails.volumeGroupInstanceName, ResourceType.VOLUME_GROUP, vfModuleDetails.isRollbackOnFailure, null, userId) val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId) val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams) - val requestParameters = VfModuleInstantiationRequestDetails.RequestParametersVfModule(userParams, vfModuleDetails.isUsePreload, testApi) + val requestParameters = RequestParametersVfModuleOrVolumeGroupInstantiation(userParams, vfModuleDetails.isUsePreload, testApi) val relatedInstances = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo)) vfModuleDetails.modelInfo.modelType = "volumeGroup" @@ -151,10 +182,10 @@ class MsoRequestBuilder return RequestDetailsWrapper(NetworkInstantiationRequestDetails(networkDetails.modelInfo, cloudConfiguration, requestInfo, null, null, null, null)) } - fun generateDeleteVfModuleRequest(vfModuleDetails: VfModule, userId: String): RequestDetailsWrapper<VfModuleInstantiationRequestDetails> { + fun generateDeleteVfModuleRequest(vfModuleDetails: VfModule, userId: String): RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> { val requestInfo = generateRequestInfo(null, null, null, null, userId) val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId) - return RequestDetailsWrapper(VfModuleInstantiationRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, null, null)) + return RequestDetailsWrapper(VfModuleOrVolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, null, null)) } private fun generateServiceName(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String): String? { @@ -178,7 +209,7 @@ class MsoRequestBuilder try { asyncInstantiationBL.updateServiceInfo(jobId) { x -> x.serviceInstanceName = serviceInstanceName } } catch (e: Exception) { - LOGGER.error("Failed updating service name {} in serviceInfo", serviceInstanceName, e) + LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed updating service name {} in serviceInfo", serviceInstanceName, e) } return serviceInstanceName @@ -264,7 +295,7 @@ class MsoRequestBuilder }.collect(Collectors.toList<VfModuleMacro>()) } - fun aggregateAllInstanceParams(instanceParams: Map<String, String>?, supplementaryParams: Map<String, String>?): List<VfModuleInstantiationRequestDetails.UserParamMap<String, String>> { + fun aggregateAllInstanceParams(instanceParams: Map<String, String>?, supplementaryParams: Map<String, String>?): List<UserParamMap<String, String>> { var instanceParamsFinal: Map<String, String> = instanceParams ?: emptyMap() val supplementaryParamsFinal: Map<String, String> = supplementaryParams ?: emptyMap() diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/MsoResultHandlerService.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoResultHandlerService.kt index 50eada64f..e60919a34 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/MsoResultHandlerService.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoResultHandlerService.kt @@ -68,11 +68,11 @@ class MsoResultHandlerService fun handleResponse(sharedData: JobSharedData, msoResponse: RestObject<RequestReferencesContainer>, actionDescription: String): MsoResult { return if (msoResponse.statusCode in 200..399) { val msoResourceIds = MsoResourceIds(msoResponse.get().requestReferences.requestId, msoResponse.get().requestReferences.instanceId) - LOGGER.debug("Successfully sent $actionDescription. Request id: ${msoResourceIds.requestId}") + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Successfully sent $actionDescription. Request id: ${msoResourceIds.requestId}") asyncInstantiationBL.addResourceInfo(sharedData, Job.JobStatus.IN_PROGRESS, msoResourceIds.instanceId) MsoResult(Job.JobStatus.COMPLETED_WITH_NO_ACTION, msoResourceIds) } else { - LOGGER.debug("Failed to $actionDescription. Details: ${msoResponse.raw}") + LOGGER.debug(EELFLoggerDelegate.debugLogger, "Failed to $actionDescription. Details: ${msoResponse.raw}") asyncInstantiationBL.addFailedResourceInfo(sharedData, msoResponse) MsoResult(Job.JobStatus.FAILED) } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceCommand.kt index a266dd002..4477a9f24 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceCommand.kt @@ -23,7 +23,6 @@ package org.onap.vid.job.command import com.fasterxml.jackson.module.kotlin.convertValue import org.apache.commons.lang3.ObjectUtils.defaultIfNull -import org.onap.logging.ref.slf4j.ONAPLogConstants import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate import org.onap.vid.changeManagement.RequestDetailsWrapper import org.onap.vid.exceptions.AbortingException @@ -38,7 +37,6 @@ import org.onap.vid.mso.RestMsoImplementation import org.onap.vid.mso.model.ModelInfo import org.onap.vid.utils.JACKSON_OBJECT_MAPPER import org.onap.vid.utils.getEnumFromMapOfStrings -import org.slf4j.MDC import org.springframework.http.HttpMethod import java.util.* @@ -114,7 +112,7 @@ abstract class ResourceCommand( jobStatus = comulateStatusAndUpdatePropertyIfFinal(jobStatus) try { - Logger.debug("job: ${this.javaClass.simpleName} ${sharedData.jobUuid} $actionPhase ${getActionType()} $internalState $jobStatus $childJobs") + Logger.debug(EELFLoggerDelegate.debugLogger, "job: ${this.javaClass.simpleName} ${sharedData.jobUuid} $actionPhase ${getActionType()} $internalState $jobStatus $childJobs") } catch (e:Exception) { /* do nothing. Just failed to log...*/} if (shallStopJob(jobStatus)) { @@ -123,7 +121,7 @@ abstract class ResourceCommand( } val (nextActionPhase, nextInternalState) = calcNextInternalState(jobStatus, internalState, actionPhase) - Logger.debug("next state for job ${sharedData.jobUuid} is $nextInternalState") + Logger.debug(EELFLoggerDelegate.debugLogger, "next state for job ${sharedData.jobUuid} is $nextInternalState") actionPhase = nextActionPhase internalState = nextInternalState @@ -133,7 +131,7 @@ abstract class ResourceCommand( } jobStatus = getExternalInProgressStatus() - Logger.debug("next status for job ${sharedData.jobUuid} is $jobStatus") + Logger.debug(EELFLoggerDelegate.debugLogger, "next status for job ${sharedData.jobUuid} is $jobStatus") // if (internalState.immediate) return call() //shortcut instead of execute another command return NextCommand(jobStatus, this) } @@ -155,7 +153,7 @@ abstract class ResourceCommand( JobStatus.IN_PROGRESS } catch (exception: AbortingException) { - Logger.error("caught AbortingException. Set job status to FAILED") + Logger.error(EELFLoggerDelegate.errorLogger, "caught AbortingException. Set job status to FAILED") JobStatus.FAILED; } } @@ -362,8 +360,6 @@ abstract class ResourceCommand( } protected fun executeAndHandleMsoInstanceRequest(restCallPlan: MsoRestCallPlan): JobStatus { - //make sure requestIds are unique - MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, UUID.randomUUID().toString()) val msoResponse = restMso.restCall( restCallPlan.httpMethod, RequestReferencesContainer::class.java, diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/RootServiceCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/RootServiceCommand.kt index c4680b2bd..875de66d6 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/RootServiceCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/RootServiceCommand.kt @@ -71,13 +71,13 @@ abstract class RootServiceCommand @Autowired constructor( try { val requests = auditService.retrieveRequestsFromMsoByServiceIdAndRequestTypeAndScope(serviceInstanceId, requestType, scope) if (requests.isEmpty() || requests[0].requestId == null) { - LOGGER.error("Failed to retrieve requestId with type: $type, scope: $scope for service instanceId $serviceInstanceId ") + LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve requestId with type: $type, scope: $scope for service instanceId $serviceInstanceId ") return Job.JobStatus.FAILED } val createMyselfCommand = planResumeMyselfRestCall(requests[0].requestId, sharedData.userId) return executeAndHandleMsoInstanceRequest(createMyselfCommand) } catch (exception: Exception) { - LOGGER.error("Failed to resume instanceId $serviceInstanceId ", exception) + LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to resume instanceId $serviceInstanceId ", exception) return Job.JobStatus.FAILED } } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt index bee42fbd4..731625c53 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt @@ -90,7 +90,7 @@ class VfmoduleCommand @Autowired constructor( val originalRequestWithNewestVfmModelInfo = getRequest().cloneWith(vfmModelInfo) - val requestDetailsWrapper = msoRequestBuilder.generateVfModuleInstantiationRequest( + val requestDetailsWrapper = msoRequestBuilder.generateVfModuleReplaceRequest( originalRequestWithNewestVfmModelInfo, serviceModelInfo, serviceInstanceId, vnfModelInfo, vnfInstanceId, null, sharedData.userId, sharedData.testApi) @@ -193,7 +193,7 @@ class VfmoduleCommand @Autowired constructor( val replaceMyselfCommand = planReplaceMyselfRestCall(commandParentData) return executeAndHandleMsoInstanceRequest(replaceMyselfCommand) } catch (exception: Exception) { - LOGGER.error("Failed to replace instanceId ${getRequest().instanceId} ", exception) + LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to replace instanceId ${getRequest().instanceId} ", exception) return Job.JobStatus.FAILED } } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt index 6f00f9ae6..48ff7b7ac 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt @@ -61,7 +61,7 @@ class VnfCommand @Autowired constructor( try { childJobs = pushChildrenJobsToBroker(vfModules.filter { filterModuleByNeedToCreateBase(it) }, dataForChild, JobType.VolumeGroupInstantiation) } catch (e: AsdcCatalogException) { - LOGGER.error("Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message , e) + LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message , e) //return Job.JobStatus.FAILED throw e; } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsSchedulerInitializer.java b/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsSchedulerInitializer.java index ad4b8c95a..114c20105 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsSchedulerInitializer.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsSchedulerInitializer.java @@ -85,7 +85,7 @@ public class DeleteOldJobsSchedulerInitializer { Trigger createTrigger() { int minutes = new Random(System.nanoTime()).nextInt(59); int hours = 6; - logger.info("trigger for DeleteOldJobs is {}:{} ", hours, minutes); + logger.info(EELFLoggerDelegate.debugLogger, "trigger for DeleteOldJobs is {}:{} ", hours, minutes); return TriggerBuilder.newTrigger() .withIdentity("DeleteOldJobsTrigger") diff --git a/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsWorker.java b/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsWorker.java index d60ddab8d..ba0a9981e 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsWorker.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/impl/DeleteOldJobsWorker.java @@ -34,7 +34,7 @@ public class DeleteOldJobsWorker extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) { - LOGGER.info("delete old final jobs that has finished before {} seconds", secondsAgo); + LOGGER.info(EELFLoggerDelegate.debugLogger, "delete old final jobs that has finished before {} seconds", secondsAgo); jobsBrokerService.deleteOldFinalJobs(secondsAgo); } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/impl/JobWorker.java b/vid-app-common/src/main/java/org/onap/vid/job/impl/JobWorker.java index 0b277b4d2..c629a665c 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/impl/JobWorker.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/impl/JobWorker.java @@ -20,23 +20,28 @@ package org.onap.vid.job.impl; +import static org.onap.vid.job.Job.JobStatus.FAILED; +import static org.onap.vid.job.Job.JobStatus.STOPPED; +import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE; +import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE; + +import java.util.Optional; +import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.onap.logging.ref.slf4j.ONAPLogConstants; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.job.*; +import org.onap.vid.job.Job; +import org.onap.vid.job.JobCommand; +import org.onap.vid.job.JobException; +import org.onap.vid.job.JobsBrokerService; +import org.onap.vid.job.NextCommand; import org.onap.vid.job.command.JobCommandFactory; import org.quartz.JobExecutionContext; +import org.slf4j.MDC; import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.stereotype.Component; -import java.util.Optional; -import java.util.UUID; - -import static org.onap.vid.job.Job.JobStatus.FAILED; -import static org.onap.vid.job.Job.JobStatus.STOPPED; -import static org.onap.vid.job.command.ResourceCommandKt.ACTION_PHASE; -import static org.onap.vid.job.command.ResourceCommandKt.INTERNAL_STATE; - @Component public class JobWorker extends QuartzJobBean { @@ -80,6 +85,8 @@ public class JobWorker extends QuartzJobBean { } protected Job executeJobAndGetNext(Job job) { + setThreadWithRandomRequestId(); + Object internalState = job.getData().get(INTERNAL_STATE); Object actionPhase = job.getData().get(ACTION_PHASE); LOGGER.debug(EELFLoggerDelegate.debugLogger, "going to execute job {} of {}: {}/{} {}/{}", @@ -96,13 +103,18 @@ public class JobWorker extends QuartzJobBean { return setNextCommandInJob(nextCommand, job); } + private void setThreadWithRandomRequestId() { + //make sure requestIds in outgoing requests are not reused + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, UUID.randomUUID().toString()); + } + private NextCommand executeCommandAndGetNext(Job job) { NextCommand nextCommand; try { final JobCommand jobCommand = jobCommandFactory.toCommand(job); nextCommand = jobCommand.call(); } catch (Exception e) { - LOGGER.error("error while executing job from queue: {}", e); + LOGGER.error(EELFLoggerDelegate.errorLogger, "error while executing job from queue: {}", e); nextCommand = new NextCommand(FAILED); } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/impl/JobsBrokerServiceInDatabaseImpl.java b/vid-app-common/src/main/java/org/onap/vid/job/impl/JobsBrokerServiceInDatabaseImpl.java index 74a729494..51803891a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/impl/JobsBrokerServiceInDatabaseImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/impl/JobsBrokerServiceInDatabaseImpl.java @@ -20,6 +20,21 @@ package org.onap.vid.job.impl; +import static org.onap.vid.job.Job.JobStatus.CREATING; +import static org.onap.vid.job.Job.JobStatus.FINAL_STATUS; +import static org.onap.vid.job.Job.JobStatus.IN_PROGRESS; +import static org.onap.vid.job.Job.JobStatus.PENDING_RESOURCE; +import static org.onap.vid.job.Job.JobStatus.RESOURCE_IN_PROGRESS; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; import org.hibernate.SessionFactory; import org.jetbrains.annotations.NotNull; @@ -37,14 +52,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; -import java.sql.Timestamp; -import java.time.LocalDateTime; -import java.util.*; -import java.util.stream.Collectors; - -import static org.onap.vid.job.Job.JobStatus.*; - @Service public class JobsBrokerServiceInDatabaseImpl implements JobsBrokerService { @@ -252,7 +259,10 @@ public class JobsBrokerServiceInDatabaseImpl implements JobsBrokerService { Integer age = jobDao.getAge(); jobDao.setAge(age + 1); - logger.debug(EELFLoggerDelegate.debugLogger, "{}/{}", jobDao.getStatus(), jobDao.getType()); + logger.debug(EELFLoggerDelegate.debugLogger, "pushing back jobDao {} of {}: {}/{}", + StringUtils.substring(String.valueOf(jobDao.getUuid()), 0, 8), + StringUtils.substring(String.valueOf(jobDao.getTemplateId()), 0, 8), + jobDao.getStatus(), jobDao.getType()); dataAccessService.saveDomainObject(jobDao, DaoUtils.getPropsMap()); } diff --git a/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggingInterceptor.java b/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggingInterceptor.java index abc7048da..fe8b470ec 100644 --- a/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggingInterceptor.java +++ b/vid-app-common/src/main/java/org/onap/vid/logging/VidLoggingInterceptor.java @@ -24,8 +24,12 @@ import java.net.InetAddress; import java.net.UnknownHostException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.onap.logging.filter.base.MDCSetup; +import org.onap.logging.filter.base.SimpleMap; import org.onap.logging.filter.spring.LoggingInterceptor; import org.onap.logging.ref.slf4j.ONAPLogConstants.MDCs; +import org.onap.vid.controller.ControllersUtils; import org.slf4j.MDC; import org.springframework.web.servlet.ModelAndView; @@ -34,6 +38,11 @@ public class VidLoggingInterceptor extends LoggingInterceptor { static final String INBOUND_INVO_ID = "InboundInvoId"; private static final String canonicalHostName = getCanonicalName(); + private final ControllersUtils controllersUtils; + + public VidLoggingInterceptor(ControllersUtils controllersUtils) { + this.controllersUtils = controllersUtils; + } private static String getCanonicalName() { try { @@ -45,9 +54,30 @@ public class VidLoggingInterceptor extends LoggingInterceptor { } @Override - protected void additionalPreHandling(HttpServletRequest request) { + protected void additionalPreHandling(HttpServletRequest request) { super.additionalPreHandling(request); storeInboundInvocationId(); + fillPartnerNameWithUserId(request); + } + + void fillPartnerNameWithUserId(HttpServletRequest request) { + String userId = controllersUtils.extractUserId(request); + if (StringUtils.isNotEmpty(userId)) { + MDC.put(MDCs.PARTNER_NAME, userId); + } + } + + @Override + //this method override fix bug in logging library + //that may throw some exceptions, e.g. StringIndexOutOfBoundsException + protected String getBasicAuthUserName(SimpleMap headers) { + try { + return super.getBasicAuthUserName(headers); + } catch (Exception e) { + MDCSetup.logger.error("failed to getBasicAuthUserName", e); + } + + return null; } /* @@ -61,6 +91,7 @@ public class VidLoggingInterceptor extends LoggingInterceptor { public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { restoreInvocationId(); fixServerFQDN(); + fillPartnerNameWithUserId(request); super.postHandle(request, response, handler, modelAndView); } diff --git a/vid-app-common/src/main/java/org/onap/vid/model/ModelUtil.java b/vid-app-common/src/main/java/org/onap/vid/model/ModelUtil.java index 45e100fb1..6c56a464b 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/ModelUtil.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/ModelUtil.java @@ -20,39 +20,26 @@ package org.onap.vid.model; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; + +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import org.apache.commons.lang3.StringUtils; +import org.onap.vid.mso.model.ModelInfo; +import org.springframework.stereotype.Component; + +@Component public class ModelUtil { - /** - * Gets the tags for the given element according to the configured namespace - * @param namespaces the namespace list from the configuration - * @param constantValue the constant portion of the tag name, i.e. resource.vf... - * @return the tags - */ - public static String[] getTags ( String[] namespaces, String constantValue ) { - String[] tags; - if ( namespaces == null || namespaces.length == 0 ) { - return null; - } - int le = namespaces.length; - tags = new String[le]; - for ( int i = 0; i < le; i++ ) { - tags[i] = namespaces[i] + constantValue; - } - return (tags); - } - /** - * Determine if a note template type matches a set of configurable tags - * @param type the node template type - * @param tags the model configurable namespaces - * @return true if type starts with a tag in the array, false otherwise - */ - public static boolean isType ( String type, String[] tags ) { - if ( (tags != null) && (tags.length > 0) ) { - for ( int i = 0; i < tags.length; i++ ) { - if ( type.startsWith (tags[i]) ) { - return (true); - } - } - } - return (false); + public <T> Map<String, Long> getExistingCounterMap(Map<String, T> nodeList, Function<T, ModelInfo> modelInfoExtractor) { + return nodeList.values().stream() + .map(it -> { + ModelInfo modelInfo = modelInfoExtractor.apply(it); + return StringUtils.defaultIfEmpty(modelInfo.getModelCustomizationId(), modelInfo.getModelVersionId()); + }) + .filter(Objects::nonNull) + .collect(groupingBy(identity(), counting())); } } diff --git a/vid-app-common/src/main/java/org/onap/vid/model/VidNotions.kt b/vid-app-common/src/main/java/org/onap/vid/model/VidNotions.kt index f67d8fbd9..c6de51c1a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/VidNotions.kt +++ b/vid-app-common/src/main/java/org/onap/vid/model/VidNotions.kt @@ -25,7 +25,7 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonValue import com.google.common.base.CaseFormat -class VidNotions(@get:JsonInclude(JsonInclude.Include.NON_NULL) +data class VidNotions(@get:JsonInclude(JsonInclude.Include.NON_NULL) val instantiationUI: InstantiationUI, val modelCategory: ModelCategory, val viewEditUI: InstantiationUI, @@ -41,7 +41,8 @@ class VidNotions(@get:JsonInclude(JsonInclude.Include.NON_NULL) TRANSPORT_SERVICE, SERVICE_WITH_COLLECTION_RESOURCE, A_LA_CARTE_VNF_SERVICE_ROLE, - INFRASTRUCTURE_VPN + INFRASTRUCTURE_VPN, + ANY_ALACARTE_WHICH_NOT_EXCLUDED, ; @JsonValue @@ -59,6 +60,8 @@ class VidNotions(@get:JsonInclude(JsonInclude.Include.NON_NULL) Transport, SERVICE_WITH_COLLECTION_RESOURCE, INFRASTRUCTURE_VPN, + PORT_MIRRORING, + VLAN_TAGGING, @JsonProperty("other") OTHER } diff --git a/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ExistingElementsCounterMaps.java b/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ExistingElementsCounterMaps.java new file mode 100644 index 000000000..de63c2c94 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ExistingElementsCounterMaps.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 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.onap.vid.model.aaiTree; + +import java.util.Map; + +public interface ExistingElementsCounterMaps { + + Map<String, Long> getExistingVNFCounterMap(); + + Map<String, Long> getExistingNetworksCounterMap(); + + Map<String, Long> getExistingVnfGroupCounterMap(); + + Map<String, Long> getExistingVRFCounterMap(); +} diff --git a/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ServiceInstance.java b/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ServiceInstance.java index 923be132f..78afe1d45 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ServiceInstance.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/ServiceInstance.java @@ -24,7 +24,7 @@ import java.util.HashMap; import java.util.Map; import org.onap.vid.mso.model.ModelInfo; -public class ServiceInstance extends AbstractNode { +public class ServiceInstance extends AbstractNode implements ExistingElementsCounterMaps { private String globalSubscriberId; private String subscriptionServiceType; @@ -198,6 +198,7 @@ public class ServiceInstance extends AbstractNode { this.validationCounter = validationCounter; } + @Override public Map<String, Long> getExistingVNFCounterMap() { return existingVNFCounterMap; } @@ -206,6 +207,7 @@ public class ServiceInstance extends AbstractNode { this.existingVNFCounterMap = existingVNFCounterMap; } + @Override public Map<String, Long> getExistingNetworksCounterMap() { return existingNetworksCounterMap; } @@ -214,6 +216,7 @@ public class ServiceInstance extends AbstractNode { this.existingNetworksCounterMap = existingNetworksCounterMap; } + @Override public Map<String, Long> getExistingVnfGroupCounterMap() { return existingVnfGroupCounterMap; } @@ -230,6 +233,7 @@ public class ServiceInstance extends AbstractNode { this.vrfs = vrfs; } + @Override public Map<String, Long> getExistingVRFCounterMap() { return existingVRFCounterMap; } diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java index 8828faf1d..e7e5783c4 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java @@ -21,18 +21,19 @@ package org.onap.vid.model.serviceInstantiation; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.ObjectUtils; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.JobType; -import org.onap.vid.model.VidNotions; -import org.onap.vid.mso.model.ModelInfo; - +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.vid.job.JobAdapter; +import org.onap.vid.job.JobType; +import org.onap.vid.model.VidNotions; +import org.onap.vid.mso.model.ModelInfo; +import org.onap.vid.utils.jackson.BooleanAsStringSerializer; public class ServiceInstantiation extends BaseResource implements JobAdapter.AsyncJobRequest { @@ -127,6 +128,13 @@ public class ServiceInstantiation extends BaseResource implements JobAdapter.Asy this.vidNotions = vidNotions; } + @Override + @JsonSerialize(using=BooleanAsStringSerializer.class) + public boolean isRollbackOnFailure() { + // this override is for the BooleanAsStringSerializer annotation, + // but for Service-Instance level only + return super.isRollbackOnFailure(); + } public String getOwningEntityId() { return owningEntityId; diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java new file mode 100644 index 000000000..17ce1bcc3 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 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.onap.vid.model.serviceInstantiation; + +import java.util.Map; +import java.util.Objects; +import org.onap.vid.model.aaiTree.ExistingElementsCounterMaps; + +public class ServiceInstantiationTemplate extends ServiceInstantiation implements ExistingElementsCounterMaps { + + private final Map<String, Long> existingVNFCounterMap; + private final Map<String, Long> existingNetworksCounterMap; + private final Map<String, Long> existingVnfGroupCounterMap; + private final Map<String, Long> existingVRFCounterMap; + + public ServiceInstantiationTemplate( + ServiceInstantiation baseService, + Map<String, Long> vnfCounterMap, + Map<String, Long> networksCounterMap, + Map<String, Long> vnfGroupCounterMap, + Map<String, Long> VRFCounterMap + ) { + super( + baseService.getModelInfo(), baseService.getOwningEntityId(), baseService.getOwningEntityName(), + baseService.getProjectName(), baseService.getGlobalSubscriberId(), baseService.getSubscriberName(), + baseService.getProductFamilyId(), baseService.getInstanceName(), baseService.getSubscriptionServiceType(), + baseService.getLcpCloudRegionId(), baseService.getLcpCloudRegionId(), baseService.getTenantId(), + baseService.getTenantName(), baseService.getAicZoneId(), baseService.getAicZoneName(), + baseService.getVnfs(), baseService.getNetworks(), baseService.getVnfGroups(), baseService.getVrfs(), + baseService.getInstanceParams(), baseService.isPause(), baseService.getBulkSize(), + baseService.isRollbackOnFailure(), baseService.isALaCarte(), baseService.getTestApi(), + baseService.getInstanceId(), Objects.toString(baseService.getAction(), null), + baseService.getTrackById(), baseService.getIsFailed(), baseService.getStatusMessage(), + baseService.getVidNotions() + ); + + this.existingVNFCounterMap = vnfCounterMap; + this.existingNetworksCounterMap = networksCounterMap; + this.existingVnfGroupCounterMap = vnfGroupCounterMap; + this.existingVRFCounterMap = VRFCounterMap; + } + + @Override + public Map<String, Long> getExistingVNFCounterMap() { + return existingVNFCounterMap; + } + + @Override + public Map<String, Long> getExistingNetworksCounterMap() { + return existingNetworksCounterMap; + } + + @Override + public Map<String, Long> getExistingVnfGroupCounterMap() { + return existingVnfGroupCounterMap; + } + + @Override + public Map<String, Long> getExistingVRFCounterMap() { + return existingVRFCounterMap; + } + +} diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java index 41da85e35..ad5b39e28 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import javax.annotation.Nullable; import org.onap.vid.job.JobAdapter; import org.onap.vid.job.JobType; import org.onap.vid.mso.model.ModelInfo; @@ -42,6 +43,12 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest @JsonInclude(NON_NULL) private Boolean usePreload; private Map<String, String> supplementaryParams; + @JsonInclude(NON_NULL) + private final Boolean retainVolumeGroups; + + @JsonInclude(NON_NULL) + private Boolean retainAssignments; + public VfModule(@JsonProperty("modelInfo") ModelInfo modelInfo, @JsonProperty("instanceName") String instanceName, @JsonProperty("volumeGroupName") String volumeGroupInstanceName, @@ -57,12 +64,16 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest @JsonProperty("trackById") String trackById, @JsonProperty("isFailed") Boolean isFailed, @JsonProperty("statusMessage") String statusMessage, + @Nullable @JsonProperty("retainAssignments") Boolean retainAssignments, + @Nullable @JsonProperty("retainVolumeGroups") Boolean retainVolumeGroups, @JsonProperty("position") Integer position) { super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage, position); this.volumeGroupInstanceName = volumeGroupInstanceName; this.usePreload = usePreload; this.supplementaryParams = supplementaryParams; + this.retainAssignments = retainAssignments; + this.retainVolumeGroups = retainVolumeGroups; } public String getVolumeGroupInstanceName() { @@ -93,6 +104,16 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest return JobType.VfmoduleInstantiation; } + @Nullable + public Boolean isRetainAssignments() { + return retainAssignments; + } + + @Nullable + public Boolean isRetainVolumeGroups() { + return retainVolumeGroups; + } + public VfModule cloneWith(ModelInfo modelInfo) { return new VfModule( modelInfo, @@ -110,6 +131,8 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest this.getTrackById(), this.getIsFailed(), this.getStatusMessage(), + this.isRetainAssignments(), + this.isRetainVolumeGroups(), this.getPosition()); } }
\ No newline at end of file diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleInstantiationRequestDetails.java b/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt index 3b6cd1d3d..bba4081dd 100644 --- a/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleInstantiationRequestDetails.java +++ b/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt @@ -17,16 +17,11 @@ * limitations under the License. * ============LICENSE_END========================================================= */ +package org.onap.vid.mso.model -package org.onap.vid.mso.model; - -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL +import java.util.* /* Based on this model: @@ -98,36 +93,33 @@ import java.util.Map; */ -public class VfModuleInstantiationRequestDetails extends BaseResourceInstantiationRequestDetails { - - public VfModuleInstantiationRequestDetails( - @JsonProperty(value = "modelInfo", required = true) ModelInfo modelInfo, - @JsonProperty(value = "cloudConfiguration", required = true) CloudConfiguration cloudConfiguration, - @JsonProperty(value = "requestInfo", required = true) RequestInfo requestInfo, - @JsonProperty(value = "relatedInstanceList", required = true) List<RelatedInstance> relatedInstanceList, - @JsonProperty(value = "requestParameters", required = true) RequestParametersVfModule requestParameters) - { - super(modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters); - } +data class VfModuleOrVolumeGroupRequestDetails( + val modelInfo: ModelInfo, + val cloudConfiguration: CloudConfiguration, + val requestInfo: RequestInfo, + val relatedInstanceList: List<RelatedInstance>?, + val requestParameters: RequestParametersVfModuleOrVolumeGroup?) + : BaseResourceInstantiationRequestDetails(modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters) - public static class RequestParametersVfModule extends BaseResourceInstantiationRequestDetails.RequestParameters { - @JsonInclude(NON_NULL) private final Boolean usePreload; +open class RequestParametersVfModuleOrVolumeGroup internal constructor( + userParams: List<UserParamTypes>, + @get:JsonInclude(NON_NULL) val isUsePreload: Boolean?, + testApi: String? +) : BaseResourceInstantiationRequestDetails.RequestParameters(userParams, testApi) - public RequestParametersVfModule(List<? extends UserParamTypes> userParams, Boolean usePreload, String testApi) { - super(userParams, testApi); - this.usePreload = usePreload; - } +class RequestParametersVfModuleOrVolumeGroupInstantiation( + userParams: List<UserParamTypes>, + usePreload: Boolean?, + testApi: String? +) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload, testApi) - public Boolean isUsePreload() { - return usePreload; - } - } +class RequestParametersVfModuleUpgrade( + userParams: List<UserParamTypes>, + usePreload: Boolean?, + testApi: String?, + @get:JsonInclude(NON_NULL) val retainAssignments: Boolean?, + @get:JsonInclude(NON_NULL) val rebuildVolumeGroups: Boolean? +) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload, testApi) - public static class UserParamMap<K,V> extends HashMap<K,V> implements UserParamTypes, Map<K,V> { - - public UserParamMap() { - super(); - } - } -} +class UserParamMap<K, V> : HashMap<K, V>(), UserParamTypes, MutableMap<K, V> diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/model/VolumeGroupRequestDetails.java b/vid-app-common/src/main/java/org/onap/vid/mso/model/VolumeGroupRequestDetails.java index e1a5e56dd..a637f85dc 100644 --- a/vid-app-common/src/main/java/org/onap/vid/mso/model/VolumeGroupRequestDetails.java +++ b/vid-app-common/src/main/java/org/onap/vid/mso/model/VolumeGroupRequestDetails.java @@ -21,7 +21,6 @@ package org.onap.vid.mso.model; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.List; public class VolumeGroupRequestDetails extends BaseResourceInstantiationRequestDetails { @@ -31,7 +30,7 @@ public class VolumeGroupRequestDetails extends BaseResourceInstantiationRequestD @JsonProperty(value = "cloudConfiguration", required = true) CloudConfiguration cloudConfiguration, @JsonProperty(value = "requestInfo", required = true) RequestInfo requestInfo, @JsonProperty(value = "relatedInstanceList", required = true) List<RelatedInstance> relatedInstanceList, - @JsonProperty(value = "requestParameters", required = true) VfModuleInstantiationRequestDetails.RequestParametersVfModule requestParameters) + @JsonProperty(value = "requestParameters", required = true) RequestParametersVfModuleOrVolumeGroup requestParameters) { super(modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters); } diff --git a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java index abee30025..990ec60c9 100644 --- a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java +++ b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java @@ -29,8 +29,6 @@ public enum Features implements Feature { * Use /docs/feature-flags.md for details */ - CREATE_INSTANCE_TEST, - EMPTY_DRAWING_BOARD_TEST, FLAG_ADD_MSO_TESTAPI_FIELD, FLAG_SERVICE_MODEL_CACHE, FLAG_NETWORK_TO_ASYNC_INSTANTIATION, @@ -38,8 +36,6 @@ public enum Features implements Feature { FLAG_UNASSIGN_SERVICE, FLAG_FABRIC_CONFIGURATION_ASSIGNMENTS, FLAG_SHOW_VERIFY_SERVICE, // AKA POMBA - FLAG_DEFAULT_VNF, - FLAG_SETTING_DEFAULTS_IN_DRAWING_BOARD, FLAG_RESTRICTED_SELECT, FLAG_5G_IN_NEW_INSTANTIATION_UI, FLAG_ASYNC_ALACARTE_VNF, @@ -51,7 +47,6 @@ public enum Features implements Feature { FLAG_ENABLE_WEBPACK_MODERN_UI, FLAG_1810_CR_LET_SELECTING_COLLECTOR_TYPE_UNCONDITIONALLY, FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST, - FLAG_1810_CR_SOFT_DELETE_ALACARTE_VF_MODULE, FLAG_1810_AAI_LOCAL_CACHE, FLAG_1810_IDENTIFY_SERVICE_FOR_NEW_UI, FLAG_1902_NEW_VIEW_EDIT, @@ -80,7 +75,14 @@ public enum Features implements Feature { FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT, FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH, FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE, - FLAG_1911_INSTANTIATION_ORDER_BUTTON_IN_ASYNC_ALACARTE + FLAG_2002_ANY_ALACARTE_BESIDES_EXCLUDED_NEW_INSTANTIATION_UI, + FLAG_2002_VNF_PLATFORM_MULTI_SELECT, + FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS, + FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND, + FLAG_2004_INSTANTIATION_STATUS_FILTER, + FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE, + FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER, + FLAG_2002_UNLIMITED_MAX, ; diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AAIServiceTree.java b/vid-app-common/src/main/java/org/onap/vid/services/AAIServiceTree.java index d62d5d5d4..7b0e5f56f 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AAIServiceTree.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AAIServiceTree.java @@ -20,8 +20,25 @@ package org.onap.vid.services; +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.toSet; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; +import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; + import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.ImmutableList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.inject.Inject; +import javax.ws.rs.core.Response; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.vid.aai.AaiClientInterface; import org.onap.vid.aai.util.AAITreeConverter; @@ -36,19 +53,6 @@ import org.onap.vid.utils.Tree; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; -import javax.inject.Inject; -import javax.ws.rs.core.Response; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.concurrent.ExecutorService; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static java.util.Comparator.comparing; -import static java.util.stream.Collectors.toSet; -import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; -import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; - @Component public class AAIServiceTree { @@ -207,12 +211,14 @@ public class AAIServiceTree { Map<String, String> modelNameByModelVersionId = new HashMap<>(); JsonNode models = getModels(aaiClient, invariantIDs); - for (JsonNode model: models) { - JsonNode modelVersions = model.get("model-vers").get("model-ver"); - for (JsonNode modelVersion: modelVersions) { - final String modelVersionId = modelVersion.get("model-version-id").asText(); - modelVersionByModelVersionId.put(modelVersionId, modelVersion.get("model-version").asText()); - modelNameByModelVersionId.put(modelVersionId, modelVersion.get("model-name").asText()); + if (models!=null) { + for (JsonNode model : models) { + JsonNode modelVersions = model.get("model-vers").get("model-ver"); + for (JsonNode modelVersion : modelVersions) { + final String modelVersionId = modelVersion.get("model-version-id").asText(); + modelVersionByModelVersionId.put(modelVersionId, modelVersion.get("model-version").asText()); + modelNameByModelVersionId.put(modelVersionId, modelVersion.get("model-name").asText()); + } } } diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AAITreeNodeBuilder.java b/vid-app-common/src/main/java/org/onap/vid/services/AAITreeNodeBuilder.java index c8434609e..209f37025 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AAITreeNodeBuilder.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AAITreeNodeBuilder.java @@ -59,6 +59,7 @@ import org.onap.vid.model.aaiTree.FailureAAITreeNode; import org.onap.vid.model.aaiTree.NodeType; import org.onap.vid.mso.model.CloudConfiguration; import org.onap.vid.properties.VidProperties; +import org.onap.vid.utils.Logging; import org.onap.vid.utils.Streams; import org.onap.vid.utils.Tree; import org.onap.vid.utils.Unchecked; @@ -71,7 +72,8 @@ import org.springframework.stereotype.Component; public class AAITreeNodeBuilder { private static final String RESULTS = "results"; - private AaiClientInterface aaiClient; + private final AaiClientInterface aaiClient; + private final Logging logging; private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AAITreeNodeBuilder.class); @@ -97,8 +99,9 @@ public class AAITreeNodeBuilder { } @Inject - public AAITreeNodeBuilder(AaiClientInterface aaiClient) { + public AAITreeNodeBuilder(AaiClientInterface aaiClient, Logging logging) { this.aaiClient = aaiClient; + this.logging = logging; } List<AAITreeNode> buildNode(NodeType nodeType, @@ -296,13 +299,7 @@ public class AAITreeNodeBuilder { } private <V> Callable<V> withCopyOfMDC(Callable<V> callable) { - //in order to be able to write the correct data while creating the node on a new thread - // save a copy of the current thread's context map, with keys and values of type String. - final Map<String, String> copyOfParentMDC = MDC.getCopyOfContextMap(); - return () -> { - MDC.setContextMap(copyOfParentMDC); - return callable.call(); - }; + return logging.withMDC(MDC.getCopyOfContextMap(), callable); } private List<AAITreeNode> getChildNode(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator, diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java index b64a233c7..b3ac16884 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java @@ -87,7 +87,9 @@ import org.onap.vid.model.aaiTree.VpnBinding; import org.onap.vid.model.aaiTree.VpnBindingKt; import org.onap.vid.roles.RoleValidator; import org.onap.vid.utils.Intersection; +import org.onap.vid.utils.Logging; import org.onap.vid.utils.Tree; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; @@ -104,6 +106,7 @@ public class AaiServiceImpl implements AaiService { private AaiResponseTranslator aaiResponseTranslator; private AAIServiceTree aaiServiceTree; private ExecutorService executorService; + private final Logging logging; private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AaiServiceImpl.class); @@ -113,12 +116,13 @@ public class AaiServiceImpl implements AaiService { AaiClientInterface aaiClient, AaiResponseTranslator aaiResponseTranslator, AAIServiceTree aaiServiceTree, - ExecutorService executorService) + ExecutorService executorService, Logging logging) { this.aaiClient = aaiClient; this.aaiResponseTranslator = aaiResponseTranslator; this.aaiServiceTree = aaiServiceTree; this.executorService = executorService; + this.logging = logging; } private List<Service> convertModelToService(Model model) { @@ -523,10 +527,12 @@ public class AaiServiceImpl implements AaiService { .map(RelatedVnf::from) .collect(Collectors.toList()); + final Map<String, String> copyOfParentMDC = MDC.getCopyOfContextMap(); + try { return executorService.submit(() -> convertedVnfs.parallelStream() - .map(this::enrichRelatedVnfWithCloudRegionAndTenant) + .map(logging.withMDC(copyOfParentMDC, this::enrichRelatedVnfWithCloudRegionAndTenant)) .collect(Collectors.toList()) ).get(); } catch (Exception e) { diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogic.java b/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogic.java index 1202fc9e3..bb1121339 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogic.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogic.java @@ -20,6 +20,10 @@ package org.onap.vid.services; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; import org.onap.vid.aai.model.ResourceType; import org.onap.vid.job.Job; import org.onap.vid.job.impl.JobSharedData; @@ -28,11 +32,6 @@ import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; import org.onap.vid.mso.RestObject; import org.onap.vid.mso.rest.AsyncRequestStatus; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import java.util.function.Consumer; - public interface AsyncInstantiationBusinessLogic { List<String> PARAMS_TO_IGNORE = Arrays.asList("vnf_name", "vf_module_name"); diff --git a/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java b/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java new file mode 100644 index 000000000..aa0031104 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 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.onap.vid.services; + +import static java.util.Collections.emptyMap; +import static java.util.Objects.requireNonNull; + +import java.util.Map; +import java.util.UUID; +import javax.inject.Inject; +import org.onap.vid.dal.AsyncInstantiationRepository; +import org.onap.vid.model.ModelUtil; +import org.onap.vid.model.serviceInstantiation.BaseResource; +import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; +import org.onap.vid.model.serviceInstantiation.ServiceInstantiationTemplate; +import org.springframework.stereotype.Component; + +@Component +public class InstantiationTemplatesService { + + private final ModelUtil modelUtil; + private final AsyncInstantiationRepository asyncInstantiationRepository; + + @Inject + public InstantiationTemplatesService(ModelUtil modelUtil, + AsyncInstantiationRepository asyncInstantiationRepository) { + this.modelUtil = modelUtil; + this.asyncInstantiationRepository = asyncInstantiationRepository; + } + + public ServiceInstantiationTemplate getJobRequestAsTemplate(UUID jobId) { + ServiceInstantiation jobRequest = requireNonNull(asyncInstantiationRepository.getJobRequest(jobId)); + + return new ServiceInstantiationTemplate( + jobRequest, + counterMap(jobRequest.getVnfs()), + counterMap(jobRequest.getNetworks()), + counterMap(jobRequest.getVnfGroups()), + emptyMap() // model info for VRF is not stored + ); + } + + private <T extends BaseResource> Map<String, Long> counterMap(Map<String, T> nodesToCount) { + return modelUtil.getExistingCounterMap( + nodesToCount, BaseResource::getModelInfo + ); + } + +} diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java index 0d8e58878..43f059d54 100644 --- a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java +++ b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java @@ -33,8 +33,11 @@ import com.google.common.collect.ImmutableList; import io.joshworks.restclient.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Map; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.function.Function; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; @@ -42,6 +45,8 @@ import org.apache.commons.lang3.StringUtils; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.util.SystemProperties; import org.onap.vid.exceptions.GenericUncheckedException; +import org.onap.vid.utils.Unchecked.UncheckedThrowingSupplier; +import org.slf4j.MDC; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; @@ -197,5 +202,29 @@ public class Logging { } } + /** + * in order to be able to write the correct data while creating the node on a new thread save a copy of the current + * thread's context map, with keys and values of type String. + */ + public <T> Callable<T> withMDC(Map<String, String> copyOfParentMDC, Callable<T> callable) { + return () -> withMDCInternal(copyOfParentMDC, callable::call); + } + + /** + * in order to be able to write the correct data while creating the node on a new thread save a copy of the current + * thread's context map, with keys and values of type String. + */ + public <T, U> Function<T, U> withMDC(Map<String, String> copyOfParentMDC, Function<T, U> function) { + return t -> withMDCInternal(copyOfParentMDC, () -> function.apply(t)); + } + + <T> T withMDCInternal(Map<String, String> copyOfParentMDC, UncheckedThrowingSupplier<T> supplier) { + try { + MDC.setContextMap(copyOfParentMDC); + return supplier.get(); + } finally { + MDC.clear(); + } + } } diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/Unchecked.java b/vid-app-common/src/main/java/org/onap/vid/utils/Unchecked.java index 23127b61a..9fb15f690 100644 --- a/vid-app-common/src/main/java/org/onap/vid/utils/Unchecked.java +++ b/vid-app-common/src/main/java/org/onap/vid/utils/Unchecked.java @@ -20,10 +20,11 @@ package org.onap.vid.utils; -import org.onap.vid.exceptions.GenericUncheckedException; - import java.net.URI; import java.net.URISyntaxException; +import java.util.function.Supplier; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.onap.vid.exceptions.GenericUncheckedException; public class Unchecked { private Unchecked() { @@ -39,5 +40,19 @@ public class Unchecked { } } + @FunctionalInterface + public interface UncheckedThrowingSupplier<T> extends Supplier<T> { + + @Override + default T get() { + try { + return getThrows(); + } catch (Exception e) { + return ExceptionUtils.rethrow(e); + } + } + + T getThrows() throws Exception; + } } diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java b/vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java new file mode 100644 index 000000000..a61044294 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 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.onap.vid.utils.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import java.io.IOException; + +public class BooleanAsStringSerializer extends JsonSerializer<Boolean> { + + /** + * Annotate a Jackson getter with <code>@JsonSerialize(using=BooleanAsStringSerializer.class)</code> + * to get a boolean value be serialized as quoted string. + */ + @Override + public void serialize(Boolean bool, JsonGenerator generator, SerializerProvider provider) throws IOException { + // bool is guaranteed not to be null + generator.writeString(bool.toString()); + } +} |