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