diff --git a/src/net/juniper/contrail/sandesh/VCenterPluginResp.java b/src/net/juniper/contrail/sandesh/VCenterPluginResp.java index d304cf2..a4df02e 100644 --- a/src/net/juniper/contrail/sandesh/VCenterPluginResp.java +++ b/src/net/juniper/contrail/sandesh/VCenterPluginResp.java @@ -7,14 +7,14 @@ import net.juniper.contrail.vcenter.VRouterNotifier; import net.juniper.contrail.vcenter.VncDB; -public class VCenterPluginResp { +public class VCenterPluginResp { private VCenterPlugin vCenterPluginInfo; - + public VCenterPluginResp(VCenterPluginReq req) { vCenterPluginInfo = new VCenterPlugin(); - + vCenterPluginInfo.setMaster(VCenterMonitor.isZookeeperLeader()); - + if (VCenterMonitor.isZookeeperLeader()) { populateVRouterStats(); populateApiServerInfo(); @@ -29,8 +29,8 @@ private void populatePluginState() { && (vCenterPluginInfo.getVCenterServerInfo().getConnected() == true) && (( vCenterPluginInfo.getVRouterStats().getDown() == 0))); } - - private void populateVRouterStats() { + + private void populateVRouterStats() { int up = 0; int down = 0; @@ -52,7 +52,7 @@ private void populateVRouterStats() { vCenterPluginInfo.getVRouterStats().setUp(up); vCenterPluginInfo.getVRouterStats().setDown(down); } - + private void populateApiServerInfo() { ApiServerInfo apiServerInfo = vCenterPluginInfo.getApiServerInfo(); VncDB vncDB = VCenterNotify.getVncDB(); @@ -62,15 +62,15 @@ private void populateApiServerInfo() { apiServerInfo.setConnected(vncDB.isServerAlive()); } } - + private void populateVCenterServerInfo() { VCenterServerInfo vCenterServerInfo = vCenterPluginInfo.getVCenterServerInfo(); - + if (VCenterNotify.getVcenterDB() != null) { vCenterServerInfo.setUrl(VCenterNotify.getVcenterDB().getVcenterUrl() ); - + vCenterServerInfo.setConnected( - VCenterNotify.getVcenterDB().isConnected()); + VCenterNotify.getVCenterConnected()); } } @@ -81,6 +81,6 @@ public void writeObject(StringBuilder s) { } s.append(""); vCenterPluginInfo.writeObject(s); - s.append(""); + s.append(""); } } diff --git a/src/net/juniper/contrail/vcenter/VCenterDB.java b/src/net/juniper/contrail/vcenter/VCenterDB.java index 17e6a01..0bb8b65 100644 --- a/src/net/juniper/contrail/vcenter/VCenterDB.java +++ b/src/net/juniper/contrail/vcenter/VCenterDB.java @@ -10,6 +10,7 @@ import java.net.URL; import java.util.HashMap; import java.util.ArrayList; +import java.util.Calendar; import java.util.List; import java.util.Hashtable; import java.util.Map; @@ -63,6 +64,7 @@ public class VCenterDB { Logger.getLogger(VCenterDB.class); private static final String esxiToVRouterIpMapFile = "/etc/contrail/ESXiToVRouterIp.map"; static final int VCENTER_READ_TIMEOUT = 30000; //30 sec + static final int VCENTER_WAIT_FOR_UPDATES_TIMEOUT = 120; // 120 seconds protected final String contrailDvSwitchName; public final String contrailDataCenterName; private final String vcenterUrl; @@ -261,8 +263,6 @@ public void setReadTimeout(int milliSecs) { serviceInstance.getServerConnection() .getVimService() .getWsc().setReadTimeout(milliSecs); - s_logger.info("ServiceInstance read timeout set to " + - serviceInstance.getServerConnection().getVimService().getWsc().getReadTimeout()); } public boolean isConnected() { @@ -987,10 +987,14 @@ public void readVirtualMachineInterfaces(VirtualMachineInfo vmInfo) } public boolean isAlive() { - Folder folder = serviceInstance.getRootFolder(); - if (folder == null) { - String msg = "Failed aliveness check for vCenter " + vcenterUrl; - s_logger.error(msg); + try { + Calendar currTime = serviceInstance.currentTime(); + if (currTime == null) { + String msg = "Failed aliveness check for vCenter " + vcenterUrl; + s_logger.error(msg); + return false; + } + } catch (Exception e) { return false; } return true; diff --git a/src/net/juniper/contrail/vcenter/VCenterMonitor.java b/src/net/juniper/contrail/vcenter/VCenterMonitor.java index f137917..de6996d 100644 --- a/src/net/juniper/contrail/vcenter/VCenterMonitor.java +++ b/src/net/juniper/contrail/vcenter/VCenterMonitor.java @@ -176,16 +176,14 @@ public static void main(String[] args) throws Exception { _apiServerAddress, _apiServerPort, _username, _password, _tenant, _authtype, _authurl, mode); - VCenterMonitorTask _monitorTask = new VCenterMonitorTask(_eventMonitor, - _vcenterURL, _vcenterUsername, _vcenterPassword, - _vcenterDcName, _vcenterDvsName, _vcenterIpFabricPg); s_logger.info("Starting the notify task.. "); _eventMonitor.start(); s_logger.info("Notify task started."); // Launch the periodic VCenterMonitorTask - s_logger.info("Starting periodic monitor task.. "); + VRouterMonitorTask _monitorTask = new VRouterMonitorTask(); + s_logger.info("Starting vrouter periodic monitor task.. "); scheduledTaskExecutor.scheduleWithFixedDelay(_monitorTask, 0, 8, //8 second periodic TimeUnit.SECONDS); s_logger.info("Periodic monitor task started."); diff --git a/src/net/juniper/contrail/vcenter/VCenterMonitorTask.java b/src/net/juniper/contrail/vcenter/VCenterMonitorTask.java deleted file mode 100644 index f9e0ed7..0000000 --- a/src/net/juniper/contrail/vcenter/VCenterMonitorTask.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. - */ - -package net.juniper.contrail.vcenter; - -import java.util.concurrent.TimeUnit; -import com.google.common.base.Throwables; -import org.apache.log4j.Logger; -import net.juniper.contrail.watchdog.TaskWatchDog; - -class VCenterMonitorTask implements Runnable { - private static Logger s_logger = Logger.getLogger(VCenterMonitorTask.class); - private VCenterDB vcenterDB; - VCenterNotify eventTask; - private boolean VcenterDBInitComplete = false; - - public VCenterMonitorTask(VCenterNotify eventTask, - String vcenterUrl, String vcenterUsername, - String vcenterPassword, String dcName, - String dvsName, String ipFabricPgName) { - this.eventTask = eventTask; - vcenterDB = new VCenterDB(vcenterUrl, vcenterUsername, vcenterPassword, - dcName, dvsName, ipFabricPgName, VCenterMonitor.mode); - } - - private void connect2vcenter() { - TaskWatchDog.startMonitoring(this, "Init VCenter", - 300000, TimeUnit.MILLISECONDS); - try { - if (vcenterDB.connect() == true) { - vcenterDB.setReadTimeout(VCenterDB.VCENTER_READ_TIMEOUT); - VcenterDBInitComplete = true; - } - } catch (Exception e) { - String stackTrace = Throwables.getStackTraceAsString(e); - s_logger.error("Error while initializing VCenter connection: " + e); - s_logger.error(stackTrace); - e.printStackTrace(); - } - TaskWatchDog.stopMonitoring(this); - } - - - @Override - public void run() { - - //check if you are the master from time to time - //sometimes things dont go as planned - if (VCenterMonitor.isZookeeperLeader() == false) { - s_logger.debug("Lost zookeeper leadership. Restarting myself\n"); - System.exit(0); - } - - checkVroutersConnection(); - - // When syncVirtualNetworks is run the first time, it also does - // addPort to vrouter agent for existing VMIs. - // Clear the flag on first run of syncVirtualNetworks. - - //check aliveness for Vcenter - if (VcenterDBInitComplete == false) { - connect2vcenter(); - } - if (vcenterDB.isAlive() == false) { - VcenterDBInitComplete = false; - eventTask.setVCenterNotifyForceRefresh(true); - VCenterNotify.stopUpdates(); - } - } - - private void checkVroutersConnection() { - TaskWatchDog.startMonitoring(this, "VRouter Keep alive check", - 60000, TimeUnit.MILLISECONDS); - // run KeepAlive with vRouter Agent. - - try { - VRouterNotifier.vrouterAgentPeriodicConnectionCheck(); - } catch (Exception e) { - String stackTrace = Throwables.getStackTraceAsString(e); - s_logger.error("Error while vrouterAgentPeriodicConnectionCheck: " + e); - s_logger.error(stackTrace); - e.printStackTrace(); - } - - TaskWatchDog.stopMonitoring(this); - } -} diff --git a/src/net/juniper/contrail/vcenter/VCenterNotify.java b/src/net/juniper/contrail/vcenter/VCenterNotify.java index 9ee788a..8b28f1d 100644 --- a/src/net/juniper/contrail/vcenter/VCenterNotify.java +++ b/src/net/juniper/contrail/vcenter/VCenterNotify.java @@ -25,6 +25,7 @@ import com.vmware.vim25.UpdateSet; import com.vmware.vim25.VirtualMachineToolsRunningStatus; import com.vmware.vim25.VmEvent; +import com.vmware.vim25.WaitOptions; import com.vmware.vim25.mo.EventHistoryCollector; import com.vmware.vim25.mo.EventManager; import com.vmware.vim25.mo.ManagedObject; @@ -53,15 +54,9 @@ public class VCenterNotify implements Runnable private static final Logger s_logger = Logger.getLogger(VCenterNotify.class); - static VCenterMonitorTask monitorTask = null; static volatile VCenterDB vcenterDB = null; static volatile VncDB vncDB; - private boolean AddPortSyncAtPluginStart = true; - private boolean VncDBInitComplete = false; - private boolean VcenterDBInitComplete = false; - public boolean VCenterNotifyForceRefresh = false; - static volatile boolean syncNeeded = true; - + private static boolean vCenterConnected = false; private final static String[] guestProps = { "guest.toolsRunningStatus", "guest.net" }; private final static String[] ipPoolProps = { "summary.ipPoolId" }; private static Map watchedVMs @@ -104,22 +99,8 @@ public static VCenterDB getVcenterDB() { return vcenterDB; } - public boolean getVCenterNotifyForceRefresh() { - return VCenterNotifyForceRefresh; - } - - public void setVCenterNotifyForceRefresh(boolean _VCenterNotifyForceRefresh) { - VCenterNotifyForceRefresh = _VCenterNotifyForceRefresh; - } - - public void setAddPortSyncAtPluginStart(boolean _AddPortSyncAtPluginStart) - { - AddPortSyncAtPluginStart = _AddPortSyncAtPluginStart; - } - - public boolean getAddPortSyncAtPluginStart() - { - return AddPortSyncAtPluginStart; + public static boolean getVCenterConnected() { + return vCenterConnected; } private void cleanupEventFilters() { @@ -456,20 +437,27 @@ public void terminate() throws Exception { watchUpdates.stop(); } - private void connect2vnc() { + private boolean connect2vnc() { TaskWatchDog.startMonitoring(this, "Init Vnc", 300000, TimeUnit.MILLISECONDS); try { - if (vncDB.Initialize() == true) { - VncDBInitComplete = true; + s_logger.info("Connecting to the API server ..."); + while (vncDB.Initialize() != true) { + s_logger.info("Waiting for API server ..."); + Thread.sleep(1000); } + s_logger.info("Connected to the API server ..."); + TaskWatchDog.stopMonitoring(this); + return true; } catch (Exception e) { String stackTrace = Throwables.getStackTraceAsString(e); - s_logger.error("Error while initializing Vnc connection: " + e); + s_logger.error("Error while initializing connection with the API server: " + + e); s_logger.error(stackTrace); e.printStackTrace(); } TaskWatchDog.stopMonitoring(this); + return false; } private void connect2vcenter() { @@ -478,7 +466,7 @@ private void connect2vcenter() { try { if (vcenterDB.connect() == true) { createEventFilters(); - VcenterDBInitComplete = true; + vCenterConnected = true; } } catch (Exception e) { String stackTrace = Throwables.getStackTraceAsString(e); @@ -492,100 +480,86 @@ private void connect2vcenter() { @Override public void run() { - String version = ""; try { - for ( ; shouldRun; ) + if (connect2vnc() == false) { + return; + } + + boolean syncNeeded = true; + for (String version = "" ; shouldRun; ) { //check if you are the master from time to time - //sometimes things dont go as planned + //sometimes things don't go as planned if (VCenterMonitor.isZookeeperLeader() == false) { s_logger.debug("Lost zookeeper leadership. Restarting myself\n"); System.exit(0); } - if (VncDBInitComplete == false) { - connect2vnc(); - } - if (VcenterDBInitComplete == false) { + if (vCenterConnected == false) { connect2vcenter(); + version = ""; + syncNeeded = true; } - // Perform sync between VNC and VCenter DBs. - if (getAddPortSyncAtPluginStart() == true || syncNeeded) { - while (vncDB.isVncApiServerAlive() == false) { - s_logger.error("Waiting for API server before starting sync"); - Thread.sleep(5000); - } + while (vncDB.isVncApiServerAlive() == false) { + s_logger.info("Waiting for API server... "); + Thread.sleep(5000); + } + // Perform sync between VNC and VCenter DBs. + if (syncNeeded) { TaskWatchDog.startMonitoring(this, "Sync", 300000, TimeUnit.MILLISECONDS); - // When syncVirtualNetworks is run the first time, it also does + // When sync is run, it also does // addPort to vrouter agent for existing VMIs. - // Clear the flag on first run of syncVirtualNetworks. try { vcenterDB.setReadTimeout(VCenterDB.VCENTER_READ_TIMEOUT); MainDB.sync(vcenterDB, vncDB, VCenterMonitor.mode); vcenterDB.setReadTimeout(0); syncNeeded = false; - setAddPortSyncAtPluginStart(false); } catch (Exception e) { + vCenterConnected = false; + TaskWatchDog.stopMonitoring(this); String stackTrace = Throwables.getStackTraceAsString(e); s_logger.error("Error in sync: " + e); s_logger.error(stackTrace); e.printStackTrace(); - if (stackTrace.contains("java.net.ConnectException: Connection refused") || - stackTrace.contains("java.rmi.RemoteException: VI SDK invoke")) { - //Remote Exception. Some issue with connection to vcenter-server - // Exception on accessing remote objects. - // Try to reinitialize the VCenter connection. - //For some reason RemoteException not thrown - s_logger.error("Problem with connection to vCenter-Server"); - s_logger.error("Restart connection and reSync"); - connect2vcenter(); - version = ""; - } - TaskWatchDog.stopMonitoring(this); continue; } - TaskWatchDog.stopMonitoring(this); + } try { + WaitOptions wOpt = new WaitOptions(); + wOpt.setMaxWaitSeconds(VCenterDB.VCENTER_WAIT_FOR_UPDATES_TIMEOUT); PropertyCollector propColl = vcenterDB.getServiceInstance().getPropertyCollector(); - @SuppressWarnings("deprecation") - UpdateSet update = propColl.waitForUpdates(version); - if (update != null && update.getFilterSet() != null) - { - - version = update.getVersion(); - - this.handleUpdate(update); - - } else - { - s_logger.error("No update is present!"); + for ( ; ; ) { + UpdateSet update = propColl.waitForUpdatesEx(version, wOpt); + if (update != null && update.getFilterSet() != null) + { + version = update.getVersion(); + + this.handleUpdate(update); + + } else + { + if (vcenterDB.isAlive() == false) { + s_logger.error("Vcenter connection lost, reconnect and resync needed"); + vCenterConnected = false; + break; + } + } } } catch (Exception e) { - syncNeeded = true; - s_logger.error("Error in event handling, resync needed"); + vCenterConnected = false; + s_logger.error("Error in event handling, reconnect and resync needed"); String stackTrace = Throwables.getStackTraceAsString(e); s_logger.error(stackTrace); e.printStackTrace(); - if (stackTrace.contains("java.net.ConnectException: Connection refused") || - stackTrace.contains("java.rmi.RemoteException: VI SDK invoke")) { - //Remote Exception. Some issue with connection to vcenter-server - // Exception on accessing remote objects. - // Try to reinitialize the VCenter connection. - //For some reason RemoteException not thrown - s_logger.error("Problem with connection to vCenter-Server"); - s_logger.error("Restart connection and reSync"); - connect2vcenter(); - version = ""; - } } } } catch (Exception e) @@ -619,16 +593,6 @@ void printVmEvent(Object value) + "\n----------\n"); } - public static void stopUpdates() { - if (vcenterDB == null || vcenterDB.getServiceInstance() == null) { - return; - } - PropertyCollector propColl = vcenterDB.getServiceInstance().getPropertyCollector(); - if (propColl != null) { - propColl.stopUpdates(); - } - } - public static VncDB getVncDB() { return vncDB; } diff --git a/src/net/juniper/contrail/vcenter/VRouterMonitorTask.java b/src/net/juniper/contrail/vcenter/VRouterMonitorTask.java new file mode 100644 index 0000000..1bbc1d1 --- /dev/null +++ b/src/net/juniper/contrail/vcenter/VRouterMonitorTask.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. + */ + +package net.juniper.contrail.vcenter; + +import java.util.concurrent.TimeUnit; +import com.google.common.base.Throwables; +import org.apache.log4j.Logger; +import net.juniper.contrail.watchdog.TaskWatchDog; + +class VRouterMonitorTask implements Runnable { + private static Logger s_logger = Logger.getLogger(VRouterMonitorTask.class); + + @Override + public void run() { + + //check if you are the master from time to time + //sometimes things don't go as planned + if (VCenterMonitor.isZookeeperLeader() == false) { + s_logger.debug("Lost zookeeper leadership. Restarting myself\n"); + System.exit(0); + } + + checkVroutersConnection(); + } + + private void checkVroutersConnection() { + TaskWatchDog.startMonitoring(this, "VRouter Keep alive check", + 60000, TimeUnit.MILLISECONDS); + + try { + // run KeepAlive with vRouter Agent. + VRouterNotifier.vrouterAgentPeriodicConnectionCheck(); + } catch (Exception e) { + String stackTrace = Throwables.getStackTraceAsString(e); + s_logger.error("Error while vrouterAgentPeriodicConnectionCheck: " + e); + s_logger.error(stackTrace); + e.printStackTrace(); + } + + TaskWatchDog.stopMonitoring(this); + } +}