re base code
[sdc.git] / openecomp-be / api / openecomp-sdc-rest-webapp / item-rest / item-rest-services / src / main / java / org / openecomp / sdcrests / item / rest / services / ItemsImpl.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.openecomp.sdcrests.item.rest.services;
18
19 import org.openecomp.sdc.activitylog.dao.type.ActivityType;
20 import org.openecomp.sdc.datatypes.model.ItemType;
21 import org.openecomp.sdc.itempermissions.PermissionsManager;
22 import org.openecomp.sdc.itempermissions.PermissionsManagerFactory;
23 import org.openecomp.sdc.itempermissions.impl.types.PermissionTypes;
24 import org.openecomp.sdc.logging.api.Logger;
25 import org.openecomp.sdc.logging.api.LoggerFactory;
26 import org.openecomp.sdc.notification.dtos.Event;
27 import org.openecomp.sdc.notification.factories.NotificationPropagationManagerFactory;
28 import org.openecomp.sdc.notification.services.NotificationPropagationManager;
29 import org.openecomp.sdc.versioning.ItemManager;
30 import org.openecomp.sdc.versioning.ItemManagerFactory;
31 import org.openecomp.sdc.versioning.VersioningManager;
32 import org.openecomp.sdc.versioning.VersioningManagerFactory;
33 import org.openecomp.sdc.versioning.dao.types.Version;
34 import org.openecomp.sdc.versioning.dao.types.VersionStatus;
35 import org.openecomp.sdc.versioning.types.Item;
36 import org.openecomp.sdc.versioning.types.ItemStatus;
37 import org.openecomp.sdc.versioning.types.NotificationEventTypes;
38 import org.openecomp.sdcrests.item.rest.Items;
39 import org.openecomp.sdcrests.item.rest.mapping.MapItemToDto;
40 import org.openecomp.sdcrests.item.types.ItemAction;
41 import org.openecomp.sdcrests.item.types.ItemActionRequestDto;
42 import org.openecomp.sdcrests.item.types.ItemDto;
43 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
44 import org.springframework.context.annotation.Scope;
45 import org.springframework.stereotype.Service;
46 import org.springframework.validation.annotation.Validated;
47
48 import javax.annotation.PostConstruct;
49 import javax.inject.Named;
50 import javax.ws.rs.core.Response;
51 import java.util.*;
52 import java.util.function.Predicate;
53 import java.util.stream.Collectors;
54
55 import static org.openecomp.sdc.itempermissions.notifications.NotificationConstants.PERMISSION_USER;
56 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.ITEM_ID;
57 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.ITEM_NAME;
58
59 @Named
60 @Service("items")
61 @Scope(value = "prototype")
62 @Validated
63 public class ItemsImpl implements Items {
64
65     private ItemManager itemManager = ItemManagerFactory.getInstance().createInterface();
66
67
68     private VersioningManager versioningManager = VersioningManagerFactory.getInstance().createInterface();
69
70     private final PermissionsManager permissionsManager = PermissionsManagerFactory.getInstance().createInterface();
71
72     private static final Logger LOGGER = LoggerFactory.getLogger(ItemsImpl.class);
73
74     private NotificationPropagationManager notifier =
75             NotificationPropagationManagerFactory.getInstance().createInterface();
76
77
78
79     private Map<ItemAction, ActionSideAffects> actionSideAffectsMap = new EnumMap<>(ItemAction.class);
80
81     @PostConstruct
82     public void initActionSideAffectsMap() {
83         actionSideAffectsMap
84                 .put(ItemAction.ARCHIVE, new ActionSideAffects(ActivityType.Archive, NotificationEventTypes.ARCHIVE));
85         actionSideAffectsMap
86                 .put(ItemAction.RESTORE, new ActionSideAffects(ActivityType.Restore, NotificationEventTypes.RESTORE));
87     }
88
89     private static final String ONBOARDING_METHOD = "onboardingMethod";
90
91
92     @Override
93     public Response actOn(ItemActionRequestDto request, String itemId, String user) {
94
95         Item item = itemManager.get(itemId);
96         if (item == null) {
97             return Response.status(Response.Status.NOT_FOUND).entity(new Exception("Item does not exist.")).build();
98         }
99
100         switch (request.getAction()) {
101             case ARCHIVE:
102                 itemManager.archive(item);
103                 break;
104             case RESTORE:
105                 itemManager.restore(item);
106                 break;
107             default:
108         }
109
110         actionSideAffectsMap.get(request.getAction()).execute(item, user);
111         try {
112             CatalogNotifier catalogNotifier = new CatalogNotifier();
113             catalogNotifier.execute(Collections.singleton(itemId), request.getAction(), 2);
114         } catch (Exception e){
115             LOGGER.error("Failed to send catalog notification on item " + itemId + " Error: " + e.getMessage());
116         }
117
118         return Response.ok().build();
119     }
120
121     @Override
122     public Response list(String itemStatusFilter, String versionStatusFilter, String itemTypeFilter,
123             String permissionFilter, String onboardingMethodFilter, String user) {
124
125         Predicate<Item> itemPredicate =
126                 createItemPredicate(itemStatusFilter, versionStatusFilter, itemTypeFilter, onboardingMethodFilter,
127                         permissionFilter, user);
128
129         GenericCollectionWrapper<ItemDto> results = new GenericCollectionWrapper<>();
130         MapItemToDto mapper = new MapItemToDto();
131         itemManager.list(itemPredicate).stream()
132                    .sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime()))
133                    .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class)));
134
135         return Response.ok(results).build();
136
137     }
138
139     @Override
140     public Response getItem(String itemId, String user) {
141         Item item = itemManager.get(itemId);
142         ItemDto itemDto = new MapItemToDto().applyMapping(item, ItemDto.class);
143
144         return Response.ok(itemDto).build();
145     }
146
147     private class SyncEvent implements Event {
148
149         private String eventType;
150         private String originatorId;
151         private Map<String, Object> attributes;
152         private String entityId;
153
154         SyncEvent(String eventType, String originatorId, Map<String, Object> attributes, String entityId) {
155             this.eventType = eventType;
156             this.originatorId = originatorId;
157             this.attributes = attributes;
158             this.entityId = entityId;
159         }
160
161         @Override
162         public String getEventType() {
163             return eventType;
164         }
165
166         @Override
167         public String getOriginatorId() {
168             return originatorId;
169         }
170
171         @Override
172         public Map<String, Object> getAttributes() {
173             return attributes;
174         }
175
176         @Override
177         public String getEntityId() {
178             return entityId;
179         }
180
181     }
182
183     private class ActionSideAffects {
184
185         private ActivityType activityType;
186         private NotificationEventTypes notificationType;
187
188         private ActionSideAffects(ActivityType activityType, NotificationEventTypes notificationType) {
189             this.activityType = activityType;
190             this.notificationType = notificationType;
191
192         }
193
194         private Version getLatestVersion(String itemId) {
195             List<Version> list = versioningManager.list(itemId);
196             Optional<Version> max = list.stream().max(Version::compareTo);
197
198             return max.orElse(null);
199         }
200
201         private void execute(Item item, String user) {
202             notifyUsers(item.getId(), item.getName(), user, this.notificationType);
203         }
204
205         private void notifyUsers(String itemId, String itemName, String userName, NotificationEventTypes eventType) {
206             Map<String, Object> eventProperties = new HashMap<>();
207             eventProperties.put(ITEM_NAME, itemName == null ? itemManager.get(itemId).getName() : itemName);
208             eventProperties.put(ITEM_ID, itemId);
209
210             eventProperties.put(PERMISSION_USER, userName);
211
212             Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
213             try {
214                 notifier.notifySubscribers(syncEvent, userName);
215             } catch (Exception e) {
216                 LOGGER.error("Failed to send sync notification to users subscribed to item '" + itemId);
217             }
218         }
219     }
220
221     private Predicate<Item> createItemPredicate(String itemStatusFilter, String versionStatusFilter,
222             String itemTypeFilter, String onboardingMethodFilter, String permissionsFilter, String user) {
223         Predicate<Item> itemPredicate = item -> true;
224
225         if (itemStatusFilter != null) {
226             validateItemStatusValue(itemStatusFilter);
227             itemPredicate = itemPredicate.and(createItemStatusPredicate(itemStatusFilter));
228         }
229         if (versionStatusFilter != null) {
230             validateVersionStatusValue(versionStatusFilter);
231             itemPredicate = itemPredicate.and(createVersionStatusPredicate(versionStatusFilter));
232         }
233         if (itemTypeFilter != null) {
234             validateItemTypeValue(itemTypeFilter);
235             itemPredicate = itemPredicate.and(createItemTypePredicate(itemTypeFilter));
236         }
237         if (onboardingMethodFilter != null) {
238             validateOnboardingMethodValue(onboardingMethodFilter);
239             itemPredicate = itemPredicate.and(createOnboardingMethodPredicate(onboardingMethodFilter));
240         }
241         if (permissionsFilter != null) {
242             validatePermissionValue(permissionsFilter);
243             itemPredicate = itemPredicate.and(createPermissionsPredicate(user, permissionsFilter));
244         }
245         return itemPredicate;
246     }
247
248     private String formatFilter(String filterValue) {
249         return filterValue.replace(",", "|");
250     }
251
252     private Predicate<Item> createItemStatusPredicate(String filterValue) {
253         return item -> item.getStatus().name().matches(formatFilter(filterValue));
254     }
255
256     private Predicate<Item> createVersionStatusPredicate(String filterValue) {
257         Set<VersionStatus> versionStatuses =
258                 Arrays.stream(filterValue.split(",")).map(VersionStatus::valueOf).collect(Collectors.toSet());
259         return item -> item.getVersionStatusCounters().keySet().stream().anyMatch(versionStatuses::contains);
260     }
261
262     private Predicate<Item> createItemTypePredicate(String filterValue) {
263         return item -> item.getType().matches(formatFilter(filterValue));
264     }
265
266     private Predicate<Item> createOnboardingMethodPredicate(String filterValue) {
267         return item -> !ItemType.vsp.name().equals(item.getType()) || ((String) item.getProperties()
268                                                                                     .get(ONBOARDING_METHOD))
269                                                                               .matches(formatFilter(filterValue));
270     }
271
272     private Predicate<Item> createPermissionsPredicate(String user, String filterValue) {
273         String[] permissions = filterValue.split(",");
274         Set<String> itemIds = new HashSet<>();
275         for (String permission : permissions) {
276             itemIds.addAll(permissionsManager.listUserPermittedItems(user, permission));
277         }
278         return item -> itemIds.contains(item.getId());
279     }
280
281     private void validateItemStatusValue(String itemStatusFilter) {
282         String[] values = itemStatusFilter.split(",");
283         for (String value : values) {
284             ItemStatus.valueOf(value);
285         }
286     }
287
288     private void validateVersionStatusValue(String versionStatusFilter) {
289         String[] values = versionStatusFilter.split(",");
290         for (String value : values) {
291             VersionStatus.valueOf(value);
292         }
293
294     }
295
296     private void validateItemTypeValue(String itemTypeFilter) {
297         String[] values = itemTypeFilter.split(",");
298         for (String value : values) {
299             ItemType.valueOf(value);
300         }
301     }
302
303     private void validateOnboardingMethodValue(String onboardingMethodFilter) {
304         String[] values = onboardingMethodFilter.split(",");
305         for (String value : values) {
306             OnboardingMethod.valueOf(value);
307         }
308     }
309
310     private void validatePermissionValue(String permissionsFilter) {
311         String[] values = permissionsFilter.split(",");
312         for (String value : values) {
313             PermissionTypes.valueOf(value);
314         }
315     }
316
317     //Do not delete - is in use, duplicates code to prevent dependency on openecomp-sdc-vendor-software-product-api
318     private enum OnboardingMethod {
319         NetworkPackage, Manual;
320     }
321 }