Use versioning, zusammen and session libs from sdc-common-be
[sdc/sdc-workflow-designer.git] / workflow-designer-be / src / main / java / org / onap / sdc / workflow / services / impl / WorkflowManagerImpl.java
1 /*
2  * Copyright © 2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.sdc.workflow.services.impl;
18
19 import static org.onap.sdc.workflow.services.impl.ItemType.WORKFLOW;
20 import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT;
21 import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET;
22 import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT;
23
24 import java.util.Collection;
25 import java.util.Comparator;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.function.Predicate;
29 import java.util.stream.Collectors;
30 import org.onap.sdc.common.versioning.services.ItemManager;
31 import org.onap.sdc.common.versioning.services.types.Item;
32 import org.onap.sdc.common.versioning.services.types.ItemStatus;
33 import org.onap.sdc.common.versioning.services.types.VersionStatus;
34 import org.onap.sdc.workflow.services.UniqueValueService;
35 import org.onap.sdc.workflow.services.WorkflowManager;
36 import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException;
37 import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException;
38 import org.onap.sdc.workflow.services.impl.mappers.ArchivingStatusMapper;
39 import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper;
40 import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper;
41 import org.onap.sdc.workflow.services.types.ArchivingStatus;
42 import org.onap.sdc.workflow.services.types.Page;
43 import org.onap.sdc.workflow.services.types.PagingRequest;
44 import org.onap.sdc.workflow.services.types.RequestSpec;
45 import org.onap.sdc.workflow.services.types.Sort;
46 import org.onap.sdc.workflow.services.types.SortingRequest;
47 import org.onap.sdc.workflow.services.types.Workflow;
48 import org.onap.sdc.workflow.services.types.WorkflowVersionState;
49 import org.openecomp.sdc.logging.api.Logger;
50 import org.openecomp.sdc.logging.api.LoggerFactory;
51 import org.springframework.beans.factory.annotation.Autowired;
52 import org.springframework.beans.factory.annotation.Qualifier;
53 import org.springframework.stereotype.Service;
54
55 @Service("workflowManager")
56 public class WorkflowManagerImpl implements WorkflowManager {
57
58     private static final String WORKFLOW_NOT_FOUND_ERROR_MSG = "Workflow with id '%s' does not exist";
59     private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME";
60     private static final Predicate<Item> WORKFLOW_ITEM_TYPE_FILTER = item -> WORKFLOW.name().equals(item.getType());
61     private static final String WORKSPACES_SORT_PROPERTY = "name";
62     private static final RequestSpec WORKSPACES_DEFAULT_REQUEST_SPEC =
63             new RequestSpec(new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT),
64                     SortingRequest.builder().sort(new Sort(WORKSPACES_SORT_PROPERTY, true)).build());
65
66     private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowManagerImpl.class);
67
68     private final ItemManager itemManager;
69     private final UniqueValueService uniqueValueService;
70     private final WorkflowMapper workflowMapper;
71     private final ArchivingStatusMapper archivingStatusMapper;
72     private final VersionStateMapper versionStateMapper;
73
74     @Autowired
75     public WorkflowManagerImpl(ItemManager itemManager,
76             @Qualifier("uniqueValueService") UniqueValueService uniqueValueService, WorkflowMapper workflowMapper,
77             ArchivingStatusMapper archivingStatusMapper, VersionStateMapper versionStateMapper) {
78         this.itemManager = itemManager;
79         this.uniqueValueService = uniqueValueService;
80         this.workflowMapper = workflowMapper;
81         this.archivingStatusMapper = archivingStatusMapper;
82         this.versionStateMapper = versionStateMapper;
83     }
84
85     @Override
86     public Page<Workflow> list(String statusFilter, String searchNameFilter,
87             Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec) {
88         requestSpec = getRequestSpec(requestSpec);
89
90         Collection<Item> workflowItems =
91                 itemManager.list(createFilter(statusFilter, searchNameFilter, versionStatesFilter));
92
93         List<Workflow> workflowsSlice = workflowItems.stream().map(workflowMapper::fromItem)
94                                                 .sorted(getWorkflowComparator(requestSpec.getSorting()))
95                                                 .skip(requestSpec.getPaging().getOffset())
96                                                 .limit(requestSpec.getPaging().getLimit()).collect(Collectors.toList());
97
98         return new Page<>(workflowsSlice, requestSpec.getPaging(), workflowItems.size());
99     }
100
101     @Override
102     public Workflow get(Workflow workflow) {
103         Item retrievedItem = itemManager.get(workflow.getId());
104         if (retrievedItem == null) {
105             throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId()));
106         }
107         return this.workflowMapper.fromItem(retrievedItem);
108     }
109
110     @Override
111     public Workflow create(Workflow workflow) {
112         Item item = new Item();
113         workflowMapper.toItem(workflow, item);
114
115         uniqueValueService.validateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflow.getName());
116         Item createdItem = itemManager.create(item);
117         uniqueValueService.createUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflow.getName());
118
119         return workflowMapper.fromItem(createdItem);
120     }
121
122     @Override
123     public void update(Workflow workflow) {
124         Item item = itemManager.get(workflow.getId());
125         if (item == null) {
126             throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId()));
127         }
128
129         if (ItemStatus.ARCHIVED.equals(item.getStatus())) {
130             throw new WorkflowModificationException(workflow.getId());
131         }
132
133         uniqueValueService.updateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, item.getName(), workflow.getName());
134
135         workflowMapper.toItem(workflow, item);
136         itemManager.update(workflow.getId(), item);
137     }
138
139     @Override
140     public void updateStatus(String workflowId, ArchivingStatus status) {
141         itemManager.updateStatus(workflowId, archivingStatusMapper.toItemStatus(status));
142     }
143
144     private static RequestSpec getRequestSpec(RequestSpec requestSpec) {
145         if (requestSpec == null) {
146             return WORKSPACES_DEFAULT_REQUEST_SPEC;
147         }
148         if (requestSpec.getPaging() == null) {
149             requestSpec.setPaging(WORKSPACES_DEFAULT_REQUEST_SPEC.getPaging());
150         } else {
151             handlePagingRequestValues(requestSpec.getPaging());
152         }
153         if (requestSpec.getSorting() == null) {
154             requestSpec.setSorting(WORKSPACES_DEFAULT_REQUEST_SPEC.getSorting());
155         }
156         return requestSpec;
157     }
158
159     private static void handlePagingRequestValues(PagingRequest paging) {
160         if (paging.getOffset() == null) {
161             paging.setOffset(DEFAULT_OFFSET);
162         }
163         if (paging.getLimit() == null) {
164             paging.setLimit(DEFAULT_LIMIT);
165         } else if (paging.getLimit() > MAX_LIMIT) {
166             paging.setLimit(MAX_LIMIT);
167         }
168     }
169
170     private static Comparator<Workflow> getWorkflowComparator(SortingRequest sorting) {
171         Boolean byNameAscending = sorting.getSorts().stream()
172                                           .filter(sort -> WORKSPACES_SORT_PROPERTY.equalsIgnoreCase(sort.getProperty()))
173                                           .findFirst().map(Sort::isAscendingOrder).orElse(true);
174         Comparator<Workflow> byName = Comparator.comparing(Workflow::getName);
175
176         return byNameAscending ? byName : byName.reversed();
177     }
178
179     private Predicate<Item> createFilter(String itemStatusFilter, String searchNameFilter,
180             Set<WorkflowVersionState> versionStatesFilter) {
181
182         Set<VersionStatus> versionStatusesFilter = versionStatesFilter == null ? null :
183                                                            versionStatesFilter.stream()
184                                                            .map(versionStateMapper::workflowVersionStateToVersionStatus)
185                                                            .collect(Collectors.toSet());
186
187         Predicate<Item> filter = addSearchNameFilter(WORKFLOW_ITEM_TYPE_FILTER, searchNameFilter);
188
189         filter = addVersionStatusFilter(filter, versionStatusesFilter);
190
191         return addItemStatusFilter(filter, itemStatusFilter);
192
193     }
194
195     private static Predicate<Item> addSearchNameFilter(Predicate<Item> filter, String searchNameFilter) {
196         return filter.and(item -> searchNameFilter == null || item.getName().toLowerCase()
197                                                                       .contains(searchNameFilter.toLowerCase()));
198     }
199
200     private static Predicate<Item> addVersionStatusFilter(Predicate<Item> filter, Set<VersionStatus> versionStatuses) {
201         return filter.and(item -> versionStatuses == null || item.getVersionStatusCounters().keySet().stream()
202                                                                      .anyMatch(versionStatuses::contains));
203     }
204
205     private static Predicate<Item> addItemStatusFilter(Predicate<Item> filter, String itemStatusFilter) {
206         if (itemStatusFilter != null) {
207             try {
208                 ItemStatus.valueOf(itemStatusFilter.toUpperCase());
209             } catch (IllegalArgumentException e) {
210                 LOGGER.debug("Illegal Workflow status filter: {}. Ignoring filter", itemStatusFilter, e);
211                 return filter;
212             }
213             return filter.and(item -> item.getStatus().equals(ItemStatus.valueOf(itemStatusFilter.toUpperCase())));
214         }
215         return filter;
216     }
217 }