a3e775ec9ef204301e97c61f59d69467d29b768a
[sdc/sdc-workflow-designer.git] /
1 package org.onap.sdc.workflow.services.impl;
2
3 import static org.onap.sdc.workflow.persistence.types.WorkflowVersionState.CERTIFIED;
4
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.util.Collection;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Optional;
12 import java.util.Set;
13 import java.util.function.Function;
14 import java.util.stream.Collectors;
15 import org.onap.sdc.workflow.persistence.ArtifactRepository;
16 import org.onap.sdc.workflow.persistence.ParameterRepository;
17 import org.onap.sdc.workflow.persistence.types.ArtifactEntity;
18 import org.onap.sdc.workflow.persistence.types.ParameterEntity;
19 import org.onap.sdc.workflow.persistence.types.ParameterRole;
20 import org.onap.sdc.workflow.persistence.types.WorkflowVersion;
21 import org.onap.sdc.workflow.persistence.types.WorkflowVersionState;
22 import org.onap.sdc.workflow.services.WorkflowVersionManager;
23 import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException;
24 import org.onap.sdc.workflow.services.exceptions.InvalidArtifactException;
25 import org.onap.sdc.workflow.services.exceptions.VersionCreationException;
26 import org.onap.sdc.workflow.services.exceptions.VersionModificationException;
27 import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException;
28 import org.onap.sdc.workflow.services.impl.mappers.VersionMapper;
29 import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper;
30 import org.openecomp.sdc.versioning.VersioningManager;
31 import org.openecomp.sdc.versioning.dao.types.Version;
32 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.stereotype.Service;
35 import org.springframework.util.StringUtils;
36 import org.springframework.web.multipart.MultipartFile;
37 import org.openecomp.sdc.logging.api.Logger;
38 import org.openecomp.sdc.logging.api.LoggerFactory;
39
40 @Service("workflowVersionManager")
41 public class WorkflowVersionManagerImpl implements WorkflowVersionManager {
42
43     private static final String VERSION_NOT_EXIST_MSG = "version with id '%s' does not exist for workflow with id '%s'";
44     private final VersioningManager versioningManager;
45     private final ArtifactRepository artifactRepository;
46     private final ParameterRepository parameterRepository;
47     private final VersionMapper versionMapper;
48     private final VersionStateMapper versionStateMapper;
49     private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowVersionManagerImpl.class);
50
51     @Autowired
52     public WorkflowVersionManagerImpl(VersioningManager versioningManager, ArtifactRepository artifactRepository,
53             VersionMapper versionMapper, VersionStateMapper versionStateMapper,
54             ParameterRepository parameterRepository) {
55         this.versioningManager = versioningManager;
56         this.artifactRepository = artifactRepository;
57         this.parameterRepository = parameterRepository;
58         this.versionMapper = versionMapper;
59         this.versionStateMapper = versionStateMapper;
60     }
61
62     @Override
63     public Collection<WorkflowVersion> list(String workflowId, Set<WorkflowVersionState> stateFilter) {
64         return versioningManager.list(workflowId).stream().map(versionMapper::versionToWorkflowVersion)
65                                 .filter(workflowVersion -> stateFilter.contains(workflowVersion.getState()))
66                                 .peek(workflowVersion -> loadAndAddParameters(workflowId, workflowVersion))
67                                 .collect(Collectors.toList());
68     }
69
70     @Override
71     public WorkflowVersion get(String workflowId, String versionId) {
72         WorkflowVersion workflowVersion = versionMapper.versionToWorkflowVersion(getVersion(workflowId, versionId));
73         loadAndAddParameters(workflowId, workflowVersion);
74         return workflowVersion;
75     }
76
77     @Override
78     public WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion workflowVersion) {
79         List<Version> versions = versioningManager.list(workflowId);
80
81         if (baseVersionId != null) {
82             if (!workflowVersion.getInputs().isEmpty() || !workflowVersion.getOutputs().isEmpty()) {
83                 throw new VersionCreationException(workflowId, baseVersionId, "Inputs/Outputs should not be supplied");
84             }
85             validateVersionExistAndCertified(workflowId, versions, baseVersionId);
86         } else if (!versions.isEmpty()) {
87             throw new VersionCreationException(workflowId);
88         }
89
90         Version version = new Version();
91         version.setDescription(workflowVersion.getDescription());
92         version.setBaseId(baseVersionId);
93         Version createdVersion = versioningManager.create(workflowId, version, VersionCreationMethod.major);
94
95         if (versions.isEmpty()) { // only for first version
96             artifactRepository.createStructure(workflowId, createdVersion.getId());
97             parameterRepository.createStructure(workflowId, createdVersion.getId());
98             updateParameters(workflowId, createdVersion.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs());
99             versioningManager.publish(workflowId, createdVersion, "Add initial data");
100         }
101
102         return get(workflowId, createdVersion.getId());
103     }
104
105     @Override
106     public void update(String workflowId, WorkflowVersion workflowVersion) {
107         Version retrievedVersion = getVersion(workflowId, workflowVersion.getId());
108         if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) {
109             throw new VersionModificationException(workflowId, workflowVersion.getId());
110         }
111
112         Version version = versionMapper.workflowVersionToVersion(workflowVersion);
113         version.setName(retrievedVersion.getName());
114         version.setStatus(retrievedVersion.getStatus());
115
116         updateParameters(workflowId, version.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs());
117
118         versioningManager.updateVersion(workflowId, version);
119         versioningManager.publish(workflowId, version, "Update version");
120     }
121
122     @Override
123     public WorkflowVersionState getState(String workflowId, String versionId) {
124         return versionStateMapper.versionStatusToWorkflowVersionState(getVersion(workflowId, versionId).getStatus());
125     }
126
127     @Override
128     public void updateState(String workflowId, String versionId, WorkflowVersionState state) {
129         WorkflowVersionState retrievedState =
130                 versionStateMapper.versionStatusToWorkflowVersionState(getVersion(workflowId, versionId).getStatus());
131
132         if (state == CERTIFIED) {
133             try {
134                 versioningManager.submit(workflowId, new Version(versionId),
135                         String.format("Update version state to %s", state.name()));
136             } catch (Exception e) {
137                 throw new VersionStateModificationException(workflowId, versionId, retrievedState, state);
138             }
139         } else {
140             throw new VersionStateModificationException(workflowId, versionId, retrievedState, state);
141         }
142     }
143
144     @Override
145     public void uploadArtifact(String workflowId, String versionId, MultipartFile artifact) {
146         Version retrievedVersion = getVersion(workflowId, versionId);
147         if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) {
148             throw new VersionModificationException(workflowId, versionId);
149         }
150
151         try (InputStream artifactData = artifact.getInputStream()) {
152             ArtifactEntity artifactEntity =
153                     new ArtifactEntity(StringUtils.cleanPath(artifact.getOriginalFilename()), artifactData);
154             artifactRepository.update(workflowId, versionId, artifactEntity);
155             versioningManager.publish(workflowId, new Version(versionId), "Update Artifact");
156
157         } catch (IOException e) {
158             LOGGER.error(String.format("Upload Artifact failed for workflow id %s and version id %s",
159                     workflowId, versionId),e);
160             throw new InvalidArtifactException(e.getMessage());
161         }
162     }
163
164     @Override
165     public ArtifactEntity getArtifact(String workflowId, String versionId) {
166         getVersion(workflowId, versionId);
167         Optional<ArtifactEntity> artifactOptional = artifactRepository.get(workflowId, versionId);
168         if (!artifactOptional.isPresent()) {
169             LOGGER.error(String.format("Workflow Version Artifact was not found for workflow id %s and version id %s",
170                     workflowId, versionId));
171             throw new EntityNotFoundException(
172                     String.format("Artifact for workflow id %S version id %S was not found", workflowId, versionId));
173         }
174         return artifactOptional.get();
175     }
176
177     @Override
178     public void deleteArtifact(String workflowId, String versionId) {
179         WorkflowVersion retrievedVersion = get(workflowId, versionId);
180         if (CERTIFIED.equals(retrievedVersion.getState())) {
181             LOGGER.error(String.format(
182                     "Workflow Version is certified and can not be edited.Workflow id %s and version id %s", workflowId,
183                     versionId));
184             throw new VersionModificationException(workflowId, versionId);
185         }
186
187         artifactRepository.delete(workflowId, versionId);
188         versioningManager.publish(workflowId, new Version(versionId), "Delete Artifact");
189     }
190
191     private void validateVersionExistAndCertified(String workflowId, List<Version> versions, String versionId) {
192         Version baseVersion = findVersion(versions, versionId).orElseThrow(
193                 () -> new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId)));
194
195         if (CERTIFIED != versionStateMapper.versionStatusToWorkflowVersionState(baseVersion.getStatus())) {
196             throw new VersionCreationException(workflowId, versionId, "base version must be CERTIFIED");
197         }
198     }
199
200     private Version getVersion(String workflowId, String versionId) {
201         try {
202             Version version = versioningManager.get(workflowId, new Version(versionId));
203             if (version == null) {
204                 throw new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId));
205             }
206             return version;
207         } catch (Exception e) {
208             LOGGER.error(String.format(
209                     "Workflow Version was not found.Workflow id %s and version id %s", workflowId,
210                     versionId),e);
211             throw new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId));
212         }
213     }
214
215     private void updateParameters(String workflowId, String versionId, Collection<ParameterEntity> inputs,
216             Collection<ParameterEntity> outputs) {
217         updateVersionParameters(workflowId, versionId, ParameterRole.INPUT, inputs);
218         updateVersionParameters(workflowId, versionId, ParameterRole.OUTPUT, outputs);
219     }
220
221     private void updateVersionParameters(String workflowId, String versionId, ParameterRole role,
222             Collection<ParameterEntity> parameters) {
223
224         Collection<ParameterEntity> retrievedParams = parameterRepository.list(workflowId, versionId, role);
225         Map<String, ParameterEntity> retrievedParamsByName =
226                 retrievedParams.stream().collect(Collectors.toMap(ParameterEntity::getName, Function.identity()));
227
228         Set<String> namesOfParamsToKeep = new HashSet<>();
229         for (ParameterEntity parameter : parameters) {
230
231             ParameterEntity retrievedParam = retrievedParamsByName.get(parameter.getName());
232             if (retrievedParam == null) {
233                 parameterRepository.create(workflowId, versionId, role, parameter);
234             } else {
235                 parameterRepository.update(workflowId, versionId, role, parameter);
236                 namesOfParamsToKeep.add(parameter.getName());
237             }
238         }
239
240         retrievedParams.stream().filter(retrievedParam -> !namesOfParamsToKeep.contains(retrievedParam.getName()))
241                        .forEach(retrievedParam -> parameterRepository
242                                                           .delete(workflowId, versionId, retrievedParam.getId()));
243     }
244
245     private void loadAndAddParameters(String workflowId, WorkflowVersion workflowVersion) {
246         workflowVersion.setInputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.INPUT));
247         workflowVersion.setOutputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.OUTPUT));
248     }
249
250     private static Optional<Version> findVersion(List<Version> versions, String versionId) {
251         return versions.stream().filter(version -> versionId.equals(version.getId())).findFirst();
252     }
253 }