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.Collection;
24 import java.util.HashMap;
25 import java.util.List;
27 import java.util.stream.Collectors;
28 import org.onap.policy.common.utils.validation.Version;
29 import org.onap.policy.models.base.PfModelException;
30 import org.onap.policy.models.pdp.concepts.PdpGroup;
31 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
32 import org.onap.policy.models.pdp.concepts.PdpUpdate;
33 import org.onap.policy.models.pdp.enums.PdpState;
34 import org.onap.policy.models.provider.PolicyModelsProvider;
35 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
36 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;
37 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
38 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
39 import org.onap.policy.pap.main.PolicyPapRuntimeException;
42 * Data used during a single REST call when updating PDP policies.
44 public class SessionData {
45 private final PolicyModelsProvider dao;
48 * Maps a group name to its group data. This accumulates the set of groups to be
49 * created and updated when the REST call completes.
51 private final Map<String, GroupData> groupCache = new HashMap<>();
54 * Maps a policy type to the list of matching groups. Every group appearing within
55 * this map has a corresponding entry in {@link #groupCache}.
57 private final Map<ToscaPolicyTypeIdentifier, List<GroupData>> type2groups = new HashMap<>();
60 * Maps a PDP name to its most recently generated update request.
62 private final Map<String, PdpUpdate> pdpUpdates = new HashMap<>();
65 * Maps a policy's identifier to the policy.
67 private final Map<ToscaPolicyIdentifier, ToscaPolicy> policyCache = new HashMap<>();
70 * Maps a policy name to its latest policy. Every policy appearing within this map has
71 * a corresponding entry in {@link #policyCache}.
73 private final Map<String, ToscaPolicy> latestPolicy = new HashMap<>();
77 * Constructs the object.
79 * @param dao DAO provider
81 public SessionData(PolicyModelsProvider dao) {
86 * Gets the policy, referenced by an identifier. Loads it from the cache, if possible.
87 * Otherwise, gets it from the DB.
89 * @param ident policy identifier
90 * @return the specified policy
91 * @throws PolicyPapRuntimeException if an error occurs
93 public ToscaPolicy getPolicy(ToscaPolicyIdentifier ident) {
95 return policyCache.computeIfAbsent(ident, key -> {
98 List<ToscaPolicy> lst = dao.getPolicyList(ident.getName(), ident.getVersion());
101 throw new PolicyPapRuntimeException(
102 "cannot find policy: " + ident.getName() + " " + ident.getVersion());
105 if (lst.size() > 1) {
106 throw new PolicyPapRuntimeException(
107 "too many policies match: " + ident.getName() + " " + ident.getVersion());
112 } catch (PfModelException e) {
113 throw new PolicyPapRuntimeException("cannot get policy: " + ident.getName() + " " + ident.getVersion(),
120 * Adds an update to the set of updates, replacing any previous entry for the given
123 * @param update the update to be added
125 public void addUpdate(PdpUpdate update) {
126 pdpUpdates.put(update.getName(), update);
130 * Gets the accumulated UPDATE requests.
132 * @return the UPDATE requests
134 public Collection<PdpUpdate> getPdpUpdates() {
135 return pdpUpdates.values();
139 * Determines if a group has been newly created as part of this REST call.
141 * @param group name to the group of interest
142 * @return {@code true} if the group has been newly created, {@code false} otherwise
144 public boolean isNewlyCreated(String group) {
145 GroupData data = groupCache.get(group);
146 return (data != null && data.isNew());
150 * Gets the policy having the given name and the maximum version.
152 * @param name name of the desired policy
153 * @return the desired policy, or {@code null} if there is no policy with given name
154 * @throws PfModelException if an error occurs
156 public ToscaPolicy getPolicyMaxVersion(String name) throws PfModelException {
157 ToscaPolicy policy = latestPolicy.get(name);
158 if (policy != null) {
162 ToscaPolicyFilter filter =
163 ToscaPolicyFilter.builder().name(name).version(ToscaPolicyFilter.LATEST_VERSION).build();
164 List<ToscaPolicy> policies = dao.getFilteredPolicyList(filter);
165 if (policies.isEmpty()) {
166 throw new PolicyPapRuntimeException("cannot find policy: " + name);
169 policy = policies.get(0);
170 policyCache.putIfAbsent(policy.getIdentifier(), policy);
171 latestPolicy.put(name, policy);
177 * Adds a new version of a group to the cache.
179 * @param newGroup the new group to be added
180 * @throws IllegalStateException if the old group has not been loaded into the cache
182 * @throws PfModelException if an error occurs
184 public void setNewGroup(PdpGroup newGroup) throws PfModelException {
185 String name = newGroup.getName();
186 GroupData data = groupCache.get(name);
188 throw new IllegalStateException("group not cached: " + name);
191 if (data.getLatestVersion() != null) {
192 // already have the latest version
193 data.setNewGroup(newGroup);
197 // must determine the latest version of this group, regardless of its state
198 PdpGroupFilter filter = PdpGroupFilter.builder().name(name).version(PdpGroupFilter.LATEST_VERSION).build();
199 List<PdpGroup> groups = dao.getFilteredPdpGroups(filter);
200 if (groups.isEmpty()) {
201 throw new PolicyPapRuntimeException("cannot find group: " + name);
204 PdpGroup group = groups.get(0);
205 Version vers = Version.makeVersion("PdpGroup", group.getName(), group.getVersion());
207 // none of the versions are numeric - start with zero and increment from there
208 vers = new Version(0, 0, 0);
211 data.setLatestVersion(vers);
212 data.setNewGroup(newGroup);
216 * Gets the active groups supporting the given policy.
218 * @param type desired policy type
219 * @return the active groups supporting the given policy
220 * @throws PfModelException if an error occurs
222 public List<PdpGroup> getActivePdpGroupsByPolicyType(ToscaPolicyTypeIdentifier type) throws PfModelException {
223 List<GroupData> data = type2groups.get(type);
225 return data.stream().map(GroupData::getCurrentGroup).collect(Collectors.toList());
228 PdpGroupFilter filter = PdpGroupFilter.builder().policyType(type).groupState(PdpState.ACTIVE).build();
230 List<PdpGroup> groups = dao.getFilteredPdpGroups(filter);
232 data = groups.stream().map(this::addGroup).collect(Collectors.toList());
233 type2groups.put(type, data);
239 * Adds a group to the group cache, if it isn't already in the cache.
241 * @param group the group to be added
242 * @return the cache entry
244 private GroupData addGroup(PdpGroup group) {
245 GroupData data = groupCache.get(group.getName());
250 data = new GroupData(group);
251 groupCache.put(group.getName(), data);
257 * Update the DB with the changes.
259 * @throws PfModelException if an error occurs
261 public void updateDb() throws PfModelException {
262 List<GroupData> updatedGroups =
263 groupCache.values().stream().filter(GroupData::isNew).collect(Collectors.toList());
264 if (updatedGroups.isEmpty()) {
268 // create new groups BEFORE we deactivate the old groups
269 dao.createPdpGroups(updatedGroups.stream().map(GroupData::getCurrentGroup).collect(Collectors.toList()));
270 dao.updatePdpGroups(updatedGroups.stream().map(GroupData::getOldGroup).collect(Collectors.toList()));