2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.vid.services;
23 import com.fasterxml.jackson.core.type.TypeReference;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import com.google.common.collect.ImmutableList;
26 import com.google.common.collect.ImmutableMap;
27 import org.apache.commons.lang3.StringUtils;
28 import org.hibernate.SessionFactory;
29 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
30 import org.onap.portalsdk.core.service.DataAccessService;
31 import org.onap.vid.aai.AaiClientInterface;
32 import org.onap.vid.aai.ExceptionWithRequestInfo;
33 import org.onap.vid.aai.model.ResourceType;
34 import org.onap.vid.changeManagement.RequestDetailsWrapper;
35 import org.onap.vid.exceptions.DbFailureUncheckedException;
36 import org.onap.vid.exceptions.GenericUncheckedException;
37 import org.onap.vid.exceptions.MaxRetriesException;
38 import org.onap.vid.exceptions.OperationNotAllowedException;
39 import org.onap.vid.job.Job;
40 import org.onap.vid.job.Job.JobStatus;
41 import org.onap.vid.job.JobAdapter;
42 import org.onap.vid.job.JobType;
43 import org.onap.vid.job.JobsBrokerService;
44 import org.onap.vid.model.Action;
45 import org.onap.vid.model.JobAuditStatus;
46 import org.onap.vid.model.NameCounter;
47 import org.onap.vid.model.ServiceInfo;
48 import org.onap.vid.model.serviceInstantiation.*;
49 import org.onap.vid.mso.MsoBusinessLogicImpl;
50 import org.onap.vid.mso.MsoProperties;
51 import org.onap.vid.mso.model.*;
52 import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.RequestParameters;
53 import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.*;
54 import org.onap.vid.mso.model.VfModuleInstantiationRequestDetails.RequestParametersVfModule;
55 import org.onap.vid.mso.model.VfModuleInstantiationRequestDetails.UserParamMap;
56 import org.onap.vid.mso.rest.AsyncRequestStatus;
57 import org.onap.vid.mso.rest.SubscriberInfo;
58 import org.onap.vid.properties.Features;
59 import org.onap.vid.utils.DaoUtils;
60 import org.springframework.beans.factory.annotation.Autowired;
61 import org.springframework.stereotype.Service;
62 import org.togglz.core.manager.FeatureManager;
64 import java.sql.Timestamp;
65 import java.time.LocalDateTime;
67 import java.util.function.Consumer;
68 import java.util.stream.Collectors;
70 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
71 import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID;
72 import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID;
73 import static org.onap.vid.utils.Logging.debugRequestDetails;
76 public class AsyncInstantiationBusinessLogicImpl implements
77 AsyncInstantiationBusinessLogic {
79 private static final int MAX_RETRIES_GETTING_COUNTER = 100;
80 private static final int MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI = 10000;
81 public static final String NAME_FOR_CHECK_AAI_STATUS = "NAME_FOR_CHECK_AAI_STATUS";
82 private static final String VID_SOURCE = "VID";
84 private final DataAccessService dataAccessService;
86 private final JobAdapter jobAdapter;
88 private final JobsBrokerService jobService;
90 private final CloudOwnerService cloudOwnerService;
92 private SessionFactory sessionFactory;
94 private AaiClientInterface aaiClient;
96 private FeatureManager featureManager;
98 private int maxRetriesGettingFreeNameFromAai = MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI;
100 private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AsyncInstantiationBusinessLogicImpl.class);
101 private Map<String, JobStatus> msoStateToJobStatusMap = ImmutableMap.<String, JobStatus>builder()
102 .put("inprogress", JobStatus.IN_PROGRESS)
103 .put("failed", JobStatus.FAILED)
104 .put("pause", JobStatus.PAUSE)
105 .put("paused", JobStatus.PAUSE)
106 .put("complete", JobStatus.COMPLETED)
107 .put("pending", JobStatus.IN_PROGRESS)
108 .put("pendingmanualtask", JobStatus.PAUSE)
109 .put("unlocked", JobStatus.IN_PROGRESS)
114 public AsyncInstantiationBusinessLogicImpl(DataAccessService dataAccessService,
115 JobAdapter jobAdapter,
116 JobsBrokerService jobService,
117 SessionFactory sessionFactory,
118 AaiClientInterface aaiClient,
119 FeatureManager featureManager,
120 CloudOwnerService cloudOwnerService) {
121 this.dataAccessService = dataAccessService;
122 this.jobAdapter = jobAdapter;
123 this.jobService = jobService;
124 this.sessionFactory = sessionFactory;
125 this.aaiClient = aaiClient;
126 this.featureManager = featureManager;
127 this.cloudOwnerService = cloudOwnerService;
131 public List<ServiceInfo> getAllServicesInfo() {
132 return dataAccessService.getList(ServiceInfo.class, filterByCreationDateAndNotDeleted(), orderByCreatedDateAndStatus(), null);
135 private String filterByCreationDateAndNotDeleted() {
136 LocalDateTime minus3Months = LocalDateTime.now().minusMonths(3);
137 Timestamp filterDate = Timestamp.valueOf(minus3Months);
140 " and deleted_at is null" + // don't fetch deleted
141 " and created >= '" + filterDate + "' ";
144 private String orderByCreatedDateAndStatus() {
145 return " createdBulkDate DESC ,\n" +
146 " (CASE jobStatus\n" +
147 " WHEN 'COMPLETED' THEN 0\n" +
148 " WHEN 'FAILED' THEN 0\n" +
149 " WHEN 'COMPLETED_WITH_ERRORS' THEN 0\n" +
150 " WHEN 'IN_PROGRESS' THEN 1\n" +
151 " WHEN 'PAUSE' THEN 2\n" +
152 " WHEN 'PENDING' THEN 3\n" +
153 " WHEN 'STOPPED' THEN 3 END),\n" +
154 " statusModifiedDate ";
157 JobType getJobType(ServiceInstantiation request) {
158 if (request.isALaCarte()) {
159 switch (defaultIfNull(request.getAction(), Action.Create)) {
161 return JobType.ALaCarteService;
163 return JobType.ALaCarteService;
165 return JobType.ALaCarteServiceInstantiation;
168 return JobType.MacroServiceInstantiation;
173 public List<UUID> pushBulkJob(ServiceInstantiation request, String userId) {
174 List<UUID> uuids = new ArrayList<>();
175 Date createdBulkDate = Calendar.getInstance().getTime();
176 int bulkSize = request.getBulkSize();
177 UUID templateId = UUID.randomUUID();
178 for (int i = 0; i < bulkSize; i++) {
179 ServiceInfo.ServiceAction serviceAction = getAction(request);
180 JobType jobType = getJobType(request);
181 final String optimisticUniqueServiceInstanceName = getOptimisticUniqueServiceInstanceName(request);
182 Job job = jobAdapter.createServiceInstantiationJob(jobType, request, templateId, userId, optimisticUniqueServiceInstanceName, i);
183 UUID jobId = jobService.add(job);
184 dataAccessService.saveDomainObject(createServiceInfo(userId, request, jobId, templateId, createdBulkDate, optimisticUniqueServiceInstanceName, serviceAction), DaoUtils.getPropsMap());
185 auditVidStatus(jobId, job.getStatus());
191 private ServiceInfo.ServiceAction getAction(ServiceInstantiation request) {
192 if (request.getAction() == null) {
193 //throw new GenericUncheckedException("Required 'action' field not provided at service level");
194 return Action.Create.getServiceAction();
196 return request.getAction().getServiceAction();
200 private String getOptimisticUniqueServiceInstanceName(ServiceInstantiation request) {
201 return StringUtils.isNotEmpty(request.getInstanceName()) ? getUniqueNameFromDbOnly(request.getInstanceName()) : request.getInstanceName();
204 protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId, UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName, ServiceInfo.ServiceAction serviceAction) {
205 return new ServiceInfo(
207 serviceInstantiation.isALaCarte(),
208 Job.JobStatus.PENDING, serviceInstantiation.isPause(), jobId, templateId,
209 serviceInstantiation.getOwningEntityId(),
210 serviceInstantiation.getOwningEntityName(),
211 serviceInstantiation.getProjectName(),
212 serviceInstantiation.getAicZoneId(),
213 serviceInstantiation.getAicZoneName(),
214 serviceInstantiation.getTenantId(),
215 serviceInstantiation.getTenantName(),
216 serviceInstantiation.getLcpCloudRegionId(),
218 serviceInstantiation.getSubscriptionServiceType(),
219 serviceInstantiation.getSubscriberName(),
220 serviceInstantiation.getGlobalSubscriberId(),
221 serviceInstantiation.getInstanceId(),
222 optimisticUniqueServiceInstanceName,
223 serviceInstantiation.getModelInfo().getModelVersionId(),
224 serviceInstantiation.getModelInfo().getModelName(),
225 serviceInstantiation.getModelInfo().getModelVersion(),
233 public RequestDetailsWrapper<ServiceInstantiationRequestDetails> generateMacroServiceInstantiationRequest(UUID jobId, ServiceInstantiation payload, String optimisticUniqueServiceInstanceName, String userId) {
234 String serviceInstanceName = generateServiceName(jobId, payload, optimisticUniqueServiceInstanceName);
236 List<ServiceInstantiationService> serviceInstantiationServiceList = generateServiceInstantiationServicesList(payload, serviceInstanceName, createServiceInstantiationVnfList(payload));
238 RequestParameters requestParameters = new RequestParameters(payload.getSubscriptionServiceType(), false, serviceInstantiationServiceList);
240 ServiceInstantiationRequestDetails requestDetails = generateServiceInstantiationRequestDetails(payload,requestParameters,serviceInstanceName, userId);
242 RequestDetailsWrapper<ServiceInstantiationRequestDetails> requestDetailsWrapper = new RequestDetailsWrapper<>(requestDetails);
243 debugRequestDetails(requestDetailsWrapper, logger);
245 return requestDetailsWrapper;
249 public RequestDetailsWrapper<ServiceInstantiationRequestDetails> generateALaCarteServiceInstantiationRequest(UUID jobId, ServiceInstantiation payload, String optimisticUniqueServiceInstanceName, String userId) {
250 String serviceInstanceName = generateServiceName(jobId, payload, optimisticUniqueServiceInstanceName);
252 List<UserParamNameAndValue> userParams = generateUserParamList();
254 RequestParameters requestParameters = new RequestParameters(payload.getSubscriptionServiceType(), true, userParams, payload.getTestApi());
256 ServiceInstantiationRequestDetails requestDetails = generateServiceInstantiationRequestDetails(payload,requestParameters,serviceInstanceName, userId);
258 RequestDetailsWrapper<ServiceInstantiationRequestDetails> requestDetailsWrapper = new RequestDetailsWrapper<>(requestDetails);
259 debugRequestDetails(requestDetailsWrapper, logger);
260 return requestDetailsWrapper;
265 public RequestDetailsWrapper<ServiceDeletionRequestDetails> generateALaCarteServiceDeletionRequest(UUID jobId, ServiceInstantiation payload, String userId){
267 ServiceDeletionRequestDetails.RequestParameters requestParameters = new ServiceDeletionRequestDetails.RequestParameters( true, payload.getTestApi());
269 ServiceDeletionRequestDetails.RequestInfo requestInfo = new ServiceDeletionRequestDetails.RequestInfo(
273 ServiceDeletionRequestDetails requestDetails = new ServiceDeletionRequestDetails(payload.getModelInfo(), requestInfo, requestParameters);
275 RequestDetailsWrapper<ServiceDeletionRequestDetails> requestDetailsWrapper = new RequestDetailsWrapper<>(requestDetails);
276 debugRequestDetails(requestDetailsWrapper, logger);
277 return requestDetailsWrapper;
281 public RequestDetailsWrapper<VnfInstantiationRequestDetails> generateVnfInstantiationRequest(Vnf vnfDetails, ModelInfo serviceModelInfo, String serviceInstanceId, String userId) {
283 VnfInstantiationRequestDetails.RequestInfo requestInfo = new VnfInstantiationRequestDetails.RequestInfo(
284 getUniqueNameIfNeeded(vnfDetails.getInstanceName(), ResourceType.GENERIC_VNF),
285 vnfDetails.getProductFamilyId(),
287 vnfDetails.isRollbackOnFailure(),
289 CloudConfiguration cloudConfiguration = generateCloudConfiguration(vnfDetails.getLcpCloudRegionId(), vnfDetails.getTenantId());
290 VnfInstantiationRequestDetails.Platform platform = new VnfInstantiationRequestDetails.Platform(vnfDetails.getPlatformName());
291 VnfInstantiationRequestDetails.LineOfBusiness lineOfBusiness = new VnfInstantiationRequestDetails.LineOfBusiness(vnfDetails.getLineOfBusiness());
292 VnfInstantiationRequestDetails.RequestParameters requestParameters = new VnfInstantiationRequestDetails.RequestParameters(generateUserParamList());
293 VnfInstantiationRequestDetails.RelatedInstance serviceInstance = new VnfInstantiationRequestDetails.RelatedInstance(serviceModelInfo, serviceInstanceId);
294 List<VnfInstantiationRequestDetails.RelatedInstance> relatedInstanceList = new ArrayList<>();
295 relatedInstanceList.add(serviceInstance);
296 return new RequestDetailsWrapper<>(new VnfInstantiationRequestDetails(vnfDetails.getModelInfo(), cloudConfiguration, requestInfo, platform, lineOfBusiness, relatedInstanceList, requestParameters));
300 public RequestDetailsWrapper<VfModuleInstantiationRequestDetails> generateVfModuleInstantiationRequest(VfModule vfModuleDetails, ModelInfo serviceModelInfo, String serviceInstanceId, ModelInfo vnfModelInfo, String vnfInstanceId, String vgInstanceId, String userId) {
302 VfModuleInstantiationRequestDetails.RequestInfo requestInfo = new VfModuleInstantiationRequestDetails.RequestInfo(
303 getUniqueNameIfNeeded(vfModuleDetails.getInstanceName(), ResourceType.VF_MODULE),
306 vfModuleDetails.isRollbackOnFailure(),
309 //cloud configuration
310 CloudConfiguration cloudConfiguration = generateCloudConfiguration(vfModuleDetails.getLcpCloudRegionId(), vfModuleDetails.getTenantId());
313 List<UserParamMap<String, String>> userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.getInstanceParams()), vfModuleDetails.getSupplementaryParams());
314 RequestParametersVfModule requestParameters = new RequestParametersVfModule(userParams, vfModuleDetails.isUsePreload());
316 //related instance list
317 VfModuleInstantiationRequestDetails.RelatedInstance serviceInstance = new VfModuleInstantiationRequestDetails.RelatedInstance(serviceModelInfo, serviceInstanceId);
318 VfModuleInstantiationRequestDetails.RelatedInstance vnfInstance = new VfModuleInstantiationRequestDetails.RelatedInstance(vnfModelInfo, vnfInstanceId);
319 List<VfModuleInstantiationRequestDetails.RelatedInstance> relatedInstanceList = new ArrayList<>();
320 relatedInstanceList.add(serviceInstance);
321 relatedInstanceList.add(vnfInstance);
322 if (vgInstanceId != null) {
323 ModelInfo volumeGroupModel = new ModelInfo();
324 volumeGroupModel.setModelType("volumeGroup");
325 VfModuleInstantiationRequestDetails.RelatedInstance volumeGroupInstance = new VfModuleInstantiationRequestDetails.RelatedInstance(volumeGroupModel, vgInstanceId, vfModuleDetails.getVolumeGroupInstanceName());
326 relatedInstanceList.add(volumeGroupInstance);
329 return new RequestDetailsWrapper<>(new VfModuleInstantiationRequestDetails(vfModuleDetails.getModelInfo(), cloudConfiguration, requestInfo, relatedInstanceList, requestParameters));
332 protected CloudConfiguration generateCloudConfiguration(String lcpCloudRegionId, String tenantId) {
333 CloudConfiguration cloudConfiguration = new CloudConfiguration();
334 cloudConfiguration.setLcpCloudRegionId(lcpCloudRegionId);
335 cloudConfiguration.setTenantId(tenantId);
336 cloudOwnerService.enrichCloudConfigurationWithCloudOwner(cloudConfiguration, lcpCloudRegionId);
337 return cloudConfiguration;
341 public RequestDetailsWrapper<VolumeGroupRequestDetails> generateVolumeGroupInstantiationRequest(VfModule vfModuleDetails, ModelInfo serviceModelInfo, String serviceInstanceId, ModelInfo vnfModelInfo, String vnfInstanceId, String userId) {
342 VolumeGroupRequestDetails.RequestInfo requestInfo = new VolumeGroupRequestDetails.RequestInfo(
343 getUniqueNameIfNeeded(vfModuleDetails.getVolumeGroupInstanceName(), ResourceType.VOLUME_GROUP),
346 vfModuleDetails.isRollbackOnFailure(),
348 CloudConfiguration cloudConfiguration = generateCloudConfiguration(vfModuleDetails.getLcpCloudRegionId(), vfModuleDetails.getTenantId());
350 List<UserParamMap<String, String>> userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.getInstanceParams()), vfModuleDetails.getSupplementaryParams());
351 RequestParametersVfModule requestParameters = new RequestParametersVfModule(userParams, vfModuleDetails.isUsePreload());
353 VfModuleInstantiationRequestDetails.RelatedInstance serviceInstance = new VfModuleInstantiationRequestDetails.RelatedInstance(serviceModelInfo, serviceInstanceId);
354 VfModuleInstantiationRequestDetails.RelatedInstance vnfInstance = new VfModuleInstantiationRequestDetails.RelatedInstance(vnfModelInfo, vnfInstanceId);
355 List<VfModuleInstantiationRequestDetails.RelatedInstance> relatedInstancs = ImmutableList.of(serviceInstance, vnfInstance);
357 ModelInfo modelInfo = vfModuleDetails.getModelInfo();
358 modelInfo.setModelType("volumeGroup");
359 return new RequestDetailsWrapper<>(new VolumeGroupRequestDetails(modelInfo, cloudConfiguration, requestInfo, relatedInstancs, requestParameters));
362 protected List<UserParamMap<String, String>> aggregateAllInstanceParams(Map<String, String> instanceParams, Map<String, String> supplementaryParams) {
363 Map<String, String> instanceParamsFinal = defaultIfNull(instanceParams, new HashMap<>());
364 Map<String, String> supplementaryParamsFinal = defaultIfNull(supplementaryParams, new HashMap<>());
366 if (!(instanceParamsFinal.isEmpty() && supplementaryParamsFinal.isEmpty())) {
367 //remove duplicate keys from instanceParams if exist in supplementaryParams
368 instanceParamsFinal = instanceParams.entrySet().stream().filter(m->
369 !supplementaryParamsFinal.containsKey(m.getKey())
370 ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
372 //aggregate the 2 collections and format them as UserParamMap
373 UserParamMap<String, String> aggregatedParams = new UserParamMap<>();
374 aggregatedParams.putAll(instanceParamsFinal);
375 aggregatedParams.putAll(supplementaryParamsFinal);
377 return ImmutableList.of(aggregatedParams);
380 return Collections.emptyList();
384 public RequestDetailsWrapper<NetworkInstantiationRequestDetails> generateNetworkInstantiationRequest(Network networkDetails, ModelInfo serviceModelInfo, String serviceInstanceId, String userId) {
386 NetworkInstantiationRequestDetails.RequestInfo requestInfo = new NetworkInstantiationRequestDetails.RequestInfo(
387 getUniqueNameIfNeeded(networkDetails.getInstanceName(), ResourceType.L3_NETWORK),
388 networkDetails.getProductFamilyId(),
390 networkDetails.isRollbackOnFailure(),
392 CloudConfiguration cloudConfiguration = generateCloudConfiguration(networkDetails.getLcpCloudRegionId(), networkDetails.getTenantId());
393 NetworkInstantiationRequestDetails.Platform platform = new NetworkInstantiationRequestDetails.Platform(networkDetails.getPlatformName());
394 NetworkInstantiationRequestDetails.LineOfBusiness lineOfBusiness = new NetworkInstantiationRequestDetails.LineOfBusiness(networkDetails.getLineOfBusiness());
395 NetworkInstantiationRequestDetails.RequestParameters requestParameters = new NetworkInstantiationRequestDetails.RequestParameters(generateUserParamList());
396 NetworkInstantiationRequestDetails.RelatedInstance serviceInstance = new NetworkInstantiationRequestDetails.RelatedInstance(serviceModelInfo, serviceInstanceId);
397 List<NetworkInstantiationRequestDetails.RelatedInstance> relatedInstanceList = new ArrayList<>();
398 relatedInstanceList.add(serviceInstance);
399 return new RequestDetailsWrapper<>(new NetworkInstantiationRequestDetails(networkDetails.getModelInfo(), cloudConfiguration, requestInfo, platform, lineOfBusiness, relatedInstanceList, requestParameters));
403 public RequestDetailsWrapper<InstanceGroupInstantiationRequestDetails> generateInstanceGroupInstantiationRequest(InstanceGroup instanceGroupDetails, ModelInfo serviceModelInfo, String serviceInstanceId, String userId) {
404 InstanceGroupInstantiationRequestDetails.RequestInfo requestInfo = new InstanceGroupInstantiationRequestDetails.RequestInfo(
405 getUniqueNameIfNeeded(instanceGroupDetails.getInstanceName(), ResourceType.INSTANCE_GROUP),
408 instanceGroupDetails.isRollbackOnFailure(),
410 InstanceGroupInstantiationRequestDetails.RequestParameters requestParameters = new InstanceGroupInstantiationRequestDetails.RequestParameters(generateUserParamList());
411 InstanceGroupInstantiationRequestDetails.RelatedInstance serviceInstance = new InstanceGroupInstantiationRequestDetails.RelatedInstance(serviceModelInfo, serviceInstanceId);
412 List<InstanceGroupInstantiationRequestDetails.RelatedInstance> relatedInstanceList = ImmutableList.of(serviceInstance);
413 return new RequestDetailsWrapper<>(new InstanceGroupInstantiationRequestDetails(instanceGroupDetails.getModelInfo(), requestInfo, relatedInstanceList, requestParameters));
417 private List<UserParamNameAndValue> generateUserParamList() {
418 return Collections.emptyList();
421 protected List<ServiceInstantiationService> generateServiceInstantiationServicesList(ServiceInstantiation payload, String serviceInstanceName, ServiceInstantiationVnfList vnfList) {
422 List<ServiceInstantiationService> serviceInstantiationServiceList = new LinkedList<>();
423 List<Map<String, String>> unFilteredInstanceParams = defaultIfNull(payload.getInstanceParams(), Collections.emptyList());
424 List<Map<String, String>> filteredInstanceParams = removeUnNeededParams(unFilteredInstanceParams);
425 ServiceInstantiationService serviceInstantiationService = new ServiceInstantiationService(
426 payload.getModelInfo(),
428 filteredInstanceParams,
431 serviceInstantiationServiceList.add(serviceInstantiationService);
432 return serviceInstantiationServiceList;
435 private ServiceInstantiationRequestDetails generateServiceInstantiationRequestDetails(ServiceInstantiation payload, RequestParameters requestParameters, String serviceInstanceName, String userId) {
436 ServiceInstantiationRequestDetails.RequestInfo requestInfo = new ServiceInstantiationRequestDetails.RequestInfo(serviceInstanceName,
437 payload.getProductFamilyId(),
439 payload.isRollbackOnFailure(),
441 ServiceInstantiationOwningEntity owningEntity = new ServiceInstantiationOwningEntity(payload.getOwningEntityId(), payload.getOwningEntityName());
442 SubscriberInfo subscriberInfo = generateSubscriberInfo(payload);
443 Project project = payload.getProjectName() != null ? new Project(payload.getProjectName()) : null;
444 return new ServiceInstantiationRequestDetails(payload.getModelInfo(), owningEntity, subscriberInfo, project, requestInfo, requestParameters);
448 protected SubscriberInfo generateSubscriberInfo(ServiceInstantiation payload) {
449 SubscriberInfo subscriberInfo = new SubscriberInfo();
450 subscriberInfo.setGlobalSubscriberId(payload.getGlobalSubscriberId());
451 return subscriberInfo;
454 protected String generateServiceName(UUID jobId, ServiceInstantiation payload, String optimisticUniqueServiceInstanceName) {
455 String serviceInstanceName = null;
456 if(StringUtils.isNotEmpty(optimisticUniqueServiceInstanceName)) {
457 serviceInstanceName = peekServiceName(jobId, payload, optimisticUniqueServiceInstanceName);
459 return serviceInstanceName;
462 protected String peekServiceName(UUID jobId, ServiceInstantiation payload, String optimisticUniqueServiceInstanceName) {
463 String serviceInstanceName;
464 // unique name already exist in service info. If it's free in AAI we use it
465 if (isNameFreeInAai(optimisticUniqueServiceInstanceName, ResourceType.SERVICE_INSTANCE)) {
466 serviceInstanceName = optimisticUniqueServiceInstanceName;
468 //otherwise we used the original service instance name (from payload) to get a new unique name from DB and AAI
470 serviceInstanceName = getUniqueName(payload.getInstanceName(), ResourceType.SERVICE_INSTANCE);
473 //update serviceInfo with new name if needed
475 updateServiceInfo(jobId, x -> x.setServiceInstanceName(serviceInstanceName));
476 } catch (Exception e) {
477 logger.error("Failed updating service name {} in serviceInfo", serviceInstanceName, e);
480 return serviceInstanceName;
484 public List<Map<String,String>> buildVnfInstanceParams(List<Map<String, String>> currentVnfInstanceParams, List<VfModuleMacro> vfModules){
485 List<Map<String, String>> filteredVnfInstanceParams = removeUnNeededParams(currentVnfInstanceParams);
487 if (!featureManager.isActive(Features.FLAG_SHIFT_VFMODULE_PARAMS_TO_VNF)) {
488 return filteredVnfInstanceParams;
491 Map<String,String> vnfInstanceParams = extractActualInstanceParams(filteredVnfInstanceParams);
493 .map(x->extractActualInstanceParams(x.getInstanceParams()))
494 .forEach(vnfInstanceParams::putAll);
495 return vnfInstanceParams.isEmpty() ? Collections.emptyList() : ImmutableList.of(vnfInstanceParams);
498 //Make sure we always get a one Map from InstanceParams
499 private Map<String, String> extractActualInstanceParams(List<Map<String, String>> originalInstanceParams) {
500 if (originalInstanceParams==null || originalInstanceParams.isEmpty() || originalInstanceParams.get(0)==null) {
501 return new HashMap<>();
503 return originalInstanceParams.get(0);
506 private List<Map<String, String>> removeUnNeededParams(List<Map<String, String>> instanceParams) {
507 List<String> keysToRemove = new ArrayList<>();
508 if (instanceParams == null || instanceParams.isEmpty()) {
509 return Collections.emptyList();
512 for (String key : instanceParams.get(0).keySet()) {
513 for (String paramToIgnore : PARAMS_TO_IGNORE)
514 if ((key.equalsIgnoreCase(paramToIgnore))) {
515 keysToRemove.add(key);
519 Map<String, String> result = instanceParams.get(0).entrySet().stream()
520 .filter(entry->!keysToRemove.contains(entry.getKey()))
521 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
523 return result.isEmpty() ? Collections.emptyList() : Collections.singletonList(result);
526 private ServiceInstantiationVnfList createServiceInstantiationVnfList(ServiceInstantiation payload) {
527 CloudConfiguration cloudConfiguration = generateCloudConfiguration(payload.getLcpCloudRegionId(), payload.getTenantId());
529 Map<String, Vnf> vnfs = payload.getVnfs();
530 List<ServiceInstantiationVnf> vnfList = new ArrayList<>();
531 for (Vnf vnf : vnfs.values()) {
532 Map<String, Map<String, VfModule>> vfModules = vnf.getVfModules();
533 List<VfModuleMacro> convertedUnFilteredVfModules = convertVfModuleMapToList(vfModules);
534 List<VfModuleMacro> filteredVfModules = filterInstanceParamsFromVfModuleAndUniqueNames(convertedUnFilteredVfModules);
535 ServiceInstantiationVnf serviceInstantiationVnf = new ServiceInstantiationVnf(
538 vnf.getPlatformName(),
539 vnf.getLineOfBusiness(),
540 payload.getProductFamilyId(),
541 buildVnfInstanceParams(vnf.getInstanceParams(), filteredVfModules),
543 getUniqueNameIfNeeded(vnf.getInstanceName(), ResourceType.GENERIC_VNF)
545 vnfList.add(serviceInstantiationVnf);
548 return new ServiceInstantiationVnfList(vnfList);
551 private List<VfModuleMacro> convertVfModuleMapToList(Map<String, Map<String, VfModule>> vfModules) {
552 ObjectMapper mapper = new ObjectMapper();
553 return vfModules.values().stream().flatMap(vfModule ->
554 vfModule.values().stream().map(item -> {
555 List<UserParamMap<String, String>> aggregatedParams = aggregateAllInstanceParams(extractActualInstanceParams(item.getInstanceParams()), item.getSupplementaryParams());
556 List<Map<String, String>> aggregatedParamsConverted = mapper.convertValue(aggregatedParams, new TypeReference<List<Map>>(){});
558 return new VfModuleMacro(
560 item.getInstanceName(),
561 item.getVolumeGroupInstanceName(),
562 aggregatedParamsConverted);
565 ).collect(Collectors.toList());
568 private List<VfModuleMacro> filterInstanceParamsFromVfModuleAndUniqueNames(List<VfModuleMacro> unFilteredVfModules) {
569 return unFilteredVfModules.stream().map(vfModule ->
571 vfModule.getModelInfo(),
572 getUniqueNameIfNeeded(vfModule.getInstanceName(), ResourceType.VF_MODULE),
573 getUniqueNameIfNeeded(vfModule.getVolumeGroupInstanceName(), ResourceType.VOLUME_GROUP),
574 removeUnNeededParams(vfModule.getInstanceParams())))
575 .collect(Collectors.toList());
578 private String getUniqueNameIfNeeded(String name, ResourceType resourceType) {
579 return StringUtils.isNotEmpty(name) ? getUniqueName(name, resourceType) : null;
583 public String getServiceInstantiationPath(ServiceInstantiation serviceInstantiationRequest) {
584 //in case pause flag is true - use assign , else - use create.
585 return MsoBusinessLogicImpl.validateEndpointPath(
586 serviceInstantiationRequest.isPause() ?
587 MsoProperties.MSO_REST_API_SERVICE_INSTANCE_ASSIGN : MsoProperties.MSO_REST_API_SERVICE_INSTANCE_CREATE
592 public String getServiceDeletionPath(String serviceInstanceId) {
593 return MsoBusinessLogicImpl.validateEndpointPath( MsoProperties.MSO_DELETE_OR_UNASSIGN_REST_API_SVC_INSTANCE) + "/" + serviceInstanceId;
597 public String getVnfInstantiationPath(String serviceInstanceId) {
598 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE).
599 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
603 public String getNetworkInstantiationPath(String serviceInstanceId) {
604 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE).
605 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
609 public String getVfmoduleInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
610 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
611 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
612 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
616 public String getVolumeGroupInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
617 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE)
618 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
619 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
623 public String getInstanceGroupInstantiationPath() {
624 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP);
628 public String getInstanceGroupDeletePath(String instanceGroupId) {
629 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
630 + '/' + instanceGroupId;
634 public String getOrchestrationRequestsPath() {
635 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQ);
639 public ServiceInfo updateServiceInfo(UUID jobUUID, Consumer<ServiceInfo> serviceUpdater) {
640 ServiceInfo serviceInfo = getServiceInfoByJobId(jobUUID);
641 serviceUpdater.accept(serviceInfo);
642 dataAccessService.saveDomainObject(serviceInfo, DaoUtils.getPropsMap());
647 public ServiceInfo updateServiceInfoAndAuditStatus(UUID jobUuid, JobStatus jobStatus) {
648 auditVidStatus(jobUuid,jobStatus);
649 return updateServiceInfo(jobUuid, x -> setServiceInfoStatus(x, jobStatus));
652 private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
653 serviceInfo.setJobStatus(jobStatus);
654 serviceInfo.setStatusModifiedDate(new Date());
657 public ServiceInfo getServiceInfoByJobId(UUID jobUUID) {
658 List<ServiceInfo> serviceInfoList = dataAccessService.getList(ServiceInfo.class, String.format(" where jobId = '%s' ", jobUUID), null, null);
659 if (serviceInfoList.size() != 1) {
660 throw new GenericUncheckedException("Failed to retrieve job with uuid " + jobUUID + " from ServiceInfo table. Instances found: " + serviceInfoList.size());
662 return serviceInfoList.get(0);
665 public List<JobAuditStatus> getAuditStatuses(UUID jobUUID, JobAuditStatus.SourceStatus source) {
666 return dataAccessService.getList(
667 JobAuditStatus.class,
668 String.format(" where SOURCE = '%s' and JOB_ID = '%s'",source, jobUUID),
669 " CREATED_DATE ", null);
672 private JobAuditStatus getLatestAuditStatus(UUID jobUUID, JobAuditStatus.SourceStatus source){
673 List<JobAuditStatus> list = getAuditStatuses(jobUUID,source);
674 return !list.isEmpty() ? list.get(list.size()-1) : null;
678 public void auditVidStatus(UUID jobUUID, JobStatus jobStatus){
679 JobAuditStatus vidStatus = new JobAuditStatus(jobUUID, jobStatus.toString(), JobAuditStatus.SourceStatus.VID);
680 auditStatus(vidStatus);
684 public void auditMsoStatus(UUID jobUUID, AsyncRequestStatus.Request msoRequestStatus){
685 auditMsoStatus(jobUUID, msoRequestStatus.requestStatus.getRequestState(), msoRequestStatus.requestId, msoRequestStatus.requestStatus.getStatusMessage());
689 public void auditMsoStatus(UUID jobUUID, String jobStatus, String requestId, String additionalInfo){
690 JobAuditStatus msoStatus = new JobAuditStatus(jobUUID, jobStatus, JobAuditStatus.SourceStatus.MSO,
691 requestId != null ? UUID.fromString(requestId) : null,
693 auditStatus(msoStatus);
696 private void auditStatus(JobAuditStatus jobAuditStatus){
697 JobAuditStatus latestStatus = getLatestAuditStatus(jobAuditStatus.getJobId(), jobAuditStatus.getSource());
698 if (latestStatus == null || !latestStatus.equals(jobAuditStatus))
699 dataAccessService.saveDomainObject(jobAuditStatus, DaoUtils.getPropsMap());
703 public Job.JobStatus calcStatus(AsyncRequestStatus asyncRequestStatus) {
704 String msoRequestState = asyncRequestStatus.request.requestStatus.getRequestState().toLowerCase().replaceAll("[^a-z]+", "");
705 JobStatus jobStatus = msoStateToJobStatusMap.get(msoRequestState);
706 return (jobStatus != null ? jobStatus : JobStatus.IN_PROGRESS);
710 public void handleFailedInstantiation(UUID jobUUID) {
711 ServiceInfo serviceInfo = updateServiceInfoAndAuditStatus(jobUUID, JobStatus.FAILED);
712 List<ServiceInfo> serviceInfoList = dataAccessService.getList(
714 String.format(" where templateId = '%s' and jobStatus = '%s'",
715 serviceInfo.getTemplateId(),
718 serviceInfoList.forEach(si -> updateServiceInfoAndAuditStatus(si.getJobId(), JobStatus.STOPPED));
722 public void deleteJob(UUID jobId) {
723 jobService.delete(jobId);
724 Date now = new Date();
725 updateServiceInfo(jobId, x -> x.setDeletedAt(now));
729 public void hideServiceInfo(UUID jobUUID) {
730 ServiceInfo serviceInfo = getServiceInfoByJobId(jobUUID);
731 if (!serviceInfo.getJobStatus().isFinal()) {
732 String message = String.format( "jobId %s: Service status does not allow hide service, status = %s",
733 serviceInfo.getJobId(),
734 serviceInfo.getJobStatus());
735 logger.error(EELFLoggerDelegate.errorLogger, message);
736 throw new OperationNotAllowedException(message);
738 serviceInfo.setHidden(true);
739 dataAccessService.saveDomainObject(serviceInfo, DaoUtils.getPropsMap());
743 public int getCounterForName(String name) {
745 String hqlSelectNC = "from NameCounter where name = :name";
746 String hqlUpdateCounter = "update NameCounter set counter = :newCounter " +
747 "where name= :name " +
748 "and counter= :prevCounter";
750 Integer counter = null;
751 GenericUncheckedException lastException = null;
752 for (int i = 0; i< MAX_RETRIES_GETTING_COUNTER && counter==null; i++) {
754 counter = calcCounter(name, hqlSelectNC, hqlUpdateCounter);
756 catch (GenericUncheckedException exception) {
757 lastException = exception; //do nothing, we will try again in the loop
765 throw lastException!=null ? new DbFailureUncheckedException(lastException) :
766 new DbFailureUncheckedException("Failed to get counter for "+name+" due to unknown error");
770 private Integer calcCounter(String name, String hqlSelectNC, String hqlUpdateCounter) {
772 counter = DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
773 NameCounter nameCounter = (NameCounter) session.createQuery(hqlSelectNC)
774 .setText("name", name)
776 if (nameCounter != null) {
777 int updatedRows = session.createQuery(hqlUpdateCounter)
778 .setText("name", nameCounter.getName())
779 .setInteger("prevCounter", nameCounter.getCounter())
780 .setInteger("newCounter", nameCounter.getCounter() + 1)
782 if (updatedRows == 1) {
783 return nameCounter.getCounter() + 1;
786 Object nameAsId = session.save(new NameCounter(name));
788 if (nameAsId != null) {
792 //in case of failure return null, in order to continue the loop
799 public int getMaxRetriesGettingFreeNameFromAai() {
800 return maxRetriesGettingFreeNameFromAai;
804 public void setMaxRetriesGettingFreeNameFromAai(int maxRetriesGettingFreeNameFromAai) {
805 this.maxRetriesGettingFreeNameFromAai = maxRetriesGettingFreeNameFromAai;
809 public String getUniqueName(String name, ResourceType resourceType) {
810 //check that name aai response well before increasing counter from DB
811 //Prevents unnecessary increasing of the counter while AAI doesn't response
812 isNameFreeInAai(NAME_FOR_CHECK_AAI_STATUS, resourceType);
814 for (int i=0; i<getMaxRetriesGettingFreeNameFromAai(); i++) {
815 String newName = getUniqueNameFromDbOnly(name);
816 if (isNameFreeInAai(newName, resourceType)) {
821 throw new MaxRetriesException("find unused name for "+name, getMaxRetriesGettingFreeNameFromAai());
824 protected String getUniqueNameFromDbOnly(String name) {
825 int counter = getCounterForName(name);
826 return formatNameAndCounter(name, counter);
829 //the method is protected so we can call it in the UT
830 protected String formatNameAndCounter(String name, int counter) {
831 return counter==0 ? name : name + "_" + String.format("%03d", counter);
834 private boolean isNameFreeInAai(String name, ResourceType resourceType) throws ExceptionWithRequestInfo {
835 return !aaiClient.isNodeTypeExistsByName(name, resourceType);