X-Git-Url: https://gerrit.onap.org/r/gitweb?p=policy%2Fengine.git;a=blobdiff_plain;f=PolicyEngineUtils%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fpolicy%2Futils%2FBackUpMonitor.java;h=c82e6968f288691bfa60e1b8e6f94a1a84bc1596;hp=3cdb51577eea17574f25555d793d12885d0b1ee6;hb=e9b8aa0223e6f042c0533176ae8222fb061852de;hpb=e0385921034ae9ce860038ea65d2d13259f7cc4c diff --git a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/BackUpMonitor.java b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/BackUpMonitor.java index 3cdb51577..c82e6968f 100644 --- a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/BackUpMonitor.java +++ b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/BackUpMonitor.java @@ -2,14 +2,15 @@ * ============LICENSE_START======================================================= * PolicyEngineUtils * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved. + * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,6 +21,13 @@ package org.onap.policy.utils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.github.fge.jackson.JsonLoader; +import com.github.fge.jsonpatch.JsonPatch; +import com.github.fge.jsonpatch.JsonPatchException; +import com.github.fge.jsonpatch.diff.JsonDiff; + import java.io.IOException; import java.util.ArrayList; import java.util.Date; @@ -40,16 +48,9 @@ import org.onap.policy.jpa.BackUpMonitorEntity; import org.onap.policy.std.NotificationStore; import org.onap.policy.std.StdPDPNotification; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.github.fge.jackson.JsonLoader; -import com.github.fge.jsonpatch.JsonPatch; -import com.github.fge.jsonpatch.JsonPatchException; -import com.github.fge.jsonpatch.diff.JsonDiff; - /** * BackUp Monitor checks Backup Status with the Database and maintains Redundancy for Gateway Applications. - * + * */ public class BackUpMonitor { private static final Logger LOGGER = Logger.getLogger(BackUpMonitor.class.getName()); @@ -57,7 +58,7 @@ public class BackUpMonitor { private static final String PING_INTERVAL = "ping_interval"; private static final String MASTER = "MASTER"; private static final String SLAVE = "SLAVE"; - + private static BackUpMonitor instance = null; private static String resourceName = null; private static String resourceNodeName = null; @@ -84,7 +85,7 @@ public class BackUpMonitor { throws BackUpMonitorException { init(resourceName, resourceNodeName, handler); // Create Persistence Entity - if(!properties.containsKey(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML)){ + if (!properties.containsKey(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML)) { properties.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/persistencePU.xml"); } emf = Persistence.createEntityManagerFactory("PolicyEngineUtils", properties); @@ -99,15 +100,20 @@ public class BackUpMonitor { // Start thread. startThread(new BMonitor()); } - - private static void startThread(BMonitor bMonitor) { - t = new Thread(bMonitor); + + private static void startThread(BMonitor monitor) { + t = new Thread(monitor); t.start(); } - public static void stop() throws InterruptedException{ + /** + * Stop. + * + * @throws InterruptedException InterruptedException + */ + public static void stop() throws InterruptedException { stopFlag = true; - if(t!=null){ + if (t != null) { t.interrupt(); t.join(); } @@ -123,19 +129,19 @@ public class BackUpMonitor { /** * Gets the BackUpMonitor Instance if given proper resourceName and properties. Else returns null. - * + * * @param resourceNodeName - * String format of the Resource Node to which the resource Belongs to. + * String format of the Resource Node to which the resource Belongs to. * @param resourceName - * String format of the ResourceName. This needs to be Unique. + * String format of the ResourceName. This needs to be Unique. * @param properties - * Properties format of the properties file. + * Properties format of the properties file. * @return BackUpMonitor instance. */ public static synchronized BackUpMonitor getInstance(String resourceNodeName, String resourceName, Properties properties, BackUpHandler handler) throws BackUpMonitorException { - if (resourceNodeName == null || resourceNodeName.trim().equals("") || resourceName == null - || resourceName.trim().equals("") || properties == null || handler == null) { + if (resourceNodeName == null || "".equals(resourceNodeName.trim()) || resourceName == null + || "".equals(resourceName.trim()) || properties == null || handler == null) { LOGGER.error("Error while getting Instance. Please check resourceName and/or properties file"); return null; } else if ((resourceNodeName.equals(ResourceNode.ASTRA.toString()) @@ -149,22 +155,21 @@ public class BackUpMonitor { // This is to validate given Properties with required values. private static Boolean validate(Properties properties) { if (properties.getProperty("javax.persistence.jdbc.driver") == null - || properties.getProperty("javax.persistence.jdbc.driver").trim().equals("")) { + || "".equals(properties.getProperty("javax.persistence.jdbc.driver").trim())) { LOGGER.error("javax.persistence.jdbc.driver property is empty"); return false; } if (properties.getProperty("javax.persistence.jdbc.url") == null - || properties.getProperty("javax.persistence.jdbc.url").trim().equals("")) { + || "".equals(properties.getProperty("javax.persistence.jdbc.url").trim())) { LOGGER.error("javax.persistence.jdbc.url property is empty"); return false; } if (properties.getProperty("javax.persistence.jdbc.user") == null - || properties.getProperty("javax.persistence.jdbc.user").trim().equals("")) { + || "".equals(properties.getProperty("javax.persistence.jdbc.user").trim())) { LOGGER.error("javax.persistence.jdbc.user property is empty"); return false; } - if (properties.getProperty(PING_INTERVAL) == null - || properties.getProperty(PING_INTERVAL).trim().equals("")) { + if (properties.getProperty(PING_INTERVAL) == null || "".equals(properties.getProperty(PING_INTERVAL).trim())) { LOGGER.info("ping_interval property not specified. Taking default value"); } else { try { @@ -185,8 +190,8 @@ public class BackUpMonitor { } /** - * Gets the Boolean value of Master(True) or Slave mode (False) - * + * Gets the Boolean value of Master(True) or Slave mode (False). + * * @return Boolean flag which if True means that the operation needs to be performed(Master mode) or if false the * operation is in slave mode. */ @@ -213,17 +218,17 @@ public class BackUpMonitor { } // Set Master - private static BackUpMonitorEntity setMaster(BackUpMonitorEntity bMEntity) { - bMEntity.setFlag(MASTER); + private static BackUpMonitorEntity setMaster(BackUpMonitorEntity entity) { + entity.setFlag(MASTER); setFlag(true); - return bMEntity; + return entity; } // Set Slave - private static BackUpMonitorEntity setSlave(BackUpMonitorEntity bMEntity) { - bMEntity.setFlag(SLAVE); + private static BackUpMonitorEntity setSlave(BackUpMonitorEntity entity) { + entity.setFlag(SLAVE); setFlag(false); - return bMEntity; + return entity; } // Check Database and set the Flag. @@ -243,153 +248,163 @@ public class BackUpMonitor { } else if (resourceNodeName.equals(ResourceNode.BRMS.toString())) { query.setParameter("nn", ResourceNode.BRMS.toString()); } - List bMList = query.getResultList(); - if (bMList.isEmpty()) { + List entityList = query.getResultList(); + if (entityList.isEmpty()) { // This is New. create an entry as Master. LOGGER.info("Adding resource " + resourceName + " to Database"); - BackUpMonitorEntity bMEntity = new BackUpMonitorEntity(); - bMEntity.setResoruceNodeName(resourceNodeName); - bMEntity.setResourceName(resourceName); - bMEntity = setMaster(bMEntity); - bMEntity.setTimeStamp(new Date()); - em.persist(bMEntity); + BackUpMonitorEntity entity = new BackUpMonitorEntity(); + entity.setResourceNodeName(resourceNodeName); + entity.setResourceName(resourceName); + entity = setMaster(entity); + entity.setTimeStamp(new Date()); + em.persist(entity); em.flush(); } else { - // Check for other Master(s) - ArrayList masterEntities = new ArrayList<>(); - // Check for self. - BackUpMonitorEntity selfEntity = null; - // Check backup monitor entities. - for (int i = 0; i < bMList.size(); i++) { - BackUpMonitorEntity bMEntity = (BackUpMonitorEntity) bMList.get(i); - LOGGER.info("Refreshing Entity. "); - em.refresh(bMEntity); - if (bMEntity.getFlag().equalsIgnoreCase(MASTER)) { - masterEntities.add(bMEntity); - } - if (bMEntity.getResourceName().equals(resourceName)) { - selfEntity = bMEntity; - } - } - if (selfEntity != null) { - LOGGER.info("Resource Name already Exists: " + resourceName); - if (selfEntity.getFlag().equalsIgnoreCase(MASTER)) { - // Already Master Mode. - setFlag(true); - LOGGER.info(resourceName + " is on Master Mode"); - selfEntity.setTimeStamp(new Date()); - selfEntity.setNotificationRecord(notificationRecord); - em.persist(selfEntity); - em.flush(); - setLastNotification(null); - if (!masterEntities.contains(selfEntity)) { - masterEntities.add(selfEntity); - } - } else { - // Already Slave Mode. - setFlag(false); - selfEntity.setTimeStamp(new Date()); - selfEntity.setNotificationRecord(notificationRecord); - em.persist(selfEntity); - em.flush(); - LOGGER.info(resourceName + " is on Slave Mode"); - } - } else { - // Resource name is null -> No resource with same name. - selfEntity = new BackUpMonitorEntity(); - selfEntity.setResoruceNodeName(resourceNodeName); - selfEntity.setResourceName(resourceName); - selfEntity.setTimeStamp(new Date()); - selfEntity = setSlave(selfEntity); - setLastNotification(null); - LOGGER.info("Creating: " + resourceName + " on Slave Mode"); - em.persist(selfEntity); - em.flush(); - } - // Correct the database if any errors and perform monitor checks. - if (masterEntities.size() != 1 || !getFlag()) { - // We are either not master or there are more masters or no masters. - if (masterEntities.isEmpty()) { - // No Masters is a problem Convert ourselves to Master. - selfEntity = setMaster(selfEntity); - selfEntity.setTimeStamp(new Date()); - selfEntity.setNotificationRecord(notificationRecord); - LOGGER.info(resourceName + " changed to Master Mode - No Masters available."); - em.persist(selfEntity); - em.flush(); - } else { - if (masterEntities.size() > 1) { - // More Masters is a problem, Fix the issue by looking for the latest one and make others - // Slave. - BackUpMonitorEntity masterEntity = null; - for (BackUpMonitorEntity currentEntity : masterEntities) { - if (currentEntity.getFlag().equalsIgnoreCase(MASTER)) { - if (masterEntity == null) { - masterEntity = currentEntity; - } else if (currentEntity.getTimeStamp().getTime() > masterEntity.getTimeStamp() - .getTime()) { - // False Master, Update master to slave and take currentMaster as Master. - masterEntity.setFlag(SLAVE); - masterEntity.setTimeStamp(new Date()); - em.persist(masterEntity); - em.flush(); - masterEntity = currentEntity; - } else { - currentEntity.setFlag(SLAVE); - currentEntity.setTimeStamp(new Date()); - em.persist(currentEntity); - em.flush(); - } - } - } - masterEntities = new ArrayList<>(); - masterEntities.add(masterEntity); - } - if (masterEntities.size() == 1) { - // Correct Size, Check if Master is Latest, if not Change Master to Slave and Slave to - // Master. - BackUpMonitorEntity masterEntity = masterEntities.get(0); - if (!masterEntity.getResourceName().equals(selfEntity.getResourceName())) { - Date currentTime = new Date(); - long timeDiff = 0; - timeDiff = currentTime.getTime() - masterEntity.getTimeStamp().getTime(); - if (timeDiff > (pingInterval + 1500)) { - // This is down or has an issue and we need to become Master while turning the - // Master to slave. - masterEntity.setFlag(SLAVE); - String lastNotification = null; - if (masterEntity.getNotificationRecord() != null) { - lastNotification = calculatePatch(masterEntity.getNotificationRecord()); - } - setLastNotification(lastNotification); - em.persist(masterEntity); - em.flush(); - // Lets Become Master. - selfEntity = setMaster(selfEntity); - LOGGER.info("Changing " + resourceName + " from slave to Master Mode"); - selfEntity.setTimeStamp(new Date()); - selfEntity.setNotificationRecord(notificationRecord); - em.persist(selfEntity); - em.flush(); - } - } - } else { - LOGGER.error( - "Backup Monitor Issue, Masters out of sync, This will be fixed in next interval."); - } - } - } + checkOtherMaster(entityList); } et.commit(); } catch (Exception e) { LOGGER.error("failed Database Operation " + e.getMessage(), e); - if (et!=null && et.isActive()) { + if (et != null && et.isActive()) { et.rollback(); } throw new BackUpMonitorException(e); } } + private void checkOtherMaster(List entityList) { + // Check for other Master(s) + ArrayList masterEntities = new ArrayList<>(); + // Check for self. + BackUpMonitorEntity selfEntity = null; + // Check backup monitor entities. + for (Object entity : entityList) { + BackUpMonitorEntity backupEntity = (BackUpMonitorEntity) entity; + LOGGER.info("Refreshing Entity. "); + em.refresh(backupEntity); + if (backupEntity.getFlag().equalsIgnoreCase(MASTER)) { + masterEntities.add(backupEntity); + } + if (backupEntity.getResourceName().equals(resourceName)) { + selfEntity = backupEntity; + } + } + if (selfEntity != null) { + LOGGER.info("Resource Name already Exists: " + resourceName); + if (selfEntity.getFlag().equalsIgnoreCase(MASTER)) { + // Already Master Mode. + setFlag(true); + LOGGER.info(resourceName + " is on Master Mode"); + selfEntity.setTimeStamp(new Date()); + selfEntity.setNotificationRecord(notificationRecord); + em.persist(selfEntity); + em.flush(); + setLastNotification(null); + if (!masterEntities.contains(selfEntity)) { + masterEntities.add(selfEntity); + } + } else { + // Already Slave Mode. + setFlag(false); + selfEntity.setTimeStamp(new Date()); + selfEntity.setNotificationRecord(notificationRecord); + em.persist(selfEntity); + em.flush(); + LOGGER.info(resourceName + " is on Slave Mode"); + } + } else { + // Resource name is null -> No resource with same name. + selfEntity = new BackUpMonitorEntity(); + selfEntity.setResourceNodeName(resourceNodeName); + selfEntity.setResourceName(resourceName); + selfEntity.setTimeStamp(new Date()); + selfEntity = setSlave(selfEntity); + setLastNotification(null); + LOGGER.info("Creating: " + resourceName + " on Slave Mode"); + em.persist(selfEntity); + em.flush(); + } + // Correct the database if any errors and perform monitor checks. + if (masterEntities.size() != 1 || !getFlag()) { + // We are either not master or there are more masters or no masters. + if (masterEntities.isEmpty()) { + // No Masters is a problem Convert ourselves to Master. + selfEntity = setMaster(selfEntity); + selfEntity.setTimeStamp(new Date()); + selfEntity.setNotificationRecord(notificationRecord); + LOGGER.info(resourceName + " changed to Master Mode - No Masters available."); + em.persist(selfEntity); + em.flush(); + } else { + if (masterEntities.size() > 1) { + masterEntities = multipleMasterEntity(masterEntities); + } + if (masterEntities.size() == 1) { + singleMasterEntity(masterEntities, selfEntity); + } else { + LOGGER.error("Backup Monitor Issue, Masters out of sync, This will be fixed in next interval."); + } + } + } + } + + private void singleMasterEntity(ArrayList masterEntities, BackUpMonitorEntity selfEntity) { + // Correct Size, Check if Master is Latest, if not Change Master to Slave and Slave to + // Master. + BackUpMonitorEntity masterEntity = masterEntities.get(0); + if (!masterEntity.getResourceName().equals(selfEntity.getResourceName())) { + Date currentTime = new Date(); + long timeDiff; + timeDiff = currentTime.getTime() - masterEntity.getTimeStamp().getTime(); + if (timeDiff > (pingInterval + 1500)) { + // This is down or has an issue and we need to become Master while turning the + // Master to slave. + masterEntity.setFlag(SLAVE); + String lastNotification = null; + if (masterEntity.getNotificationRecord() != null) { + lastNotification = calculatePatch(masterEntity.getNotificationRecord()); + } + setLastNotification(lastNotification); + em.persist(masterEntity); + em.flush(); + // Lets Become Master. + LOGGER.info("Changing " + resourceName + " from slave to Master Mode"); + selfEntity.setTimeStamp(new Date()); + selfEntity.setNotificationRecord(notificationRecord); + em.persist(selfEntity); + em.flush(); + } + } + } + + private ArrayList multipleMasterEntity(ArrayList masterEntities) { + // More Masters is a problem, Fix the issue by looking for the latest one and make others + // Slave. + BackUpMonitorEntity masterEntity = null; + for (BackUpMonitorEntity currentEntity : masterEntities) { + if (currentEntity.getFlag().equalsIgnoreCase(MASTER)) { + if (masterEntity == null) { + masterEntity = currentEntity; + } else if (currentEntity.getTimeStamp().getTime() > masterEntity.getTimeStamp().getTime()) { + // False Master, Update master to slave and take currentMaster as Master. + masterEntity.setFlag(SLAVE); + masterEntity.setTimeStamp(new Date()); + em.persist(masterEntity); + em.flush(); + masterEntity = currentEntity; + } else { + currentEntity.setFlag(SLAVE); + currentEntity.setTimeStamp(new Date()); + em.persist(currentEntity); + em.flush(); + } + } + } + masterEntities = new ArrayList<>(); + masterEntities.add(masterEntity); + return masterEntities; + } + private static void setNotificationRecord() throws BackUpMonitorException { try { notificationRecord = PolicyUtils.objectToJsonString(NotificationStore.getNotificationRecord()); @@ -407,26 +422,28 @@ public class BackUpMonitor { JsonNode patchNode = JsonDiff.asJson(oldNotification, notification); LOGGER.info("Generated JSON Patch is " + patchNode.toString()); JsonPatch patch = JsonPatch.fromJson(patchNode); - try { - JsonNode patched = patch.apply(oldNotification); - LOGGER.info("Generated New Notification is : " + patched.toString()); - return patched.toString(); - } catch (JsonPatchException e) { - LOGGER.error("Error generating Patched " + e.getMessage(), e); - return null; - } + return generatePatchNotification(patch, oldNotification); } catch (IOException e) { LOGGER.error("Error generating Patched " + e.getMessage(), e); return null; } } + private String generatePatchNotification(JsonPatch patch, JsonNode oldNotification) { + try { + JsonNode patched = patch.apply(oldNotification); + LOGGER.info("Generated New Notification is : " + patched.toString()); + return patched.toString(); + } catch (JsonPatchException e) { + LOGGER.error("Error generating Patched " + e.getMessage(), e); + return null; + } + } + /** * Updates Notification in the Database while Performing the health check. - * - * @param notification - * String format of notification record to store in the Database. - * @throws Exception + * + * @throws BackUpMonitorException BackUpMonitorException */ public synchronized void updateNotification() throws BackUpMonitorException { checkDataBase(); @@ -436,16 +453,12 @@ public class BackUpMonitor { private static void callHandler(String notification) { if (handler != null) { try { - PDPNotification notificationObject = PolicyUtils.jsonStringToObject(notification, - StdPDPNotification.class); + PDPNotification notificationObject = + PolicyUtils.jsonStringToObject(notification, StdPDPNotification.class); if (notificationObject.getNotificationType() != null) { LOGGER.info("Performing Patched notification "); - try { - handler.runOnNotification(notificationObject); - notificationRecord = lastMasterNotification; - } catch (Exception e) { - LOGGER.error("Error in Clients Handler Object : " + e.getMessage(), e); - } + performPatchNotification(notificationObject); + } } catch (IOException e) { LOGGER.info("Error while notification Conversion " + e.getMessage(), e); @@ -453,11 +466,21 @@ public class BackUpMonitor { } } + private static void performPatchNotification(PDPNotification notificationObject) { + try { + handler.runOnNotification(notificationObject); + notificationRecord = lastMasterNotification; + } catch (Exception e) { + LOGGER.error("Error in Clients Handler Object : " + e.getMessage(), e); + } + + } + // Used to set LastMasterNotification Record. private static void setLastNotification(String notification) { synchronized (notificationLock) { lastMasterNotification = notification; - if (lastMasterNotification != null && !lastMasterNotification.equals("\"notificationType\":null")) { + if (lastMasterNotification != null && !"\"notificationType\":null".equals(lastMasterNotification)) { if (lastMasterNotification.equals(notificationRecord)) { return; }