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