import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.infra.TypedWriteTransaction;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
@Inject
public IdManager(DataBroker db, LockManagerService lockManager, IdUtils idUtils,
- @Reference DataImportBootReady dataImportBootReady, @Reference JobCoordinator jobCoordinator)
+ @Reference DataImportBootReady dataImportBootReady,
+ @Reference JobCoordinator jobCoordinator, @Reference ShardStatusMonitor shardStatusMonitor)
throws ReadFailedException, InterruptedException {
this.broker = db;
this.txRunner = new ManagedNewTransactionRunnerImpl(db);
// it appears to be (is) un-used from a Java code PoV!
this.localPool = new ConcurrentHashMap<>();
- populateCache();
+ boolean isDatastoreAvailable = false;
+ int retryCount = 0;
+ int totalRetry = 1000;
+ try {
+ while (retryCount < totalRetry) {
+ isDatastoreAvailable = shardStatusMonitor.getShardStatus(NwConstants.IdManagerShards.getShardList());
+ if (isDatastoreAvailable) {
+ LOG.info("IDManager is UP");
+ populateCache();
+ break;
+ }
+ LOG.error("IdManager: retrying shard status check for the {} time, pending retries {}",
+ ++retryCount, totalRetry - retryCount);
+ Thread.sleep(2000);
+ }
+ } catch (InterruptedException e) {
+ LOG.error("IDManager is DOWN, shard status check failed");
+ }
+
+ if (!isDatastoreAvailable) {
+ LOG.error("IDManager is DOWN, as shards were not available at bundle bringup");
+ }
}
@Override
import org.opendaylight.genius.lockmanager.impl.LockListener;
import org.opendaylight.genius.lockmanager.impl.LockManagerServiceImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.testutils.TestShardStatusMonitor;
import org.opendaylight.infrautils.inject.guice.testutils.AbstractGuiceJsr250Module;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.testutils.DataBrokerTestModule;
bind(JobCoordinatorEventsWaiter.class).to(TestableJobCoordinatorEventsWaiter.class);
DataBroker dataBroker = DataBrokerTestModule.dataBroker();
bind(DataBroker.class).toInstance(dataBroker);
+ bind(ShardStatusMonitor.class).toInstance(TestShardStatusMonitor.newInstance());
}
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Other;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
flowBasedServicesStateRendererFactoryResolver,
final InterfaceServiceRecoveryHandler
interfaceServiceRecoveryHandler,
- @Reference final ServiceRecoveryRegistry serviceRecoveryRegistry) {
+ @Reference final ServiceRecoveryRegistry serviceRecoveryRegistry,
+ final IdManagerService idManagerService) {
super(dataBroker, LogicalDatastoreType.OPERATIONAL,
InstanceIdentifier.create(InterfacesState.class).child(Interface.class));
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.serviceutils.tools.listener.AbstractSyncDataTreeChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
public FlowBasedServicesNodeStateListener(@Reference final DataBroker dataBroker,
@Reference final JobCoordinator jobCoordinator,
final FlowBasedServicesStateRendererFactoryResolver
- flowBasedServicesStateRendererFactoryResolver) {
+ flowBasedServicesStateRendererFactoryResolver,
+ final IdManagerService idManagerService) {
super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class));
this.jobCoordinator = jobCoordinator;
this.flowBasedServicesStateRendererFactoryResolver = flowBasedServicesStateRendererFactoryResolver;
import org.opendaylight.genius.lockmanager.impl.LockListener;
import org.opendaylight.genius.lockmanager.impl.LockManagerServiceImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.testutils.TestShardStatusMonitor;
import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
import org.opendaylight.infrautils.caches.CacheProvider;
bind(LockManagerService.class).to(LockManagerServiceImpl.class);
bind(LockListener.class);
bind(IdManagerService.class).to(IdManager.class);
+ bind(ShardStatusMonitor.class).toInstance(TestShardStatusMonitor.newInstance());
bind(IInterfaceManager.class).to(InterfacemgrProvider.class);
TestIMdsalApiManager mdsalManager = TestIMdsalApiManager.newInstance();
import org.opendaylight.serviceutils.tools.listener.AbstractSyncDataTreeChangeListener;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
@Inject
public OvsdbNodeListener(DataBroker dataBroker, ItmConfig itmConfig, JobCoordinator jobCoordinator,
- DataTreeEventCallbackRegistrar eventCallbacks) {
+ DataTreeEventCallbackRegistrar eventCallbacks,
+ final IdManagerService idManagerService) {
super(dataBroker, LogicalDatastoreType.OPERATIONAL,
InstanceIdentifier.create(NetworkTopology.class).child(Topology.class).child(Node.class));
this.dataBroker = dataBroker;
import org.opendaylight.genius.itm.rpc.ItmManagerRpcService;
import org.opendaylight.genius.lockmanager.impl.LockManagerServiceImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.testutils.TestShardStatusMonitor;
import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
import org.opendaylight.infrautils.diagstatus.DiagStatusService;
import org.opendaylight.infrautils.inject.guice.testutils.AbstractGuiceJsr250Module;
bind(TestIMdsalApiManager.class).toInstance(mdsalManager);
bind(DataImportBootReady.class).toInstance(new DataImportBootReady() {});
bind(DiagStatusService.class).toInstance(mock(DiagStatusService.class));
+ bind(ShardStatusMonitor.class).toInstance(TestShardStatusMonitor.newInstance());
}
}
*/
package org.opendaylight.genius.mdsalutil;
+
+import java.util.ArrayList;
+import java.util.List;
import org.opendaylight.yangtools.yang.common.Uint64;
public interface NwConstants {
return flowModHeaderLen;
}
}
+
+ enum IdManagerShards {
+ DefaultConfig("default:config"),
+ DefaultOper("default:oper"),
+ InventoryConfig("inventory:config"),
+ InventoryOper("inventory:oper"),
+ TopologyConfig("topology:config"),
+ TopologyOper("topology:oper"),
+ EntityOper("entity:oper");
+
+ private String shardName;
+
+ IdManagerShards(String shardName) {
+ this.shardName = shardName;
+ }
+
+ public static List<String> getShardList() {
+ List<String> list = new ArrayList<>();
+ for (IdManagerShards val : IdManagerShards.values()) {
+ list.add(val.shardName);
+ }
+ return list;
+ }
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2019 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.mdsalutil.interfaces;
+
+import java.util.List;
+
+public interface ShardStatusMonitor {
+
+ String JMX_OBJECT_NAME_LIST_OF_CONFIG_SHARDS =
+ "org.opendaylight.controller:type=DistributedConfigDatastore,"
+ + "Category=ShardManager,name=shard-manager-config";
+ String JMX_OBJECT_NAME_LIST_OF_OPER_SHARDS =
+ "org.opendaylight.controller:type=DistributedOperationalDatastore,"
+ + "Category=ShardManager,name=shard-manager-operational";
+
+ boolean getShardStatus(List<String> shards);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.mdsalutil.internal;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public final class ShardStatusMonitorImpl implements ShardStatusMonitor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ShardStatusMonitorImpl.class);
+
+ @Inject
+ public ShardStatusMonitorImpl() {
+ // Do nothing
+ }
+
+ public boolean getShardStatus(List<String> shards) {
+ boolean status = true;
+ for (String shard : shards) {
+ String[] params = shard.split(":");
+ if (!getDataStoreStatus(params[0], params[1]).equalsIgnoreCase("operational")) {
+ status = false;
+ break;
+ }
+ }
+ return status;
+ }
+
+ @SuppressWarnings("IllegalCatch")
+ private static String getDataStoreStatus(String name, String type) {
+ boolean statusResult = true;
+ try {
+ ArrayList listOfShards;
+ if (type.equalsIgnoreCase("config")) {
+ listOfShards = getAttributeJMXCommand(JMX_OBJECT_NAME_LIST_OF_CONFIG_SHARDS, "LocalShards");
+ } else {
+ listOfShards = getAttributeJMXCommand(JMX_OBJECT_NAME_LIST_OF_OPER_SHARDS, "LocalShards");
+ }
+ if (listOfShards != null) {
+ for (int i = 0; i < listOfShards.size(); i++) {
+ if (listOfShards.get(i).toString().contains(name)) {
+ String jmxObjectShardStatus;
+ if (type.equalsIgnoreCase("config")) {
+ jmxObjectShardStatus = "org.opendaylight.controller:Category=Shards,name="
+ + listOfShards.get(i) + ",type=DistributedConfigDatastore";
+ } else {
+ jmxObjectShardStatus = "org.opendaylight.controller:Category=Shards,name="
+ + listOfShards.get(i) + ",type=DistributedOperationalDatastore";
+ }
+ LOG.info(jmxObjectShardStatus);
+ String leader = getLeaderJMX(jmxObjectShardStatus,"Leader");
+ if (leader != null && leader.length() > 1) {
+ if (type.equalsIgnoreCase("config")) {
+ LOG.info("{} ::Config DS has the Leader as:: {}", listOfShards.get(i), leader);
+ } else {
+ LOG.info("{} ::Oper DS has the Leader as:: {}", listOfShards.get(i), leader);
+ }
+ } else {
+ statusResult = false;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("ERROR::", e);
+ statusResult = false;
+ }
+ if (statusResult) {
+ return "OPERATIONAL";
+ } else {
+ return "ERROR";
+ }
+ }
+
+ @SuppressWarnings("IllegalCatch")
+ private static ArrayList getAttributeJMXCommand(String objectName, String attributeName) {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ArrayList listOfShards = new ArrayList();
+ if (mbs != null) {
+ try {
+ listOfShards = (ArrayList) mbs.getAttribute(new ObjectName(objectName), attributeName);
+ } catch (MalformedObjectNameException monEx) {
+ LOG.error("CRITICAL EXCEPTION : Malformed Object Name Exception");
+ } catch (MBeanException mbEx) {
+ LOG.error("CRITICAL EXCEPTION : MBean Exception");
+ } catch (InstanceNotFoundException infEx) {
+ LOG.error("CRITICAL EXCEPTION : Instance Not Found Exception");
+ } catch (ReflectionException rEx) {
+ LOG.error("CRITICAL EXCEPTION : Reflection Exception");
+ } catch (Exception e) {
+ LOG.error("Attribute not found");
+ }
+ }
+ return listOfShards;
+ }
+
+ @SuppressWarnings("IllegalCatch")
+ private static String getLeaderJMX(String objectName, String atrName) {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ String leader = "";
+ if (mbs != null) {
+ try {
+ leader = (String) mbs.getAttribute(new ObjectName(objectName), atrName);
+ } catch (MalformedObjectNameException monEx) {
+ LOG.error("CRITICAL EXCEPTION : Malformed Object Name Exception");
+ } catch (MBeanException mbEx) {
+ LOG.error("CRITICAL EXCEPTION : MBean Exception");
+ } catch (InstanceNotFoundException infEx) {
+ LOG.error("CRITICAL EXCEPTION : Instance Not Found Exception");
+ } catch (ReflectionException rEx) {
+ LOG.error("CRITICAL EXCEPTION : Reflection Exception");
+ } catch (Exception e) {
+ LOG.error("Attribute not found");
+ }
+ }
+ return leader;
+ }
+}
\ No newline at end of file
<service ref="hwvtepNodeHACacheImpl"
interface="org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache"/>
+ <service ref="shardStatusMonitorImpl"
+ interface="org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor" />
</blueprint>
<artifactId>blueprint-maven-plugin-annotation</artifactId>
<optional>true</optional>
</dependency>
-
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>compile</scope>
+ </dependency>
<!-- Now all <scope>test here: -->
<dependency>
<groupId>org.opendaylight.infrautils</groupId>
--- /dev/null
+/*
+ * Copyright (c) 2019 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.mdsalutil.testutils;
+
+import static org.opendaylight.yangtools.testutils.mockito.MoreAnswers.realOrException;
+
+import java.util.List;
+import org.mockito.Mockito;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
+
+public abstract class TestShardStatusMonitor implements ShardStatusMonitor {
+
+ public static TestShardStatusMonitor newInstance() {
+ return Mockito.mock(TestShardStatusMonitor.class, realOrException());
+ }
+
+ @Override
+ public boolean getShardStatus(List<String> shards) {
+ return true;
+ }
+}
\ No newline at end of file
import org.opendaylight.daexim.DataImportBootReady;
import org.opendaylight.genius.idmanager.IdManager;
import org.opendaylight.genius.lockmanager.impl.LockManagerServiceImpl;
+import org.opendaylight.genius.mdsalutil.interfaces.ShardStatusMonitor;
+import org.opendaylight.genius.mdsalutil.testutils.TestShardStatusMonitor;
import org.opendaylight.genius.networkutils.RDUtils;
import org.opendaylight.genius.networkutils.VniUtils;
import org.opendaylight.genius.networkutils.impl.RDUtilsImpl;
bind(DataBroker.class).toInstance(dataBroker);
bind(NetworkConfig.class).toInstance(mock(NetworkConfig.class));
bind(IdManagerService.class).to(IdManager.class);
+ bind(ShardStatusMonitor.class).toInstance(TestShardStatusMonitor.newInstance());
bind(DataImportBootReady.class).toInstance(new DataImportBootReady() {});
bind(LockManagerService.class).to(LockManagerServiceImpl.class);
bind(VniUtils.class).to(VniUtilsImpl.class);