6164418d91e481633fda9a75ae43244a405275f6
[policy/engine.git] / PolicyEngineUtils / src / main / java / org / onap / policy / std / NotificationStore.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * PolicyEngineUtils
4  * ================================================================================
5  * Copyright (C) 2017 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 import org.onap.policy.api.LoadedPolicy;
29 import org.onap.policy.api.NotificationType;
30 import org.onap.policy.api.PDPNotification;
31 import org.onap.policy.api.RemovedPolicy;
32
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     public static StdPDPNotification getDeltaNotification(StdPDPNotification newNotification) {
50         StdPDPNotification notificationDelta = new StdPDPNotification();
51         ArrayList<StdRemovedPolicy> removedDelta = new ArrayList<>();
52         ArrayList<StdLoadedPolicy> updatedDelta = new ArrayList<>();
53         Collection<StdLoadedPolicy> newUpdatedPolicies = new ArrayList<>();
54         Collection<StdRemovedPolicy> newRemovedPolicies = new ArrayList<>();
55         Collection<LoadedPolicy> oldUpdatedLostPolicies = notificationRecord.getLoadedPolicies();
56         Collection<RemovedPolicy> oldRemovedPolicies = notificationRecord.getRemovedPolicies();
57         Collection<LoadedPolicy> oldUpdatedPolicies = notificationRecord.getLoadedPolicies();
58         Boolean update = false;
59         Boolean remove = false;
60         // if the NotificationRecord is empty
61         if (notificationRecord.getRemovedPolicies() == null || notificationRecord.getLoadedPolicies() == null) {
62             if (newNotification != null) {
63                 notificationRecord = newNotification;
64             }
65             return notificationDelta;
66         }
67
68         if (newNotification == null) {
69             return notificationDelta;
70         }
71         // do the Delta operation.
72         // check for old removed policies.
73         if (!newNotification.getRemovedPolicies().isEmpty()) {
74             for (RemovedPolicy newRemovedPolicy : newNotification.getRemovedPolicies()) {
75                 remove = updateRemovedPolicies(removedDelta, oldUpdatedLostPolicies, oldRemovedPolicies, oldUpdatedPolicies, remove, newRemovedPolicy);
76             }
77         }
78         // Check for old Updated Policies.
79         if (!newNotification.getLoadedPolicies().isEmpty()) {
80             for (LoadedPolicy newUpdatedPolicy : newNotification.getLoadedPolicies()) {
81                 update = modifyUpdatedPolicies(updatedDelta, oldUpdatedLostPolicies, oldRemovedPolicies, oldUpdatedPolicies, update, newUpdatedPolicy);
82             }
83             // Conversion of Update to Remove if that occurred.
84             if (!oldUpdatedLostPolicies.isEmpty()) {
85                 for (LoadedPolicy updatedPolicy : oldUpdatedLostPolicies) {
86                     StdRemovedPolicy removedPolicy = new StdRemovedPolicy();
87                     removedPolicy.setPolicyName(updatedPolicy.getPolicyName());
88                     removedPolicy.setVersionNo(updatedPolicy.getVersionNo());
89                     removedDelta.add(removedPolicy);
90                     remove = true;
91                 }
92             }
93         }
94         // Update our Record.
95         if (!oldUpdatedPolicies.isEmpty()) {
96             for (LoadedPolicy updatedPolicy : oldUpdatedPolicies) {
97                 newUpdatedPolicies.add((StdLoadedPolicy) updatedPolicy);
98             }
99         }
100         if (!oldRemovedPolicies.isEmpty()) {
101             for (RemovedPolicy removedPolicy : oldRemovedPolicies) {
102                 newRemovedPolicies.add((StdRemovedPolicy) removedPolicy);
103             }
104         }
105         notificationRecord.setRemovedPolicies(newRemovedPolicies);
106         notificationRecord.setLoadedPolicies(newUpdatedPolicies);
107         // Update the notification Result.
108         notificationDelta.setRemovedPolicies(removedDelta);
109         notificationDelta.setLoadedPolicies(updatedDelta);
110         if (remove && update) {
111             notificationDelta.setNotificationType(NotificationType.BOTH);
112         } else if (remove) {
113             notificationDelta.setNotificationType(NotificationType.REMOVE);
114         } else if (update) {
115             notificationDelta.setNotificationType(NotificationType.UPDATE);
116         }
117
118         return notificationDelta;
119     }
120
121     private static Boolean modifyUpdatedPolicies(ArrayList<StdLoadedPolicy> updatedDelta, Collection<LoadedPolicy> oldUpdatedLostPolicies, Collection<RemovedPolicy> oldRemovedPolicies, Collection<LoadedPolicy> oldUpdatedPolicies, Boolean update, LoadedPolicy newUpdatedPolicy) {
122         // Look for policies which are not in Update
123         Boolean updated = true;
124         String policyName = newUpdatedPolicy.getPolicyName();
125         String ver = newUpdatedPolicy.getVersionNo();
126         for (LoadedPolicy oldUpdatedPolicy : notificationRecord.getLoadedPolicies()) {
127             if (policyName.equals(oldUpdatedPolicy.getPolicyName())
128                 && ver.equals(oldUpdatedPolicy.getVersionNo())) {
129                 updated = false;
130                 // Remove the policy from copy.
131                 oldUpdatedLostPolicies.remove(oldUpdatedPolicy);
132                 // Eliminating Duplicate.
133                 oldUpdatedPolicies.remove(oldUpdatedPolicy);
134             }
135         }
136         // Change the record if the policy has been Removed earlier.
137         for (RemovedPolicy oldRemovedPolicy : notificationRecord.getRemovedPolicies()) {
138             if (oldRemovedPolicy.getPolicyName().equals(policyName)
139                 && oldRemovedPolicy.getVersionNo().equals(ver)) {
140                 oldRemovedPolicies.remove(oldRemovedPolicy);
141             }
142         }
143         if (updated) {
144             update = true;
145             updatedDelta.add((StdLoadedPolicy) newUpdatedPolicy);
146         }
147         // This will be converted to new Later
148         oldUpdatedPolicies.add(newUpdatedPolicy);
149         return update;
150     }
151
152     private static Boolean updateRemovedPolicies(ArrayList<StdRemovedPolicy> removedDelta, Collection<LoadedPolicy> oldUpdatedLostPolicies, Collection<RemovedPolicy> oldRemovedPolicies, Collection<LoadedPolicy> oldUpdatedPolicies, Boolean remove, RemovedPolicy newRemovedPolicy) {
153         //Look for policy Not in Remove
154         Boolean removed = true;
155         String policyName = newRemovedPolicy.getPolicyName();
156         String ver = newRemovedPolicy.getVersionNo();
157         for (RemovedPolicy oldRemovedPolicy : notificationRecord.getRemovedPolicies()) {
158             if (policyName.equals(oldRemovedPolicy.getPolicyName())
159                 && ver.equals(oldRemovedPolicy.getVersionNo())) {
160                 removed = false;
161                 // Don't want a duplicate.
162                 oldRemovedPolicies.remove(oldRemovedPolicy);
163             }
164         }
165         //We need to change our record we have an Update record of this remove.
166         for (LoadedPolicy oldUpdatedPolicy : notificationRecord.getLoadedPolicies()) {
167             if (policyName.equals(oldUpdatedPolicy.getPolicyName())
168                 && ver.equals(oldUpdatedPolicy.getVersionNo())) {
169                 oldUpdatedPolicies.remove(oldUpdatedPolicy);
170                 oldUpdatedLostPolicies.remove(oldUpdatedPolicy);
171             }
172         }
173         if (removed) {
174             remove = true;
175             notificationRecord.getRemovedPolicies().add(newRemovedPolicy);
176             removedDelta.add((StdRemovedPolicy) newRemovedPolicy);
177         }
178         // This will be converted to New Later.
179         oldRemovedPolicies.add(newRemovedPolicy);
180         return remove;
181     }
182
183     public static void recordNotification(StdPDPNotification notification) {
184         if (notification == null) {
185             return;
186         }
187
188         if (notificationRecord.getRemovedPolicies() == null || notificationRecord.getLoadedPolicies() == null) {
189             notificationRecord = notification;
190         } else {
191             // Check if there is anything new and update the record.
192             if (notificationRecord.getLoadedPolicies() != null || notificationRecord.getRemovedPolicies() != null) {
193                 HashSet<StdRemovedPolicy> removedPolicies = new HashSet<>();
194                 for (RemovedPolicy rPolicy : notificationRecord.getRemovedPolicies()) {
195                     StdRemovedPolicy sRPolicy = new StdRemovedPolicy();
196                     sRPolicy.setPolicyName(rPolicy.getPolicyName());
197                     sRPolicy.setVersionNo(rPolicy.getVersionNo());
198                     removedPolicies.add(sRPolicy);
199                 }
200                 HashSet<StdLoadedPolicy> updatedPolicies = new HashSet<>();
201                 for (LoadedPolicy uPolicy : notificationRecord.getLoadedPolicies()) {
202                     StdLoadedPolicy sUPolicy = new StdLoadedPolicy();
203                     sUPolicy.setMatches(uPolicy.getMatches());
204                     sUPolicy.setPolicyName(uPolicy.getPolicyName());
205                     sUPolicy.setVersionNo(uPolicy.getVersionNo());
206                     sUPolicy.setUpdateType(uPolicy.getUpdateType());
207                     updatedPolicies.add(sUPolicy);
208                 }
209
210                 // Checking with the new updated policies.
211                 if (notification.getLoadedPolicies() != null && !notification.getLoadedPolicies().isEmpty()) {
212                     checkNewUpdatedPolicies(notification, removedPolicies, updatedPolicies);
213                 }
214                 // Checking with New Removed Policies.
215                 if (notification.getRemovedPolicies() != null && !notification.getRemovedPolicies().isEmpty()) {
216                     checkNewRemovedPolicies(notification, removedPolicies, updatedPolicies);
217                 }
218                 notificationRecord.setRemovedPolicies(removedPolicies);
219                 notificationRecord.setLoadedPolicies(updatedPolicies);
220             }
221             if (!notificationRecord.getLoadedPolicies().isEmpty() && !notificationRecord.getRemovedPolicies()
222                 .isEmpty()) {
223                 notificationRecord.setNotificationType(NotificationType.BOTH);
224             } else if (!notificationRecord.getLoadedPolicies().isEmpty()) {
225                 notificationRecord.setNotificationType(NotificationType.UPDATE);
226             } else if (!notificationRecord.getRemovedPolicies().isEmpty()) {
227                 notificationRecord.setNotificationType(NotificationType.REMOVE);
228             }
229         }
230     }
231
232     private static void checkNewUpdatedPolicies(StdPDPNotification notification, HashSet<StdRemovedPolicy> removedPolicies, HashSet<StdLoadedPolicy> updatedPolicies) {
233         for (LoadedPolicy newUpdatedPolicy : notification.getLoadedPolicies()) {
234             // If it was removed earlier then we need to remove from our record
235             Iterator<StdRemovedPolicy> oldRemovedPolicy = removedPolicies.iterator();
236             String policyName = newUpdatedPolicy.getPolicyName();
237             String ver = newUpdatedPolicy.getVersionNo();
238             while (oldRemovedPolicy.hasNext()) {
239                 RemovedPolicy policy = oldRemovedPolicy.next();
240                 if (policyName.equals(policy.getPolicyName())
241                     && ver.equals(policy.getVersionNo())) {
242                     oldRemovedPolicy.remove();
243                 }
244             }
245             // If it was previously updated need to Overwrite it to the record.
246             updatedPolicies.removeIf(policy -> policyName.equals(policy.getPolicyName())
247                 && ver.equals(policy.getVersionNo()));
248
249             StdLoadedPolicy sUPolicy = new StdLoadedPolicy();
250             sUPolicy.setMatches(newUpdatedPolicy.getMatches());
251             sUPolicy.setPolicyName(newUpdatedPolicy.getPolicyName());
252             sUPolicy.setVersionNo(newUpdatedPolicy.getVersionNo());
253             sUPolicy.setUpdateType(newUpdatedPolicy.getUpdateType());
254             updatedPolicies.add(sUPolicy);
255         }
256     }
257
258     private static void checkNewRemovedPolicies(StdPDPNotification notification, HashSet<StdRemovedPolicy> removedPolicies, HashSet<StdLoadedPolicy> updatedPolicies) {
259         for (RemovedPolicy newRemovedPolicy : notification.getRemovedPolicies()) {
260             // If it was previously removed Overwrite it to the record.
261             Iterator<StdRemovedPolicy> oldRemovedPolicy = removedPolicies.iterator();
262             String policyName = newRemovedPolicy.getPolicyName();
263             String ver = newRemovedPolicy.getVersionNo();
264             while (oldRemovedPolicy.hasNext()) {
265                 RemovedPolicy policy = oldRemovedPolicy.next();
266                 if (policyName.equals(policy.getPolicyName())
267                     && ver.equals(policy.getVersionNo())) {
268                     oldRemovedPolicy.remove();
269                 }
270             }
271             // If it was added earlier then we need to remove from our record.
272             updatedPolicies.removeIf(policy -> policyName.equals(policy.getPolicyName())
273                 && ver.equals(policy.getVersionNo()));
274
275             StdRemovedPolicy sRPolicy = new StdRemovedPolicy();
276             sRPolicy.setPolicyName(policyName);
277             sRPolicy.setVersionNo(ver);
278             removedPolicies.add(sRPolicy);
279         }
280     }
281
282     // This should return the current Notification Record.
283     public static PDPNotification getNotificationRecord() {
284         return notificationRecord;
285     }
286 }