2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.pap.main.rest.depundep;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.List;
28 import java.util.stream.Collectors;
29 import org.onap.policy.common.utils.validation.Version;
30 import org.onap.policy.models.base.PfModelException;
31 import org.onap.policy.models.pdp.concepts.PdpGroup;
32 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
33 import org.onap.policy.models.pdp.concepts.PdpUpdate;
34 import org.onap.policy.models.pdp.enums.PdpState;
35 import org.onap.policy.models.provider.PolicyModelsProvider;
36 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
37 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;
38 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
40 import org.onap.policy.pap.main.PolicyPapRuntimeException;
43 * Data used during a single REST call when updating PDP policies.
45 public class SessionData {
46 private final PolicyModelsProvider dao;
49 * Maps a group name to its group data. This accumulates the set of groups to be
50 * created and updated when the REST call completes.
52 private final Map<String, GroupData> groupCache = new HashMap<>();
55 * Maps a policy type to the list of matching groups. Every group appearing within
56 * this map has a corresponding entry in {@link #groupCache}.
58 private final Map<ToscaPolicyTypeIdentifier, List<GroupData>> type2groups = new HashMap<>();
61 * Maps a PDP name to its most recently generated update request.
63 private final Map<String, PdpUpdate> pdpUpdates = new HashMap<>();
66 * Maps a policy's identifier to the policy.
68 private final Map<ToscaPolicyIdentifier, ToscaPolicy> policyCache = new HashMap<>();
71 * Maps a policy name to its latest policy. Every policy appearing within this map has
72 * a corresponding entry in {@link #policyCache}.
74 private final Map<String, ToscaPolicy> latestPolicy = new HashMap<>();
78 * Constructs the object.
80 * @param dao DAO provider
82 public SessionData(PolicyModelsProvider dao) {
87 * Gets the policy, referenced by an identifier. Loads it from the cache, if possible.
88 * Otherwise, gets it from the DB.
90 * @param ident policy identifier
91 * @return the specified policy
92 * @throws PolicyPapRuntimeException if an error occurs
94 public ToscaPolicy getPolicy(ToscaPolicyIdentifier ident) {
96 return policyCache.computeIfAbsent(ident, key -> {
99 List<ToscaPolicy> lst = dao.getPolicyList(ident.getName(), ident.getVersion());
102 throw new PolicyPapRuntimeException(
103 "cannot find policy: " + ident.getName() + " " + ident.getVersion());
106 if (lst.size() > 1) {
107 throw new PolicyPapRuntimeException(
108 "too many policies match: " + ident.getName() + " " + ident.getVersion());
113 } catch (PfModelException e) {
114 throw new PolicyPapRuntimeException("cannot get policy: " + ident.getName() + " " + ident.getVersion(),
121 * Adds an update to the set of updates, replacing any previous entry for the given
124 * @param update the update to be added
126 public void addUpdate(PdpUpdate update) {
127 pdpUpdates.put(update.getName(), update);
131 * Gets the accumulated UPDATE requests.
133 * @return the UPDATE requests
135 public Collection<PdpUpdate> getPdpUpdates() {
136 return pdpUpdates.values();
140 * Determines if a group has been newly created as part of this REST call.
142 * @param group name to the group of interest
143 * @return {@code true} if the group has been newly created, {@code false} otherwise
145 public boolean isNewlyCreated(String group) {
146 GroupData data = groupCache.get(group);
147 return (data != null && data.isNew());
151 * Gets the policy having the given name and the maximum version.
153 * @param name name of the desired policy
154 * @return the desired policy, or {@code null} if there is no policy with given name
155 * @throws PfModelException if an error occurs
157 public ToscaPolicy getPolicyMaxVersion(String name) throws PfModelException {
158 ToscaPolicy policy = latestPolicy.get(name);
159 if (policy != null) {
163 ToscaPolicyFilter filter =
164 ToscaPolicyFilter.builder().name(name).version(ToscaPolicyFilter.LATEST_VERSION).build();
165 List<ToscaPolicy> policies = dao.getFilteredPolicyList(filter);
166 if (policies.isEmpty()) {
167 throw new PolicyPapRuntimeException("cannot find policy: " + name);
170 policy = policies.get(0);
171 policyCache.putIfAbsent(policy.getIdentifier(), policy);
172 latestPolicy.put(name, policy);
178 * Adds a new version of a group to the cache.
180 * @param newGroup the new group to be added
181 * @throws IllegalStateException if the old group has not been loaded into the cache
183 * @throws PfModelException if an error occurs
185 public void setNewGroup(PdpGroup newGroup) throws PfModelException {
186 String name = newGroup.getName();
187 GroupData data = groupCache.get(name);
189 throw new IllegalStateException("group not cached: " + name);
192 if (data.getLatestVersion() != null) {
193 // already have the latest version
194 data.setNewGroup(newGroup);
198 // must determine the latest version of this group, regardless of its state
199 PdpGroupFilter filter = PdpGroupFilter.builder().name(name).version(PdpGroupFilter.LATEST_VERSION).build();
200 List<PdpGroup> groups = dao.getFilteredPdpGroups(filter);
201 if (groups.isEmpty()) {
202 throw new PolicyPapRuntimeException("cannot find group: " + name);
205 PdpGroup group = groups.get(0);
206 Version vers = Version.makeVersion("PdpGroup", group.getName(), group.getVersion());
208 // none of the versions are numeric - start with zero and increment from there
209 vers = new Version(0, 0, 0);
212 data.setLatestVersion(vers);
213 data.setNewGroup(newGroup);
217 * Gets the active groups supporting the given policy.
219 * @param type desired policy type
220 * @return the active groups supporting the given policy
221 * @throws PfModelException if an error occurs
223 public List<PdpGroup> getActivePdpGroupsByPolicyType(ToscaPolicyTypeIdentifier type) throws PfModelException {
224 List<GroupData> data = type2groups.get(type);
226 return data.stream().map(GroupData::getCurrentGroup).collect(Collectors.toList());
229 final List<ToscaPolicyTypeIdentifier> policyTypeList = new ArrayList<>(1);
230 policyTypeList.add(type);
232 PdpGroupFilter filter = PdpGroupFilter.builder().policyTypeList(policyTypeList).matchPolicyTypesExactly(true)
233 .groupState(PdpState.ACTIVE).build();
235 List<PdpGroup> groups = dao.getFilteredPdpGroups(filter);
237 data = groups.stream().map(this::addGroup).collect(Collectors.toList());
238 type2groups.put(type, data);
244 * Adds a group to the group cache, if it isn't already in the cache.
246 * @param group the group to be added
247 * @return the cache entry
249 private GroupData addGroup(PdpGroup group) {
250 GroupData data = groupCache.get(group.getName());
255 data = new GroupData(group);
256 groupCache.put(group.getName(), data);
262 * Update the DB with the changes.
264 * @throws PfModelException if an error occurs
266 public void updateDb() throws PfModelException {
267 List<GroupData> updatedGroups =
268 groupCache.values().stream().filter(GroupData::isNew).collect(Collectors.toList());
269 if (updatedGroups.isEmpty()) {
273 // create new groups BEFORE we deactivate the old groups
274 dao.createPdpGroups(updatedGroups.stream().map(GroupData::getCurrentGroup).collect(Collectors.toList()));
275 dao.updatePdpGroups(updatedGroups.stream().map(GroupData::getOldGroup).collect(Collectors.toList()));