2 * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.applications.frm.util;
10 import java.lang.management.ManagementFactory;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.TimeUnit;
16 import java.util.concurrent.TimeoutException;
17 import javax.management.AttributeNotFoundException;
18 import javax.management.InstanceNotFoundException;
19 import javax.management.MBeanException;
20 import javax.management.MBeanServer;
21 import javax.management.MalformedObjectNameException;
22 import javax.management.ObjectName;
23 import javax.management.ReflectionException;
24 import org.opendaylight.openflowplugin.applications.frm.ActionType;
25 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.arbitrator.reconcile.service.rev180227.GetActiveBundleInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.arbitrator.reconcile.service.rev180227.GetActiveBundleOutput;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.opendaylight.yangtools.yang.common.RpcResult;
49 import org.opendaylight.yangtools.yang.common.Uint32;
50 import org.opendaylight.yangtools.yang.common.Uint64;
51 import org.opendaylight.yangtools.yang.common.Uint8;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 @SuppressWarnings("IllegalCatch")
56 public final class FrmUtil {
57 private static final Logger LOG = LoggerFactory.getLogger(FrmUtil.class);
58 private static final String SEPARATOR = ":";
59 private static final long RPC_RESULT_TIMEOUT = 2500;
60 public static final String OPENFLOW_PREFIX = "openflow:";
62 private static final String JMX_OBJ_NAME_LIST_OF_SHRDS = "org.opendaylight.controller:type="
63 + "DistributedConfigDatastore,Category=ShardManager,name=shard-manager-config";
64 private static String JMX_OBJECT_SHARD_STATUS = "";
70 public static NodeId getNodeIdFromNodeIdentifier(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
71 return nodeIdent.firstKeyOf(Node.class).getId();
74 public static String getNodeIdValueFromNodeIdentifier(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
75 return getNodeIdFromNodeIdentifier(nodeIdent).getValue();
78 public static String getFlowId(final FlowRef flowRef) {
79 return flowRef.getValue().firstKeyOf(Flow.class).getId().getValue();
82 public static String getFlowId(final InstanceIdentifier<Flow> identifier) {
83 return getFlowId(new FlowRef(identifier));
86 public static Uint8 getTableId(final FlowTableRef flowTableRef) {
87 return flowTableRef.getValue().firstKeyOf(Table.class).getId();
90 public static Uint8 getTableId(final InstanceIdentifier<Flow> identifier) {
91 return getTableId(new FlowTableRef(identifier));
94 public static Uint64 getDpnIdFromNodeName(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
95 String nodeId = nodeIdent.firstKeyOf(Node.class).getId().getValue();
96 return Uint64.valueOf(nodeId.substring(nodeId.lastIndexOf(SEPARATOR) + 1));
99 public static Uint32 isFlowDependentOnGroup(final Flow flow) {
100 LOG.debug("Check if flow {} is dependent on group", flow);
101 if (flow.getInstructions() != null) {
102 Collection<Instruction> instructions = flow.getInstructions().nonnullInstruction().values();
103 for (Instruction instruction : instructions) {
104 Collection<Action> actions = Collections.emptyList();
105 if (instruction.getInstruction().implementedInterface()
106 .equals(ActionType.APPLY_ACTION.getActionType())) {
107 actions = ((ApplyActionsCase) instruction.getInstruction())
108 .getApplyActions().nonnullAction().values();
109 } else if (instruction.getInstruction().implementedInterface()
110 .equals(ActionType.WRITE_ACTION.getActionType())) {
111 actions = ((WriteActionsCase)instruction.getInstruction())
112 .getWriteActions().nonnullAction().values();
114 if (actions != null) {
115 for (Action action : actions) {
116 if (action.getAction().implementedInterface().equals(ActionType.GROUP_ACTION.getActionType())) {
117 return ((GroupActionCase) action.getAction()).getGroupAction().getGroupId();
126 public static InstanceIdentifier<Group> buildGroupInstanceIdentifier(
127 final InstanceIdentifier<FlowCapableNode> nodeIdent, final Uint32 groupId) {
128 NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
129 InstanceIdentifier<Group> groupInstanceId = InstanceIdentifier.builder(Nodes.class)
130 .child(Node.class, new NodeKey(nodeId))
131 .augmentation(FlowCapableNode.class)
132 .child(Group.class, new GroupKey(new GroupId(groupId)))
134 return groupInstanceId;
137 public static BundleId getActiveBundle(final InstanceIdentifier<FlowCapableNode> nodeIdent,
138 final ForwardingRulesManager provider) {
139 final Uint64 dpId = getDpnIdFromNodeName(nodeIdent);
140 final NodeRef nodeRef = new NodeRef(nodeIdent.firstIdentifierOf(Node.class));
141 GetActiveBundleInputBuilder input = new GetActiveBundleInputBuilder().setNodeId(dpId).setNode(nodeRef);
143 RpcResult<GetActiveBundleOutput> result = provider.getArbitratorReconciliationManager()
144 .getActiveBundle(input.build()).get(RPC_RESULT_TIMEOUT, TimeUnit.MILLISECONDS);
145 if (!result.isSuccessful()) {
146 LOG.trace("Error while retrieving active bundle present for node {}", dpId);
148 return result.getResult().getResult();
150 } catch (InterruptedException | ExecutionException | TimeoutException e) {
151 LOG.error("Error while retrieving active bundle present for node {} is {}", dpId , e.getMessage());
156 public static boolean isGroupExistsOnDevice(final InstanceIdentifier<FlowCapableNode> nodeIdent,
157 final Uint32 groupId,
158 final ForwardingRulesManager provider) {
159 String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent);
160 return provider.getDevicesGroupRegistry().isGroupPresent(nodeId, groupId);
163 public static String getInventoryConfigDataStoreStatus() {
164 boolean statusResult = true;
166 final var listOfShards = getAttributeJMXCommand(JMX_OBJ_NAME_LIST_OF_SHRDS, "LocalShards");
167 if (listOfShards != null) {
168 for (Object listOfShard : listOfShards) {
169 LOG.info("Listofshard is {} ",listOfShard);
170 if (listOfShard.toString().contains("inventory")) {
171 JMX_OBJECT_SHARD_STATUS =
172 "org.opendaylight.controller:Category=Shards,name=" + listOfShard
173 + ",type=DistributedConfigDatastore";
174 LOG.info("JMX object shard status is {} ",JMX_OBJECT_SHARD_STATUS);
175 String leader = getLeaderJMX(JMX_OBJECT_SHARD_STATUS, "Leader");
176 if (leader != null && leader.length() > 1) {
177 LOG.info("{} ::Inventory Shard has the Leader as:: {}", listOfShard, leader);
179 statusResult = false;
184 } catch (Exception e) {
185 LOG.error("ERROR ::", e);
188 return "OPERATIONAL";
194 private static List<?> getAttributeJMXCommand(final String objectName, final String attributeName) {
195 final var mbs = ManagementFactory.getPlatformMBeanServer();
198 return (List<?>) mbs.getAttribute(new ObjectName(objectName), attributeName);
199 } catch (MBeanException | AttributeNotFoundException | InstanceNotFoundException
200 | MalformedObjectNameException | ReflectionException e) {
201 LOG.error("Exception while reading list of shards ", e);
207 private static String getLeaderJMX(final String objectName, final String atrName) {
208 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
212 leader = (String) mbs.getAttribute(new ObjectName(objectName), atrName);
213 } catch (MalformedObjectNameException monEx) {
214 LOG.error("CRITICAL EXCEPTION : Malformed Object Name Exception");
215 } catch (MBeanException mbEx) {
216 LOG.error("CRITICAL EXCEPTION : MBean Exception");
217 } catch (InstanceNotFoundException infEx) {
218 LOG.error("CRITICAL EXCEPTION : Instance Not Found Exception");
219 } catch (ReflectionException rEx) {
220 LOG.error("CRITICAL EXCEPTION : Reflection Exception");
221 } catch (Exception e) {
222 LOG.error("Attribute not found");