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