2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2021 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.comm;
23 import java.util.HashMap;
25 import lombok.Builder;
26 import lombok.NonNull;
27 import org.onap.policy.models.base.PfModelException;
28 import org.onap.policy.models.pdp.concepts.Pdp;
29 import org.onap.policy.models.pdp.concepts.PdpGroup;
30 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
31 import org.onap.policy.models.provider.PolicyModelsProvider;
32 import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
33 import org.onap.policy.pap.main.PolicyPapRuntimeException;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Tracks PDPs. When a PDP is added to the tracker, a timer is started. If the PDP is not
39 * re-added to the tracker before the timer expires, then
40 * {@link PdpModifyRequestMap#removeFromGroups(String)} is called.
42 public class PdpTracker {
43 private static final Logger logger = LoggerFactory.getLogger(PdpTracker.class);
46 * PDP expiration timers.
48 private final TimerManager timers;
51 * Maps a PDP name to its expiration timer.
53 private final Map<String, TimerManager.Timer> pdp2timer = new HashMap<>();
56 * PDP modification lock.
58 private final Object modifyLock;
61 * Used to remove a PDP from its group/subgroup.
63 private final PdpModifyRequestMap requestMap;
67 * Constructs the object. Loads the list of PDPs to be tracked, from the DB.
69 * @param requestMap map used to remove a PDP from its group/subgroup
70 * @param modifyLock object to be locked while data structures are updated
71 * @param timers timers used to detect missed heart beats
72 * @param daoFactory DAO factory
75 public PdpTracker(@NonNull PdpModifyRequestMap requestMap, @NonNull Object modifyLock, @NonNull TimerManager timers,
76 @NonNull PolicyModelsProviderFactoryWrapper daoFactory) {
78 this.requestMap = requestMap;
79 this.modifyLock = modifyLock;
86 * Loads the PDPs from the DB.
88 * @param daoFactory DAO factory
90 private void loadPdps(PolicyModelsProviderFactoryWrapper daoFactory) {
91 synchronized (modifyLock) {
92 try (PolicyModelsProvider dao = daoFactory.create()) {
93 for (PdpGroup group : dao.getPdpGroups(null)) {
94 loadPdpsFromGroup(group);
97 } catch (PfModelException e) {
98 throw new PolicyPapRuntimeException("cannot load PDPs from the DB", e);
104 * Loads the PDPs appearing within a group.
106 * @param group group whose PDPs are to be loaded
108 private void loadPdpsFromGroup(PdpGroup group) {
109 for (PdpSubGroup subgrp : group.getPdpSubgroups()) {
110 for (Pdp pdp : subgrp.getPdpInstances()) {
111 add(pdp.getInstanceId());
117 * Adds a PDP to the tracker and starts its timer. If a timer is already running, the
118 * old timer is cancelled.
120 * @param pdpName name of the PDP
122 public void add(String pdpName) {
123 synchronized (modifyLock) {
124 var timer = pdp2timer.remove(pdpName);
129 timer = timers.register(pdpName, this::handleTimeout);
130 pdp2timer.put(pdpName, timer);
135 * Handles a timeout. Removes the PDP from {@link #pdp2timer}.
137 * @param pdpName name of the PDP whose timer has expired
139 private void handleTimeout(String pdpName) {
140 synchronized (modifyLock) {
141 // remove timer - no need to cancel it, as TimerManager does that
142 logger.warn("missed heart beats - removing PDP {}", pdpName);
143 pdp2timer.remove(pdpName);
146 requestMap.removeFromGroups(pdpName);
148 } catch (PfModelException e) {
149 logger.warn("unable to remove PDP {} from its group/subgroup", pdpName, e);