Re-format source code
[policy/engine.git] / PolicyEngineUtils / src / main / java / org / onap / policy / std / NotificationStore.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * PolicyEngineUtils
4  * ================================================================================
5  * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.std;
23
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashSet;
27 import java.util.Iterator;
28
29 import org.onap.policy.api.LoadedPolicy;
30 import org.onap.policy.api.NotificationType;
31 import org.onap.policy.api.PDPNotification;
32 import org.onap.policy.api.RemovedPolicy;
33
34 /*
35  * This Should Compare and save the Notifications from the beginning of Time.
36  * If there is something new (missed) We notify the client.
37  * Works for PDP failures.
38  *
39  */
40 public class NotificationStore {
41
42     private static StdPDPNotification notificationRecord = new StdPDPNotification();
43
44     private NotificationStore() {
45         // Sonar prefers that we have an empty public constructor
46         // as opposed to an implicit public constructor.
47     }
48
49     /**
50      * getDeltaNotification.
51      *
52      * @param newNotification StdPDPNotification
53      * @return StdPDPNotification
54      */
55     public static StdPDPNotification getDeltaNotification(StdPDPNotification newNotification) {
56         StdPDPNotification notificationDelta = new StdPDPNotification();
57         ArrayList<StdRemovedPolicy> removedDelta = new ArrayList<>();
58         ArrayList<StdLoadedPolicy> updatedDelta = new ArrayList<>();
59         Collection<StdLoadedPolicy> newUpdatedPolicies = new ArrayList<>();
60         Collection<StdRemovedPolicy> newRemovedPolicies = new ArrayList<>();
61         Collection<LoadedPolicy> oldUpdatedLostPolicies = notificationRecord.getLoadedPolicies();
62         Collection<RemovedPolicy> oldRemovedPolicies = notificationRecord.getRemovedPolicies();
63         Collection<LoadedPolicy> oldUpdatedPolicies = notificationRecord.getLoadedPolicies();
64         Boolean update = false;
65         Boolean remove = false;
66         // if the NotificationRecord is empty
67         if (notificationRecord.getRemovedPolicies() == null || notificationRecord.getLoadedPolicies() == null) {
68             if (newNotification != null) {
69                 notificationRecord = newNotification;
70             }
71             return notificationDelta;
72         }
73
74         if (newNotification == null) {
75             return notificationDelta;
76         }
77         // do the Delta operation.
78         // check for old removed policies.
79         if (!newNotification.getRemovedPolicies().isEmpty()) {
80             for (RemovedPolicy newRemovedPolicy : newNotification.getRemovedPolicies()) {
81                 remove = updateRemovedPolicies(removedDelta, oldUpdatedLostPolicies, oldRemovedPolicies,
82                         oldUpdatedPolicies, remove, newRemovedPolicy);
83             }
84         }
85         // Check for old Updated Policies.
86         if (!newNotification.getLoadedPolicies().isEmpty()) {
87             for (LoadedPolicy newUpdatedPolicy : newNotification.getLoadedPolicies()) {
88                 update = modifyUpdatedPolicies(updatedDelta, oldUpdatedLostPolicies, oldRemovedPolicies,
89                         oldUpdatedPolicies, update, newUpdatedPolicy);
90             }
91             // Conversion of Update to Remove if that occurred.
92             if (!oldUpdatedLostPolicies.isEmpty()) {
93                 for (LoadedPolicy updatedPolicy : oldUpdatedLostPolicies) {
94                     StdRemovedPolicy removedPolicy = new StdRemovedPolicy();
95                     removedPolicy.setPolicyName(updatedPolicy.getPolicyName());
96                     removedPolicy.setVersionNo(updatedPolicy.getVersionNo());
97                     removedDelta.add(removedPolicy);
98                     remove = true;
99                 }
100             }
101         }
102         // Update our Record.
103         if (!oldUpdatedPolicies.isEmpty()) {
104             for (LoadedPolicy updatedPolicy : oldUpdatedPolicies) {
105                 newUpdatedPolicies.add((StdLoadedPolicy) updatedPolicy);
106             }
107         }
108         if (!oldRemovedPolicies.isEmpty()) {
109             for (RemovedPolicy removedPolicy : oldRemovedPolicies) {
110                 newRemovedPolicies.add((StdRemovedPolicy) removedPolicy);
111             }
112         }
113         notificationRecord.setRemovedPolicies(newRemovedPolicies);
114         notificationRecord.setLoadedPolicies(newUpdatedPolicies);
115         // Update the notification Result.
116         notificationDelta.setRemovedPolicies(removedDelta);
117         notificationDelta.setLoadedPolicies(updatedDelta);
118         if (remove && update) {
119             notificationDelta.setNotificationType(NotificationType.BOTH);
120         } else if (remove) {
121             notificationDelta.setNotificationType(NotificationType.REMOVE);
122         } else if (update) {
123             notificationDelta.setNotificationType(NotificationType.UPDATE);
124         }
125
126         return notificationDelta;
127     }
128
129     private static Boolean modifyUpdatedPolicies(ArrayList<StdLoadedPolicy> updatedDelta,
130             Collection<LoadedPolicy> oldUpdatedLostPolicies, Collection<RemovedPolicy> oldRemovedPolicies,
131             Collection<LoadedPolicy> oldUpdatedPolicies, Boolean update, LoadedPolicy newUpdatedPolicy) {
132         // Look for policies which are not in Update
133         Boolean updated = true;
134         String policyName = newUpdatedPolicy.getPolicyName();
135         String ver = newUpdatedPolicy.getVersionNo();
136         for (LoadedPolicy oldUpdatedPolicy : notificationRecord.getLoadedPolicies()) {
137             if (policyName.equals(oldUpdatedPolicy.getPolicyName()) && ver.equals(oldUpdatedPolicy.getVersionNo())) {
138                 updated = false;
139                 // Remove the policy from copy.
140                 oldUpdatedLostPolicies.remove(oldUpdatedPolicy);
141                 // Eliminating Duplicate.
142                 oldUpdatedPolicies.remove(oldUpdatedPolicy);
143             }
144         }
145         // Change the record if the policy has been Removed earlier.
146         for (RemovedPolicy oldRemovedPolicy : notificationRecord.getRemovedPolicies()) {
147             if (oldRemovedPolicy.getPolicyName().equals(policyName) && oldRemovedPolicy.getVersionNo().equals(ver)) {
148                 oldRemovedPolicies.remove(oldRemovedPolicy);
149             }
150         }
151         if (updated) {
152             update = true;
153             updatedDelta.add((StdLoadedPolicy) newUpdatedPolicy);
154         }
155         // This will be converted to new Later
156         oldUpdatedPolicies.add(newUpdatedPolicy);
157         return update;
158     }
159
160     private static Boolean updateRemovedPolicies(ArrayList<StdRemovedPolicy> removedDelta,
161             Collection<LoadedPolicy> oldUpdatedLostPolicies, Collection<RemovedPolicy> oldRemovedPolicies,
162             Collection<LoadedPolicy> oldUpdatedPolicies, Boolean remove, RemovedPolicy newRemovedPolicy) {
163         // Look for policy Not in Remove
164         Boolean removed = true;
165         String policyName = newRemovedPolicy.getPolicyName();
166         String ver = newRemovedPolicy.getVersionNo();
167         for (RemovedPolicy oldRemovedPolicy : notificationRecord.getRemovedPolicies()) {
168             if (policyName.equals(oldRemovedPolicy.getPolicyName()) && ver.equals(oldRemovedPolicy.getVersionNo())) {
169                 removed = false;
170                 // Don't want a duplicate.
171                 oldRemovedPolicies.remove(oldRemovedPolicy);
172             }
173         }
174         // We need to change our record we have an Update record of this remove.
175         for (LoadedPolicy oldUpdatedPolicy : notificationRecord.getLoadedPolicies()) {
176             if (policyName.equals(oldUpdatedPolicy.getPolicyName()) && ver.equals(oldUpdatedPolicy.getVersionNo())) {
177                 oldUpdatedPolicies.remove(oldUpdatedPolicy);
178                 oldUpdatedLostPolicies.remove(oldUpdatedPolicy);
179             }
180         }
181         if (removed) {
182             remove = true;
183             notificationRecord.getRemovedPolicies().add(newRemovedPolicy);
184             removedDelta.add((StdRemovedPolicy) newRemovedPolicy);
185         }
186         // This will be converted to New Later.
187         oldRemovedPolicies.add(newRemovedPolicy);
188         return remove;
189     }
190
191     /**
192      * recordNotification.
193      *
194      * @param notification StdPDPNotification
195      */
196     public static void recordNotification(StdPDPNotification notification) {
197         if (notification == null) {
198             return;
199         }
200
201         if (notificationRecord.getRemovedPolicies() == null || notificationRecord.getLoadedPolicies() == null) {
202             notificationRecord = notification;
203             return;
204         }
205         // Check if there is anything new and update the record.
206         if (notificationRecord.getLoadedPolicies() != null || notificationRecord.getRemovedPolicies() != null) {
207             HashSet<StdRemovedPolicy> removedPolicies = new HashSet<>();
208             for (RemovedPolicy removedPolicy : notificationRecord.getRemovedPolicies()) {
209                 StdRemovedPolicy stdRemovedPolicy = new StdRemovedPolicy();
210                 stdRemovedPolicy.setPolicyName(removedPolicy.getPolicyName());
211                 stdRemovedPolicy.setVersionNo(removedPolicy.getVersionNo());
212                 removedPolicies.add(stdRemovedPolicy);
213             }
214             HashSet<StdLoadedPolicy> updatedPolicies = new HashSet<>();
215             for (LoadedPolicy loadedPolicy : notificationRecord.getLoadedPolicies()) {
216                 StdLoadedPolicy stdLoadedPolicy = new StdLoadedPolicy();
217                 stdLoadedPolicy.setMatches(loadedPolicy.getMatches());
218                 stdLoadedPolicy.setPolicyName(loadedPolicy.getPolicyName());
219                 stdLoadedPolicy.setVersionNo(loadedPolicy.getVersionNo());
220                 stdLoadedPolicy.setUpdateType(loadedPolicy.getUpdateType());
221                 updatedPolicies.add(stdLoadedPolicy);
222             }
223
224             // Checking with the new updated policies.
225             if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) {
226                 checkNewUpdatedPolicies(notification, removedPolicies, updatedPolicies);
227             }
228             // Checking with New Removed Policies.
229             if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) {
230                 checkNewRemovedPolicies(notification, removedPolicies, updatedPolicies);
231             }
232             notificationRecord.setRemovedPolicies(removedPolicies);
233             notificationRecord.setLoadedPolicies(updatedPolicies);
234         }
235         if (!notificationRecord.getLoadedPolicies().isEmpty()
236                 && !notificationRecord.getRemovedPolicies().isEmpty()) {
237             notificationRecord.setNotificationType(NotificationType.BOTH);
238         } else if (!notificationRecord.getLoadedPolicies().isEmpty()) {
239             notificationRecord.setNotificationType(NotificationType.UPDATE);
240         } else if (!notificationRecord.getRemovedPolicies().isEmpty()) {
241             notificationRecord.setNotificationType(NotificationType.REMOVE);
242         }
243     }
244
245     private static void checkNewUpdatedPolicies(StdPDPNotification notification,
246             HashSet<StdRemovedPolicy> removedPolicies, HashSet<StdLoadedPolicy> updatedPolicies) {
247         for (LoadedPolicy newUpdatedPolicy : notification.getLoadedPolicies()) {
248             // If it was removed earlier then we need to remove from our record
249             Iterator<StdRemovedPolicy> oldRemovedPolicy = removedPolicies.iterator();
250             String policyName = newUpdatedPolicy.getPolicyName();
251             String ver = newUpdatedPolicy.getVersionNo();
252             while (oldRemovedPolicy.hasNext()) {
253                 RemovedPolicy policy = oldRemovedPolicy.next();
254                 if (policyName.equals(policy.getPolicyName()) && ver.equals(policy.getVersionNo())) {
255                     oldRemovedPolicy.remove();
256                 }
257             }
258             // If it was previously updated need to Overwrite it to the record.
259             updatedPolicies
260                     .removeIf(policy -> policyName.equals(policy.getPolicyName()) && ver.equals(policy.getVersionNo()));
261
262             StdLoadedPolicy stdLoadedPolicy = new StdLoadedPolicy();
263             stdLoadedPolicy.setMatches(newUpdatedPolicy.getMatches());
264             stdLoadedPolicy.setPolicyName(newUpdatedPolicy.getPolicyName());
265             stdLoadedPolicy.setVersionNo(newUpdatedPolicy.getVersionNo());
266             stdLoadedPolicy.setUpdateType(newUpdatedPolicy.getUpdateType());
267             updatedPolicies.add(stdLoadedPolicy);
268         }
269     }
270
271     private static void checkNewRemovedPolicies(StdPDPNotification notification,
272             HashSet<StdRemovedPolicy> removedPolicies, HashSet<StdLoadedPolicy> updatedPolicies) {
273         for (RemovedPolicy newRemovedPolicy : notification.getRemovedPolicies()) {
274             // If it was previously removed Overwrite it to the record.
275             Iterator<StdRemovedPolicy> oldRemovedPolicy = removedPolicies.iterator();
276             String policyName = newRemovedPolicy.getPolicyName();
277             String ver = newRemovedPolicy.getVersionNo();
278             while (oldRemovedPolicy.hasNext()) {
279                 RemovedPolicy policy = oldRemovedPolicy.next();
280                 if (policyName.equals(policy.getPolicyName()) && ver.equals(policy.getVersionNo())) {
281                     oldRemovedPolicy.remove();
282                 }
283             }
284             // If it was added earlier then we need to remove from our record.
285             updatedPolicies
286                     .removeIf(policy -> policyName.equals(policy.getPolicyName()) && ver.equals(policy.getVersionNo()));
287
288             StdRemovedPolicy stdRemovedPolicy = new StdRemovedPolicy();
289             stdRemovedPolicy.setPolicyName(policyName);
290             stdRemovedPolicy.setVersionNo(ver);
291             removedPolicies.add(stdRemovedPolicy);
292         }
293     }
294
295     // This should return the current Notification Record.
296     public static PDPNotification getNotificationRecord() {
297         return notificationRecord;
298     }
299 }