2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.interfacemanager.rpcservice;
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;
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;
84 public class InterfaceManagerServiceImpl implements InterfaceManagerService {
86 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerServiceImpl.class);
88 private final DataBroker dataBroker;
89 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
90 private final InterfaceMetaUtils interfaceMetaUtils;
91 private final IfIndexInterfaceCache ifIndexInterfaceCache;
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;
104 public ListenableFuture<GetDpidFromInterfaceOutput> getDpidFromInterface(GetDpidFromInterfaceInput input) {
105 String interfaceName = input.getIntfName();
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"));
113 if (Tunnel.class.equals(interfaceInfo.getType())) {
114 ParentRefs parentRefs = interfaceInfo.augmentation(ParentRefs.class);
115 dpId = parentRefs.getDatapathNodeIdentifier();
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);
125 throw new IllegalArgumentException(
126 getDpidFromInterfaceErrorMessage(interfaceName, "missing Interface-state"));
129 return Futures.immediateFuture(new GetDpidFromInterfaceOutputBuilder().setDpid(dpId).build());
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);
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
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());
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());
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));
172 return Futures.immediateFuture(
173 new GetInterfaceTypeOutputBuilder().setInterfaceType(interfaceInfo.getType()).build());
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",
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());
191 throw new IllegalArgumentException("Retrieval of interface type failed for key: " + interfaceName);
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
203 .immediateFuture(new GetEgressActionsForInterfaceOutputBuilder().setAction(actionsList).build());
207 public ListenableFuture<GetPortFromInterfaceOutput> getPortFromInterface(GetPortFromInterfaceInput input) {
208 String interfaceName = input.getIntfName();
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());
225 throw new IllegalArgumentException(
226 "Retrieval of Port for the key " + interfaceName + " failed due to missing Interface state");
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());
245 public ListenableFuture<GetInterfaceFromIfIndexOutput> getInterfaceFromIfIndex(
246 GetInterfaceFromIfIndexInput input) {
247 Integer ifIndex = input.getIfIndex();
248 Optional<IfIndexInterface> ifIndexesInterface;
250 ifIndexesInterface = ifIndexInterfaceCache.get(ifIndex);
251 } catch (ReadFailedException e) {
252 return Futures.immediateFailedFuture(e);
255 if (!ifIndexesInterface.isPresent()) {
256 return Futures.immediateFailedFuture(new IllegalArgumentException(
257 "Could not find " + ifIndex + " in OperationalDS"));
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());
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();
275 Map<InterfaceNameEntryKey, InterfaceNameEntry> interfaceNameEntries = entry.get().getInterfaceNameEntry();
277 if (interfaceNameEntries == null || interfaceNameEntries.isEmpty()) {
278 LOG.debug("No Interface list found in Operational for DPN {}", dpnid);
279 return buildEmptyInterfaceListResult();
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());
289 // TODO as above, simplify the success case later, as we have the failure case below
291 .immediateFuture(new GetDpnInterfaceListOutputBuilder().setInterfaces(interfaceList).build());
294 private ListenableFuture<GetDpnInterfaceListOutput> buildEmptyInterfaceListResult() {
295 GetDpnInterfaceListOutput emptyListResult =
296 new GetDpnInterfaceListOutputBuilder().setInterfaces(Collections.emptyList()).build();
297 return Futures.immediateFuture(emptyListResult);