2 * Copyright © 2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.sdc.workflow.services.impl;
19 import static org.onap.sdc.workflow.persistence.types.WorkflowVersionState.CERTIFIED;
21 import com.amdocs.zusammen.datatypes.response.ErrorCode;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.Collection;
25 import java.util.Comparator;
26 import java.util.HashSet;
27 import java.util.List;
29 import java.util.Optional;
31 import java.util.function.Function;
32 import java.util.stream.Collectors;
33 import org.onap.sdc.workflow.persistence.ArtifactRepository;
34 import org.onap.sdc.workflow.persistence.ParameterRepository;
35 import org.onap.sdc.workflow.persistence.types.ArtifactEntity;
36 import org.onap.sdc.workflow.persistence.types.ParameterEntity;
37 import org.onap.sdc.workflow.persistence.types.ParameterRole;
38 import org.onap.sdc.workflow.persistence.types.WorkflowVersion;
39 import org.onap.sdc.workflow.persistence.types.WorkflowVersionState;
40 import org.onap.sdc.workflow.services.WorkflowVersionManager;
41 import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException;
42 import org.onap.sdc.workflow.services.exceptions.InvalidArtifactException;
43 import org.onap.sdc.workflow.services.exceptions.VersionCreationException;
44 import org.onap.sdc.workflow.services.exceptions.VersionModificationException;
45 import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException;
46 import org.onap.sdc.workflow.services.impl.mappers.VersionMapper;
47 import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper;
48 import org.openecomp.sdc.common.errors.SdcRuntimeException;
49 import org.openecomp.sdc.logging.api.Logger;
50 import org.openecomp.sdc.logging.api.LoggerFactory;
51 import org.openecomp.sdc.versioning.VersioningManager;
52 import org.openecomp.sdc.versioning.dao.types.Version;
53 import org.openecomp.sdc.versioning.dao.types.VersionStatus;
54 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
55 import org.springframework.beans.factory.annotation.Autowired;
56 import org.springframework.stereotype.Service;
57 import org.springframework.util.StringUtils;
58 import org.springframework.web.multipart.MultipartFile;
60 @Service("workflowVersionManager")
61 public class WorkflowVersionManagerImpl implements WorkflowVersionManager {
63 private static final String VERSION_NOT_EXIST_MSG = "version with id '%s' does not exist for workflow with id '%s'";
64 private final VersioningManager versioningManager;
65 private final ArtifactRepository artifactRepository;
66 private final ParameterRepository parameterRepository;
67 private final VersionMapper versionMapper;
68 private final VersionStateMapper versionStateMapper;
69 private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowVersionManagerImpl.class);
72 public WorkflowVersionManagerImpl(VersioningManager versioningManager, ArtifactRepository artifactRepository,
73 VersionMapper versionMapper, VersionStateMapper versionStateMapper,
74 ParameterRepository parameterRepository) {
75 this.versioningManager = versioningManager;
76 this.artifactRepository = artifactRepository;
77 this.parameterRepository = parameterRepository;
78 this.versionMapper = versionMapper;
79 this.versionStateMapper = versionStateMapper;
83 public Collection<WorkflowVersion> list(String workflowId, Set<WorkflowVersionState> stateFilter) {
84 Set<VersionStatus> versionStatusFilter =
85 stateFilter == null ? null :
86 stateFilter.stream().map(versionStateMapper::workflowVersionStateToVersionStatus)
87 .collect(Collectors.toSet());
89 return versioningManager.list(workflowId).stream()
90 .filter(version -> versionStatusFilter == null || versionStatusFilter.contains(
92 .map(versionMapper::versionToWorkflowVersion)
93 .sorted(Comparator.comparing(WorkflowVersion::getName).reversed())
94 .peek(workflowVersion -> loadAndAddParameters(workflowId, workflowVersion))
95 .collect(Collectors.toList());
99 public WorkflowVersion get(String workflowId, String versionId) {
100 WorkflowVersion workflowVersion = versionMapper.versionToWorkflowVersion(getVersion(workflowId, versionId));
101 loadAndAddParameters(workflowId, workflowVersion);
102 workflowVersion.setHasArtifact(artifactRepository.isExist(workflowId,versionId));
103 return workflowVersion;
107 public WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion workflowVersion) {
108 List<Version> versions = versioningManager.list(workflowId);
110 if (baseVersionId != null) {
111 if (!workflowVersion.getInputs().isEmpty() || !workflowVersion.getOutputs().isEmpty()) {
112 throw new VersionCreationException(workflowId, baseVersionId, "Inputs/Outputs should not be supplied");
114 validateVersionExistAndCertified(workflowId, versions, baseVersionId);
115 } else if (!versions.isEmpty()) {
116 throw new VersionCreationException(workflowId);
119 Version version = new Version();
120 version.setDescription(workflowVersion.getDescription());
121 version.setBaseId(baseVersionId);
122 Version createdVersion = versioningManager.create(workflowId, version, VersionCreationMethod.major);
124 if (versions.isEmpty()) { // only for first version
125 artifactRepository.createStructure(workflowId, createdVersion.getId());
126 parameterRepository.createStructure(workflowId, createdVersion.getId());
127 updateParameters(workflowId, createdVersion.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs());
128 versioningManager.publish(workflowId, createdVersion, "Add initial data");
131 return get(workflowId, createdVersion.getId());
135 public void update(String workflowId, WorkflowVersion workflowVersion) {
136 Version retrievedVersion = getVersion(workflowId, workflowVersion.getId());
137 if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) {
138 throw new VersionModificationException(workflowId, workflowVersion.getId());
141 Version version = versionMapper.workflowVersionToVersion(workflowVersion);
142 version.setName(retrievedVersion.getName());
143 version.setStatus(retrievedVersion.getStatus());
145 updateParameters(workflowId, version.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs());
147 versioningManager.updateVersion(workflowId, version);
149 Version updatedVersion = versioningManager.get(workflowId, version);
150 if(updatedVersion.getState().isDirty()) {
151 versioningManager.publish(workflowId, version, "Update version");
157 public WorkflowVersionState getState(String workflowId, String versionId) {
158 return versionStateMapper.versionStatusToWorkflowVersionState(getVersion(workflowId, versionId).getStatus());
162 public void updateState(String workflowId, String versionId, WorkflowVersionState state) {
163 WorkflowVersionState retrievedState =
164 versionStateMapper.versionStatusToWorkflowVersionState(getVersion(workflowId, versionId).getStatus());
166 if (state == CERTIFIED) {
168 versioningManager.submit(workflowId, new Version(versionId),
169 String.format("Update version state to %s", state.name()));
170 } catch (Exception e) {
171 throw new VersionStateModificationException(workflowId, versionId, retrievedState, state);
174 throw new VersionStateModificationException(workflowId, versionId, retrievedState, state);
179 public void uploadArtifact(String workflowId, String versionId, MultipartFile artifact) {
180 Version retrievedVersion = getVersion(workflowId, versionId);
181 if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) {
182 throw new VersionModificationException(workflowId, versionId);
185 try (InputStream artifactData = artifact.getInputStream()) {
186 ArtifactEntity artifactEntity =
187 new ArtifactEntity(StringUtils.cleanPath(artifact.getOriginalFilename()), artifactData);
188 artifactRepository.update(workflowId, versionId, artifactEntity);
189 versioningManager.publish(workflowId, new Version(versionId), "Update Artifact");
191 } catch (IOException e) {
192 LOGGER.error(String.format("Upload Artifact failed for workflow id %s and version id %s",
193 workflowId, versionId),e);
194 throw new InvalidArtifactException(e.getMessage());
199 public ArtifactEntity getArtifact(String workflowId, String versionId) {
200 getVersion(workflowId, versionId);
201 Optional<ArtifactEntity> artifactOptional = artifactRepository.get(workflowId, versionId);
202 if (!artifactOptional.isPresent()) {
203 LOGGER.error(String.format("Workflow Version Artifact was not found for workflow id %s and version id %s",
204 workflowId, versionId));
205 throw new EntityNotFoundException(
206 String.format("Artifact for workflow id %S version id %S was not found", workflowId, versionId));
208 return artifactOptional.get();
212 public void deleteArtifact(String workflowId, String versionId) {
213 WorkflowVersion retrievedVersion = get(workflowId, versionId);
214 if (CERTIFIED.equals(retrievedVersion.getState())) {
215 LOGGER.error(String.format(
216 "Workflow Version is certified and can not be edited.Workflow id %s and version id %s", workflowId,
218 throw new VersionModificationException(workflowId, versionId);
221 artifactRepository.delete(workflowId, versionId);
222 versioningManager.publish(workflowId, new Version(versionId), "Delete Artifact");
225 private void validateVersionExistAndCertified(String workflowId, List<Version> versions, String versionId) {
226 Version baseVersion = findVersion(versions, versionId).orElseThrow(
227 () -> new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId)));
229 if (CERTIFIED != versionStateMapper.versionStatusToWorkflowVersionState(baseVersion.getStatus())) {
230 throw new VersionCreationException(workflowId, versionId, "base version must be CERTIFIED");
234 private Version getVersion(String workflowId, String versionId) {
236 Version version = versioningManager.get(workflowId, new Version(versionId));
237 if (version == null) {
238 throw new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId));
241 } catch (Exception e) {
242 LOGGER.error(String.format(
243 "Workflow Version was not found.Workflow id %s and version id %s", workflowId,
245 throw new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId));
249 private void updateParameters(String workflowId, String versionId, Collection<ParameterEntity> inputs,
250 Collection<ParameterEntity> outputs) {
251 updateVersionParameters(workflowId, versionId, ParameterRole.INPUT, inputs);
252 updateVersionParameters(workflowId, versionId, ParameterRole.OUTPUT, outputs);
255 private void updateVersionParameters(String workflowId, String versionId, ParameterRole role,
256 Collection<ParameterEntity> parameters) {
258 Collection<ParameterEntity> retrievedParams = parameterRepository.list(workflowId, versionId, role);
259 Map<String, ParameterEntity> retrievedParamsByName =
260 retrievedParams.stream().collect(Collectors.toMap(ParameterEntity::getName, Function.identity()));
262 Set<String> namesOfParamsToKeep = new HashSet<>();
263 for (ParameterEntity parameter : parameters) {
265 ParameterEntity retrievedParam = retrievedParamsByName.get(parameter.getName());
266 if (retrievedParam == null) {
267 parameterRepository.create(workflowId, versionId, role, parameter);
269 parameterRepository.update(workflowId, versionId, role, parameter);
270 namesOfParamsToKeep.add(parameter.getName());
274 retrievedParams.stream().filter(retrievedParam -> !namesOfParamsToKeep.contains(retrievedParam.getName()))
275 .forEach(retrievedParam -> parameterRepository
276 .delete(workflowId, versionId, retrievedParam.getId()));
279 private void loadAndAddParameters(String workflowId, WorkflowVersion workflowVersion) {
280 workflowVersion.setInputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.INPUT));
281 workflowVersion.setOutputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.OUTPUT));
284 private static Optional<Version> findVersion(List<Version> versions, String versionId) {
285 return versions.stream().filter(version -> versionId.equals(version.getId())).findFirst();