MRI version bump for Aluminium
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / rpcservice / InterfaceManagerServiceImpl.java
1 /*
2  * Copyright (c) 2016, 2017 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.genius.interfacemanager.rpcservice;
9
10 import com.google.common.util.concurrent.Futures;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Optional;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.apache.aries.blueprint.annotation.service.Reference;
20 import org.opendaylight.genius.interfacemanager.IfmUtil;
21 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
22 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
23 import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
24 import org.opendaylight.genius.interfacemanager.listeners.IfIndexInterfaceCache;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
27 import org.opendaylight.mdsal.common.api.ReadFailedException;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntryKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterface;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutputBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpnInterfaceListInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpnInterfaceListOutput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpnInterfaceListOutputBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceOutput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressInstructionsForInterfaceOutputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEndpointIpForDpnOutputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexOutput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexOutputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceTypeOutputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetNodeconnectorIdFromInterfaceOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetTunnelTypeInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetTunnelTypeOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetTunnelTypeOutputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.get.dpn._interface.list.output.Interfaces;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.get.dpn._interface.list.output.InterfacesBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
78 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
79 import org.opendaylight.yangtools.yang.common.Uint64;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82
83 @Singleton
84 public class InterfaceManagerServiceImpl implements InterfaceManagerService {
85
86     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerServiceImpl.class);
87
88     private final DataBroker dataBroker;
89     private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
90     private final InterfaceMetaUtils interfaceMetaUtils;
91     private final IfIndexInterfaceCache ifIndexInterfaceCache;
92
93     @Inject
94     public InterfaceManagerServiceImpl(@Reference final DataBroker dataBroker,
95             final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
96             final InterfaceMetaUtils interfaceMetaUtils, final IfIndexInterfaceCache ifIndexInterfaceCache) {
97         this.dataBroker = dataBroker;
98         this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
99         this.interfaceMetaUtils = interfaceMetaUtils;
100         this.ifIndexInterfaceCache = ifIndexInterfaceCache;
101     }
102
103     @Override
104     public ListenableFuture<GetDpidFromInterfaceOutput> getDpidFromInterface(GetDpidFromInterfaceInput input) {
105         String interfaceName = input.getIntfName();
106         Uint64 dpId;
107         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
108         Interface interfaceInfo = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey);
109         if (interfaceInfo == null) {
110             throw new IllegalArgumentException(
111                     getDpidFromInterfaceErrorMessage(interfaceName, "missing Interface in Config DataStore"));
112         }
113         if (Tunnel.class.equals(interfaceInfo.getType())) {
114             ParentRefs parentRefs = interfaceInfo.augmentation(ParentRefs.class);
115             dpId = parentRefs.getDatapathNodeIdentifier();
116         } else {
117             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
118                 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
119                     .getInterfaceState(interfaceName);
120             if (ifState != null) {
121                 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
122                 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
123                 dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
124             } else {
125                 throw new IllegalArgumentException(
126                         getDpidFromInterfaceErrorMessage(interfaceName, "missing Interface-state"));
127             }
128         }
129         return Futures.immediateFuture(new GetDpidFromInterfaceOutputBuilder().setDpid(dpId).build());
130     }
131
132     private String getDpidFromInterfaceErrorMessage(final String interfaceName, final String dueTo) {
133         return String.format("Retrieval of datapath id for the key {%s} failed due to %s",
134                 interfaceName, dueTo);
135     }
136
137     @Override
138     public ListenableFuture<GetEndpointIpForDpnOutput> getEndpointIpForDpn(GetEndpointIpForDpnInput input) {
139         BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(input.getDpid());
140         InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier = InterfaceMetaUtils
141                 .getBridgeEntryIdentifier(bridgeEntryKey);
142         BridgeEntry bridgeEntry = interfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier);
143         // local ip of any of the bridge interface entry will be the dpn end
144         // point ip
145         BridgeInterfaceEntry bridgeInterfaceEntry = bridgeEntry.getBridgeInterfaceEntry().values().iterator().next();
146         InterfaceKey interfaceKey = new InterfaceKey(bridgeInterfaceEntry.getInterfaceName());
147         Interface interfaceInfo = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey);
148         IfTunnel tunnel = interfaceInfo.augmentation(IfTunnel.class);
149         return Futures.immediateFuture(new GetEndpointIpForDpnOutputBuilder()
150                 .setLocalIps(Collections.singletonList(tunnel.getTunnelSource())).build());
151     }
152
153     @Override
154     public ListenableFuture<GetEgressInstructionsForInterfaceOutput> getEgressInstructionsForInterface(
155             GetEgressInstructionsForInterfaceInput input) {
156         List<Instruction> instructions = IfmUtil.getEgressInstructionsForInterface(input.getIntfName(),
157                 input.getTunnelKey() != null ? input.getTunnelKey().toJava() : null,
158                 interfaceManagerCommonUtils, false);
159         return Futures.immediateFuture(
160                 new GetEgressInstructionsForInterfaceOutputBuilder().setInstruction(instructions).build());
161     }
162
163     @Override
164     public ListenableFuture<GetInterfaceTypeOutput> getInterfaceType(GetInterfaceTypeInput input) {
165         String interfaceName = input.getIntfName();
166         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
167         Interface interfaceInfo = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey);
168         if (interfaceInfo == null) {
169             throw new IllegalStateException(String.format("getInterfaceType() Retrieval of Interface Type for "
170                     + "the key {%s} failed due to missing Interface in Config DataStore", interfaceName));
171         }
172         return Futures.immediateFuture(
173                 new GetInterfaceTypeOutputBuilder().setInterfaceType(interfaceInfo.getType()).build());
174     }
175
176     @Override
177     public ListenableFuture<GetTunnelTypeOutput> getTunnelType(GetTunnelTypeInput input) {
178         String interfaceName = input.getIntfName();
179         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
180         Interface interfaceInfo = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey);
181         if (interfaceInfo == null) {
182             throw new IllegalArgumentException(String.format(
183                     "Retrieval of Tunnel Type for the key {%s} failed due to missing Interface in Config DataStore",
184                     interfaceName));
185         }
186         if (Tunnel.class.equals(interfaceInfo.getType())) {
187             IfTunnel tnl = interfaceInfo.augmentation(IfTunnel.class);
188             Class<? extends TunnelTypeBase> tunType = tnl.getTunnelInterfaceType();
189             return Futures.immediateFuture(new GetTunnelTypeOutputBuilder().setTunnelType(tunType).build());
190         } else {
191             throw new IllegalArgumentException("Retrieval of interface type failed for key: " + interfaceName);
192         }
193     }
194
195     @Override
196     public ListenableFuture<GetEgressActionsForInterfaceOutput> getEgressActionsForInterface(
197             GetEgressActionsForInterfaceInput input) {
198         List<Action> actionsList = IfmUtil.getEgressActionsForInterface(input.getIntfName(),
199                 input.getTunnelKey() != null ? input.getTunnelKey().toJava() : null,
200                 input.getActionKey(), interfaceManagerCommonUtils, false);
201         // TODO as above, simplify the success case later, as we have the failure case below
202         return Futures
203                 .immediateFuture(new GetEgressActionsForInterfaceOutputBuilder().setAction(actionsList).build());
204     }
205
206     @Override
207     public ListenableFuture<GetPortFromInterfaceOutput> getPortFromInterface(GetPortFromInterfaceInput input) {
208         String interfaceName = input.getIntfName();
209         Uint64 dpId = null;
210         long portNo = 0;
211         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
212             .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
213                 .getInterfaceState(interfaceName);
214         if (ifState != null) {
215             String lowerLayerIf = ifState.getLowerLayerIf().get(0);
216             NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
217             dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
218             portNo = IfmUtil.getPortNumberFromNodeConnectorId(nodeConnectorId);
219             String phyAddress = ifState.getPhysAddress().getValue();
220             // FIXME Assuming portName and interfaceName are same
221             // TODO as above, simplify the success case later, as we have the failure case below
222             return Futures.immediateFuture(new GetPortFromInterfaceOutputBuilder().setDpid(dpId)
223                     .setPortname(interfaceName).setPortno(portNo).setPhyAddress(phyAddress).build());
224         } else {
225             throw new IllegalArgumentException(
226                     "Retrieval of Port for the key " + interfaceName + " failed due to missing Interface state");
227         }
228     }
229
230     @Override
231     public ListenableFuture<GetNodeconnectorIdFromInterfaceOutput> getNodeconnectorIdFromInterface(
232             GetNodeconnectorIdFromInterfaceInput input) {
233         String interfaceName = input.getIntfName();
234         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
235             .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
236                 .getInterfaceState(interfaceName);
237         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
238         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
239         // TODO as above, simplify the success case later, as we have the failure case below
240         return Futures.immediateFuture(
241                 new GetNodeconnectorIdFromInterfaceOutputBuilder().setNodeconnectorId(nodeConnectorId).build());
242     }
243
244     @Override
245     public ListenableFuture<GetInterfaceFromIfIndexOutput> getInterfaceFromIfIndex(
246             GetInterfaceFromIfIndexInput input) {
247         Integer ifIndex = input.getIfIndex();
248         Optional<IfIndexInterface> ifIndexesInterface;
249         try {
250             ifIndexesInterface = ifIndexInterfaceCache.get(ifIndex);
251         } catch (ReadFailedException e) {
252             return Futures.immediateFailedFuture(e);
253         }
254
255         if (!ifIndexesInterface.isPresent()) {
256             return Futures.immediateFailedFuture(new IllegalArgumentException(
257                     "Could not find " + ifIndex + " in OperationalDS"));
258         }
259         String interfaceName = ifIndexesInterface.get().getInterfaceName();
260         // TODO as above, simplify the success case later, as we have the failure case below
261         return Futures.immediateFuture(
262                 new GetInterfaceFromIfIndexOutputBuilder().setInterfaceName(interfaceName).build());
263     }
264
265     @Override
266     public ListenableFuture<GetDpnInterfaceListOutput> getDpnInterfaceList(GetDpnInterfaceListInput input) {
267         Uint64 dpnid = input.getDpid();
268         InstanceIdentifier<DpnToInterface> id = InstanceIdentifier.builder(DpnToInterfaceList.class)
269                 .child(DpnToInterface.class, new DpnToInterfaceKey(dpnid)).build();
270         Optional<DpnToInterface> entry = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, dataBroker);
271         if (!entry.isPresent()) {
272             LOG.warn("Could not find Operational DpnToInterface info for DPN {}. Returning empty list", dpnid);
273             return buildEmptyInterfaceListResult();
274         }
275         Map<InterfaceNameEntryKey, InterfaceNameEntry> interfaceNameEntries = entry.get().getInterfaceNameEntry();
276
277         if (interfaceNameEntries == null || interfaceNameEntries.isEmpty()) {
278             LOG.debug("No Interface list found in Operational for DPN {}", dpnid);
279             return buildEmptyInterfaceListResult();
280         }
281         List<Interfaces> interfaceList = new ArrayList<>();
282         interfaceNameEntries.values().forEach(
283             (interfaceNameEntry) -> {
284                 InterfacesBuilder intf = new InterfacesBuilder()
285                     .setInterfaceName(interfaceNameEntry.getInterfaceName())
286                     .setInterfaceType(interfaceNameEntry.getInterfaceType());
287                 interfaceList.add(intf.build());
288             });
289         // TODO as above, simplify the success case later, as we have the failure case below
290         return Futures
291                 .immediateFuture(new GetDpnInterfaceListOutputBuilder().setInterfaces(interfaceList).build());
292     }
293
294     private ListenableFuture<GetDpnInterfaceListOutput> buildEmptyInterfaceListResult() {
295         GetDpnInterfaceListOutput emptyListResult =
296             new GetDpnInterfaceListOutputBuilder().setInterfaces(Collections.emptyList()).build();
297         return Futures.immediateFuture(emptyListResult);
298     }
299 }