* ============LICENSE_START=======================================================
* ONAP PAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.policy.pap.main.comm;
+import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import lombok.Setter;
import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pap.concepts.PolicyNotification;
import org.onap.policy.models.pdp.concepts.Pdp;
import org.onap.policy.models.pdp.concepts.PdpGroup;
import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
import org.onap.policy.models.pdp.concepts.PdpMessage;
import org.onap.policy.models.pdp.concepts.PdpStateChange;
+import org.onap.policy.models.pdp.concepts.PdpStatus;
import org.onap.policy.models.pdp.concepts.PdpSubGroup;
import org.onap.policy.models.pdp.concepts.PdpUpdate;
import org.onap.policy.models.pdp.enums.PdpState;
import org.onap.policy.pap.main.comm.msgdata.RequestListener;
import org.onap.policy.pap.main.comm.msgdata.StateChangeReq;
import org.onap.policy.pap.main.comm.msgdata.UpdateReq;
+import org.onap.policy.pap.main.notification.DeploymentStatus;
import org.onap.policy.pap.main.notification.PolicyNotifier;
import org.onap.policy.pap.main.parameters.PdpModifyRequestMapParams;
import org.onap.policy.pap.main.parameters.RequestParams;
* Adds an UPDATE request to the map.
*
* @param update the UPDATE request or {@code null}
+ * @return the new request (this should only be used by junit tests)
*/
- public void addRequest(PdpUpdate update) {
+ public Request addRequest(PdpUpdate update) {
if (update == null) {
- return;
+ return null;
}
if (isBroadcast(update)) {
// @formatter:on
String name = update.getName() + " " + PdpUpdate.class.getSimpleName();
- UpdateReq request = new UpdateReq(reqparams, name, update);
+ var request = new UpdateReq(reqparams, name, update);
addSingleton(request);
+ return request;
}
/**
* Adds a STATE-CHANGE request to the map.
*
* @param stateChange the STATE-CHANGE request or {@code null}
+ * @return the new request (this should only be used by junit tests)
*/
- public void addRequest(PdpStateChange stateChange) {
+ public Request addRequest(PdpStateChange stateChange) {
if (stateChange == null) {
- return;
+ return null;
}
if (isBroadcast(stateChange)) {
// @formatter:on
String name = stateChange.getName() + " " + PdpStateChange.class.getSimpleName();
- StateChangeReq request = new StateChangeReq(reqparams, name, stateChange);
+ var request = new StateChangeReq(reqparams, name, stateChange);
addSingleton(request);
+ return request;
}
/**
}
/**
- * Removes a PDP from all active groups.
- *
- * @param pdpName name of the PDP to be removed
- * @return {@code true} if the PDP was removed from a group, {@code false} if it was
- * not assigned to a group
- * @throws PfModelException if an error occurred
+ * Removes expired PDPs from all active groups.
*/
- public boolean removeFromGroups(String pdpName) throws PfModelException {
+ public void removeExpiredPdps() {
+
+ synchronized (modifyLock) {
+ logger.info("check for PDP records older than {}ms", params.getMaxPdpAgeMs());
+
+ try (PolicyModelsProvider dao = daoFactory.create()) {
+
+ PdpGroupFilter filter = PdpGroupFilter.builder().groupState(PdpState.ACTIVE).build();
+ List<PdpGroup> groups = dao.getFilteredPdpGroups(filter);
+ List<PdpGroup> updates = new ArrayList<>(1);
- try (PolicyModelsProvider dao = daoFactory.create()) {
+ var status = new DeploymentStatus(dao);
- PdpGroupFilter filter = PdpGroupFilter.builder().groupState(PdpState.ACTIVE).build();
- List<PdpGroup> groups = dao.getFilteredPdpGroups(filter);
- List<PdpGroup> updates = new ArrayList<>(1);
+ Instant minAge = Instant.now().minusMillis(params.getMaxPdpAgeMs());
- for (PdpGroup group : groups) {
- if (removeFromGroup(pdpName, group)) {
- updates.add(group);
+ for (PdpGroup group : groups) {
+ Set<String> pdps = removeFromGroup(minAge, group);
+ if (!pdps.isEmpty()) {
+ updates.add(group);
+ status.loadByGroup(group.getName());
+ pdps.forEach(status::deleteDeployment);
+ }
}
- }
- if (updates.isEmpty()) {
- return false;
+ if (!updates.isEmpty()) {
+ dao.updatePdpGroups(updates);
- } else {
- dao.updatePdpGroups(updates);
- return true;
+ var notification = new PolicyNotification();
+ status.flush(notification);
+
+ policyNotifier.publish(notification);
+ }
+
+ } catch (PfModelException e) {
+ logger.warn("failed to remove expired PDPs", e);
}
}
}
/**
- * Removes a PDP from a group.
+ * Removes expired PDPs from a group.
*
- * @param pdpName name of the PDP to be removed
- * @param group group from which it should be removed
- * @return {@code true} if the PDP was removed from the group, {@code false} if it was
- * not assigned to the group
+ * @param minAge minimum age for active PDPs
+ * @param group group from which expired PDPs should be removed
+ * @return the expired PDPs
*/
- private boolean removeFromGroup(String pdpName, PdpGroup group) {
+ private Set<String> removeFromGroup(Instant minAge, PdpGroup group) {
+ Set<String> pdps = new HashSet<>();
for (PdpSubGroup subgrp : group.getPdpSubgroups()) {
- if (removeFromSubgroup(pdpName, group, subgrp)) {
- return true;
- }
+ removeFromSubgroup(minAge, group, subgrp, pdps);
}
- return false;
+ return pdps;
}
/**
- * Removes a PDP from a subgroup.
+ * Removes expired PDPs from a subgroup.
*
- * @param pdpName name of the PDP to be removed
+ * @param minAge minimum age for active PDPs
* @param group group from which to attempt to remove the PDP
* @param subgrp subgroup from which to attempt to remove the PDP
- * @return {@code true} if the PDP was removed, {@code false} if the PDP was not in
- * the group
+ * @param pdps where to place the expired PDPs
*/
- private boolean removeFromSubgroup(String pdpName, PdpGroup group, PdpSubGroup subgrp) {
+ private void removeFromSubgroup(Instant minAge, PdpGroup group, PdpSubGroup subgrp, Set<String> pdps) {
Iterator<Pdp> iter = subgrp.getPdpInstances().iterator();
while (iter.hasNext()) {
Pdp instance = iter.next();
- if (pdpName.equals(instance.getInstanceId())) {
+ if (instance.getLastUpdate().isBefore(minAge)) {
+ String pdpName = instance.getInstanceId();
logger.info("removed {} from group={} subgroup={}", pdpName, group.getName(), subgrp.getPdpType());
iter.remove();
subgrp.setCurrentInstanceCount(subgrp.getPdpInstances().size());
- return true;
+ pdps.add(pdpName);
}
}
-
- return false;
}
/**
return new PdpRequests(pdpName, policyNotifier);
}
+ /**
+ * Makes a handler for PDP responses.
+ * @return a response handler
+ */
+ protected PdpStatusMessageHandler makePdpResponseHandler() {
+ return new PdpStatusMessageHandler(params.getParams(), params.isSavePdpStatistics());
+ }
+
/**
* Listener for singleton request events.
*/
}
@Override
- public void success(String responsePdpName) {
+ public void success(String responsePdpName, PdpStatus response) {
requestCompleted(responsePdpName);
+
+ if (!(request instanceof UpdateReq)) {
+ // other response types may not include the list of policies
+ return;
+ }
+
+ /*
+ * Update PDP time stamps. Also send pdp-update and pdp-state-change, as
+ * necessary, if the response does not reflect what's in the DB.
+ */
+ var handler = makePdpResponseHandler();
+ handler.handlePdpStatus(response);
}
/**
}
@Override
- public void retryCountExhausted() {
- removePdp();
+ public void retryCountExhausted(Request request) {
+ if (pdp2requests.get(pdpName) == requests) {
+ requests.stopPublishing();
+ startNextRequest(request);
+ }
}
/**
pdp2requests.remove(pdpName, requests);
}
}
-
- /**
- * Removes a PDP from its subgroup.
- */
- private void removePdp() {
- requests.stopPublishing();
-
- // remove the requests from the map
- if (!pdp2requests.remove(pdpName, requests)) {
- // wasn't in the map - the requests must be old
- logger.warn("discarding old requests for {}", pdpName);
- return;
- }
-
- logger.warn("removing {}", pdpName);
-
- policyNotifier.removePdp(pdpName);
-
- // remove the PDP from all groups
- try {
- removeFromGroups(pdpName);
- } catch (PfModelException e) {
- logger.info("unable to remove PDP {} from subgroup", pdpName, e);
- }
- }
}
}