summaryrefslogtreecommitdiffstats
path: root/policy-persistence/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'policy-persistence/src/main')
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java160
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorRestManager.java91
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java57
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java442
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java17
-rw-r--r--policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java171
-rw-r--r--policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.PolicySessionFeatureAPI (renamed from policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI)0
-rw-r--r--policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.features.PolicyEngineFeatureAPI1
8 files changed, 592 insertions, 347 deletions
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java
index 2b6058fd..dc63d719 100644
--- a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/DroolsPDPIntegrityMonitor.java
@@ -22,23 +22,18 @@ package org.openecomp.policy.drools.core;
import java.io.File;
import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
import java.net.InetSocketAddress;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.Properties;
-import java.util.concurrent.Callable;
import org.openecomp.policy.common.im.IntegrityMonitor;
-import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
import org.openecomp.policy.common.logging.flexlogger.Logger;
-import org.openecomp.policy.common.logging.eelf.MessageCodes;
-import org.openecomp.policy.drools.persistence.DroolsPdpsElectionHandler;
+import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
+import org.openecomp.policy.drools.http.server.HttpServletServer;
import org.openecomp.policy.drools.persistence.XacmlPersistenceProperties;
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-import com.sun.net.httpserver.HttpServer;
+import org.openecomp.policy.drools.properties.Startable;
/**
* This class extends 'IntegrityMonitor' for use in the 'Drools PDP'
@@ -233,11 +228,11 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor
// create http server
try {
logger.info("init: Starting HTTP server, addr=" + addr);
- HttpServer server = HttpServer.create(addr, 0);
- server.createContext("/test", new TestHandler());
- server.setExecutor(null);
- server.start();
- System.out.println("init: Started server on hostPort=" + hostPort);
+ IntegrityMonitorRestServer server = new IntegrityMonitorRestServer();
+
+ server.init(integrityMonitorProperties);
+
+ System.out.println("init: Started server on hostPort=" + hostPort);
} catch (Exception e) {
if (PolicyContainer.isUnitTesting) {
System.out
@@ -378,100 +373,59 @@ public class DroolsPDPIntegrityMonitor extends IntegrityMonitor
*/
abstract void invoke(Properties droolsPersistenceProperties) throws Exception;
}
-
- /* ============================================================ */
-
- /**
- * This class is the HTTP handler for the REST 'test' invocation
- */
- static class TestHandler implements HttpHandler
- {
- /**
- * Handle an incoming REST 'test' invocation
- * @param ex used to pass incoming and outgoing HTTP information
- */
- @Override
- public void handle(HttpExchange ex) throws IOException
- {
-
- System.out.println("TestHandler.handle: Entering");
-
- // The responses are stored within the audit objects, so we need to
- // invoke the audits and get responses before we handle another
- // request.
- synchronized(TestHandler.class)
- {
- // will include messages associated with subsystem failures
- StringBuilder body = new StringBuilder();
-
- // 200=SUCCESS, 500=failure
- int responseValue = 200;
-
- if (im != null)
- {
- try
- {
- // call 'IntegrityMonitor.evaluateSanity()'
- im.evaluateSanity();
- }
- catch (Exception e)
- {
- // this exception isn't coming from one of the audits,
- // because those are caught in 'subsystemTest()'
- logger.error
- (MessageCodes.EXCEPTION_ERROR, e,
- "DroolsPDPIntegrityMonitor.evaluateSanity()");
-
- // include exception in HTTP response
- body.append("\nException: " + e + "\n");
- responseValue = 500;
+
+ public static class IntegrityMonitorRestServer implements Startable {
+ protected volatile HttpServletServer server = null;
+ protected volatile Properties integrityMonitorRestServerProperties = null;
+
+ public void init(Properties props) {
+ this.integrityMonitorRestServerProperties = props;
+ this.start();
+ }
+
+ @Override
+ public boolean start() throws IllegalStateException {
+ try {
+ ArrayList<HttpServletServer> servers = HttpServletServer.factory.build(integrityMonitorRestServerProperties);
+
+ if (!servers.isEmpty()) {
+ server = servers.get(0);
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
+ } catch (Exception e) {
+ return false;
}
-/*
- * Audit failures are being logged. A string will be generated which captures the
- * the audit failures. This string will be included in an exception coming from im.evaluateSanity().
- *
- // will contain list of subsystems where the audit failed
- LinkedList<String> subsystems = new LinkedList<String>();
+
+ return true;
+ }
- // Loop through all of the audits, and see which ones have failed.
- // NOTE: response information is stored within the audit objects
- // themselves -- only one can run at a time.
- for (AuditBase audit : audits)
- {
- String response = audit.getResponse();
- if (response != null)
- {
- // the audit has failed -- update 'subsystems', 'body',
- // and 'responseValue' with the new information
- subsystems.add(audit.getName());
- body
- .append('\n')
- .append(audit.getName())
- .append(":\n")
- .append(response)
- .append('\n');
- responseValue = 500;
- }
+ @Override
+ public boolean stop() throws IllegalStateException {
+ try {
+ server.stop();
+ } catch (Exception e) {
+ e.printStackTrace();
}
+
+ return true;
+ }
- if (subsystems.size() != 0)
- {
- // there is at least one failure -- add HTTP headers
- ex.getResponseHeaders().put("X-ECOMP-SubsystemFailure",
- subsystems);
- }
-*/
- // send response, including the contents of 'body'
- // (which is empty if everything is successful)
- ex.sendResponseHeaders(responseValue, body.length());
- OutputStream os = ex.getResponseBody();
- os.write(body.toString().getBytes());
- os.close();
- System.out.println("TestHandler.handle: Exiting");
+ @Override
+ public void shutdown() throws IllegalStateException {
+ this.stop();
}
- }
- }
+
+ @Override
+ public synchronized boolean isAlive() {
+ return this.integrityMonitorRestServerProperties != null;
+ }
+ }
+
public static DroolsPDPIntegrityMonitor getInstance() throws Exception{
logger.info("getInstance() called");
if (im == null) {
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorRestManager.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorRestManager.java
new file mode 100644
index 00000000..e0cb0638
--- /dev/null
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/IntegrityMonitorRestManager.java
@@ -0,0 +1,91 @@
+package org.openecomp.policy.drools.core;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+
+import org.openecomp.policy.common.logging.eelf.MessageCodes;
+import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
+import org.openecomp.policy.common.logging.flexlogger.Logger;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@Api(value = "test")
+ @Path("/")
+public class IntegrityMonitorRestManager {
+ private static Logger logger = FlexLogger.getLogger(IntegrityMonitorRestManager.class);
+ private DroolsPDPIntegrityMonitor im;
+
+ /**
+ * Test interface for Integrity Monitor
+ *
+ * @return Exception message if exception, otherwise empty
+ */
+ @ApiOperation(
+ value = "Test endpoint for integrity monitor",
+ notes = "The TEST command is used to request data from a subcomponent "
+ + "instance that can be used to determine its operational state. "
+ + "A 200/success response status code should be returned if the "
+ + "subcomponent instance is functioning properly and able to respond to requests.",
+ response = String.class)
+ @ApiResponses(value = {
+ @ApiResponse(
+ code = 200,
+ message = "Integrity monitor sanity check passed"),
+ @ApiResponse(
+ code = 500,
+ message = "Integrity monitor sanity check encountered an exception. This can indicate operational state disabled or administrative state locked")
+ })
+ @GET
+ @Path("test")
+ public Response test() {
+ logger.error("integrity monitor /test accessed");
+ // The responses are stored within the audit objects, so we need to
+ // invoke the audits and get responses before we handle another
+ // request.
+ synchronized (IntegrityMonitorRestManager.class) {
+ // will include messages associated with subsystem failures
+ StringBuilder body = new StringBuilder();
+
+ // 200=SUCCESS, 500=failure
+ int responseValue = 200;
+
+ if (im == null) {
+ try {
+ im = DroolsPDPIntegrityMonitor.getInstance();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ body.append("\nException: " + e + "\n");
+ responseValue = 500;
+ }
+ }
+
+ if (im != null) {
+ try {
+ // call 'IntegrityMonitor.evaluateSanity()'
+ im.evaluateSanity();
+ } catch (Exception e) {
+ // this exception isn't coming from one of the audits,
+ // because those are caught in 'subsystemTest()'
+ logger.error(MessageCodes.EXCEPTION_ERROR, e, "DroolsPDPIntegrityMonitor.evaluateSanity()");
+
+ // include exception in HTTP response
+ body.append("\nException: " + e + "\n");
+ responseValue = 500;
+ }
+ }
+
+ // send response, including the contents of 'body'
+ // (which is empty if everything is successful)
+ if (responseValue == 200)
+ return Response.status(Response.Status.OK).build();
+ else
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(body.toString()).build();
+ }
+ }
+} \ No newline at end of file
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java
index 86c672e2..c4301364 100644
--- a/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/core/RepositoryAudit.java
@@ -79,8 +79,12 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
logger.info("Running 'RepositoryAudit.invoke'");
boolean isActive = true;
+ boolean ignoreErrors = true; // ignore errors by default
String repoAuditIsActive = IntegrityMonitorProperties.getProperty("repository.audit.is.active");
- logger.debug("RepositoryAudit.invoke: repoAuditIsActive = " + repoAuditIsActive);
+ String repoAuditIgnoreErrors =
+ IntegrityMonitorProperties.getProperty("repository.audit.ignore.errors");
+ logger.debug("RepositoryAudit.invoke: repoAuditIsActive = " + repoAuditIsActive
+ + ", repoAuditIgnoreErrors = " + repoAuditIgnoreErrors);
if (repoAuditIsActive != null) {
try {
@@ -95,6 +99,18 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
return;
}
+ if (repoAuditIgnoreErrors != null)
+ {
+ try
+ {
+ ignoreErrors = Boolean.parseBoolean(repoAuditIgnoreErrors.trim());
+ }
+ catch (NumberFormatException e)
+ {
+ logger.warn("RepositoryAudit.invoke: Ignoring invalid property: repository.audit.ignore.errors = " + repoAuditIgnoreErrors);
+ }
+ }
+
// Fetch repository information from 'IntegrityMonitorProperties'
String repositoryId =
IntegrityMonitorProperties.getProperty("repository.audit.id");
@@ -126,9 +142,12 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
logger.error
("RepositoryAudit: Invalid 'repository.audit.timeout' value: '"
+ timeoutString + "'");
- response.append("Invalid 'repository.audit.timeout' value: '")
- .append(timeoutString).append("'\n");
- setResponse(response.toString());
+ if (!ignoreErrors)
+ {
+ response.append("Invalid 'repository.audit.timeout' value: '")
+ .append(timeoutString).append("'\n");
+ setResponse(response.toString());
+ }
}
}
@@ -191,8 +210,11 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
{
logger.error
("RepositoryAudit: 'mvn deploy:deploy-file' failed");
- response.append("'mvn deploy:deploy-file' failed\n");
- setResponse(response.toString());
+ if (!ignoreErrors)
+ {
+ response.append("'mvn deploy:deploy-file' failed\n");
+ setResponse(response.toString());
+ }
}
else
{
@@ -295,8 +317,11 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
{
logger.error
("RepositoryAudit: 'mvn compile' invocation failed");
- response.append("'mvn compile' invocation failed\n");
- setResponse(response.toString());
+ if (!ignoreErrors)
+ {
+ response.append("'mvn compile' invocation failed\n");
+ setResponse(response.toString());
+ }
}
/*
@@ -362,9 +387,12 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
// Audit ERROR: artifact download failed for some reason
logger.error("RepositoryAudit: "
+ artifact.toString() + ": does not exist");
- response.append("Failed to download artifact: ")
- .append(artifact).append('\n');
- setResponse(response.toString());
+ if (!ignoreErrors)
+ {
+ response.append("Failed to download artifact: ")
+ .append(artifact).append('\n');
+ setResponse(response.toString());
+ }
}
}
@@ -385,8 +413,11 @@ public class RepositoryAudit extends DroolsPDPIntegrityMonitor.AuditBase
{
logger.error
("RepositoryAudit: delete of uploaded artifact failed");
- response.append("delete of uploaded artifact failed\n");
- setResponse(response.toString());
+ if (!ignoreErrors)
+ {
+ response.append("delete of uploaded artifact failed\n");
+ setResponse(response.toString());
+ }
}
else
{
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java
index 82ee5d1d..40a8a56b 100644
--- a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/DroolsPdpsElectionHandler.java
@@ -499,159 +499,38 @@ public class DroolsPdpsElectionHandler implements ThreadRunningChecker {
/*
* We have checked the four combinations of isDesignated and isCurrent. Where appropriate,
* we added the PDPs to the potential list of designated pdps
- * Check if listOfDesignated is empty, has one entry or has multiple entries
- * If it has multiple designated PDPs, then we must determine if myPdp is on the list and if
- * it is the lowest priority. If it is on the list and it is not the lowest
- * priority, it must be demoted. Then, we must find the lowest priority
- * PDP so we can get the right list of sessions
+ *
+ * We need to give priority to pdps on the same site that is currently being used
+ * First, however, we must sanitize the list of designated to make sure their are
+ * only designated members or non-designated members. There should not be both in
+ * the list. Because there are real time delays, it is possible that both types could
+ * be on the list.
*/
- //we need to give priority to pdps on the same site that is currently being used
-
-
- //we need to figure out the last pdp that was the primary so we can get the last site name and the last session numbers
- DroolsPdp mostRecentPrimary = new DroolsPdpImpl(null, true, 1, new Date(0));
- mostRecentPrimary.setSiteName(null);
- for(DroolsPdp pdp : pdps){
- if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) > 0){
- mostRecentPrimary = pdp;
- }
- }
-
- if(listOfDesignated.size() > 1){
- logger.debug
- //System.out.println
- ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated.size(): " + listOfDesignated.size());
- DroolsPdp rejectedPdp = null;
- DroolsPdp lowestPrioritySameSite = null;
- DroolsPdp lowestPriorityDifferentSite = null;
- for(DroolsPdp pdp : listOfDesignated){
- // We need to determine if another PDP is the lowest priority
- if(nullSafeEquals(pdp.getSiteName(),mostRecentPrimary.getSiteName())){
- if(lowestPrioritySameSite == null){
- if(lowestPriorityDifferentSite != null){
- rejectedPdp = lowestPriorityDifferentSite;
- }
- lowestPrioritySameSite = pdp;
- }else{
- if(pdp.getPdpId().equals((lowestPrioritySameSite.getPdpId()))){
- continue;//nothing to compare
- }
- if(pdp.comparePriority(lowestPrioritySameSite) <0){
- logger.debug
- //System.out.println
- ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
- + " has lower priority than pdp ID: " + lowestPrioritySameSite.getPdpId());
-
- //we need to reject lowestPrioritySameSite
- rejectedPdp = lowestPrioritySameSite;
- lowestPrioritySameSite = pdp;
- } else{
- //we need to reject pdp and keep lowestPrioritySameSite
- logger.debug
- //System.out.println
- ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
- + " has higher priority than pdp ID: " + lowestPrioritySameSite.getPdpId());
- rejectedPdp = pdp;
- }
- }
- } else{
- if(lowestPrioritySameSite != null){
- //if we already have a candidate for same site, we don't want to bother with different sites
- rejectedPdp = pdp;
- } else{
- if(lowestPriorityDifferentSite == null){
- lowestPriorityDifferentSite = pdp;
- continue;
- }
- if(pdp.getPdpId().equals((lowestPriorityDifferentSite.getPdpId()))){
- continue;//nothing to compare
- }
- if(pdp.comparePriority(lowestPriorityDifferentSite) <0){
- logger.debug
- //System.out.println
- ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
- + " has lower priority than pdp ID: " + lowestPriorityDifferentSite.getPdpId());
-
- //we need to reject lowestPriorityDifferentSite
- rejectedPdp = lowestPriorityDifferentSite;
- lowestPriorityDifferentSite = pdp;
- } else{
- //we need to reject pdp and keep lowestPriorityDifferentSite
- logger.debug
- //System.out.println
- ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
- + " has higher priority than pdp ID: " + lowestPriorityDifferentSite.getPdpId());
- rejectedPdp = pdp;
- }
- }
- }
- // If the rejectedPdp is myPdp, we need to stand it down and demote it. Each pdp is responsible
- // for demoting itself
- if(rejectedPdp != null && nullSafeEquals(rejectedPdp.getPdpId(),myPdp.getPdpId())){
- logger.debug
- //System.out.println
- ("\n\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated myPdp ID: " + myPdp.getPdpId()
- + " is NOT the lowest priority. Executing stateManagement.demote()" + "\n\n");
- // We found that myPdp is on the listOfDesignated and it is not the lowest priority
- // So, we must demote it
- try {
- //Keep the order like this. StateManagement is last since it triggers controller shutdown
- myPdp.setDesignated(false);
- pdpsConnector.setDesignated(myPdp, false);
- isDesignated = false;
- String standbyStatus = stateManagement.getStandbyStatus();
- if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) ||
- standbyStatus.equals(StateManagement.COLD_STANDBY))){
- /*
- * Only call demote if it is not already in the right state. Don't worry about
- * synching the lower level topic endpoint states. That is done by the
- * refreshStateAudit.
- */
- stateManagement.demote();
- }
- } catch (Exception e) {
- myPdp.setDesignated(false);
- pdpsConnector.setDesignated(myPdp, false);
- isDesignated = false;
- logger.error
- //System.out.println
- ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to demote myPdp'"
- + myPdp.getPdpId()
- + "', message="
- + e.getMessage());
- System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
- + "from stateManagement.demote()");
- e.printStackTrace();
- }
- }
- } //end: for(DroolsPdp pdp : listOfDesignated)
- if(lowestPrioritySameSite != null){
- lowestPriorityPdp = lowestPrioritySameSite;
- } else {
- lowestPriorityPdp = lowestPriorityDifferentSite;
- }
- //now we have a valid value for lowestPriorityPdp
- logger.debug
- //System.out.println
- ("\n\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated found the LOWEST priority pdp ID: "
- + lowestPriorityPdp.getPdpId()
- + " It is now the designatedPpd from the perspective of myPdp ID: " + myPdp + "\n\n");
- designatedPdp = lowestPriorityPdp;
- this.sessions = mostRecentPrimary.getSessions();
+
+ listOfDesignated = santizeDesignatedList(listOfDesignated);
- } else if(listOfDesignated.isEmpty()){
- logger.debug
- //System.out.println
- ("\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated is: EMPTY.");
- designatedPdp = null;
- } else{ //only one in listOfDesignated
- logger.debug
- //System.out.println
- ("\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated has ONE entry. PDP ID: "
- + listOfDesignated.get(0).getPdpId());
- designatedPdp = listOfDesignated.get(0);
- this.sessions = mostRecentPrimary.getSessions();
- }
+ /*
+ * We need to figure out the last pdp that was the primary so we can get the last site
+ * name and the last session numbers. We need to create a "dummy" droolspdp since
+ * it will be used in later comparrisons and cannot be null.
+ */
+
+ DroolsPdp mostRecentPrimary = computeMostRecentPrimary(pdps, listOfDesignated);
+
+
+ /*
+ * It is possible to get here with more than one pdp designated and providingservice. This normally
+ * occurs when there is a race condition with multiple nodes coming up at the same time. If that is
+ * the case we must determine which one is the one that should be designated and which one should
+ * be demoted.
+ *
+ * It is possible to have 0, 1, 2 or more but not all, or all designated.
+ * If we have one designated and current, we chose it and are done
+ * If we have 2 or more, but not all, we must determine which one is in the same site as
+ * the previously designated pdp.
+ */
+
+ designatedPdp = computeDesignatedPdp(listOfDesignated, mostRecentPrimary);
if (designatedPdp == null) {
@@ -686,7 +565,10 @@ public class DroolsPdpsElectionHandler implements ThreadRunningChecker {
* Only call promote if it is not already in the right state. Don't worry about
* synching the lower level topic endpoint states. That is done by the
* refreshStateAudit.
+ * Note that we need to fetch the session list from 'mostRecentPrimary'
+ * at this point -- soon, 'mostRecentPrimary' will be set to this host.
*/
+ this.sessions = mostRecentPrimary.getSessions();
stateManagement.promote();
}
} catch (StandbyStatusException e) {
@@ -784,6 +666,262 @@ public class DroolsPdpsElectionHandler implements ThreadRunningChecker {
} // end run
}
+ public ArrayList<DroolsPdp> santizeDesignatedList(ArrayList<DroolsPdp> listOfDesignated){
+
+ boolean containsDesignated = false;
+ boolean containsHotStandby = false;
+ ArrayList<DroolsPdp> listForRemoval = new ArrayList<DroolsPdp>();
+ for(DroolsPdp pdp : listOfDesignated){
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run sanitizing: pdp = " + pdp.getPdpId()
+ + " isDesignated = " + pdp.isDesignated());
+ if(pdp.isDesignated()){
+ containsDesignated = true;
+ }else {
+ containsHotStandby = true;
+ listForRemoval.add(pdp);
+ }
+ }
+ if(containsDesignated && containsHotStandby){
+ //remove the hot standby from the list
+ listOfDesignated.removeAll(listForRemoval);
+ containsHotStandby = false;
+ }
+ return listOfDesignated;
+ }
+
+ public DroolsPdp computeMostRecentPrimary(Collection<DroolsPdp> pdps, ArrayList<DroolsPdp> listOfDesignated){
+ boolean containsDesignated = false;
+ for(DroolsPdp pdp : listOfDesignated){
+ if(pdp.isDesignated()){
+ containsDesignated = true;
+ }
+ }
+ DroolsPdp mostRecentPrimary = new DroolsPdpImpl(null, true, 1, new Date(0));
+ mostRecentPrimary.setSiteName(null);
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run listOfDesignated.size() = " + listOfDesignated.size());
+ if(listOfDesignated.size() <=1){
+ logger.debug("DesignatedWainter.run: listOfDesignated.size <=1");
+ //Only one or none is designated or hot standby. Choose the latest designated date
+ for(DroolsPdp pdp : pdps){
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run pdp = " + pdp.getPdpId()
+ + " pdp.getDesignatedDate() = " + pdp.getDesignatedDate());
+ if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) > 0){
+ mostRecentPrimary = pdp;
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run mostRecentPrimary = " + mostRecentPrimary.getPdpId());
+ }
+ }
+ }else if(listOfDesignated.size() == pdps.size()){
+ logger.debug("DesignatedWainter.run: listOfDesignated.size = pdps.size() which is " + pdps.size());
+ //They are all designated or all hot standby.
+ mostRecentPrimary = null;
+ for(DroolsPdp pdp : pdps){
+ if(mostRecentPrimary == null){
+ mostRecentPrimary = pdp;
+ continue;
+ }
+ if(containsDesignated){ //Choose the site of the first designated date
+ if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) < 0){
+ mostRecentPrimary = pdp;
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run mostRecentPrimary = " + mostRecentPrimary.getPdpId());
+ }
+ }else{ //Choose the site with the latest designated date
+ if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) > 0){
+ mostRecentPrimary = pdp;
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run mostRecentPrimary = " + mostRecentPrimary.getPdpId());
+ }
+ }
+ }
+ }else{
+ logger.debug("DesignatedWainter.run: Some but not all are designated or hot standby. ");
+ //Some but not all are designated or hot standby.
+ if(containsDesignated){
+ logger.debug("DesignatedWainter.run: containsDesignated = " + containsDesignated);
+ /*
+ * The list only contains designated. This is a problem. It is most likely a race
+ * condition that resulted in two thinking they should be designated. Choose the
+ * site with the latest designated date for the pdp not included on the designated list.
+ * This should be the site that had the last designation before this race condition
+ * occurred.
+ */
+ for(DroolsPdp pdp : pdps){
+ if(listOfDesignated.contains(pdp)){
+ continue; //Don't consider this entry
+ }
+ if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) > 0){
+ mostRecentPrimary = pdp;
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run mostRecentPrimary = " + mostRecentPrimary.getPdpId());
+ }
+ }
+ }else{
+ logger.debug("DesignatedWainter.run: containsDesignated = " + containsDesignated);
+ //The list only contains hot standby. Choose the site of the latest designated date
+ for(DroolsPdp pdp : pdps){
+ if(pdp.getDesignatedDate().compareTo(mostRecentPrimary.getDesignatedDate()) > 0){
+ mostRecentPrimary = pdp;
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run mostRecentPrimary = " + mostRecentPrimary.getPdpId());
+ }
+ }
+ }
+ }
+ return mostRecentPrimary;
+ }
+
+ public DroolsPdp computeDesignatedPdp(ArrayList<DroolsPdp> listOfDesignated, DroolsPdp mostRecentPrimary){
+ DroolsPdp designatedPdp = null;
+ DroolsPdp lowestPriorityPdp = null;
+ if(listOfDesignated.size() > 1){
+ logger.debug
+ //System.out.println
+ ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated.size(): " + listOfDesignated.size());
+ DroolsPdp rejectedPdp = null;
+ DroolsPdp lowestPrioritySameSite = null;
+ DroolsPdp lowestPriorityDifferentSite = null;
+ for(DroolsPdp pdp : listOfDesignated){
+ // We need to determine if another PDP is the lowest priority
+ if(nullSafeEquals(pdp.getSiteName(),mostRecentPrimary.getSiteName())){
+ if(lowestPrioritySameSite == null){
+ if(lowestPriorityDifferentSite != null){
+ rejectedPdp = lowestPriorityDifferentSite;
+ }
+ lowestPrioritySameSite = pdp;
+ }else{
+ if(pdp.getPdpId().equals((lowestPrioritySameSite.getPdpId()))){
+ continue;//nothing to compare
+ }
+ if(pdp.comparePriority(lowestPrioritySameSite) <0){
+ logger.debug
+ //System.out.println
+ ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
+ + " has lower priority than pdp ID: " + lowestPrioritySameSite.getPdpId());
+
+ //we need to reject lowestPrioritySameSite
+ rejectedPdp = lowestPrioritySameSite;
+ lowestPrioritySameSite = pdp;
+ } else{
+ //we need to reject pdp and keep lowestPrioritySameSite
+ logger.debug
+ //System.out.println
+ ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
+ + " has higher priority than pdp ID: " + lowestPrioritySameSite.getPdpId());
+ rejectedPdp = pdp;
+ }
+ }
+ } else{
+ if(lowestPrioritySameSite != null){
+ //if we already have a candidate for same site, we don't want to bother with different sites
+ rejectedPdp = pdp;
+ } else{
+ if(lowestPriorityDifferentSite == null){
+ lowestPriorityDifferentSite = pdp;
+ continue;
+ }
+ if(pdp.getPdpId().equals((lowestPriorityDifferentSite.getPdpId()))){
+ continue;//nothing to compare
+ }
+ if(pdp.comparePriority(lowestPriorityDifferentSite) <0){
+ logger.debug
+ //System.out.println
+ ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
+ + " has lower priority than pdp ID: " + lowestPriorityDifferentSite.getPdpId());
+
+ //we need to reject lowestPriorityDifferentSite
+ rejectedPdp = lowestPriorityDifferentSite;
+ lowestPriorityDifferentSite = pdp;
+ } else{
+ //we need to reject pdp and keep lowestPriorityDifferentSite
+ logger.debug
+ //System.out.println
+ ("\nDesignatedWaiter.run: myPdp" + myPdp.getPdpId() + " listOfDesignated pdp ID: " + pdp.getPdpId()
+ + " has higher priority than pdp ID: " + lowestPriorityDifferentSite.getPdpId());
+ rejectedPdp = pdp;
+ }
+ }
+ }
+ // If the rejectedPdp is myPdp, we need to stand it down and demote it. Each pdp is responsible
+ // for demoting itself
+ if(rejectedPdp != null && nullSafeEquals(rejectedPdp.getPdpId(),myPdp.getPdpId())){
+ logger.debug
+ //System.out.println
+ ("\n\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated myPdp ID: " + myPdp.getPdpId()
+ + " is NOT the lowest priority. Executing stateManagement.demote()" + "\n\n");
+ // We found that myPdp is on the listOfDesignated and it is not the lowest priority
+ // So, we must demote it
+ try {
+ //Keep the order like this. StateManagement is last since it triggers controller shutdown
+ myPdp.setDesignated(false);
+ pdpsConnector.setDesignated(myPdp, false);
+ isDesignated = false;
+ String standbyStatus = stateManagement.getStandbyStatus();
+ if(!(standbyStatus.equals(StateManagement.HOT_STANDBY) ||
+ standbyStatus.equals(StateManagement.COLD_STANDBY))){
+ /*
+ * Only call demote if it is not already in the right state. Don't worry about
+ * synching the lower level topic endpoint states. That is done by the
+ * refreshStateAudit.
+ */
+ stateManagement.demote();
+ }
+ } catch (Exception e) {
+ myPdp.setDesignated(false);
+ pdpsConnector.setDesignated(myPdp, false);
+ isDesignated = false;
+ logger.error
+ //System.out.println
+ ("DesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " Caught Exception attempting to demote myPdp'"
+ + myPdp.getPdpId()
+ + "', message="
+ + e.getMessage());
+ System.out.println(new Date() + " DesignatedWaiter.run: caught unexpected exception "
+ + "from stateManagement.demote()");
+ e.printStackTrace();
+ }
+ }
+ } //end: for(DroolsPdp pdp : listOfDesignated)
+ if(lowestPrioritySameSite != null){
+ lowestPriorityPdp = lowestPrioritySameSite;
+ } else {
+ lowestPriorityPdp = lowestPriorityDifferentSite;
+ }
+ //now we have a valid value for lowestPriorityPdp
+ logger.debug
+ //System.out.println
+ ("\n\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated found the LOWEST priority pdp ID: "
+ + lowestPriorityPdp.getPdpId()
+ + " It is now the designatedPpd from the perspective of myPdp ID: " + myPdp + "\n\n");
+ designatedPdp = lowestPriorityPdp;
+
+ } else if(listOfDesignated.isEmpty()){
+ logger.debug
+ //System.out.println
+ ("\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated is: EMPTY.");
+ designatedPdp = null;
+ } else{ //only one in listOfDesignated
+ logger.debug
+ //System.out.println
+ ("\nDesignatedWaiter.run: myPdp: " + myPdp.getPdpId() + " listOfDesignated has ONE entry. PDP ID: "
+ + listOfDesignated.get(0).getPdpId());
+ designatedPdp = listOfDesignated.get(0);
+ }
+ return designatedPdp;
+
+ }
+
private class TimerUpdateClass extends TimerTask{
@Override
@@ -926,7 +1064,7 @@ public class DroolsPdpsElectionHandler implements ThreadRunningChecker {
long nowModMs = nowMs % pdpUpdateInterval;
// Time to the start of the next pdpUpdateInterval multiple
- long startMs = pdpUpdateInterval - nowModMs;
+ long startMs = 2*pdpUpdateInterval - nowModMs;
// Give the start time a minimum of a 5 second cushion
if(startMs < 5000){
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java
index ac9255a2..d2032895 100644
--- a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/JpaDroolsPdpsConnector.java
@@ -27,6 +27,7 @@ import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
+import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.Query;
@@ -54,7 +55,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
try {
em.getTransaction().begin();
Query droolsPdpsListQuery = em.createQuery("SELECT p FROM DroolsPdpEntity p");
- List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.PESSIMISTIC_READ).getResultList();
+ List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
LinkedList<DroolsPdp> droolsPdpsReturnList = new LinkedList<DroolsPdp>();
for(Object o : droolsPdpsList){
if(o instanceof DroolsPdp){
@@ -105,7 +106,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
em.getTransaction().begin();
Query droolsPdpsListQuery = em.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
droolsPdpsListQuery.setParameter("pdpId", pdp.getPdpId());
- List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.PESSIMISTIC_WRITE).getResultList();
+ List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
//em.getTransaction().begin();
DroolsPdpEntity droolsPdpEntity;
if(droolsPdpsList.size() == 1 && (droolsPdpsList.get(0) instanceof DroolsPdpEntity)){
@@ -210,7 +211,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
em.getTransaction().begin();
Query droolsPdpsListQuery = em.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
droolsPdpsListQuery.setParameter("pdpId", pdp.getPdpId());
- List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.PESSIMISTIC_WRITE).getResultList();
+ List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
if(droolsPdpsList.size() == 1 && droolsPdpsList.get(0) instanceof DroolsPdpEntity){
if (logger.isDebugEnabled()) {
logger.debug("isPdpCurrent: PDP=" + pdp.getPdpId() + " designated but not current; setting designated to false");
@@ -254,7 +255,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
droolsPdpsListQuery.setParameter("pdpId", pdp.getPdpId());
List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(
- LockModeType.PESSIMISTIC_WRITE).getResultList();
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
if (droolsPdpsList.size() == 1
&& droolsPdpsList.get(0) instanceof DroolsPdpEntity) {
DroolsPdpEntity droolsPdpEntity = (DroolsPdpEntity) droolsPdpsList
@@ -306,7 +307,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
droolsPdpsListQuery.setParameter("pdpId", pdpId);
List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(
- LockModeType.PESSIMISTIC_WRITE).getResultList();
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
DroolsPdpEntity droolsPdpEntity;
if (droolsPdpsList.size() == 1
&& (droolsPdpsList.get(0) instanceof DroolsPdpEntity)) {
@@ -460,7 +461,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
.createQuery("SELECT p FROM DroolsPdpEntity p WHERE p.pdpId=:pdpId");
droolsPdpsListQuery.setParameter("pdpId", pdpId);
List<?> droolsPdpsList = droolsPdpsListQuery.setLockMode(
- LockModeType.PESSIMISTIC_WRITE).getResultList();
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
if (droolsPdpsList.size() == 1
&& droolsPdpsList.get(0) instanceof DroolsPdpEntity) {
droolsPdpEntity = (DroolsPdpEntity) droolsPdpsList.get(0);
@@ -553,7 +554,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
.createQuery("SELECT p FROM DroolsPdpEntity p");
@SuppressWarnings("unchecked")
List<DroolsPdp> droolsPdpsList = droolsPdpsListQuery.setLockMode(
- LockModeType.NONE).getResultList();
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
logger.info("deleteAllPdps: Deleting " + droolsPdpsList.size() + " PDPs");
for (DroolsPdp droolsPdp : droolsPdpsList) {
String pdpId = droolsPdp.getPdpId();
@@ -634,7 +635,7 @@ public class JpaDroolsPdpsConnector implements DroolsPdpsConnector {
.createQuery("SELECT p FROM DroolsSessionEntity p");
@SuppressWarnings("unchecked")
List<DroolsSession> droolsSessionsList = droolsSessionListQuery.setLockMode(
- LockModeType.NONE).getResultList();
+ LockModeType.NONE).setFlushMode(FlushModeType.COMMIT).getResultList();
logger.info("deleteAllSessions: Deleting " + droolsSessionsList.size() + " Sessions");
for (DroolsSession droolsSession : droolsSessionsList) {
logger.info("deleteAllSessions: Deleting droolsSession with pdpId="
diff --git a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java
index e2c7f402..e592220e 100644
--- a/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java
+++ b/policy-persistence/src/main/java/org/openecomp/policy/drools/persistence/PersistenceFeature.java
@@ -43,10 +43,11 @@ import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
import org.openecomp.policy.common.logging.flexlogger.Logger;
import org.openecomp.policy.common.logging.flexlogger.PropertyUtil;
import org.openecomp.policy.drools.core.DroolsPDPIntegrityMonitor;
-import org.openecomp.policy.drools.core.FeatureAPI;
+import org.openecomp.policy.drools.core.PolicySessionFeatureAPI;
import org.openecomp.policy.drools.core.IntegrityMonitorProperties;
import org.openecomp.policy.drools.core.PolicyContainer;
import org.openecomp.policy.drools.core.PolicySession;
+import org.openecomp.policy.drools.features.PolicyEngineFeatureAPI;
import org.openecomp.policy.drools.im.PMStandbyStateChangeNotifier;
import org.openecomp.policy.drools.system.PolicyEngine;
@@ -64,7 +65,7 @@ import bitronix.tm.resource.jdbc.PoolingDataSource;
* 'PolicyContainer' and 'Main'. It was moved here as part of making this
* a separate optional feature.
*/
-public class PersistenceFeature implements FeatureAPI
+public class PersistenceFeature implements PolicySessionFeatureAPI, PolicyEngineFeatureAPI
{
// get an instance of logger
private static Logger logger =
@@ -199,88 +200,116 @@ public class PersistenceFeature implements FeatureAPI
getContainerAdjunct(policySession.getPolicyContainer())
.destroyKieSession();
}
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void beforeStartEngine()
- {
- return;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void afterStartEngine()
- {
- PolicyEngine.manager.lock();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void beforeShutdownEngine()
- {
- return;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void beforeCreateController(String name, Properties properties)
- {
- return;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void afterCreateController(String name)
- {
- return;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void afterShutdownEngine()
- {
- return;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void beforeStartController(String name)
- {
- return;
- }
/**
* {@inheritDoc}
*/
@Override
- public void afterStartController(String name)
+ public boolean isPersistenceEnabled()
{
- return;
+ return(!persistenceDisabled);
}
-
+
/**
* {@inheritDoc}
*/
@Override
- public boolean isPersistenceEnabled()
+ public boolean afterStart(PolicyEngine engine)
{
- return(!persistenceDisabled);
+ // ASSERTION: engine == PolicyEngine.manager
+ PolicyEngine.manager.lock();
+ return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeStart(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeShutdown(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterShutdown(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeConfigure(PolicyEngine engine, Properties properties) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterConfigure(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeActivate(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterActivate(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeDeactivate(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterDeactivate(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeStop(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterStop(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeLock(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterLock(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean beforeUnlock(PolicyEngine engine) {return false;}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean afterUnlock(PolicyEngine engine) {return false;}
/**************************/
diff --git a/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI b/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.PolicySessionFeatureAPI
index 540a4bd4..540a4bd4 100644
--- a/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.FeatureAPI
+++ b/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.core.PolicySessionFeatureAPI
diff --git a/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.features.PolicyEngineFeatureAPI b/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.features.PolicyEngineFeatureAPI
new file mode 100644
index 00000000..540a4bd4
--- /dev/null
+++ b/policy-persistence/src/main/resources/META-INF/services/org.openecomp.policy.drools.features.PolicyEngineFeatureAPI
@@ -0,0 +1 @@
+org.openecomp.policy.drools.persistence.PersistenceFeature