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