Convert ListenerRegistrationHelper into a component
[openflowplugin.git] / applications / forwardingrules-manager / src / main / java / org / opendaylight / openflowplugin / applications / frm / util / FrmUtil.java
1 /*
2  * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.openflowplugin.applications.frm.util;
9
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;
54
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:";
61
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 = "";
65
66     private FrmUtil() {
67         // Hidden on purpose
68     }
69
70     public static NodeId getNodeIdFromNodeIdentifier(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
71         return nodeIdent.firstKeyOf(Node.class).getId();
72     }
73
74     public static String getNodeIdValueFromNodeIdentifier(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
75         return getNodeIdFromNodeIdentifier(nodeIdent).getValue();
76     }
77
78     public static String getFlowId(final FlowRef flowRef) {
79         return flowRef.getValue().firstKeyOf(Flow.class).getId().getValue();
80     }
81
82     public static String getFlowId(final InstanceIdentifier<Flow> identifier) {
83         return getFlowId(new FlowRef(identifier));
84     }
85
86     public static Uint8 getTableId(final FlowTableRef flowTableRef) {
87         return flowTableRef.getValue().firstKeyOf(Table.class).getId();
88     }
89
90     public static Uint8 getTableId(final InstanceIdentifier<Flow> identifier) {
91         return getTableId(new FlowTableRef(identifier));
92     }
93
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));
97     }
98
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();
113                 }
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();
118                         }
119                     }
120                 }
121             }
122         }
123         return null;
124     }
125
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)))
133                 .build();
134         return groupInstanceId;
135     }
136
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);
142         try {
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);
147             } else {
148                 return result.getResult().getResult();
149             }
150         } catch (InterruptedException | ExecutionException | TimeoutException e) {
151             LOG.error("Error while retrieving active bundle present for node {} is {}", dpId , e.getMessage());
152         }
153         return null;
154     }
155
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);
161     }
162
163     public static String getInventoryConfigDataStoreStatus() {
164         boolean statusResult = true;
165         try {
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);
178                         } else {
179                             statusResult = false;
180                         }
181                     }
182                 }
183             }
184         } catch (Exception e) {
185             LOG.error("ERROR ::", e);
186         }
187         if (statusResult) {
188             return "OPERATIONAL";
189         } else {
190             return "ERROR";
191         }
192     }
193
194     private static List<?> getAttributeJMXCommand(final String objectName, final String attributeName) {
195         final var mbs = ManagementFactory.getPlatformMBeanServer();
196         if (mbs != null) {
197             try {
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);
202             }
203         }
204         return List.of();
205     }
206
207     private static String getLeaderJMX(final String objectName, final String atrName) {
208         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
209         String leader = "";
210         if (mbs != null) {
211             try {
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");
223             }
224         }
225         return leader;
226     }
227 }