diff options
Diffstat (limited to 'vid-app-common/src/main/java/org/onap/vid/job/command')
42 files changed, 1330 insertions, 1770 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceCommand.kt index 29897aceb..9bef3c11b 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceCommand.kt @@ -7,9 +7,9 @@ * 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. @@ -21,14 +21,16 @@ package org.onap.vid.job.command import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate -import org.onap.vid.changeManagement.RequestDetailsWrapper -import org.onap.vid.job.* -import org.onap.vid.model.Action +import org.onap.vid.job.Job +import org.onap.vid.job.JobAdapter +import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.model.serviceInstantiation.BaseResource import org.onap.vid.model.serviceInstantiation.ServiceInstantiation import org.onap.vid.mso.RestMsoImplementation -import org.onap.vid.mso.model.ServiceDeletionRequestDetails import org.onap.vid.properties.VidProperties import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.onap.vid.services.AuditService import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.config.ConfigurableBeanFactory import org.springframework.context.annotation.Scope @@ -38,6 +40,8 @@ import java.time.ZonedDateTime import java.time.temporal.ChronoUnit import java.util.* +const val UNIQUE_INSTANCE_NAME = "optimisticUniqueServiceInstanceName" + class ServiceExpiryChecker : ExpiryChecker { override fun isExpired(jobStartTime: ZonedDateTime?): Boolean { @@ -48,22 +52,20 @@ class ServiceExpiryChecker : ExpiryChecker { } } - @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) class ALaCarteServiceCommand @Autowired constructor( inProgressStatusService: InProgressStatusService, watchChildrenJobsBL: WatchChildrenJobsBL, private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, - private val jobsBrokerService: JobsBrokerService, + jobsBrokerService: JobsBrokerService, + private val msoRequestBuilder: MsoRequestBuilder, msoResultHandlerService: MsoResultHandlerService, - private val jobAdapter: JobAdapter, - restMso: RestMsoImplementation -) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, watchChildrenJobsBL), JobCommand { - - override fun getExpiryChecker(): ExpiryChecker { - return ServiceExpiryChecker(); - } + jobAdapter: JobAdapter, + restMso: RestMsoImplementation, + auditService: AuditService +) : RootServiceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter, asyncInstantiationBL, auditService, msoRequestBuilder), JobCommand { companion object { private val LOGGER = EELFLoggerDelegate.getLogger(ALaCarteServiceCommand::class.java) @@ -74,69 +76,27 @@ class ALaCarteServiceCommand @Autowired constructor( } override fun createChildren(): Job.JobStatus { - val dataForChild = buildDataForChild(getRequest())//.plus(ACTION_PHASE to actionPhase) - - val childJobType = when (actionPhase) { - Action.Create -> JobType.InstanceGroupInstantiation - Action.Delete -> JobType.InstanceGroup - else -> return Job.JobStatus.COMPLETED - } + val dataForChild = buildDataForChild(getRequest(), actionPhase) - childJobs = getRequest().vnfGroups - .map { jobAdapter.createChildJob(childJobType, Job.JobStatus.CREATING, it.value, sharedData, dataForChild) } - .map { jobsBrokerService.add(it) } - .map { it.toString() } + childJobs = pushChildrenJobsToBroker(getRequest().children, dataForChild) return Job.JobStatus.COMPLETED_WITH_NO_ACTION } - private fun buildDataForChild(request: ServiceInstantiation): Map<String, Any> { - val commandParentData = CommandParentData() - commandParentData.addInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID, request.instanceId) + override fun addMyselfToChildrenData(commandParentData: CommandParentData, request: BaseResource) { + val instanceId = getActualInstanceId(request) + commandParentData.addInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID, instanceId) commandParentData.addModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO, request.modelInfo) - return commandParentData.parentData } - override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { - TODO("not implemented") - } - - override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { - val requestDetailsWrapper = generateServiceDeletionRequest() - val path = asyncInstantiationBL.getServiceDeletionPath(getRequest().instanceId) - return MsoRestCallPlan(HttpMethod.DELETE, path, Optional.of(requestDetailsWrapper), Optional.empty(), - "delete instance with id ${getRequest().instanceId}") - - } + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + val instantiatePath = asyncInstantiationBL.getServiceInstantiationPath(request as ServiceInstantiation) - override fun handleInProgressStatus(jobStatus: Job.JobStatus): Job.JobStatus { - if (jobStatus==Job.JobStatus.FAILED) { - asyncInstantiationBL.handleFailedInstantiation(sharedData.jobUuid) - return jobStatus - } + val requestDetailsWrapper = msoRequestBuilder.generateALaCarteServiceInstantiationRequest( + request, optimisticUniqueServiceInstanceName, userId) - asyncInstantiationBL.updateServiceInfoAndAuditStatus(sharedData.jobUuid, jobStatus) - return if (jobStatus == Job.JobStatus.PAUSE) Job.JobStatus.IN_PROGRESS else jobStatus - } - - - private fun generateServiceDeletionRequest(): RequestDetailsWrapper<ServiceDeletionRequestDetails> { - return asyncInstantiationBL.generateALaCarteServiceDeletionRequest( - sharedData.jobUuid, getRequest(), sharedData.userId - ) - } - - override fun getExternalInProgressStatus() = Job.JobStatus.IN_PROGRESS - - override fun isServiceCommand(): Boolean = true - - override fun onFinal(jobStatus: Job.JobStatus) { - asyncInstantiationBL.updateServiceInfoAndAuditStatus(sharedData.jobUuid, jobStatus) - } + val actionDescription = "create service instance" - override fun onInitial(phase: Action) { - if (phase== Action.Delete) { - asyncInstantiationBL.updateServiceInfoAndAuditStatus(sharedData.jobUuid, Job.JobStatus.IN_PROGRESS) - } + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) } } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceInstantiationCommand.java deleted file mode 100644 index 38d5ede8a..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ALaCarteServiceInstantiationCommand.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.JobCommand; -import org.onap.vid.mso.model.ServiceInstantiationRequestDetails; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class ALaCarteServiceInstantiationCommand extends ServiceInstantiationCommand implements JobCommand { - - @Override - protected RequestDetailsWrapper<ServiceInstantiationRequestDetails> generateServiceInstantiationRequest() { - return asyncInstantiationBL.generateALaCarteServiceInstantiationRequest( - getSharedData().getJobUuid(), getRequest(), optimisticUniqueServiceInstanceName, getSharedData().getUserId() - ); - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/AggregateStateCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/AggregateStateCommand.java index e64c304cb..34861d0ef 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/AggregateStateCommand.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/AggregateStateCommand.java @@ -7,9 +7,9 @@ * 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. diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseInProgressStatusCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/BaseInProgressStatusCommand.java deleted file mode 100644 index d21973dc2..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseInProgressStatusCommand.java +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * ============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.job.command; - -import com.google.common.collect.ImmutableMap; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.job.*; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.mso.RestMsoImplementation; -import org.onap.vid.mso.RestObject; -import org.onap.vid.mso.rest.AsyncRequestStatus; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.togglz.core.manager.FeatureManager; - -import javax.inject.Inject; -import java.util.Map; - -public abstract class BaseInProgressStatusCommand extends BaseInstantiationCommand implements JobCommand { - private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(BaseInProgressStatusCommand.class); - - @Inject - protected AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Inject - protected JobsBrokerService jobsBrokerService; - - @Inject - protected JobAdapter jobAdapter; - - @Inject - protected RestMsoImplementation restMso; - - @Inject - protected FeatureManager featureManager; - - @Inject - protected InProgressStatusService inProgressStatusService; - - - protected String requestId; - - protected String instanceId; - - - @Override - public NextCommand call() { - - try { - Job.JobStatus jobStatus = inProgressStatusService.call(getExpiryChecker(), getSharedData(), requestId); - return processJobStatus(jobStatus); - } catch (javax.ws.rs.ProcessingException e) { - // Retry when we can't connect MSO during getStatus - LOGGER.error(EELFLoggerDelegate.errorLogger, "Cannot get orchestration status for {}, will retry: {}", requestId, e, e); - return new NextCommand(Job.JobStatus.IN_PROGRESS, this); - } catch (InProgressStatusService.BadResponseFromMso e) { - return handleFailedMsoResponse(e.getMsoResponse()); - } - catch (RuntimeException e) { - LOGGER.error(EELFLoggerDelegate.errorLogger, "Cannot get orchestration status for {}, stopping: {}", requestId, e, e); - return new NextCommand(Job.JobStatus.STOPPED, this); - } - } - - protected abstract ExpiryChecker getExpiryChecker(); - - abstract NextCommand processJobStatus(Job.JobStatus jobStatus); - - private NextCommand handleFailedMsoResponse(RestObject<AsyncRequestStatus> msoResponse) { - inProgressStatusService.handleFailedMsoResponse(getSharedData().getJobUuid(), requestId, msoResponse); - return new NextCommand(Job.JobStatus.IN_PROGRESS, this); - } - - @Override - public BaseInProgressStatusCommand init(JobSharedData sharedData, Map<String, Object> commandData) { - return init(sharedData, (String) commandData.get("requestId"), (String) commandData.get("instanceId")); - } - - - protected BaseInProgressStatusCommand init(JobSharedData sharedData, - String requestId, - String instanceId) { - init(sharedData); - this.requestId = requestId; - this.instanceId = instanceId; - return this; - } - - @Override - public Map<String, Object> getData() { - return ImmutableMap.of( - "requestId", requestId, - "instanceId", instanceId - ); - } - - -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/BaseInstantiationCommand.java deleted file mode 100644 index 20d71ab29..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseInstantiationCommand.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.job.impl.JobSharedData; - -import java.util.Map; - - -public abstract class BaseInstantiationCommand extends CommandBase{ - - - protected CommandParentData commandParentData = new CommandParentData(); - - protected BaseInstantiationCommand init(JobSharedData sharedData, Map<String, Object> commandData) { - super.init(sharedData); - commandParentData.initParentData(commandData); - return this; - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseRootCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/BaseRootCommand.java deleted file mode 100644 index 4b81a9412..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseRootCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.RequestReferencesContainer; -import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; -import org.onap.vid.mso.RestObject; - -import javax.inject.Inject; - - -public abstract class BaseRootCommand extends CommandBase{ - - @Inject - private MsoResultHandlerService msoResultHandlerService; - - @Override - protected CommandBase init(JobSharedData sharedData) { - super.init(sharedData); - return this; - } - - protected ServiceInstantiation getRequest() { - return msoResultHandlerService.getRequest(getSharedData()); - } - - protected NextCommand handleRootResponse(RestObject<RequestReferencesContainer> msoResponse){ - MsoResult msoResult = msoResultHandlerService.handleRootResponse(getSharedData().getJobUuid(), msoResponse); - return new NextCommand(msoResult.getJobStatus(), - (msoResult.getMsoResourceIds()!=null) ? - new ServiceInProgressStatusCommand(getSharedData(), msoResult.getMsoResourceIds()) : - null - ); - - } - - protected NextCommand handleCommandFailed() { - return new NextCommand(msoResultHandlerService.handleRootCommandFailed(getSharedData().getJobUuid()).getJobStatus()); - } - -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseWatchingCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/BaseWatchingCommand.java deleted file mode 100644 index a0b7cd784..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/BaseWatchingCommand.java +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * ============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.job.command; - -import org.apache.commons.lang3.ObjectUtils; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.job.Job; -import org.onap.vid.job.JobCommand; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public abstract class BaseWatchingCommand extends BaseInstantiationCommand implements JobCommand { - - private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(BaseWatchingCommand.class); - - @Inject - protected AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Inject - private WatchChildrenJobsBL watchChildrenJobsBL; - - private List<String> childrenJobsIds; - - protected boolean isService; - - public BaseWatchingCommand() {} - - public BaseWatchingCommand(JobSharedData sharedData, List<String> childrenJobsIds, boolean isService) { - init(sharedData, childrenJobsIds, isService); - } - - @Override - public NextCommand call() { - Job.JobStatus cumulativeJobsStatus = watchChildrenJobsBL.cumulateJobStatus( - watchChildrenJobsBL.retrieveChildrenJobsStatus(childrenJobsIds), - Job.JobStatus.COMPLETED); - return getNextCommand(cumulativeJobsStatus); - } - - protected abstract NextCommand getNextCommand(Job.JobStatus cumulativeJobsStatus); - - @Override - public BaseWatchingCommand init(JobSharedData sharedData, Map<String, Object> commandData) { - return init( - sharedData, - (List<String>) commandData.get("childrenJobs"), - (boolean) commandData.get("isService") - ); - } - - protected BaseWatchingCommand init(JobSharedData sharedData, List<String> childrenJobsIds, boolean isService) { - super.init(sharedData); - this.childrenJobsIds = ObjectUtils.defaultIfNull(childrenJobsIds, new ArrayList<>()); - this.isService = isService; - return this; - } - - @Override - public Map<String, Object> getData() { - Map<String, Object> data = new HashMap<>(); - data.put("childrenJobs", childrenJobsIds); - data.put("isService", isService); - return data; - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/CommandBase.java b/vid-app-common/src/main/java/org/onap/vid/job/command/CommandBase.java index a13e4dc38..a9b524e01 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/CommandBase.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/CommandBase.java @@ -7,9 +7,9 @@ * 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. diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/CommandParentData.java b/vid-app-common/src/main/java/org/onap/vid/job/command/CommandParentData.java index 35f631183..744b2fe39 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/CommandParentData.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/CommandParentData.java @@ -7,9 +7,9 @@ * 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. @@ -21,12 +21,15 @@ package org.onap.vid.job.command; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import org.onap.vid.model.Action; import org.onap.vid.mso.model.ModelInfo; import java.util.HashMap; import java.util.Map; +import static java.util.Collections.emptyMap; +import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; + public class CommandParentData { @@ -36,6 +39,7 @@ public class CommandParentData { VNF_INSTANCE_ID, VNF_MODEL_INFO, VG_INSTANCE_ID, + VNF_GROUP_INSTANCE_ID, ; } @@ -49,32 +53,30 @@ public class CommandParentData { new TypeReference<Map<CommandDataKey, ModelInfo>> () {}; - private ObjectMapper objectMapper = new ObjectMapper(); - private Map<CommandDataKey,ModelInfo> getModelInfosByCommandData(Map<String, Object> commandData) { - Object object = commandData.get(RESOURCE_MODEL_INFOS); - if (object != null) { - return objectMapper.convertValue(object, mapCommandKeyToModelInfo); - } - return null; + Object object = commandData.getOrDefault(RESOURCE_MODEL_INFOS, emptyMap()); + return JACKSON_OBJECT_MAPPER.convertValue(object, mapCommandKeyToModelInfo); } private Map<CommandDataKey,String> getInstanceIdsByCommandData(Map<String, Object> commandData) { - Object object = commandData.get(RESOURCE_INSTANCE_IDS); - if (object != null) { - return objectMapper.convertValue(object, mapCommandKeyToString); - } - return null; + Object object = commandData.getOrDefault(RESOURCE_INSTANCE_IDS, emptyMap()); + return JACKSON_OBJECT_MAPPER.convertValue(object, mapCommandKeyToString); } public Map<String, Object> getParentData() { Map<String, Object> data = new HashMap<>(); data.put(RESOURCE_INSTANCE_IDS, resourceInstancesIds); data.put(RESOURCE_MODEL_INFOS, resourceModelInfos); + + if (actionPhase != null) { + data.put(ResourceCommandKt.ACTION_PHASE, actionPhase); + } + return data; } private Map<CommandDataKey, String> resourceInstancesIds = new HashMap<>(); private Map<CommandDataKey, ModelInfo> resourceModelInfos = new HashMap<>(); + private Action actionPhase = null; public void addModelInfo(CommandDataKey modelInfoKey, ModelInfo modelInfo) { resourceModelInfos.put(modelInfoKey, modelInfo); @@ -83,6 +85,11 @@ public class CommandParentData { public void addInstanceId(CommandDataKey instanceIdKey, String instanceId) { resourceInstancesIds.put(instanceIdKey, instanceId); } + + public void setActionPhase(Action actionPhase) { + this.actionPhase = actionPhase; + } + public ModelInfo getModelInfo(CommandDataKey modelInfoKey) { return resourceModelInfos.get(modelInfoKey); } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/CommandUtils.java b/vid-app-common/src/main/java/org/onap/vid/job/command/CommandUtils.java index e9936ed4c..0fe7255c4 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/CommandUtils.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/CommandUtils.java @@ -7,9 +7,9 @@ * 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. diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ExpiryChecker.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ExpiryChecker.java index c41963d14..5d608255a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ExpiryChecker.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/ExpiryChecker.java @@ -7,9 +7,9 @@ * 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. diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/HttpCallCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/HttpCallCommand.java index 21c10ffac..9dc88dfea 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/HttpCallCommand.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/HttpCallCommand.java @@ -7,9 +7,9 @@ * 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. diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/InProgressStatusService.java b/vid-app-common/src/main/java/org/onap/vid/job/command/InProgressStatusService.java index 842a1bd17..3d1d78f8b 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/InProgressStatusService.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/InProgressStatusService.java @@ -7,9 +7,9 @@ * 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. @@ -26,10 +26,12 @@ import org.onap.vid.job.impl.JobSharedData; import org.onap.vid.mso.RestMsoImplementation; import org.onap.vid.mso.RestObject; import org.onap.vid.mso.rest.AsyncRequestStatus; +import org.onap.vid.properties.Features; import org.onap.vid.services.AsyncInstantiationBusinessLogic; import org.onap.vid.services.AuditService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.togglz.core.manager.FeatureManager; import java.time.ZonedDateTime; import java.time.format.DateTimeParseException; @@ -48,30 +50,37 @@ public class InProgressStatusService { private final AuditService auditService; + private final FeatureManager featureManager; + @Autowired - public InProgressStatusService(AsyncInstantiationBusinessLogic asyncInstantiationBL, RestMsoImplementation restMso, AuditService auditService) { + public InProgressStatusService(AsyncInstantiationBusinessLogic asyncInstantiationBL, RestMsoImplementation restMso, AuditService auditService, FeatureManager featureManager) { this.asyncInstantiationBL = asyncInstantiationBL; this.restMso = restMso; this.auditService = auditService; + this.featureManager = featureManager; } public Job.JobStatus call(ExpiryChecker expiryChecker, JobSharedData sharedData, String requestId) { RestObject<AsyncRequestStatus> asyncRequestStatus = getAsyncRequestStatus(requestId); - asyncInstantiationBL.auditMsoStatus(sharedData.getRootJobId(), asyncRequestStatus.get().request); + auditService.auditMsoStatus(sharedData.getRootJobId(), asyncRequestStatus.get().request); Job.JobStatus jobStatus = asyncInstantiationBL.calcStatus(asyncRequestStatus.get()); ZonedDateTime jobStartTime = getZonedDateTime(asyncRequestStatus, requestId); jobStatus = expiryChecker.isExpired(jobStartTime) ? Job.JobStatus.FAILED : jobStatus; + asyncInstantiationBL.updateResourceInfo(sharedData, jobStatus, asyncRequestStatus.get()); return jobStatus; } - private RestObject<AsyncRequestStatus> getAsyncRequestStatus(String requestId) { - String path = asyncInstantiationBL.getOrchestrationRequestsPath()+"/"+requestId; + RestObject<AsyncRequestStatus> getAsyncRequestStatus(String requestId) { + String path = asyncInstantiationBL.getOrchestrationRequestsPath() + "/" + requestId + + (featureManager.isActive(Features.FLAG_1908_RESUME_MACRO_SERVICE) ? "?format=detail" : ""); RestObject<AsyncRequestStatus> msoResponse = restMso.GetForObject(path, AsyncRequestStatus.class); + if (msoResponse.getStatusCode() >= 400 || msoResponse.get() == null) { throw new BadResponseFromMso(msoResponse); } + return msoResponse; } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupCommand.kt index e81fcd34e..26fb9aa09 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupCommand.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupCommand.kt @@ -7,9 +7,9 @@ * 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. @@ -24,6 +24,8 @@ import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate import org.onap.vid.job.Job import org.onap.vid.job.JobAdapter import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.model.serviceInstantiation.BaseResource import org.onap.vid.model.serviceInstantiation.InstanceGroup import org.onap.vid.mso.RestMsoImplementation import org.onap.vid.services.AsyncInstantiationBusinessLogic @@ -39,29 +41,42 @@ import java.util.* class InstanceGroupCommand @Autowired constructor( private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, restMso: RestMsoImplementation, + private val msoRequestBuilder: MsoRequestBuilder, msoResultHandlerService: MsoResultHandlerService, inProgressStatusService:InProgressStatusService, - watchChildrenJobsBL: WatchChildrenJobsBL -) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, watchChildrenJobsBL), JobCommand { + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter + ) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { companion object { private val LOGGER = EELFLoggerDelegate.getLogger(InstanceGroupCommand::class.java) } override fun createChildren(): Job.JobStatus { + val dataForChild = buildDataForChild(getRequest(), actionPhase) + + childJobs = pushChildrenJobsToBroker(getRequest().vnfGroupMembers.values, dataForChild); + return Job.JobStatus.COMPLETED_WITH_NO_ACTION } - override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + override fun addMyselfToChildrenData(commandParentData: CommandParentData, request: BaseResource) { + commandParentData.addInstanceId(CommandParentData.CommandDataKey.VNF_GROUP_INSTANCE_ID, request.instanceId) + } + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO) val instantiatePath = asyncInstantiationBL.getInstanceGroupInstantiationPath() - val requestDetailsWrapper = asyncInstantiationBL.generateInstanceGroupInstantiationRequest( + val requestDetailsWrapper = msoRequestBuilder.generateInstanceGroupInstantiationRequest( request as InstanceGroup, serviceModelInfo, serviceInstanceId, - userId + userId, + testApi ) val actionDescription = "create instance group in $serviceInstanceId" @@ -76,4 +91,7 @@ class InstanceGroupCommand @Autowired constructor( } -} + override fun getRequest(): InstanceGroup { + return sharedData.request as InstanceGroup + } +}
\ No newline at end of file diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupInstantiationCommand.java deleted file mode 100644 index 6d9ddd499..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupInstantiationCommand.java +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * ============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.job.command;//package org.onap.vid.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.model.Action; -import org.onap.vid.model.serviceInstantiation.InstanceGroup; -import org.onap.vid.mso.model.InstanceGroupInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class InstanceGroupInstantiationCommand extends ResourceInstantiationCommand { - - @Inject - private AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Override - protected String getRequestPath() { - return asyncInstantiationBL.getInstanceGroupInstantiationPath(); - } - - @Override - protected RequestDetailsWrapper<InstanceGroupInstantiationRequestDetails> generateMSORequest(JobAdapter.AsyncJobRequest request, String userId) { - return asyncInstantiationBL.generateInstanceGroupInstantiationRequest( - (InstanceGroup) getSharedData().getRequest(), - commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID), - getSharedData().getUserId() - ); - } - - @Override - protected String getJobAuditMSOStatus() { - return "INSTANCE_GROUP_REQUESTED"; - } - - @Override - protected boolean shouldInstantiateMyself() { - return Action.Create == ((InstanceGroup) getSharedData().getRequest()).getAction(); - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupMemberCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupMemberCommand.kt new file mode 100644 index 000000000..d8e9297a3 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/InstanceGroupMemberCommand.kt @@ -0,0 +1,63 @@ +package org.onap.vid.job.command + +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.job.Job +import org.onap.vid.job.JobAdapter +import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.model.serviceInstantiation.InstanceGroupMember +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import java.util.* + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +class InstanceGroupMemberCommand @Autowired constructor( + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + restMso: RestMsoImplementation, + private val msoRequestBuilder: MsoRequestBuilder, + msoResultHandlerService: MsoResultHandlerService, + inProgressStatusService:InProgressStatusService, + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter +) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { + + companion object { + private val LOGGER = EELFLoggerDelegate.getLogger(InstanceGroupMemberCommand::class.java) + } + + override fun createChildren(): Job.JobStatus { + return Job.JobStatus.COMPLETED_WITH_NO_ACTION + } + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + val instanceGroupId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_GROUP_INSTANCE_ID) + + val instantiatePath = asyncInstantiationBL.getInstanceGroupMemberInstantiationPath(instanceGroupId) + + val requestDetailsWrapper = msoRequestBuilder.generateInstanceGroupMemberRequest(getRequest().instanceId, userId) + + val actionDescription = "add instance group member ${getRequest().instanceId} to instance group $instanceGroupId" + + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) + } + + override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + val instanceGroupId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_GROUP_INSTANCE_ID) + val path = asyncInstantiationBL.getInstanceGroupMemberDeletePath(instanceGroupId) + val requestDetailsWrapper = msoRequestBuilder.generateInstanceGroupMemberRequest(getRequest().instanceId, userId) + return MsoRestCallPlan(HttpMethod.POST, path, Optional.of(requestDetailsWrapper), Optional.of(userId), + "delete instance group member ${getRequest().instanceId} from instance group $instanceGroupId") + } + + override fun getRequest(): InstanceGroupMember { + return sharedData.request as InstanceGroupMember + } +}
\ No newline at end of file diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/JobCommandFactory.java b/vid-app-common/src/main/java/org/onap/vid/job/command/JobCommandFactory.java index 9f9a62201..32828ad5c 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/JobCommandFactory.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/JobCommandFactory.java @@ -7,9 +7,9 @@ * 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. 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 new file mode 100644 index 000000000..8ce73d713 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceCommand.kt @@ -0,0 +1,98 @@ +package org.onap.vid.job.command + +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.aai.ExceptionWithRequestInfo +import org.onap.vid.changeManagement.RequestDetailsWrapper +import org.onap.vid.exceptions.AbortingException +import org.onap.vid.exceptions.MaxRetriesException +import org.onap.vid.exceptions.TryAgainException +import org.onap.vid.job.Job +import org.onap.vid.job.JobAdapter +import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.model.Action +import org.onap.vid.model.VidNotions.ModelCategory.* +import org.onap.vid.model.serviceInstantiation.ServiceInstantiation +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.onap.vid.services.AuditService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import java.util.* + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +class MacroServiceCommand @Autowired constructor( + inProgressStatusService: InProgressStatusService, + watchChildrenJobsBL: WatchChildrenJobsBL, + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + jobsBrokerService: JobsBrokerService, + private val msoRequestBuilder: MsoRequestBuilder, + msoResultHandlerService: MsoResultHandlerService, + jobAdapter: JobAdapter, + restMso: RestMsoImplementation, + auditService: AuditService +) : RootServiceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter, asyncInstantiationBL, auditService, msoRequestBuilder), JobCommand { + + + companion object { + private val Logger = EELFLoggerDelegate.getLogger(MacroServiceCommand::class.java) + } + + override fun createChildren(): Job.JobStatus { + return Job.JobStatus.COMPLETED_WITH_NO_ACTION + } + + private val pre1806Models = setOf(Transport, INFRASTRUCTURE_VPN, SERVICE_WITH_COLLECTION_RESOURCE); + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + try { + val instantiatePath = asyncInstantiationBL.getServiceInstantiationPath(request as ServiceInstantiation) + + val requestDetailsWrapper = generateRequest(sharedData.jobUuid, request, optimisticUniqueServiceInstanceName, userId) + + val actionDescription = "create macro service instance" + + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) + } + + //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) + 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) + throw AbortingException(exception); + } + } + + private fun generateRequest(jobUuid: UUID?, request: ServiceInstantiation, optimisticUniqueServiceInstanceName: String, userId: String): RequestDetailsWrapper<out Any> { + // for transport or for infrastructure VPN - send the pre 1806 request + if (shouldUsePre1806Request(request)){ + return msoRequestBuilder.generateMacroServicePre1806InstantiationRequest(request, userId) + } + return msoRequestBuilder.generateMacroServiceInstantiationRequest(jobUuid, request, optimisticUniqueServiceInstanceName, userId) + } + + protected fun shouldUsePre1806Request(request: ServiceInstantiation): Boolean { + return (request.vidNotions != null && pre1806Models.contains(request.vidNotions.modelCategory)) + } + + + override fun handleInProgressStatus(jobStatus: Job.JobStatus): Job.JobStatus { + asyncInstantiationBL.updateServiceInfoAndAuditStatus(sharedData.jobUuid, jobStatus) + return if (jobStatus==Job.JobStatus.PAUSE) Job.JobStatus.IN_PROGRESS else jobStatus + } + + override fun isDescendantHasAction(phase: Action): Boolean { + return false + } + +}
\ No newline at end of file diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceInstantiationCommand.java deleted file mode 100644 index 6687a2c2e..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/MacroServiceInstantiationCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.JobCommand; -import org.onap.vid.mso.model.ServiceInstantiationRequestDetails; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class MacroServiceInstantiationCommand extends ServiceInstantiationCommand implements JobCommand { - - public MacroServiceInstantiationCommand() { - // empty constructor - } - - @Override - protected RequestDetailsWrapper<ServiceInstantiationRequestDetails> generateServiceInstantiationRequest() { - return asyncInstantiationBL.generateMacroServiceInstantiationRequest( - getSharedData().getJobUuid(), getRequest(), optimisticUniqueServiceInstanceName, getSharedData().getUserId() - ); - } - -} 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 new file mode 100644 index 000000000..c8502b1e5 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt @@ -0,0 +1,411 @@ +package org.onap.vid.job.command + +import com.google.common.collect.ImmutableList +import org.apache.commons.lang3.ObjectUtils.defaultIfNull +import org.apache.commons.lang3.StringUtils +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.aai.AaiClientInterface +import org.onap.vid.aai.ExceptionWithRequestInfo +import org.onap.vid.aai.model.ResourceType +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.services.AsyncInstantiationBusinessLogic +import org.onap.vid.services.CloudOwnerService +import org.onap.vid.utils.JACKSON_OBJECT_MAPPER +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service +import org.togglz.core.manager.FeatureManager +import java.util.* +import java.util.Collections.emptyList +import java.util.stream.Collectors + +@Service +class MsoRequestBuilder +@Autowired constructor(private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + private val cloudOwnerService: CloudOwnerService, + private val aaiClient: AaiClientInterface, + private val featureManager: FeatureManager) { + + companion object { + private val LOGGER = EELFLoggerDelegate.getLogger(MsoRequestBuilder::class.java) + private const val VID_SOURCE = "VID" + } + + fun generateALaCarteServiceInstantiationRequest(payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> { + val userParams = generateUserParamList() + + val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, true, userParams, payload.testApi) + + val requestDetails = generateServiceInstantiationRequestDetails(payload, requestParameters, optimisticUniqueServiceInstanceName, userId) + + return RequestDetailsWrapper(requestDetails) + } + + fun generateServiceDeletionRequest(payload: ServiceInstantiation, userId: String): RequestDetailsWrapper<ServiceDeletionRequestDetails> { + + val requestParameters = ServiceDeletionRequestDetails.RequestParameters(payload.isALaCarte, payload.testApi) + + val requestInfo = ServiceDeletionRequestDetails.RequestInfo( + VID_SOURCE, + userId) + + val requestDetails = ServiceDeletionRequestDetails(payload.modelInfo, requestInfo, requestParameters) + + return RequestDetailsWrapper(requestDetails) + } + + fun generateMacroServiceInstantiationRequest(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> { + val serviceInstanceName = generateServiceName(jobId, payload, optimisticUniqueServiceInstanceName) + + val serviceInstantiationServiceList = generateServiceInstantiationServicesList(payload, serviceInstanceName, createServiceInstantiationVnfList(jobId, payload)) + + val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, serviceInstantiationServiceList) + + val requestDetails = generateServiceInstantiationRequestDetails(payload, requestParameters, serviceInstanceName, userId) + + return RequestDetailsWrapper(requestDetails) + } + + fun generateNetworkInstantiationRequest(networkDetails: Network, serviceModelInfo: ModelInfo, serviceInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<NetworkInstantiationRequestDetails> { + val requestInfo = generateRequestInfo(networkDetails.instanceName, ResourceType.L3_NETWORK, networkDetails.isRollbackOnFailure, networkDetails.productFamilyId, userId) + val cloudConfiguration = generateCloudConfiguration(networkDetails.lcpCloudRegionId, networkDetails.tenantId) + val platform = Platform(networkDetails.platformName) + val lineOfBusiness = LineOfBusiness.of(networkDetails.lineOfBusiness) + val requestParameters = BaseResourceInstantiationRequestDetails.RequestParameters(generateUserParamList(), testApi) + val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo)) + return RequestDetailsWrapper(NetworkInstantiationRequestDetails(networkDetails.modelInfo, cloudConfiguration, requestInfo, platform, lineOfBusiness, relatedInstanceList, requestParameters)) + } + + fun generateVnfInstantiationRequest(vnfDetails: Vnf, serviceModelInfo: ModelInfo, serviceInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<VnfInstantiationRequestDetails> { + val requestInfo = generateRequestInfo(vnfDetails.instanceName, ResourceType.GENERIC_VNF, vnfDetails.isRollbackOnFailure, vnfDetails.productFamilyId, userId) + val cloudConfiguration = generateCloudConfiguration(vnfDetails.lcpCloudRegionId, vnfDetails.tenantId) + val platform = Platform(vnfDetails.platformName) + val lineOfBusiness = LineOfBusiness.of(vnfDetails.lineOfBusiness) + val requestParameters = BaseResourceInstantiationRequestDetails.RequestParameters(generateUserParamList(), testApi) + val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo)) + return RequestDetailsWrapper(VnfInstantiationRequestDetails(vnfDetails.modelInfo, cloudConfiguration, requestInfo, platform, lineOfBusiness, relatedInstanceList, requestParameters)) + } + + fun generateDeleteVnfRequest(vnfDetails: Vnf, userId: String): RequestDetailsWrapper<VnfInstantiationRequestDetails> { + val requestInfo = generateRequestInfo(null, null, null, null, userId) + val cloudConfiguration = generateCloudConfiguration(vnfDetails.lcpCloudRegionId, vnfDetails.tenantId) + 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> { + 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)) + if (StringUtils.isNotEmpty(vgInstanceId)) { + val volumeGroupModel = ModelInfo() + volumeGroupModel.modelType = "volumeGroup" + relatedInstanceList.add(RelatedInstance(volumeGroupModel, vgInstanceId, vfModuleDetails.volumeGroupInstanceName)) + } + return RequestDetailsWrapper(VfModuleInstantiationRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters)) + } + + 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 relatedInstances = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo)) + + vfModuleDetails.modelInfo.modelType = "volumeGroup" + return RequestDetailsWrapper(VolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstances, requestParameters)) + } + + fun generateInstanceGroupInstantiationRequest(instanceGroupDetails: InstanceGroup, serviceModelInfo: ModelInfo, serviceInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<InstanceGroupInstantiationRequestDetails> { + val requestInfo = generateRequestInfo(instanceGroupDetails.instanceName, ResourceType.INSTANCE_GROUP, instanceGroupDetails.isRollbackOnFailure, null, userId) + val requestParameters = BaseResourceInstantiationRequestDetails.RequestParameters(generateUserParamList(), testApi) + val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo)) + return RequestDetailsWrapper(InstanceGroupInstantiationRequestDetails(instanceGroupDetails.modelInfo, requestInfo, relatedInstanceList, requestParameters)) + } + + fun generateInstanceGroupMemberRequest(instanceGroupMemberId: String, userId: String): RequestDetailsWrapper<AddOrRemoveInstanceGroupMemberRequestDetails> { + val requestInfo = generateRequestInfo(null, null, null, null, userId) + val modelInfo = ModelInfo() + modelInfo.modelType = "vnf" + val relatedInstanceList = generateRelatedInstances(mapOf(instanceGroupMemberId to modelInfo)) + return RequestDetailsWrapper(AddOrRemoveInstanceGroupMemberRequestDetails(requestInfo, relatedInstanceList)) + } + + fun generateDeleteNetworkRequest(networkDetails: Network, userId: String): RequestDetailsWrapper<NetworkInstantiationRequestDetails> { + val requestInfo = generateRequestInfo(null, null, null, null, userId) + val cloudConfiguration = generateCloudConfiguration(networkDetails.lcpCloudRegionId, networkDetails.tenantId) + return RequestDetailsWrapper(NetworkInstantiationRequestDetails(networkDetails.modelInfo, cloudConfiguration, requestInfo, null, null, null, null)) + } + + fun generateDeleteVfModuleRequest(vfModuleDetails: VfModule, userId: String): RequestDetailsWrapper<VfModuleInstantiationRequestDetails> { + val requestInfo = generateRequestInfo(null, null, null, null, userId) + val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId) + return RequestDetailsWrapper(VfModuleInstantiationRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, null, null)) + } + + private fun generateServiceName(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String): String? { + var serviceInstanceName: String? = null + if (StringUtils.isNotEmpty(optimisticUniqueServiceInstanceName)) { + serviceInstanceName = peekServiceName(jobId, payload, optimisticUniqueServiceInstanceName) + } + return serviceInstanceName + } + + private fun peekServiceName(jobId: UUID?, payload: ServiceInstantiation, optimisticUniqueServiceInstanceName: String): String { + val serviceInstanceName: String + // unique name already exist in service info. If it's free in AAI we use it + if (isNameFreeInAai(optimisticUniqueServiceInstanceName, ResourceType.SERVICE_INSTANCE)) { + serviceInstanceName = optimisticUniqueServiceInstanceName + } else { + serviceInstanceName = asyncInstantiationBL.getUniqueName(payload.instanceName, ResourceType.SERVICE_INSTANCE) + }//otherwise we used the original service instance name (from payload) to get a new unique name from DB and AAI + + //update serviceInfo with new name if needed + try { + asyncInstantiationBL.updateServiceInfo(jobId) { x -> x.serviceInstanceName = serviceInstanceName } + } catch (e: Exception) { + LOGGER.error("Failed updating service name {} in serviceInfo", serviceInstanceName, e) + } + + return serviceInstanceName + } + + @Throws(ExceptionWithRequestInfo::class) + private fun isNameFreeInAai(name: String, resourceType: ResourceType): Boolean { + return !aaiClient.isNodeTypeExistsByName(name, resourceType) + } + + private fun generateServiceInstantiationServicesList(payload: ServiceInstantiation, serviceInstanceName: String?, vnfList: ServiceInstantiationRequestDetails.ServiceInstantiationVnfList): List<ServiceInstantiationRequestDetails.ServiceInstantiationService> { + val serviceInstantiationServiceList = LinkedList<ServiceInstantiationRequestDetails.ServiceInstantiationService>() + val unFilteredInstanceParams = defaultIfNull<List<MutableMap<String, String>>>(payload.instanceParams, emptyList()) + val filteredInstanceParams = removeUnNeededParams(unFilteredInstanceParams) + val serviceInstantiationService = ServiceInstantiationRequestDetails.ServiceInstantiationService( + payload.modelInfo, + serviceInstanceName, + filteredInstanceParams, + vnfList + ) + serviceInstantiationServiceList.add(serviceInstantiationService) + return serviceInstantiationServiceList + } + + private fun removeUnNeededParams(instanceParams: List<MutableMap<String, String>>?): List<MutableMap<String, String>> { + val keysToRemove = mutableListOf<String>() + if (instanceParams.isNullOrEmpty()) { + return emptyList() + } + + for (key in instanceParams[0].keys) { + for (paramToIgnore in AsyncInstantiationBusinessLogic.PARAMS_TO_IGNORE) + if (key.equals(paramToIgnore, ignoreCase = true)) { + keysToRemove.add(key) + } + } + + val result : MutableMap<String, String> = instanceParams[0].entries.stream() + .filter { entry -> !keysToRemove.contains(entry.key) } + .collect(Collectors.toMap({it.key}, {it.value})) + + return if (result.isEmpty()) emptyList() else listOf(result) + } + + private fun createServiceInstantiationVnfList(jobId: UUID?, payload: ServiceInstantiation): ServiceInstantiationRequestDetails.ServiceInstantiationVnfList { + val cloudConfiguration = generateCloudConfiguration(payload.lcpCloudRegionId, payload.tenantId) + val isBulk = asyncInstantiationBL.isPartOfBulk(jobId) + + val vnfs = payload.vnfs + val vnfList = mutableListOf<ServiceInstantiationRequestDetails.ServiceInstantiationVnf>() + for (vnf in vnfs.values) { + val vfModules = vnf.vfModules + val convertedUnFilteredVfModules = convertVfModuleMapToList(vfModules) + val filteredVfModules = filterInstanceParamsFromVfModuleAndUniqueNames(convertedUnFilteredVfModules, isBulk) + val serviceInstantiationVnf = ServiceInstantiationRequestDetails.ServiceInstantiationVnf( + vnf.modelInfo, + cloudConfiguration, + vnf.platformName, + vnf.lineOfBusiness, + payload.productFamilyId, + buildVnfInstanceParams(vnf.instanceParams, filteredVfModules), + filteredVfModules, + getUniqueNameIfNeeded(vnf.instanceName, ResourceType.GENERIC_VNF, isBulk) + ) + vnfList.add(serviceInstantiationVnf) + } + + return ServiceInstantiationRequestDetails.ServiceInstantiationVnfList(vnfList) + } + + private fun convertVfModuleMapToList(vfModules: Map<String, Map<String, VfModule>>): List<VfModuleMacro> { + return vfModules.values.stream().flatMap { vfModule -> + vfModule.values.stream().map { item -> + val aggregatedParams = aggregateAllInstanceParams(extractActualInstanceParams(item.instanceParams), item.supplementaryParams) + val aggregatedParamsConverted = JACKSON_OBJECT_MAPPER.convertValue(aggregatedParams, List::class.java) + + VfModuleMacro( + item.modelInfo, + item.instanceName, + item.volumeGroupInstanceName, + aggregatedParamsConverted as List<Map<String, String>>) + } + }.collect(Collectors.toList<VfModuleMacro>()) + } + + fun aggregateAllInstanceParams(instanceParams: Map<String, String>?, supplementaryParams: Map<String, String>?): List<VfModuleInstantiationRequestDetails.UserParamMap<String, String>> { + var instanceParamsFinal: Map<String, String> = instanceParams ?: emptyMap() + val supplementaryParamsFinal: Map<String, String> = supplementaryParams ?: emptyMap() + + if (!(instanceParamsFinal.isEmpty() && supplementaryParamsFinal.isEmpty())) { + //remove duplicate keys from instanceParams if exist in supplementaryParams + instanceParamsFinal = instanceParamsFinal.entries.stream() + .filter { m -> !supplementaryParamsFinal.containsKey(m.key) } + .collect(Collectors.toMap({ it.key }, { it.value })) + + //aggregate the 2 collections and format them as UserParamMap + val aggregatedParams = UserParamMap<String, String>() + aggregatedParams.putAll(instanceParamsFinal) + aggregatedParams.putAll(supplementaryParamsFinal) + + return mutableListOf(aggregatedParams) + } + + return emptyList() + } + + //Make sure we always get a one Map from InstanceParams + private fun extractActualInstanceParams(originalInstanceParams: List<MutableMap<String, String>>?): MutableMap<String, String> { + return if (originalInstanceParams.isNullOrEmpty() || originalInstanceParams[0].isNullOrEmpty()) { + mutableMapOf() + } else originalInstanceParams[0] + } + + private fun filterInstanceParamsFromVfModuleAndUniqueNames(unFilteredVfModules: List<VfModuleMacro>, isBulk: Boolean): List<VfModuleMacro> { + return unFilteredVfModules.stream().map { vfModule -> + VfModuleMacro( + vfModule.modelInfo, + getUniqueNameIfNeeded(vfModule.instanceName, ResourceType.VF_MODULE, isBulk), + getUniqueNameIfNeeded(vfModule.volumeGroupInstanceName, ResourceType.VOLUME_GROUP, isBulk), + removeUnNeededParams(vfModule.instanceParams)) + } + .collect(Collectors.toList<VfModuleMacro>()) + } + + fun buildVnfInstanceParams(currentVnfInstanceParams: List<MutableMap<String, String>>, vfModules: List<VfModuleMacro>): List<Map<String, String>> { + val filteredVnfInstanceParams = removeUnNeededParams(currentVnfInstanceParams) + + val vnfInstanceParams = extractActualInstanceParams(filteredVnfInstanceParams) + vfModules.stream() + .map { x -> extractActualInstanceParams(x.instanceParams) } + .forEach { vnfInstanceParams.putAll(it) } + return if (vnfInstanceParams.isEmpty()) emptyList() else ImmutableList.of(vnfInstanceParams) + } + + private fun generateServiceInstantiationRequestDetails(payload: ServiceInstantiation, requestParameters: ServiceInstantiationRequestDetails.RequestParameters, serviceInstanceName: String?, userId: String): ServiceInstantiationRequestDetails { + val requestInfo = ServiceInstantiationRequestDetails.RequestInfo(serviceInstanceName, + payload.productFamilyId, + VID_SOURCE, + payload.isRollbackOnFailure, + userId) + val owningEntity = ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.owningEntityId, payload.owningEntityName) + val subscriberInfo = generateSubscriberInfo(payload) + val project = if (payload.projectName != null) ServiceInstantiationRequestDetails.Project(payload.projectName) else null + return ServiceInstantiationRequestDetails(payload.modelInfo, owningEntity, subscriberInfo, project, requestInfo, requestParameters) + } + + private fun generateSubscriberInfo(payload: ServiceInstantiation): SubscriberInfo { + val subscriberInfo = SubscriberInfo() + subscriberInfo.globalSubscriberId = payload.globalSubscriberId + return subscriberInfo + } + + private fun generateCloudConfiguration(lcpCloudRegionId: String?, tenantId: String?): CloudConfiguration { + val cloudConfiguration = CloudConfiguration(lcpCloudRegionId, tenantId) + if(lcpCloudRegionId != null){ + cloudOwnerService.enrichCloudConfigurationWithCloudOwner(cloudConfiguration, lcpCloudRegionId) + } + return cloudConfiguration + } + + private fun generateRelatedInstances(relatedInstances: Map<String, ModelInfo>): MutableList<RelatedInstance> { + return relatedInstances.entries.stream() + .map { RelatedInstance(it.value, it.key) } + .collect(Collectors.toList()) + } + + private fun generateRequestInfo(instanceName: String?, resourceType: ResourceType?, rollbackOnFailure: Boolean?, productFamilyId: String?, userId: String) : BaseResourceInstantiationRequestDetails.RequestInfo { + return BaseResourceInstantiationRequestDetails.RequestInfo( + if (resourceType == null) null else getUniqueNameIfNeeded(instanceName, resourceType, false), + productFamilyId, + VID_SOURCE, + rollbackOnFailure, + userId) + + } + + private fun getUniqueNameIfNeeded(name: String?, resourceType: ResourceType, isBulk: Boolean): String? { + return if (StringUtils.isNotEmpty(name)) { + if (isBulk) asyncInstantiationBL.getUniqueName(name, resourceType) else name + } else { + null + } + } + + private fun generateUserParamList(): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> { + return emptyList() + } + + fun generateMacroServicePre1806InstantiationRequest(payload: ServiceInstantiation, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> { + val requestInfo = ServiceInstantiationRequestDetails.RequestInfo(payload.instanceName, payload.productFamilyId, VID_SOURCE, payload.isRollbackOnFailure, userId) + val userParams = generateUserParamsNameAndValue(payload.instanceParams) + val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, userParams) + val subscriberInfo = generateSubscriberInfoPre1806(payload) + val project = if (payload.projectName != null) ServiceInstantiationRequestDetails.Project(payload.projectName) else null + val owningEntity = ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.owningEntityId, payload.owningEntityName) + val cloudConfiguration = generateCloudConfiguration(payload.lcpCloudRegionId, payload.tenantId) + val relatedInstanceList = generateRelatedInstanceListForVrfEntry(payload.vrfs) + + return RequestDetailsWrapper(ServiceInstantiationPre1806RequestDetails( + payload.modelInfo, + owningEntity, + subscriberInfo, + project, + requestInfo, + requestParameters, + cloudConfiguration, + relatedInstanceList)) + } + + private fun generateUserParamsNameAndValue(instanceParams: List<Map<String, String>>): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> { + if (instanceParams == null){ + return emptyList() + } + return instanceParams.getOrElse(0, {emptyMap()}).map{x-> ServiceInstantiationRequestDetails.UserParamNameAndValue(x.key, x.value)} + } + + private fun generateSubscriberInfoPre1806(payload: ServiceInstantiation): SubscriberInfo { + val subscriberInfo = SubscriberInfo() + subscriberInfo.globalSubscriberId = payload.globalSubscriberId + subscriberInfo.subscriberName = payload.subscriberName + return subscriberInfo + } + + private fun generateRelatedInstanceListForVrfEntry(vrfEntries: MutableMap<String, VrfEntry>): List<RelatedInstance> { + //fe send map of vrfs, with maps of networks and vpns, but actually we expect to only one vpn and one network + return if (vrfEntries.isEmpty() || vrfEntries.values.first().vpns.isEmpty() || vrfEntries.values.first().networks.isEmpty()) emptyList() + else { + val vpn = vrfEntries.values.first().vpns.values.first() + val network = vrfEntries.values.first().networks.values.first() + listOf(vpn, network).map { RelatedInstance(it.modelInfo, it.instanceId, it.instanceName) } + } + } +} 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 e1e9b1397..50eada64f 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 @@ -7,9 +7,9 @@ * 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. @@ -44,43 +44,42 @@ class MsoResultHandlerService return jobSharedData.request as ServiceInstantiation } - fun handleRootResponse(jobUUID: UUID, msoResponse: RestObject<RequestReferencesContainer>): MsoResult { + fun handleRootResponse(sharedData: JobSharedData, msoResponse: RestObject<RequestReferencesContainer>): MsoResult { + val jobUUID:UUID = sharedData.jobUuid return if (msoResponse.statusCode in 200..399) { val jobStatus = Job.JobStatus.IN_PROGRESS val msoResourceIds = MsoResourceIds(msoResponse.get().requestReferences.requestId, msoResponse.get().requestReferences.instanceId) - asyncInstantiationBL.auditVidStatus(jobUUID, jobStatus) + auditService.auditVidStatus(jobUUID, jobStatus) setInitialRequestAuditStatusFromMso(jobUUID, msoResourceIds.requestId) asyncInstantiationBL.updateServiceInfo(jobUUID) { x -> x.jobStatus = jobStatus x.serviceInstanceId = msoResourceIds.instanceId x.msoRequestId = UUID.fromString(msoResourceIds.requestId) } - MsoResult(jobStatus, msoResourceIds) + asyncInstantiationBL.addResourceInfo(sharedData, jobStatus, msoResourceIds.instanceId) + MsoResult(Job.JobStatus.COMPLETED_WITH_NO_ACTION, msoResourceIds) } else { auditService.setFailedAuditStatusFromMso(jobUUID, null, msoResponse.statusCode, msoResponse.raw) - handleRootCommandFailed(jobUUID) + asyncInstantiationBL.addFailedResourceInfo(sharedData, msoResponse) + return MsoResult(Job.JobStatus.FAILED) } } - fun handleResponse(msoResponse: RestObject<RequestReferencesContainer>, actionDescription: String): MsoResult { + 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}") + 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}") + asyncInstantiationBL.addFailedResourceInfo(sharedData, msoResponse) MsoResult(Job.JobStatus.FAILED) } } - - fun handleRootCommandFailed(jobUUID: UUID): MsoResult { - asyncInstantiationBL.handleFailedInstantiation(jobUUID) - return MsoResult(Job.JobStatus.FAILED) - } - private fun setInitialRequestAuditStatusFromMso(jobUUID: UUID, requestId: String) { val initialMsoRequestStatus = "REQUESTED" - asyncInstantiationBL.auditMsoStatus(jobUUID, initialMsoRequestStatus, requestId, null) + auditService.auditMsoStatus(jobUUID, initialMsoRequestStatus, requestId, null) } } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/NetworkCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/NetworkCommand.kt new file mode 100644 index 000000000..bc4de7ccd --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/NetworkCommand.kt @@ -0,0 +1,65 @@ +package org.onap.vid.job.command + +import org.onap.vid.job.Job +import org.onap.vid.job.JobAdapter +import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.model.Action +import org.onap.vid.model.serviceInstantiation.Network +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import java.util.* + + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +class NetworkCommand @Autowired constructor( + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + restMso: RestMsoImplementation, + private val msoRequestBuilder: MsoRequestBuilder, + msoResultHandlerService: MsoResultHandlerService, + inProgressStatusService:InProgressStatusService, + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter + ) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { + override fun createChildren(): Job.JobStatus { + return Job.JobStatus.COMPLETED_WITH_NO_ACTION + } + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO) + + val instantiatePath = asyncInstantiationBL.getNetworkInstantiationPath(serviceInstanceId) + val requestDetailsWrapper = msoRequestBuilder.generateNetworkInstantiationRequest( + request as Network, + serviceModelInfo, + serviceInstanceId, + userId, + testApi + ) + + val actionDescription = "create network in $serviceInstanceId" + + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) + } + + override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val path = asyncInstantiationBL.getNetworkDeletePath(serviceInstanceId, getRequest().instanceId) + val requestDetailsWrapper = msoRequestBuilder.generateDeleteNetworkRequest(getRequest() as Network, userId) + return MsoRestCallPlan(HttpMethod.DELETE, path, Optional.of(requestDetailsWrapper), Optional.of(userId), + "delete network ${getRequest().instanceId} from service instance $serviceInstanceId") + } + + override fun isDescendantHasAction(phase: Action): Boolean { + return false + } +}
\ No newline at end of file diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/NetworkInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/NetworkInstantiationCommand.java deleted file mode 100644 index 2b7f79c15..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/NetworkInstantiationCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.model.serviceInstantiation.Network; -import org.onap.vid.mso.model.NetworkInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class NetworkInstantiationCommand extends ResourceInstantiationCommand { - - @Inject - private AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Override - protected String getRequestPath() { - return asyncInstantiationBL.getNetworkInstantiationPath(commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID)); - } - - @Override - protected RequestDetailsWrapper<NetworkInstantiationRequestDetails> generateMSORequest(JobAdapter.AsyncJobRequest request, String userId) { - return asyncInstantiationBL.generateNetworkInstantiationRequest( - (Network) getSharedData().getRequest(), - commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID), - getSharedData().getUserId() - ); - } - - @Override - protected String getJobAuditMSOStatus() { - return "NETWORK_REQUESTED"; - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/NoOpCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/NoOpCommand.java index 9be37bbf2..4cc54e5d7 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/NoOpCommand.java +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/NoOpCommand.java @@ -7,9 +7,9 @@ * 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. 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 7f3a05be8..0e9ab7b7a 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 @@ -7,9 +7,9 @@ * 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,14 +20,14 @@ package org.onap.vid.job.command + import com.fasterxml.jackson.module.kotlin.convertValue import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate import org.onap.vid.changeManagement.RequestDetailsWrapper -import org.onap.vid.job.Job +import org.onap.vid.exceptions.AbortingException +import org.onap.vid.exceptions.TryAgainException +import org.onap.vid.job.* import org.onap.vid.job.Job.JobStatus -import org.onap.vid.job.JobAdapter -import org.onap.vid.job.JobCommand -import org.onap.vid.job.NextCommand import org.onap.vid.job.impl.JobSharedData import org.onap.vid.model.Action import org.onap.vid.model.RequestReferencesContainer @@ -38,6 +38,7 @@ import org.onap.vid.utils.getEnumFromMapOfStrings import org.springframework.http.HttpMethod import java.util.* + const val INTERNAL_STATE = "internalState" const val ACTION_PHASE = "actionPhase" const val CHILD_JOBS = "childJobs" @@ -51,7 +52,9 @@ enum class InternalState constructor(val immediate:Boolean=false) { DELETE_MYSELF, CREATE_MYSELF, IN_PROGRESS, - TERMINAL + TERMINAL, + RESUME_MYSELF, + REPLACE_MYSELF, } data class NextInternalState(val nextActionPhase: Action, val nextInternalState: InternalState) @@ -69,8 +72,10 @@ abstract class ResourceCommand( protected val restMso: RestMsoImplementation, protected val inProgressStatusService: InProgressStatusService, protected val msoResultHandlerService: MsoResultHandlerService, - protected val watchChildrenJobsBL: WatchChildrenJobsBL -) : CommandBase(), JobCommand { + protected val watchChildrenJobsBL: WatchChildrenJobsBL, + private val jobsBrokerService: JobsBrokerService, + private val jobAdapter: JobAdapter + ) : CommandBase(), JobCommand { companion object { private val Logger = EELFLoggerDelegate.getLogger(ResourceCommand::class.java) @@ -78,7 +83,7 @@ abstract class ResourceCommand( abstract fun createChildren():JobStatus - abstract fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan + abstract fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan abstract fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan @@ -86,23 +91,28 @@ abstract class ResourceCommand( Pair(InternalState.CREATING_CHILDREN, ::createChildren), Pair(InternalState.WATCHING, ::watchChildren), Pair(InternalState.CREATE_MYSELF, ::createMyself), + Pair(InternalState.RESUME_MYSELF, ::resumeMyself), Pair(InternalState.DELETE_MYSELF, ::deleteMyself), - Pair(InternalState.IN_PROGRESS, ::inProgress) + Pair(InternalState.IN_PROGRESS, ::inProgress), + Pair(InternalState.REPLACE_MYSELF, ::replaceMyself) ) private lateinit var internalState:InternalState protected lateinit var actionPhase: Action - private var commandParentData: CommandParentData = CommandParentData() - private var msoResourceIds: MsoResourceIds = EMPTY_MSO_RESOURCE_ID + protected var commandParentData: CommandParentData = CommandParentData() + protected var msoResourceIds: MsoResourceIds = EMPTY_MSO_RESOURCE_ID protected var childJobs:List<String> = emptyList() private lateinit var cumulativeStatus:JobStatus override fun call(): NextCommand { - var jobStatus:JobStatus = invokeCommand() + var jobStatus:JobStatus = if (internalState!=InternalState.TERMINAL) invokeCommand() else cumulativeStatus jobStatus = comulateStatusAndUpdatePropertyIfFinal(jobStatus) - Logger.debug("command for job ${sharedData.jobUuid} invoked and finished with jobStatus $jobStatus") + try { + Logger.debug("job: ${this.javaClass.simpleName} ${sharedData.jobUuid} $actionPhase ${getActionType()} $internalState $jobStatus $childJobs") + } catch (e:Exception) { /* do nothing. Just failed to log...*/} + if (shallStopJob(jobStatus)) { onFinal(jobStatus) return NextCommand(jobStatus) @@ -133,7 +143,17 @@ abstract class ResourceCommand( protected open fun getExternalInProgressStatus() = JobStatus.RESOURCE_IN_PROGRESS private fun invokeCommand(): JobStatus { - return commandByInternalState.getOrDefault (internalState, ::throwIllegalState).invoke() + return try { + commandByInternalState.getOrDefault(internalState, ::throwIllegalState).invoke() + } + catch (exception: TryAgainException) { + Logger.warn("caught TryAgainException. Set job status to IN_PROGRESS") + JobStatus.IN_PROGRESS + } + catch (exception: AbortingException) { + Logger.error("caught AbortingException. Set job status to FAILED") + JobStatus.FAILED; + } } private fun throwIllegalState():JobStatus { @@ -177,7 +197,7 @@ abstract class ResourceCommand( InternalState.DELETE_MYSELF -> InternalState.IN_PROGRESS InternalState.IN_PROGRESS -> { - if (jobStatus == Job.JobStatus.COMPLETED) InternalState.TERMINAL else InternalState.IN_PROGRESS + if (jobStatus == JobStatus.COMPLETED) InternalState.TERMINAL else InternalState.IN_PROGRESS } else -> InternalState.TERMINAL @@ -187,10 +207,28 @@ abstract class ResourceCommand( protected fun calcNextStateCreatePhase(jobStatus: JobStatus, internalState: InternalState): InternalState { return when (internalState) { - InternalState.CREATE_MYSELF -> InternalState.IN_PROGRESS + InternalState.CREATE_MYSELF -> when (jobStatus) { + JobStatus.IN_PROGRESS -> InternalState.CREATE_MYSELF + else -> InternalState.IN_PROGRESS + } + + InternalState.RESUME_MYSELF -> when (jobStatus) { + JobStatus.IN_PROGRESS -> InternalState.RESUME_MYSELF + else -> InternalState.IN_PROGRESS + } + + InternalState.REPLACE_MYSELF -> when (jobStatus) { + JobStatus.IN_PROGRESS -> InternalState.REPLACE_MYSELF + else -> InternalState.IN_PROGRESS + } InternalState.IN_PROGRESS -> { - if (jobStatus == Job.JobStatus.COMPLETED) InternalState.CREATING_CHILDREN else InternalState.IN_PROGRESS + when { + jobStatus != JobStatus.COMPLETED -> InternalState.IN_PROGRESS + isDescendantHasAction(Action.Create) -> InternalState.CREATING_CHILDREN + isDescendantHasAction(Action.Replace) -> InternalState.CREATING_CHILDREN + else -> InternalState.TERMINAL + } } InternalState.CREATING_CHILDREN -> InternalState.WATCHING @@ -202,7 +240,6 @@ abstract class ResourceCommand( } } - else -> InternalState.TERMINAL } } @@ -214,7 +251,7 @@ abstract class ResourceCommand( MSO_RESOURCE_ID to msoResourceIds, CHILD_JOBS to childJobs, CUMULATIVE_STATUS to cumulativeStatus - ) + ) + commandParentData.parentData } override fun init(sharedData: JobSharedData, commandData: Map<String, Any>): ResourceCommand { @@ -232,13 +269,24 @@ abstract class ResourceCommand( return this } - private fun calcInitialState(commandData: Map<String, Any>, phase: Action):InternalState { + fun calcInitialState(commandData: Map<String, Any>, phase: Action):InternalState { val status:InternalState = getEnumFromMapOfStrings(commandData, INTERNAL_STATE, InternalState.INITIAL) if (status == InternalState.INITIAL) { onInitial(phase) return when (phase) { - Action.Delete -> InternalState.CREATING_CHILDREN - Action.Create -> if (isNeedToCreateMyself()) InternalState.CREATE_MYSELF else InternalState.CREATING_CHILDREN + Action.Delete -> when { + isDescendantHasAction(phase) -> InternalState.CREATING_CHILDREN + isNeedToDeleteMyself() -> InternalState.DELETE_MYSELF + else -> InternalState.TERMINAL + } + Action.Create -> when { + isNeedToCreateMyself() -> InternalState.CREATE_MYSELF + isNeedToResumeMySelf() -> InternalState.RESUME_MYSELF + isNeedToReplaceMySelf() -> InternalState.REPLACE_MYSELF + isDescendantHasAction(phase) -> InternalState.CREATING_CHILDREN + isDescendantHasAction(Action.Replace) -> InternalState.CREATING_CHILDREN + else -> InternalState.TERMINAL + } else -> throw IllegalStateException("state $internalState is not supported yet") } } @@ -269,7 +317,11 @@ abstract class ResourceCommand( protected open fun isNeedToCreateMyself(): Boolean = getActionType() == Action.Create - protected open fun inProgress(): Job.JobStatus { + protected open fun isNeedToResumeMySelf(): Boolean = getActionType() == Action.Resume + + protected open fun isNeedToReplaceMySelf(): Boolean = false + + protected open fun inProgress(): JobStatus { val requestId:String = msoResourceIds.requestId; return try { val jobStatus = inProgressStatusService.call(getExpiryChecker(), sharedData, requestId) @@ -277,29 +329,35 @@ abstract class ResourceCommand( } catch (e: javax.ws.rs.ProcessingException) { // Retry when we can't connect MSO during getStatus Logger.error(EELFLoggerDelegate.errorLogger, "Cannot get orchestration status for {}, will retry: {}", requestId, e, e) - Job.JobStatus.IN_PROGRESS; + JobStatus.IN_PROGRESS; } catch (e: InProgressStatusService.BadResponseFromMso) { inProgressStatusService.handleFailedMsoResponse(sharedData.jobUuid, requestId, e.msoResponse) - Job.JobStatus.IN_PROGRESS + JobStatus.IN_PROGRESS } catch (e: RuntimeException) { Logger.error(EELFLoggerDelegate.errorLogger, "Cannot get orchestration status for {}, stopping: {}", requestId, e, e) - Job.JobStatus.STOPPED + JobStatus.STOPPED } } - fun createMyself(): Job.JobStatus { - val createMyselfCommand = planCreateMyselfRestCall(commandParentData, sharedData.request, sharedData.userId) - + fun createMyself(): JobStatus { + val createMyselfCommand = planCreateMyselfRestCall(commandParentData, sharedData.request, sharedData.userId, sharedData.testApi) return executeAndHandleMsoInstanceRequest(createMyselfCommand) } - fun deleteMyself(): Job.JobStatus { - val deleteMyselfCommand = planDeleteMyselfRestCall(commandParentData, sharedData.request, sharedData.userId) + protected open fun resumeMyself(): JobStatus { + throw NotImplementedError("Resume is not implemented for this command " + this.javaClass) + } + + protected open fun replaceMyself(): JobStatus { + throw NotImplementedError("Replace is not implemented for this command " + this.javaClass) + } + fun deleteMyself(): JobStatus { + val deleteMyselfCommand = planDeleteMyselfRestCall(commandParentData, sharedData.request, sharedData.userId) return executeAndHandleMsoInstanceRequest(deleteMyselfCommand) } - private fun executeAndHandleMsoInstanceRequest(restCallPlan: MsoRestCallPlan): JobStatus { + protected fun executeAndHandleMsoInstanceRequest(restCallPlan: MsoRestCallPlan): JobStatus { val msoResponse = restMso.restCall( restCallPlan.httpMethod, RequestReferencesContainer::class.java, @@ -309,9 +367,9 @@ abstract class ResourceCommand( ) val msoResult = if (isServiceCommand()) { - msoResultHandlerService.handleRootResponse(sharedData.jobUuid, msoResponse) + msoResultHandlerService.handleRootResponse(sharedData, msoResponse) } else { - msoResultHandlerService.handleResponse(msoResponse, restCallPlan.actionDescription) + msoResultHandlerService.handleResponse(sharedData, msoResponse, restCallPlan.actionDescription) } this.msoResourceIds = msoResult.msoResourceIds @@ -321,14 +379,14 @@ abstract class ResourceCommand( protected open fun getExpiryChecker(): ExpiryChecker = ExpiryChecker {false} protected open fun handleInProgressStatus(jobStatus: JobStatus): JobStatus { - return if (jobStatus == Job.JobStatus.PAUSE) Job.JobStatus.IN_PROGRESS else jobStatus + return if (jobStatus == JobStatus.PAUSE) JobStatus.IN_PROGRESS else jobStatus } protected open fun watchChildren():JobStatus { return watchChildrenJobsBL.retrieveChildrenJobsStatus(childJobs) } - private fun comulateStatusAndUpdatePropertyIfFinal(internalStateStatus: JobStatus): JobStatus { + protected fun comulateStatusAndUpdatePropertyIfFinal(internalStateStatus: JobStatus): JobStatus { val status = watchChildrenJobsBL.cumulateJobStatus(internalStateStatus, cumulativeStatus) //we want to update cumulativeStatus only for final status @@ -338,6 +396,44 @@ abstract class ResourceCommand( return status } + + protected fun buildDataForChild(request: BaseResource, actionPhase: Action): Map<String, Any> { + addMyselfToChildrenData(commandParentData, request) + commandParentData.setActionPhase(actionPhase) + return commandParentData.parentData + } + + protected open fun addMyselfToChildrenData(commandParentData: CommandParentData, request: BaseResource) { + // Nothing by default + } + + protected open fun isDescendantHasAction(phase:Action):Boolean = isDescendantHasAction(getRequest(), phase, true ) + + + @JvmOverloads + fun isDescendantHasAction(request: BaseResource, phase: Action, isFirstLevel:Boolean=true): Boolean { + if (!isFirstLevel && request.action == phase) { + return true; + } + + return request.children.map {this.isDescendantHasAction(it, phase, false)}.any {it} + } + + protected fun getActualInstanceId(request: BaseResource):String = + if (getActionType() == Action.Create) msoResourceIds.instanceId else request.instanceId + + + protected fun pushChildrenJobsToBroker(children:Collection<BaseResource>, + dataForChild: Map<String, Any>, + jobType: JobType?=null): List<String> { + var counter = 0; + return children + .map {Pair(it, counter++)} + .map { jobAdapter.createChildJob(jobType ?: it.first.jobType, it.first, sharedData, dataForChild, it.second) } + .map { jobsBrokerService.add(it) } + .map { it.toString() } + } + } diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceInProgressStatusCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceInProgressStatusCommand.java deleted file mode 100644 index 123d38bd0..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceInProgressStatusCommand.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.job.Job; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class ResourceInProgressStatusCommand extends BaseInProgressStatusCommand { - - public ResourceInProgressStatusCommand() { - } - - ResourceInProgressStatusCommand(JobSharedData sharedData, String requestId, String instanceId) { - init(sharedData, requestId, instanceId); - } - - @Override - protected ExpiryChecker getExpiryChecker() { - return x->false; - } - - @Override - protected NextCommand processJobStatus(Job.JobStatus jobStatus) { - return new NextCommand(jobStatus, this); - } - - -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceInstantiationCommand.java deleted file mode 100644 index 98980a35d..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceInstantiationCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.Job; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.JobCommand; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.RequestReferencesContainer; -import org.onap.vid.mso.RestMsoImplementation; -import org.onap.vid.mso.RestObject; -import org.onap.vid.mso.model.BaseResourceInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.onap.vid.services.AuditService; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; -import java.util.Map; - - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public abstract class ResourceInstantiationCommand extends BaseInstantiationCommand implements JobCommand { - - - @Inject - protected RestMsoImplementation restMso; - - @Inject - private AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Inject - private AuditService auditService; - - @Override - public ResourceInstantiationCommand init(JobSharedData sharedData, Map<String, Object> commandData) { - super.init(sharedData, commandData); - return this; - } - - @Override - public Map<String, Object> getData() { - return commandParentData.getParentData(); - } - - @Override - public NextCommand call() { - if (!shouldInstantiateMyself()) { - return new NextCommand(Job.JobStatus.COMPLETED_WITH_NO_ACTION); - } - - RequestDetailsWrapper<? extends BaseResourceInstantiationRequestDetails> requestDetailsWrapper = generateMSORequest( - getSharedData().getRequest(), - getSharedData().getUserId() - ); - String instantiatePath = getRequestPath(); - - RestObject<RequestReferencesContainer> msoResponse = restMso.PostForObject(requestDetailsWrapper, - instantiatePath, RequestReferencesContainer.class); - - if (msoResponse.getStatusCode() >= 200 && msoResponse.getStatusCode() < 400) { - String requestId = msoResponse.get().getRequestReferences().getRequestId(); - String instanceId = msoResponse.get().getRequestReferences().getInstanceId(); - asyncInstantiationBL.auditMsoStatus(getSharedData().getRootJobId(), getJobAuditMSOStatus(), requestId, null); - return getNextCommand(requestId, instanceId); - } - else { - auditService.setFailedAuditStatusFromMso(getSharedData().getRootJobId(), null, msoResponse.getStatusCode(), msoResponse.getRaw()); - return new NextCommand(Job.JobStatus.FAILED); - } - } - protected NextCommand getNextCommand(String requestId, String instanceId){ - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, new ResourceInProgressStatusCommand(getSharedData(), requestId, instanceId)); - } - - protected boolean shouldInstantiateMyself() { - return true; - } - - protected abstract String getRequestPath(); - protected abstract RequestDetailsWrapper<? extends BaseResourceInstantiationRequestDetails> generateMSORequest(JobAdapter.AsyncJobRequest request, String userId); - protected abstract String getJobAuditMSOStatus(); -} - - diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceWithChildrenInProgressCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceWithChildrenInProgressCommand.java deleted file mode 100644 index 0a345c52c..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ResourceWithChildrenInProgressCommand.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.job.Job; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; - -import java.util.HashMap; -import java.util.Map; - - -public class ResourceWithChildrenInProgressCommand extends BaseInProgressStatusCommand { - - public ResourceWithChildrenInProgressCommand() { - } - - public ResourceWithChildrenInProgressCommand(JobSharedData sharedData, - String requestId, - String instanceId, - CommandParentData commandParentData) { - init(sharedData, requestId, instanceId, commandParentData); - } - - protected BaseInProgressStatusCommand init(JobSharedData sharedData, - String requestId, - String instanceId, - CommandParentData commandParentData) { - init(sharedData, requestId, instanceId); - this.commandParentData= commandParentData; - return this; - } - - - @Override - public Map<String, Object> getData() { - Map<String, Object> data = new HashMap<>(super.getData()); - data.putAll(buildDataForChild()); - return data; - } - - @Override - public BaseInProgressStatusCommand init(JobSharedData sharedData, Map<String, Object> commandData) { - return init( - sharedData, - (String) commandData.get("requestId"), - (String) commandData.get("instanceId"), - commandParentData.initParentData(commandData)); - } - - protected Map<String, Object> buildDataForChild() { - return commandParentData.getParentData(); - } - - - - @Override - protected NextCommand processJobStatus(Job.JobStatus jobStatus) { - return new NextCommand(jobStatus, this); - } - - @Override - protected ExpiryChecker getExpiryChecker() { - return x->false; - } - -} 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 new file mode 100644 index 000000000..c4680b2bd --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/RootServiceCommand.kt @@ -0,0 +1,98 @@ +package org.onap.vid.job.command + +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.job.Job +import org.onap.vid.job.JobAdapter +import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.job.impl.JobSharedData +import org.onap.vid.model.Action +import org.onap.vid.model.serviceInstantiation.ServiceInstantiation +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.onap.vid.services.AuditService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.HttpMethod +import java.util.* + +abstract class RootServiceCommand @Autowired constructor( + restMso: RestMsoImplementation, + inProgressStatusService: InProgressStatusService, + msoResultHandlerService: MsoResultHandlerService, + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter, + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + private val auditService: AuditService, + private val msoRequestBuilder: MsoRequestBuilder +) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { + + lateinit var optimisticUniqueServiceInstanceName: String + + companion object { + private val LOGGER = EELFLoggerDelegate.getLogger(RootServiceCommand::class.java) + } + + final override fun onInitial(phase: Action) { + if (phase== Action.Delete) { + asyncInstantiationBL.updateServiceInfoAndAuditStatus(sharedData.jobUuid, Job.JobStatus.IN_PROGRESS) + } + } + + final override fun getExternalInProgressStatus() = Job.JobStatus.IN_PROGRESS + + final override fun getData(): Map<String, Any?> { + return super.getData() + mapOf(UNIQUE_INSTANCE_NAME to optimisticUniqueServiceInstanceName) + } + + final override fun onFinal(jobStatus: Job.JobStatus) { + asyncInstantiationBL.updateServiceInfoAndAuditStatus(sharedData.jobUuid, jobStatus) + if (jobStatus.isFailure) { + asyncInstantiationBL.handleFailedInstantiation(sharedData.jobUuid) + } + } + + final override fun init(sharedData: JobSharedData, commandData: Map<String, Any>): ResourceCommand { + optimisticUniqueServiceInstanceName = commandData.getOrDefault(UNIQUE_INSTANCE_NAME, "") as String + return super<ResourceCommand>.init(sharedData, commandData) + } + + final override fun isServiceCommand(): Boolean = true + + final override fun getExpiryChecker(): ExpiryChecker { + return ServiceExpiryChecker() + } + + override fun resumeMyself(): Job.JobStatus { + val requestType = "createInstance" + val scope = "service" + val serviceInstanceId = getActualInstanceId(getRequest()) + 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 ") + 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) + return Job.JobStatus.FAILED + } + } + + private fun planResumeMyselfRestCall(requestId: String, userId: String): MsoRestCallPlan { + val path = asyncInstantiationBL.getResumeRequestPath(requestId) + return MsoRestCallPlan(HttpMethod.POST, path, Optional.empty(), Optional.of(userId), "resume request $requestId") + } + + override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + val requestDetailsWrapper = msoRequestBuilder.generateServiceDeletionRequest( + request as ServiceInstantiation, userId + ) + val path = asyncInstantiationBL.getServiceDeletionPath(request.instanceId) + return MsoRestCallPlan(HttpMethod.DELETE, path, Optional.of(requestDetailsWrapper), Optional.empty(), + "delete instance with id ${request.instanceId}") + } +}
\ No newline at end of file diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ServiceInProgressStatusCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ServiceInProgressStatusCommand.java deleted file mode 100644 index 6fd22132f..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ServiceInProgressStatusCommand.java +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * ============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.job.command; - -import org.apache.commons.collections.MapUtils; -import org.onap.vid.job.Job; -import org.onap.vid.job.Job.JobStatus; -import org.onap.vid.job.JobCommand; -import org.onap.vid.job.JobType; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; -import org.onap.vid.properties.Features; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class ServiceInProgressStatusCommand extends BaseInProgressStatusCommand { - - public ServiceInProgressStatusCommand() { - } - - ServiceInProgressStatusCommand(JobSharedData sharedData, MsoResourceIds msoResourceIds) { - init(sharedData, msoResourceIds.getRequestId(), msoResourceIds.getInstanceId()); - } - - @Override - protected ExpiryChecker getExpiryChecker() { - return new ServiceExpiryChecker(); - } - - protected NextCommand processJobStatus(Job.JobStatus jobStatus) { - JobCommand jobCommand = this; - Job.JobStatus nextJobStatus = jobStatus; - switch (jobStatus) { - case FAILED: - asyncInstantiationBL.handleFailedInstantiation(getSharedData().getJobUuid()); - return new NextCommand(nextJobStatus, jobCommand); - case PAUSE: - nextJobStatus = Job.JobStatus.IN_PROGRESS; - break; - case COMPLETED: - ServiceInstantiation request = (ServiceInstantiation) getSharedData().getRequest(); - if (isNeedToCreateChildJobs(request)) { - List<String> childrenJobs = getChildJobs(request); - nextJobStatus = Job.JobStatus.IN_PROGRESS; - jobCommand = new WatchingCommand(getSharedData(), childrenJobs, true); - return new NextCommand(nextJobStatus, jobCommand); - } - break; - default: // for sonar - } - asyncInstantiationBL.updateServiceInfoAndAuditStatus(getSharedData().getJobUuid(), jobStatus); - return new NextCommand(nextJobStatus, jobCommand); - } - - private List<String> getChildJobs(ServiceInstantiation request) { - Map<String, Object> dataForChild = buildDataForChild(request); - - Stream<String> vnfJobs = request.getVnfs().values().stream().map( - vnf -> jobsBrokerService.add( - jobAdapter.createChildJob(JobType.VnfInstantiation, JobStatus.CREATING , vnf, getSharedData(), dataForChild)).toString() - ); - - Stream<String> networkJobs = request.getNetworks().values().stream().map( - network -> jobsBrokerService.add( - jobAdapter.createChildJob(JobType.NetworkInstantiation, JobStatus.CREATING , network, getSharedData(), dataForChild)).toString() - ); - - Stream<String> instanceGroupJobs = request.getVnfGroups().values().stream().map( - instanceGroup -> jobsBrokerService.add( - jobAdapter.createChildJob(JobType.InstanceGroupInstantiation, JobStatus.CREATING , instanceGroup, getSharedData(), dataForChild)).toString() - ); - - return Stream.of(vnfJobs, networkJobs, instanceGroupJobs) - .reduce(Stream::concat) - .orElseGet(Stream::empty) - .collect(Collectors.toList()); - } - - public boolean isNeedToCreateChildJobs(ServiceInstantiation request) { - return featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF) && request.isALaCarte() && - ( - MapUtils.isNotEmpty(request.getVnfs()) || MapUtils.isNotEmpty(request.getNetworks()) || - (featureManager.isActive(Features.FLAG_1902_VNF_GROUPING) && MapUtils.isNotEmpty(request.getVnfGroups())) - ); - } - - protected Map<String, Object> buildDataForChild(ServiceInstantiation request) { - commandParentData.addInstanceId(CommandDataKey.SERVICE_INSTANCE_ID, this.instanceId); - commandParentData.addModelInfo(CommandDataKey.SERVICE_MODEL_INFO, request.getModelInfo()); - return commandParentData.getParentData(); - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/ServiceInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/ServiceInstantiationCommand.java deleted file mode 100644 index 414379b0d..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/ServiceInstantiationCommand.java +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * ============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.job.command; - -import com.google.common.collect.ImmutableMap; -import org.apache.commons.lang3.ObjectUtils; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.aai.ExceptionWithRequestInfo; -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.exceptions.MaxRetriesException; -import org.onap.vid.job.Job; -import org.onap.vid.job.JobCommand; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.RequestReferencesContainer; -import org.onap.vid.model.serviceInstantiation.ServiceInstantiation; -import org.onap.vid.mso.RestMsoImplementation; -import org.onap.vid.mso.RestObject; -import org.onap.vid.mso.model.ServiceInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; - -import javax.inject.Inject; -import java.util.Map; - - -public abstract class ServiceInstantiationCommand extends BaseRootCommand implements JobCommand { - - private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(ServiceInstantiationCommand.class); - - @Inject - protected AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Inject - private RestMsoImplementation restMso; - - protected String optimisticUniqueServiceInstanceName; - - public ServiceInstantiationCommand() { - } - - @Override - public NextCommand call() { - RequestDetailsWrapper<ServiceInstantiationRequestDetails> requestDetailsWrapper ; - try { - requestDetailsWrapper = generateServiceInstantiationRequest(); - } - - //Aai return bad response while checking names uniqueness - catch (ExceptionWithRequestInfo exception) { - return handleAaiNameUniquenessBadResponse(exception); - } - - //Vid reached to max retries while trying to find unique name in AAI - catch (MaxRetriesException exception) { - return handleMaxRetryInNameUniqueness(exception); - } - - String path = asyncInstantiationBL.getServiceInstantiationPath(getRequest()); - - RestObject<RequestReferencesContainer> msoResponse = restMso.PostForObject(requestDetailsWrapper, - path, RequestReferencesContainer.class); - - return handleRootResponse(msoResponse); - - } - - @Override - protected ServiceInstantiation getRequest() { - return (ServiceInstantiation) getSharedData().getRequest(); - } - - protected abstract RequestDetailsWrapper<ServiceInstantiationRequestDetails> generateServiceInstantiationRequest(); - - private NextCommand handleMaxRetryInNameUniqueness(MaxRetriesException exception) { - LOGGER.error("Failed to find unused name in AAI. Set the job to FAILED ", exception); - return handleCommandFailed(); - } - - private NextCommand handleAaiNameUniquenessBadResponse(ExceptionWithRequestInfo exception) { - LOGGER.error("Failed to check name uniqueness in AAI. VID will try again later", exception); - //put the job in_progress so we will keep trying to check name uniqueness in AAI - //And then send the request to MSO - return new NextCommand(Job.JobStatus.IN_PROGRESS, this); - } - - @Override - public ServiceInstantiationCommand init(JobSharedData sharedData, Map<String, Object> commandData) { - - return init( - sharedData, - (String) commandData.get("optimisticUniqueServiceInstanceName") - ); - } - - protected ServiceInstantiationCommand init(JobSharedData sharedData, String optimisticUniqueServiceInstanceName) { - init(sharedData); - this.optimisticUniqueServiceInstanceName = ObjectUtils.defaultIfNull(optimisticUniqueServiceInstanceName, - (getRequest()).getInstanceName()); - return this; - } - - @Override - public Map<String, Object> getData() { - return ImmutableMap.of( - "optimisticUniqueServiceInstanceName", optimisticUniqueServiceInstanceName - ); - } -} 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 new file mode 100644 index 000000000..af52fa049 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt @@ -0,0 +1,106 @@ +package org.onap.vid.job.command + +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.job.Job +import org.onap.vid.job.JobAdapter +import org.onap.vid.job.JobCommand +import org.onap.vid.job.JobsBrokerService +import org.onap.vid.model.Action +import org.onap.vid.model.serviceInstantiation.VfModule +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import java.util.* + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +class VfmoduleCommand @Autowired constructor( + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + restMso: RestMsoImplementation, + private val msoRequestBuilder: MsoRequestBuilder, + msoResultHandlerService: MsoResultHandlerService, + inProgressStatusService:InProgressStatusService, + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter +) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { + + companion object { + private val LOGGER = EELFLoggerDelegate.getLogger(VfmoduleCommand::class.java) + } + + override fun createChildren(): Job.JobStatus { + return Job.JobStatus.COMPLETED_WITH_NO_ACTION + } + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO) + val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO) + val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID) + val vgInstaceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VG_INSTANCE_ID) + + val instantiatePath = asyncInstantiationBL.getVfmoduleInstantiationPath(serviceInstanceId, vnfInstanceId) + + val requestDetailsWrapper = msoRequestBuilder.generateVfModuleInstantiationRequest( + request as VfModule, + serviceModelInfo, serviceInstanceId, vnfModelInfo, vnfInstanceId, vgInstaceId, userId, testApi) + + val actionDescription = "create vfmodule in $vnfInstanceId" + + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) + + } + + override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID) + + val path = asyncInstantiationBL.getVfModuleDeletePath(serviceInstanceId, vnfInstanceId, getRequest().instanceId) + val requestDetailsWrapper = msoRequestBuilder.generateDeleteVfModuleRequest(getRequest(), userId) + return MsoRestCallPlan(HttpMethod.DELETE, path, Optional.of(requestDetailsWrapper), Optional.of(userId), + "delete vfmodule ${getRequest().instanceId} from service instance $serviceInstanceId and vnf $vnfInstanceId") + } + + override fun getRequest(): VfModule { + return sharedData.request as VfModule + } + + override fun isDescendantHasAction(phase: Action): Boolean { + return false + } + + private fun planReplaceMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO) + val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO) + val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID) + val replacePath = asyncInstantiationBL.getVfModuleReplacePath(serviceInstanceId, vnfInstanceId, getRequest().instanceId) + + val requestDetailsWrapper = msoRequestBuilder.generateVfModuleInstantiationRequest( + request as VfModule, serviceModelInfo, serviceInstanceId,vnfModelInfo, vnfInstanceId,null,userId, testApi) + + val actionDescription = "replace vfmodule ${request.instanceId}" + + return MsoRestCallPlan(HttpMethod.POST, replacePath, Optional.of(requestDetailsWrapper), Optional.of(userId), actionDescription) + } + + override fun replaceMyself(): Job.JobStatus { + try { + val replaceMyselfCommand = planReplaceMyselfRestCall(commandParentData, sharedData.request, sharedData.userId, sharedData.testApi ) + return executeAndHandleMsoInstanceRequest(replaceMyselfCommand) + } catch (exception: Exception) { + LOGGER.error("Failed to replace instanceId ${getRequest().instanceId} ", exception) + return Job.JobStatus.FAILED + } + } + + override fun isNeedToReplaceMySelf(): Boolean { + return getActionType() == Action.Replace + } +} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleInstantiationCommand.java deleted file mode 100644 index 75bf97f8d..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleInstantiationCommand.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.model.serviceInstantiation.VfModule; -import org.onap.vid.mso.model.VfModuleInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class VfmoduleInstantiationCommand extends ResourceInstantiationCommand { - @Inject - private AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Override - protected String getRequestPath() { - return asyncInstantiationBL.getVfmoduleInstantiationPath(commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID),commandParentData.getInstanceId(CommandDataKey.VNF_INSTANCE_ID)); - } - - @Override - protected RequestDetailsWrapper<VfModuleInstantiationRequestDetails> generateMSORequest(JobAdapter.AsyncJobRequest request, String userId) { - return asyncInstantiationBL.generateVfModuleInstantiationRequest( - (VfModule) getSharedData().getRequest(), - commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID), - commandParentData.getModelInfo(CommandDataKey.VNF_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.VNF_INSTANCE_ID), - commandParentData.getInstanceId(CommandDataKey.VG_INSTANCE_ID), - getSharedData().getUserId() - ); - } - - @Override - protected String getJobAuditMSOStatus() { - return "VF_MODULE_REQUESTED"; - } - -} 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 new file mode 100644 index 000000000..a89e196de --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt @@ -0,0 +1,140 @@ +package org.onap.vid.job.command + +import org.apache.commons.collections.MapUtils +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.asdc.AsdcCatalogException +import org.onap.vid.job.* +import org.onap.vid.job.impl.JobSharedData +import org.onap.vid.model.Action +import org.onap.vid.model.serviceInstantiation.BaseResource +import org.onap.vid.model.serviceInstantiation.VfModule +import org.onap.vid.model.serviceInstantiation.Vnf +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.properties.Features +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import org.togglz.core.manager.FeatureManager +import java.util.* +import java.util.stream.Collectors +import kotlin.properties.Delegates + +const val NEED_TO_CREATE_BASE_MODULE = "needToCreateBaseModule" + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +class VnfCommand @Autowired constructor( + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + restMso: RestMsoImplementation, + private val msoRequestBuilder: MsoRequestBuilder, + msoResultHandlerService: MsoResultHandlerService, + inProgressStatusService:InProgressStatusService, + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter, + private val featureManager: FeatureManager +) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { + + private var needToCreateBaseModule:Boolean by Delegates.notNull<Boolean>() + + override fun getData(): Map<String, Any?> { + return super.getData() + mapOf(NEED_TO_CREATE_BASE_MODULE to needToCreateBaseModule) + } + + override fun init(sharedData: JobSharedData, commandData: Map<String, Any>): ResourceCommand { + super<ResourceCommand>.init(sharedData, commandData) + needToCreateBaseModule = commandData.getOrDefault(NEED_TO_CREATE_BASE_MODULE, actionPhase != Action.Delete) as Boolean + return this + } + + + override fun createChildren(): Job.JobStatus { + val request:Vnf = getRequest() + if(isNeedToCreateChildJobs()){ + val dataForChild = buildDataForChild(request, actionPhase) + val vfModules:List<VfModule> = request.vfModules.values.stream().flatMap { vfKey -> vfKey.values.stream() }.collect(Collectors.toList<VfModule>()) + + 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) + return Job.JobStatus.FAILED + } + } + + return Job.JobStatus.COMPLETED_WITH_NO_ACTION + } + + private fun filterModuleByNeedToCreateBase(it: VfModule):Boolean { + return needToCreateBaseModule == + commandUtils.isVfModuleBaseModule( + commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO).getModelVersionId(), + it.modelInfo.modelVersionId) + } + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO) + + val instantiatePath = asyncInstantiationBL.getVnfInstantiationPath(serviceInstanceId) + + val requestDetailsWrapper = msoRequestBuilder.generateVnfInstantiationRequest( + request as Vnf, + serviceModelInfo, serviceInstanceId, + userId, + testApi + ) + + val actionDescription = "create vnf in $serviceInstanceId" + + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) + + } + + override fun addMyselfToChildrenData(commandParentData: CommandParentData, request: BaseResource) { + commandParentData.addModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO, request.modelInfo); + commandParentData.addInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID, getActualInstanceId(request)) + } + + override fun getRequest(): Vnf { + return sharedData.request as Vnf + } + + private fun isNeedToCreateChildJobs(): Boolean { + return featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE) && + MapUtils.isNotEmpty(getRequest().vfModules) + } + + override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val path = asyncInstantiationBL.getVnfDeletionPath(serviceInstanceId, getRequest().instanceId) + val requestDetailsWrapper = msoRequestBuilder.generateDeleteVnfRequest(getRequest(), userId) + return MsoRestCallPlan(HttpMethod.DELETE, path, Optional.of(requestDetailsWrapper), Optional.of(userId), + "delete vnf ${getRequest().instanceId} from service $serviceInstanceId") + + } + + companion object { + private val LOGGER = EELFLoggerDelegate.getLogger(VnfCommand::class.java) + } + + //in Delete phase - we delete all non-base vf-modules first, before base vf-module + //in Create phase - we create base vf-module first, and then all the others + override fun watchChildren(): Job.JobStatus { + val childrenStatus:Job.JobStatus = comulateStatusAndUpdatePropertyIfFinal(watchChildrenJobsBL.retrieveChildrenJobsStatus(childJobs)) + if (!childrenStatus.isFinal || + childrenStatus.isFailure || + (actionPhase == Action.Create && !needToCreateBaseModule) || + (actionPhase == Action.Delete && needToCreateBaseModule)) { + return childrenStatus + } + + needToCreateBaseModule = !needToCreateBaseModule; + createChildren() + return Job.JobStatus.IN_PROGRESS + } +} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfInProgressStatusCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfInProgressStatusCommand.java deleted file mode 100644 index 832c575db..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfInProgressStatusCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * ============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.job.command; - -import org.apache.commons.collections.MapUtils; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.asdc.AsdcCatalogException; -import org.onap.vid.job.Job; -import org.onap.vid.job.JobType; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.serviceInstantiation.BaseResource; -import org.onap.vid.model.serviceInstantiation.VfModule; -import org.onap.vid.model.serviceInstantiation.Vnf; -import org.onap.vid.properties.Features; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class VnfInProgressStatusCommand extends ResourceWithChildrenInProgressCommand { - private static final EELFLoggerDelegate LOG = EELFLoggerDelegate.getLogger(VnfInProgressStatusCommand.class); - - public VnfInProgressStatusCommand(JobSharedData sharedData, - String requestId, - String instanceId, - CommandParentData commandParentData) { - super(sharedData, requestId, instanceId, commandParentData); - } - - public VnfInProgressStatusCommand() { - } - - @Override - protected NextCommand processJobStatus(Job.JobStatus jobStatus) { - if (jobStatus == Job.JobStatus.FAILED) { - return new NextCommand(jobStatus); - } - - Vnf request = (Vnf) getSharedData().getRequest(); - - if (isNeedToCreateChildJobs(jobStatus, request)) { - commandParentData.addInstanceId(CommandDataKey.VNF_INSTANCE_ID, instanceId); - commandParentData.addModelInfo(CommandDataKey.VNF_MODEL_INFO, request.getModelInfo()); - //create volume group of base module job - Map<String, Object> dataForChild = buildDataForChild(); - List<VfModule> vfModules = request.getVfModules().values().stream().flatMap(vfKey -> vfKey.values().stream()).collect(Collectors.toList()); - List<String> vgBaseJobs = new ArrayList<>(); - for( VfModule vfModule : vfModules){ - try { - if(commandUtils.isVfModuleBaseModule(commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO).getModelVersionId(), vfModule.getModelInfo().getModelVersionId())) { - vgBaseJobs.add(jobsBrokerService.add( - jobAdapter.createChildJob(JobType.VolumeGroupInstantiation, Job.JobStatus.CREATING, vfModule, getSharedData(), dataForChild)).toString()); - } - } catch (AsdcCatalogException e) { - LOG.error("Failed to retrieve service definitions from SDC, for VfModule is BaseModule. Error: "+e.getMessage() , e); - return new NextCommand(Job.JobStatus.COMPLETED_WITH_ERRORS); - } - } - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, new WatchingCommandBaseModule(getSharedData(), vgBaseJobs, false, commandParentData)); - } - - //in case of JobStatus.PAUSE we leave the job itself as IN_PROGRESS, for keep tracking job progress - if (jobStatus == Job.JobStatus.PAUSE) { - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, this); - } - return new NextCommand(jobStatus, this); - } - - - protected boolean isNeedToCreateChildJobs(Job.JobStatus jobStatus, BaseResource request) { - return featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE) && - jobStatus == Job.JobStatus.COMPLETED && - MapUtils.isNotEmpty(((Vnf)request).getVfModules()); - } - - - @Override - protected ExpiryChecker getExpiryChecker() { - return x->false; - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfInstantiationCommand.java deleted file mode 100644 index d3bfde3b6..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfInstantiationCommand.java +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.Job; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.model.serviceInstantiation.Vnf; -import org.onap.vid.mso.model.VnfInstantiationRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class VnfInstantiationCommand extends ResourceInstantiationCommand { - - @Inject - private AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Override - protected String getRequestPath() { - return asyncInstantiationBL.getVnfInstantiationPath( commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID)); - } - - @Override - protected RequestDetailsWrapper<VnfInstantiationRequestDetails> generateMSORequest(JobAdapter.AsyncJobRequest request, String userId) { - return asyncInstantiationBL.generateVnfInstantiationRequest( - (Vnf) getSharedData().getRequest(), - commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID), - getSharedData().getUserId() - ); - } - - @Override - protected String getJobAuditMSOStatus() { - return "VNF_REQUESTED"; - } - - @Override - protected NextCommand getNextCommand(String requestId, String instanceId) { - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, - new VnfInProgressStatusCommand(getSharedData(), requestId, instanceId, commandParentData)); - } - -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupCommand.kt new file mode 100644 index 000000000..4da1dad15 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupCommand.kt @@ -0,0 +1,94 @@ +package org.onap.vid.job.command + +import org.apache.commons.lang3.StringUtils.isNotEmpty +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate +import org.onap.vid.job.* +import org.onap.vid.model.Action +import org.onap.vid.model.serviceInstantiation.BaseResource +import org.onap.vid.model.serviceInstantiation.VfModule +import org.onap.vid.mso.RestMsoImplementation +import org.onap.vid.services.AsyncInstantiationBusinessLogic +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.config.ConfigurableBeanFactory +import org.springframework.context.annotation.Scope +import org.springframework.http.HttpMethod +import org.springframework.stereotype.Component +import java.util.* + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +class VolumeGroupCommand @Autowired constructor( + private val asyncInstantiationBL: AsyncInstantiationBusinessLogic, + restMso: RestMsoImplementation, + private val msoRequestBuilder: MsoRequestBuilder, + msoResultHandlerService: MsoResultHandlerService, + inProgressStatusService:InProgressStatusService, + watchChildrenJobsBL: WatchChildrenJobsBL, + jobsBrokerService: JobsBrokerService, + jobAdapter: JobAdapter +) : ResourceCommand(restMso, inProgressStatusService, msoResultHandlerService, + watchChildrenJobsBL, jobsBrokerService, jobAdapter), JobCommand { + + companion object { + private val LOGGER = EELFLoggerDelegate.getLogger(VolumeGroupCommand::class.java) + } + + override fun createChildren(): Job.JobStatus { + val request: VfModule = getRequest() + val dataForChild = buildDataForChild(request, actionPhase) + + childJobs = pushChildrenJobsToBroker(listOf(request), dataForChild, JobType.VfmoduleInstantiation) + + return Job.JobStatus.COMPLETED_WITH_NO_ACTION + } + + override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan { + + val serviceInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.SERVICE_INSTANCE_ID) + val serviceModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.SERVICE_MODEL_INFO) + val vnfInstanceId = commandParentData.getInstanceId(CommandParentData.CommandDataKey.VNF_INSTANCE_ID) + val vnfModelInfo = commandParentData.getModelInfo(CommandParentData.CommandDataKey.VNF_MODEL_INFO) + + val instantiatePath = asyncInstantiationBL.getVolumeGroupInstantiationPath(serviceInstanceId,vnfInstanceId) + + val requestDetailsWrapper = msoRequestBuilder.generateVolumeGroupInstantiationRequest( + request as VfModule, + serviceModelInfo, serviceInstanceId, + vnfModelInfo,vnfInstanceId, + userId, + testApi + ) + + val actionDescription = "create volumeGroup in $vnfInstanceId" + + return MsoRestCallPlan(HttpMethod.POST, instantiatePath, Optional.of(requestDetailsWrapper), Optional.empty(), actionDescription) + } + + override fun planDeleteMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String): MsoRestCallPlan { + TODO("not implemented") + } + + override fun isNeedToCreateMyself(): Boolean { + return super.isNeedToCreateMyself() && isNotEmpty(getRequest().volumeGroupInstanceName) + } + + override fun isNeedToDeleteMyself(): Boolean { + return false + } + + override fun getRequest(): VfModule { + return sharedData.request as VfModule + } + + override fun isDescendantHasAction(phase: Action): Boolean { + return phase == getRequest().action + } + + override fun addMyselfToChildrenData(commandParentData: CommandParentData, request: BaseResource) { + commandParentData.addInstanceId(CommandParentData.CommandDataKey.VG_INSTANCE_ID, getActualInstanceId(request)); + } + + override fun replaceMyself(): Job.JobStatus { + return Job.JobStatus.COMPLETED + } +} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupInProgressStatusCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupInProgressStatusCommand.java deleted file mode 100644 index 9c4d7b825..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupInProgressStatusCommand.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.job.Job; -import org.onap.vid.job.JobType; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.serviceInstantiation.VfModule; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class VolumeGroupInProgressStatusCommand extends ResourceWithChildrenInProgressCommand { - - public VolumeGroupInProgressStatusCommand( - JobSharedData sharedData, - String requestId, - String instanceId, - CommandParentData parentData) { - super(sharedData, requestId, instanceId, parentData); - } - - public VolumeGroupInProgressStatusCommand() { - } - - @Override - protected NextCommand processJobStatus(Job.JobStatus jobStatus) { - if (jobStatus == Job.JobStatus.FAILED) { - return new NextCommand(Job.JobStatus.FAILED); - } - VfModule request = (VfModule) getSharedData().getRequest(); - - if (jobStatus == Job.JobStatus.COMPLETED) { - //vf module creation - Map<String, Object> dataForChild = buildDataForChild(); - List<String> vfModuleJob = Arrays.asList(jobsBrokerService.add( - jobAdapter.createChildJob(JobType.VfmoduleInstantiation, Job.JobStatus.CREATING , request, getSharedData(), dataForChild)).toString()); - - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, new WatchingCommand(getSharedData(), vfModuleJob, false)); - } - - //in case of JobStatus.PAUSE we leave the job itself as IN_PROGRESS, for keep tracking job progress - if (jobStatus == Job.JobStatus.PAUSE) { - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, this); - } - return new NextCommand(jobStatus, this); - } - - @Override - protected Map<String, Object> buildDataForChild() { - commandParentData.addInstanceId(CommandDataKey.VG_INSTANCE_ID, this.instanceId); - return super.buildDataForChild(); - } - - @Override - protected ExpiryChecker getExpiryChecker() { - return x->false; - } -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupInstantiationCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupInstantiationCommand.java deleted file mode 100644 index eff12ec73..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/VolumeGroupInstantiationCommand.java +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * ============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.job.command; - - -import org.apache.commons.lang3.StringUtils; -import org.onap.vid.changeManagement.RequestDetailsWrapper; -import org.onap.vid.job.*; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.model.serviceInstantiation.VfModule; -import org.onap.vid.mso.model.VolumeGroupRequestDetails; -import org.onap.vid.services.AsyncInstantiationBusinessLogic; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class VolumeGroupInstantiationCommand extends ResourceInstantiationCommand { - @Inject - private AsyncInstantiationBusinessLogic asyncInstantiationBL; - - @Inject - protected JobsBrokerService jobsBrokerService; - - @Inject - protected JobAdapter jobAdapter; - - @Override - protected String getRequestPath() { - return asyncInstantiationBL.getVolumeGroupInstantiationPath(commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID),commandParentData.getInstanceId(CommandDataKey.VNF_INSTANCE_ID)); - } - - @Override - protected RequestDetailsWrapper<VolumeGroupRequestDetails> generateMSORequest(JobAdapter.AsyncJobRequest request, String userId) { - return asyncInstantiationBL.generateVolumeGroupInstantiationRequest( - (VfModule) getSharedData().getRequest(), - commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.SERVICE_INSTANCE_ID), - commandParentData.getModelInfo(CommandDataKey.VNF_MODEL_INFO), - commandParentData.getInstanceId(CommandDataKey.VNF_INSTANCE_ID), - getSharedData().getUserId() - ); - } - - @Override - protected NextCommand getNextCommand(String requestId, String instanceId){ - return new NextCommand( - Job.JobStatus.RESOURCE_IN_PROGRESS, - new VolumeGroupInProgressStatusCommand(getSharedData(), requestId, instanceId, commandParentData) - ); - } - - @Override - protected String getJobAuditMSOStatus() { - return "VOLUME_GROUP_REQUESTED"; - } - - @Override - public NextCommand call() { - String vgName = ((VfModule)getSharedData().getRequest()).getVolumeGroupInstanceName(); - if(StringUtils.isNotEmpty(vgName)){ - return super.call();//create volume group - }else { - //go to vf module creation - VfModule request = (VfModule) getSharedData().getRequest(); - Map<String, Object> dataForChild = buildDataForChild(); - List<String> vfModuleJob = Collections.singletonList(jobsBrokerService.add( - jobAdapter.createChildJob(JobType.VfmoduleInstantiation, Job.JobStatus.CREATING, request, getSharedData(), dataForChild)).toString()); - - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, new WatchingCommand(getSharedData(), vfModuleJob, false)); - } - - } - - private Map<String, Object> buildDataForChild() { - return commandParentData.getParentData(); - } - -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/WatchChildrenJobsBL.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/WatchChildrenJobsBL.kt index 7cebe2188..194fe4ba2 100644 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/WatchChildrenJobsBL.kt +++ b/vid-app-common/src/main/java/org/onap/vid/job/command/WatchChildrenJobsBL.kt @@ -7,9 +7,9 @@ * 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. @@ -21,11 +21,11 @@ package org.onap.vid.job.command import org.apache.commons.lang3.StringUtils -import org.onap.portalsdk.core.service.DataAccessService import org.onap.vid.job.Job import org.onap.vid.job.Job.JobStatus.* import org.onap.vid.job.impl.JobDaoImpl import org.onap.vid.utils.DaoUtils +import org.onap.portalsdk.core.service.DataAccessService import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service import java.util.* diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/WatchingCommand.java b/vid-app-common/src/main/java/org/onap/vid/job/command/WatchingCommand.java deleted file mode 100644 index 758cb56d7..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/WatchingCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * ============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.job.command; - -import org.onap.vid.job.Job; -import org.onap.vid.job.NextCommand; -import org.onap.vid.job.impl.JobSharedData; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import java.util.List; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class WatchingCommand extends BaseWatchingCommand { - - public WatchingCommand() {} - - public WatchingCommand(JobSharedData sharedData, List<String> childrenJobsIds, boolean isService) { - super(sharedData, childrenJobsIds, isService); - } - - protected NextCommand getNextCommand(Job.JobStatus cumulativeJobsStatus) { - if (cumulativeJobsStatus==Job.JobStatus.IN_PROGRESS) { - return (isService) ? new NextCommand(Job.JobStatus.IN_PROGRESS, this) - : new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, this); - } - if (isService) { - asyncInstantiationBL.updateServiceInfoAndAuditStatus(getSharedData().getJobUuid(), cumulativeJobsStatus); - } - return new NextCommand(cumulativeJobsStatus); - } - -} diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/WatchingCommandBaseModule.java b/vid-app-common/src/main/java/org/onap/vid/job/command/WatchingCommandBaseModule.java deleted file mode 100644 index 258811a01..000000000 --- a/vid-app-common/src/main/java/org/onap/vid/job/command/WatchingCommandBaseModule.java +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * ============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.job.command; - -import com.google.common.collect.ImmutableMap; -import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.asdc.AsdcCatalogException; -import org.onap.vid.job.*; -import org.onap.vid.job.command.CommandParentData.CommandDataKey; -import org.onap.vid.job.impl.JobSharedData; -import org.onap.vid.model.serviceInstantiation.VfModule; -import org.onap.vid.model.serviceInstantiation.Vnf; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Component -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class WatchingCommandBaseModule extends BaseWatchingCommand { - @Inject - protected JobsBrokerService jobsBrokerService; - - @Inject - protected JobAdapter jobAdapter; - private static final EELFLoggerDelegate LOG = EELFLoggerDelegate.getLogger(WatchingCommandBaseModule.class); - - public WatchingCommandBaseModule( - JobSharedData sharedData, - List<String> childrenJobsIds, - boolean isService, - CommandParentData commandParentData) { - super(sharedData, childrenJobsIds, isService); - this.commandParentData = commandParentData; - } - - public WatchingCommandBaseModule() { - - } - - @Override - protected NextCommand getNextCommand(Job.JobStatus cumulativeJobsStatus) { - - if (cumulativeJobsStatus== Job.JobStatus.IN_PROGRESS) { - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, this); - } - - if(cumulativeJobsStatus==Job.JobStatus.FAILED || cumulativeJobsStatus==Job.JobStatus.COMPLETED_WITH_ERRORS){ - return new NextCommand(Job.JobStatus.COMPLETED_WITH_ERRORS); - } - Vnf request = (Vnf) getSharedData().getRequest(); - Map<String, Object> dataForChild = buildDataForChild(); - //Create non-base Volume groups job - List<VfModule> vfModules = request.getVfModules().values().stream().flatMap(vfKey -> vfKey.values().stream()).collect(Collectors.toList()); - List<String> vgNonBaseJobs = new ArrayList<>(); - for( VfModule vfModule : vfModules){ - try { - if(!commandUtils.isVfModuleBaseModule(commandParentData.getModelInfo(CommandDataKey.SERVICE_MODEL_INFO).getModelVersionId(), vfModule.getModelInfo().getModelVersionId())) { - vgNonBaseJobs.add(jobsBrokerService.add( - jobAdapter.createChildJob(JobType.VolumeGroupInstantiation, Job.JobStatus.CREATING, vfModule, getSharedData(), dataForChild)).toString()); - } - } catch (AsdcCatalogException e) { - LOG.error("Failed to retrieve service definitions from SDC, for VfModule is BaseModule. Error: "+e.getMessage() , e); - return new NextCommand(Job.JobStatus.COMPLETED_WITH_ERRORS); - } - } - return new NextCommand(Job.JobStatus.RESOURCE_IN_PROGRESS, new WatchingCommand(getSharedData(), vgNonBaseJobs, false)); - } - - @Override - public WatchingCommandBaseModule init(JobSharedData sharedData, Map<String, Object> commandData) { - super.init(sharedData, commandData); - commandParentData.initParentData(commandData); - return this; - } - - protected Map<String, Object> buildDataForChild() { - return commandParentData.getParentData(); - } - - @Override - public Map<String, Object> getData() { - return ImmutableMap.<String, Object>builder() - .putAll(super.getData()) - .putAll(commandParentData.getParentData()) - .build(); - } - - -} |