aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/main/java/org/onap/policy/pap/main/notification/PolicyTrackerData.java
blob: 7dfb378f6ab2b6cdaa77a3025ad4deee7360b30c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*-
 * ============LICENSE_START=======================================================
 * ONAP PAP
 * ================================================================================
 * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
 * Modifications Copyright (C) 2021 Nordix Foundation.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 */

package org.onap.policy.pap.main.notification;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import lombok.Getter;
import org.onap.policy.models.pap.concepts.PolicyStatus;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;

/**
 * Data associated with a policy, used by PolicyTracker. PDPs start in
 * {@link #incompletePdps} and are moved to either {@link #successPdps} or
 * {@link #failPdps}, depending on their response. Objects of this type are not
 * multi-thread safe.
 */
public class PolicyTrackerData {
    /**
     * The policy type associated with the policy.
     */
    @Getter
    private final ToscaConceptIdentifier policyType;

    /**
     * PDPs that have successfully completed an update of the policy.
     */
    private final Set<String> successPdps = new HashSet<>();

    /**
     * PDPs that have failed to complete an update of the policy.
     */
    private final Set<String> failPdps = new HashSet<>();

    /**
     * PDPs for which we're still awaiting a response.
     */
    private final Set<String> incompletePdps = new HashSet<>();


    /**
     * Constructs the object.
     *
     * @param policyType policy type
     */
    public PolicyTrackerData(ToscaConceptIdentifier policyType) {
        this.policyType = policyType;
    }

    /**
     * Determines if this is complete (i.e., it is not waiting for responses from any
     * other PDPs).
     *
     * @return {@code true} if this is complete, {@code false} otherwise
     */
    public boolean isComplete() {
        return incompletePdps.isEmpty();
    }

    /**
     * Determines if everything has succeeded.
     *
     * @return {@code true} if this is complete <i>and</i> nothing has failed,
     *         {@code false} otherwise
     */
    public boolean allSucceeded() {
        return (failPdps.isEmpty() && incompletePdps.isEmpty());
    }

    /**
     * Determines if all of the sets within the data are empty (i.e., contain no PDPs).
     *
     * @return {@code true} if the data is completely empty, {@code false} otherwise
     */
    public boolean isEmpty() {
        return (successPdps.isEmpty() && failPdps.isEmpty() && incompletePdps.isEmpty());
    }

    /**
     * Puts the values from this data into the given status object.
     *
     * @param status object whose values are to be set
     */
    public void putValuesInto(PolicyStatus status) {
        status.setFailureCount(failPdps.size());
        status.setIncompleteCount(incompletePdps.size());
        status.setSuccessCount(successPdps.size());
    }

    /**
     * Adds PDPs to {@link #incompletePdps}, removing them from any other sets in which
     * they appear.
     *
     * @param pdps PDPs to be added
     */
    public void addPdps(Collection<String> pdps) {
        successPdps.removeAll(pdps);
        failPdps.removeAll(pdps);

        incompletePdps.addAll(pdps);
    }

    /**
     * Removes PDPs from the sets.
     *
     * @param pdps PDPs to be removed
     * @return {@code true} if anything changed and the policy is now complete, {@code false} otherwise
     */
    public boolean removePdps(Collection<String> pdps) {
        boolean changed = successPdps.removeAll(pdps);
        changed = failPdps.removeAll(pdps) || changed;
        changed = incompletePdps.removeAll(pdps) || changed;

        return (changed && incompletePdps.isEmpty());
    }

    /**
     * Removes a PDP from all sets.
     *
     * @param pdp PDP to be removed
     * @return {@code true} if anything changed and the policy is now complete, {@code false} otherwise
     */
    public boolean removePdp(String pdp) {
        boolean changed = successPdps.remove(pdp);
        changed = failPdps.remove(pdp) || changed;
        changed = incompletePdps.remove(pdp) || changed;

        return (changed && incompletePdps.isEmpty());
    }

    /**
     * Indicates that a PDP has successfully processed this policy.
     *
     * @param pdp the PDP of interest
     * @return {@code true} if the policy is now complete, {@code false} otherwise
     */
    public boolean success(String pdp) {
        return complete(pdp, successPdps, failPdps);
    }

    /**
     * Indicates that a PDP has processed this policy, but was unsuccessful.
     *
     * @param pdp the PDP of interest
     * @return {@code true} if the policy is now complete, {@code false} otherwise
     */
    public boolean fail(String pdp) {
        return complete(pdp, failPdps, successPdps);
    }

    /**
     * Indicates that a PDP has processed this policy, either successfully or
     * unsuccessfully.
     *
     * @param pdp the PDP of interest
     * @param addSet set to which the PDP should be added
     * @param removeSet set from which the PDP should be removed
     * @return {@code true} if the policy is now complete, {@code false} otherwise
     */
    private boolean complete(String pdp, Set<String> addSet, Set<String> removeSet) {
        if (incompletePdps.remove(pdp) || removeSet.remove(pdp)) {
            // successfully removed from one of the sets
            addSet.add(pdp);
            return incompletePdps.isEmpty();
        }

        /*
         * Else: wasn't in either set, thus it's already in the "addSet" or it isn't
         * relevant to this policy. Either way, just discard it without triggering any new
         * notification.
         */
        return false;
    }
}