import org.onap.policy.models.pdp.concepts.PdpGroup;
 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
 import org.onap.policy.models.pdp.concepts.PdpStateChange;
-import org.onap.policy.models.pdp.concepts.PdpStatistics;
 import org.onap.policy.models.pdp.concepts.PdpStatus;
 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
 import org.onap.policy.models.pdp.concepts.PdpUpdate;
 
     private static final Logger LOGGER = LoggerFactory.getLogger(PdpStatusMessageHandler.class);
 
+    /**
+     * Lock used when updating PDPs.
+     */
+    private final Object updateLock;
+
+    /**
+     * Used to send UPDATE and STATE-CHANGE requests to the PDPs.
+     */
+    private final PdpModifyRequestMap requestMap;
+
+    /**
+     * Factory for PAP DAO.
+     */
+    PolicyModelsProviderFactoryWrapper modelProviderWrapper;
+
+    /**
+     * Constructs the object.
+     */
+    public PdpStatusMessageHandler() {
+        modelProviderWrapper = Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
+        updateLock = Registry.get(PapConstants.REG_PDP_MODIFY_LOCK, Object.class);
+        requestMap = Registry.get(PapConstants.REG_PDP_MODIFY_MAP, PdpModifyRequestMap.class);
+    }
+
     /**
      * Handles the PdpStatus message coming from various PDP's.
      *
      * @param message the PdpStatus message
      */
     public void handlePdpStatus(final PdpStatus message) {
-        final PolicyModelsProviderFactoryWrapper modelProviderWrapper =
-                Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
-        try (PolicyModelsProvider databaseProvider = modelProviderWrapper.create()) {
-            if (message.getPdpGroup() == null && message.getPdpSubgroup() == null) {
-                handlePdpRegistration(message, databaseProvider);
-            } else {
-                handlePdpHeartbeat(message, databaseProvider);
+        synchronized (updateLock) {
+            try (PolicyModelsProvider databaseProvider = modelProviderWrapper.create()) {
+                if (message.getPdpGroup() == null && message.getPdpSubgroup() == null) {
+                    handlePdpRegistration(message, databaseProvider);
+                } else {
+                    handlePdpHeartbeat(message, databaseProvider);
+                }
+            } catch (final PolicyPapException exp) {
+                LOGGER.error("Operation Failed", exp);
+            } catch (final Exception exp) {
+                LOGGER.error("Failed connecting to database provider", exp);
             }
-        } catch (final PolicyPapException exp) {
-            LOGGER.error("Operation Failed", exp);
-        } catch (final Exception exp) {
-            LOGGER.error("Failed connecting to database provider", exp);
         }
     }
 
         boolean pdpGroupFound = false;
         Optional<PdpSubGroup> subGroup = null;
         final PdpGroupFilter filter = PdpGroupFilter.builder().pdpType(message.getPdpType())
-                .policyTypeList(message.getSupportedPolicyTypes()).matchPolicyTypesExactly(true).build();
+                .policyTypeList(message.getSupportedPolicyTypes()).matchPolicyTypesExactly(true)
+                .groupState(PdpState.ACTIVE).version(PdpGroupFilter.LATEST_VERSION).build();
         final List<PdpGroup> pdpGroups = databaseProvider.getFilteredPdpGroups(filter);
         for (final PdpGroup pdpGroup : pdpGroups) {
             subGroup = findPdpSubGroup(message, pdpGroup);
         Optional<Pdp> pdpInstance = null;
 
         final PdpGroupFilter filter =
-                PdpGroupFilter.builder().name(message.getPdpGroup()).version(PdpGroupFilter.LATEST_VERSION).build();
+                PdpGroupFilter.builder().name(message.getPdpGroup()).groupState(PdpState.ACTIVE).build();
         final List<PdpGroup> pdpGroups = databaseProvider.getFilteredPdpGroups(filter);
         if (!pdpGroups.isEmpty()) {
             final PdpGroup pdpGroup = pdpGroups.get(0);
     private void processPdpDetails(final PdpStatus message, final PdpSubGroup pdpSubGroup, final Pdp pdpInstance,
             final PdpGroup pdpGroup, final PolicyModelsProvider databaseProvider) throws PfModelException {
         if (PdpState.TERMINATED.equals(message.getState())) {
-            processPdpTermination(message, pdpSubGroup, pdpInstance, pdpGroup, databaseProvider);
+            processPdpTermination(pdpSubGroup, pdpInstance, pdpGroup, databaseProvider);
         } else if (validatePdpDetails(message, pdpGroup, pdpSubGroup, pdpInstance)) {
             LOGGER.debug("PdpInstance details are correct. Saving current state in DB - {}", pdpInstance);
             updatePdpHealthStatus(message, pdpSubGroup, pdpInstance, pdpGroup, databaseProvider);
         }
     }
 
-    private void processPdpTermination(final PdpStatus message, final PdpSubGroup pdpSubGroup, final Pdp pdpInstance,
-            final PdpGroup pdpGroup, final PolicyModelsProvider databaseProvider) throws PfModelException {
+    private void processPdpTermination(final PdpSubGroup pdpSubGroup, final Pdp pdpInstance, final PdpGroup pdpGroup,
+            final PolicyModelsProvider databaseProvider) throws PfModelException {
         pdpSubGroup.getPdpInstances().remove(pdpInstance);
         pdpSubGroup.setCurrentInstanceCount(pdpSubGroup.getCurrentInstanceCount() - 1);
         databaseProvider.updatePdpSubGroup(pdpGroup.getName(), pdpGroup.getVersion(), pdpSubGroup);
                 createPdpUpdateMessage(pdpGroupName, subGroup, pdpInstanceId, databaseProvider);
         final PdpStateChange pdpStateChangeMessage =
                 createPdpStateChangeMessage(pdpGroupName, subGroup, pdpInstanceId, pdpState);
-        final PdpModifyRequestMap requestMap = Registry.get(PapConstants.REG_PDP_MODIFY_MAP, PdpModifyRequestMap.class);
         requestMap.addRequest(pdpUpdatemessage, pdpStateChangeMessage);
         LOGGER.debug("Sent PdpUpdate message - {}", pdpUpdatemessage);
         LOGGER.debug("Sent PdpStateChange message - {}", pdpStateChangeMessage);
 
 
     private static final Logger LOGGER = LoggerFactory.getLogger(PdpGroupStateChangeProvider.class);
 
+    /**
+     * Lock used when updating PDPs.
+     */
+    private final Object updateLock;
+
+    /**
+     * Used to send UPDATE and STATE-CHANGE requests to the PDPs.
+     */
+    private final PdpModifyRequestMap requestMap;
+
+    /**
+     * Factory for PAP DAO.
+     */
     PolicyModelsProviderFactoryWrapper modelProviderWrapper;
 
     /**
      */
     public PdpGroupStateChangeProvider() {
         modelProviderWrapper = Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class);
+        updateLock = Registry.get(PapConstants.REG_PDP_MODIFY_LOCK, Object.class);
+        requestMap = Registry.get(PapConstants.REG_PDP_MODIFY_MAP, PdpModifyRequestMap.class);
     }
 
     /**
      */
     public Pair<Response.Status, PdpGroupStateChangeResponse> changeGroupState(final String groupName,
             final String groupVersion, final PdpState pdpGroupState) throws PfModelException {
-
-        switch (pdpGroupState) {
-            case ACTIVE:
-                handleActiveState(groupName, groupVersion);
-                break;
-            case PASSIVE:
-                handlePassiveState(groupName, groupVersion);
-                break;
-            default:
-                throw new PfModelException(Response.Status.BAD_REQUEST,
-                        "Only ACTIVE or PASSIVE state changes are allowed");
+        synchronized (updateLock) {
+            switch (pdpGroupState) {
+                case ACTIVE:
+                    handleActiveState(groupName, groupVersion);
+                    break;
+                case PASSIVE:
+                    handlePassiveState(groupName, groupVersion);
+                    break;
+                default:
+                    throw new PfModelException(Response.Status.BAD_REQUEST,
+                            "Only ACTIVE or PASSIVE state changes are allowed");
+            }
+            return Pair.of(Response.Status.OK, new PdpGroupStateChangeResponse());
         }
-        return Pair.of(Response.Status.OK, new PdpGroupStateChangeResponse());
     }
 
     private void handleActiveState(final String groupName, final String groupVersion) throws PfModelException {
             final List<PdpGroup> activePdpGroups = databaseProvider.getFilteredPdpGroups(filter);
             final List<PdpGroup> pdpGroups = databaseProvider.getPdpGroups(groupName, groupVersion);
             if (activePdpGroups.isEmpty() && !pdpGroups.isEmpty()) {
-                sendPdpMessage(pdpGroups.get(0), PdpState.ACTIVE, databaseProvider);
                 updatePdpGroupAndPdp(databaseProvider, pdpGroups, PdpState.ACTIVE);
+                sendPdpMessage(pdpGroups.get(0), PdpState.ACTIVE, databaseProvider);
             } else if (!pdpGroups.isEmpty() && !activePdpGroups.isEmpty()
                     && !pdpGroups.get(0).getVersion().equals(activePdpGroups.get(0).getVersion())) {
-                sendPdpMessage(pdpGroups.get(0), PdpState.ACTIVE, databaseProvider);
                 updatePdpGroupAndPdp(databaseProvider, pdpGroups, PdpState.ACTIVE);
                 updatePdpGroup(databaseProvider, activePdpGroups, PdpState.PASSIVE);
+                sendPdpMessage(pdpGroups.get(0), PdpState.ACTIVE, databaseProvider);
             }
         }
     }
         try (PolicyModelsProvider databaseProvider = modelProviderWrapper.create()) {
             final List<PdpGroup> pdpGroups = databaseProvider.getPdpGroups(groupName, groupVersion);
             if (!pdpGroups.isEmpty() && !PdpState.PASSIVE.equals(pdpGroups.get(0).getPdpGroupState())) {
-                sendPdpMessage(pdpGroups.get(0), PdpState.PASSIVE, databaseProvider);
                 updatePdpGroupAndPdp(databaseProvider, pdpGroups, PdpState.PASSIVE);
+                sendPdpMessage(pdpGroups.get(0), PdpState.PASSIVE, databaseProvider);
             }
         }
     }
                         createPdpUpdateMessage(pdpGroup.getName(), subGroup, pdp.getInstanceId(), databaseProvider);
                 final PdpStateChange pdpStateChangeMessage =
                         createPdpStateChangeMessage(pdpGroup.getName(), subGroup, pdp.getInstanceId(), pdpState);
-                final PdpModifyRequestMap requestMap =
-                        Registry.get(PapConstants.REG_PDP_MODIFY_MAP, PdpModifyRequestMap.class);
                 requestMap.addRequest(pdpUpdatemessage, pdpStateChangeMessage);
                 LOGGER.debug("Sent PdpUpdate message - {}", pdpUpdatemessage);
                 LOGGER.debug("Sent PdpStateChange message - {}", pdpStateChangeMessage);