NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / vpnmanager / api / src / main / java / org / opendaylight / netvirt / vpnmanager / api / InterfaceUtils.java
1 /*
2  * Copyright (c) 2015 - 2016 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.netvirt.vpnmanager.api;
9
10 import java.util.List;
11 import java.util.Optional;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.Future;
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
43 import org.opendaylight.yangtools.yang.binding.DataObject;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.opendaylight.yangtools.yang.common.RpcResult;
46 import org.opendaylight.yangtools.yang.common.Uint64;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 public final class InterfaceUtils {
51     private static final Logger LOG = LoggerFactory.getLogger(InterfaceUtils.class);
52     private static String OF_URI_SEPARATOR = ":";
53
54     private InterfaceUtils() {
55
56     }
57
58     public static Uint64 getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
59         Uint64 nodeId = Uint64.ZERO;
60         try {
61             GetDpidFromInterfaceInput
62                 dpIdInput =
63                 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
64             Future<RpcResult<GetDpidFromInterfaceOutput>>
65                 dpIdOutput =
66                 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
67             RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
68             if (dpIdResult.isSuccessful()) {
69                 nodeId = dpIdResult.getResult().getDpid();
70             } else {
71                 LOG.info("getDpnForInterface: Could not retrieve DPN Id for interface {}", ifName);
72             }
73         } catch (NullPointerException | InterruptedException | ExecutionException e) {
74             LOG.error("getDpnForInterface: Exception when getting dpn for interface {}", ifName, e);
75         }
76         return nodeId;
77     }
78
79     public static String getEndpointIpAddressForDPN(DataBroker broker, Uint64 dpnId) {
80         String nextHopIp = null;
81         InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
82                 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
83                         new DPNTEPsInfoKey(dpnId)).build();
84         Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
85         if (tunnelInfo.isPresent()) {
86             List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
87             if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
88                 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
89             }
90         }
91         return nextHopIp;
92     }
93
94     public static InstanceIdentifier<BoundServices> buildServiceId(String vpnInterfaceName, short serviceIndex) {
95         return InstanceIdentifier.builder(ServiceBindings.class).child(ServicesInfo.class,
96             new ServicesInfoKey(vpnInterfaceName, ServiceModeIngress.class))
97             .child(BoundServices.class, new BoundServicesKey(serviceIndex)).build();
98     }
99
100     public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
101         Uint64 cookie, List<Instruction> instructions) {
102         StypeOpenflowBuilder augBuilder =
103             new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority).setInstruction(instructions);
104         return new BoundServicesBuilder().withKey(new BoundServicesKey(servicePriority))
105             .setServiceName(serviceName).setServicePriority(servicePriority)
106             .setServiceType(ServiceTypeFlowBased.class).addAugmentation(StypeOpenflow.class,
107                 augBuilder.build()).build();
108     }
109
110     public static boolean isOperational(DataBroker dataBroker, String ifName) {
111         return getInterfaceStateFromOperDS(dataBroker, ifName) != null;
112     }
113
114     public static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
115         InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
116             InstanceIdentifier.builder(InterfacesState.class)
117                 .child(
118                     org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
119                         .state.Interface.class,
120                     new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
121                         .state.InterfaceKey(
122                         interfaceName));
123         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
124             .rev140508.interfaces.state.Interface>
125             id = idBuilder.build();
126         return id;
127     }
128
129     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
130         .@Nullable Interface getInterfaceStateFromOperDS(
131         DataBroker dataBroker, String interfaceName) {
132         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
133             .rev140508.interfaces.state.Interface>
134             ifStateId =
135             buildStateInterfaceId(interfaceName);
136         Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
137         if (ifStateOptional.isPresent()) {
138             return ifStateOptional.get();
139         }
140
141         return null;
142     }
143
144     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
145         .@Nullable Interface getInterface(
146         DataBroker broker, String interfaceName) {
147         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
148             .Interface>
149             optInterface = read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
150         if (optInterface.isPresent()) {
151             return optInterface.get();
152         }
153         return null;
154     }
155
156     public static Optional<String> getMacAddressForInterface(DataBroker dataBroker, String interfaceName) {
157         Optional<String> macAddressOptional = Optional.empty();
158         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
159             .rev140508.interfaces.state.Interface>
160             ifStateId =
161             buildStateInterfaceId(interfaceName);
162         Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
163         if (ifStateOptional.isPresent()) {
164             PhysAddress macAddress = ifStateOptional.get().getPhysAddress();
165             if (macAddress != null) {
166                 macAddressOptional = Optional.of(macAddress.getValue());
167             }
168         }
169         return macAddressOptional;
170     }
171
172     public static Optional<String> getMacAddressFromInterfaceState(Interface ifState) {
173         Optional<String> macAddressOptional = Optional.empty();
174         PhysAddress macAddress = ifState.getPhysAddress();
175         if (macAddress != null) {
176             macAddressOptional = Optional.of(macAddress.getValue());
177         }
178         return macAddressOptional;
179     }
180
181     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
182         .rev140508.interfaces.Interface> getInterfaceIdentifier(
183         String interfaceName) {
184         return InstanceIdentifier.builder(Interfaces.class)
185             .child(
186                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
187                     .Interface.class,
188                 new InterfaceKey(interfaceName)).build();
189     }
190
191     public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
192         /*
193          * NodeConnectorId is of form 'openflow:dpnid:portnum'
194          */
195         String[] split = portId.getValue().split(OF_URI_SEPARATOR);
196         return split[1];
197     }
198
199     public static Uint64 getDpIdFromInterface(
200         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
201             ifState) {
202         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
203         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
204         return Uint64.valueOf(getDpnFromNodeConnectorId(nodeConnectorId)).intern();
205     }
206
207     private static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
208             InstanceIdentifier<T> path) {
209         try {
210             return SingleTransactionDataBroker.syncReadOptional(broker, datastoreType, path);
211         } catch (ExecutionException | InterruptedException e) {
212             throw new RuntimeException(e);
213         }
214     }
215 }