6cd40cab71572d100ba3da2893f440709810b75a
[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
9 package org.opendaylight.openflowplugin.applications.frm.util;
10
11 import java.math.BigInteger;
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 org.opendaylight.openflowplugin.applications.frm.ActionType;
18 import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.arbitrator.reconcile.service.rev180227.GetActiveBundleInputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.arbitrator.reconcile.service.rev180227.GetActiveBundleOutput;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.RpcResult;
42 import org.opendaylight.yangtools.yang.common.Uint32;
43 import org.opendaylight.yangtools.yang.common.Uint8;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public final class FrmUtil {
48     private static final Logger LOG = LoggerFactory.getLogger(FrmUtil.class);
49     private static final String SEPARATOR = ":";
50     private static final long RPC_RESULT_TIMEOUT = 2500;
51
52     private FrmUtil() {
53         throw new IllegalStateException("This class should not be instantiated.");
54     }
55
56     public static NodeId getNodeIdFromNodeIdentifier(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
57         return nodeIdent.firstKeyOf(Node.class).getId();
58     }
59
60     public static String getNodeIdValueFromNodeIdentifier(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
61         return getNodeIdFromNodeIdentifier(nodeIdent).getValue();
62     }
63
64     public static String getFlowId(final FlowRef flowRef) {
65         return flowRef.getValue().firstKeyOf(Flow.class).getId().getValue();
66     }
67
68     public static String getFlowId(final InstanceIdentifier<Flow> identifier) {
69         return getFlowId(new FlowRef(identifier));
70     }
71
72     public static Uint8 getTableId(final FlowTableRef flowTableRef) {
73         return flowTableRef.getValue().firstKeyOf(Table.class).getId();
74     }
75
76     public static Uint8 getTableId(final InstanceIdentifier<Flow> identifier) {
77         return getTableId(new FlowTableRef(identifier));
78     }
79
80     public static BigInteger getDpnIdFromNodeName(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
81         String nodeId = nodeIdent.firstKeyOf(Node.class).getId().getValue();
82         String dpId = nodeId.substring(nodeId.lastIndexOf(SEPARATOR) + 1);
83         return new BigInteger(dpId);
84     }
85
86     public static Uint32 isFlowDependentOnGroup(final Flow flow) {
87         LOG.debug("Check if flow {} is dependent on group", flow);
88         if (flow.getInstructions() != null) {
89             List<Instruction> instructions = flow.getInstructions().getInstruction();
90             for (Instruction instruction : instructions) {
91                 List<Action> actions = Collections.emptyList();
92                 if (instruction.getInstruction().implementedInterface()
93                         .equals(ActionType.APPLY_ACTION.getActionType())) {
94                     actions = ((ApplyActionsCase) instruction.getInstruction())
95                             .getApplyActions().getAction();
96                 } else if (instruction.getInstruction().implementedInterface()
97                         .equals(ActionType.WRITE_ACTION.getActionType())) {
98                     actions = ((WriteActionsCase)instruction.getInstruction())
99                             .getWriteActions().getAction();
100                 }
101                 for (Action action : actions) {
102                     if (action.getAction().implementedInterface()
103                             .equals(ActionType.GROUP_ACTION.getActionType())) {
104                         return ((GroupActionCase) action.getAction()).getGroupAction()
105                                 .getGroupId();
106                     }
107                 }
108             }
109         }
110         return null;
111     }
112
113     public static InstanceIdentifier<Group> buildGroupInstanceIdentifier(
114             final InstanceIdentifier<FlowCapableNode> nodeIdent, final Uint32 groupId) {
115         NodeId nodeId = getNodeIdFromNodeIdentifier(nodeIdent);
116         InstanceIdentifier<Group> groupInstanceId = InstanceIdentifier.builder(Nodes.class)
117                 .child(Node.class, new NodeKey(nodeId))
118                 .augmentation(FlowCapableNode.class)
119                 .child(Group.class, new GroupKey(new GroupId(groupId)))
120                 .build();
121         return groupInstanceId;
122     }
123
124     public static BundleId getActiveBundle(final InstanceIdentifier<FlowCapableNode> nodeIdent,
125                                            final ForwardingRulesManager provider) {
126         BigInteger dpId = getDpnIdFromNodeName(nodeIdent);
127         final NodeRef nodeRef = new NodeRef(nodeIdent.firstIdentifierOf(Node.class));
128         GetActiveBundleInputBuilder input = new GetActiveBundleInputBuilder().setNodeId(dpId).setNode(nodeRef);
129         try {
130             RpcResult<GetActiveBundleOutput> result = provider.getArbitratorReconciliationManager()
131                     .getActiveBundle(input.build()).get(RPC_RESULT_TIMEOUT, TimeUnit.MILLISECONDS);
132             if (!result.isSuccessful()) {
133                 LOG.trace("Error while retrieving active bundle present for node {}", dpId);
134             } else {
135                 return result.getResult().getResult();
136             }
137         } catch (InterruptedException | ExecutionException | TimeoutException e) {
138             LOG.error("Error while retrieving active bundle present for node {} is {}", dpId , e.getMessage());
139         }
140         return null;
141     }
142
143     public static boolean isGroupExistsOnDevice(final InstanceIdentifier<FlowCapableNode> nodeIdent,
144                                                 final Uint32 groupId,
145                                                 final ForwardingRulesManager provider) {
146         String nodeId = getNodeIdValueFromNodeIdentifier(nodeIdent);
147         return provider.getDevicesGroupRegistry().isGroupPresent(nodeId, groupId);
148     }
149 }