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;
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;
82 public class InterfaceManagerServiceImpl implements InterfaceManagerService {
84 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerServiceImpl.class);
86 private final DataBroker dataBroker;
87 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
88 private final InterfaceMetaUtils interfaceMetaUtils;
89 private final IfIndexInterfaceCache ifIndexInterfaceCache;
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;
102 public ListenableFuture<GetDpidFromInterfaceOutput> getDpidFromInterface(GetDpidFromInterfaceInput input) {
103 String interfaceName = input.getIntfName();
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"));
111 if (Tunnel.class.equals(interfaceInfo.getType())) {
112 ParentRefs parentRefs = interfaceInfo.augmentation(ParentRefs.class);
113 dpId = parentRefs.getDatapathNodeIdentifier();
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);
123 throw new IllegalArgumentException(
124 getDpidFromInterfaceErrorMessage(interfaceName, "missing Interface-state"));
127 return Futures.immediateFuture(new GetDpidFromInterfaceOutputBuilder().setDpid(dpId).build());
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);
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
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());
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());
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));
170 return Futures.immediateFuture(
171 new GetInterfaceTypeOutputBuilder().setInterfaceType(interfaceInfo.getType()).build());
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",
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());
189 throw new IllegalArgumentException("Retrieval of interface type failed for key: " + interfaceName);
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
201 .immediateFuture(new GetEgressActionsForInterfaceOutputBuilder().setAction(actionsList).build());
205 public ListenableFuture<GetPortFromInterfaceOutput> getPortFromInterface(GetPortFromInterfaceInput input) {
206 String interfaceName = input.getIntfName();
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());
223 throw new IllegalArgumentException(
224 "Retrieval of Port for the key " + interfaceName + " failed due to missing Interface state");
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());
243 public ListenableFuture<GetInterfaceFromIfIndexOutput> getInterfaceFromIfIndex(
244 GetInterfaceFromIfIndexInput input) {
245 Integer ifIndex = input.getIfIndex();
246 Optional<IfIndexInterface> ifIndexesInterface;
248 ifIndexesInterface = ifIndexInterfaceCache.get(ifIndex);
249 } catch (ReadFailedException e) {
250 return Futures.immediateFailedFuture(e);
253 if (!ifIndexesInterface.isPresent()) {
254 return Futures.immediateFailedFuture(new IllegalArgumentException(
255 "Could not find " + ifIndex + " in OperationalDS"));
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());
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();
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();
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());
287 // TODO as above, simplify the success case later, as we have the failure case below
289 .immediateFuture(new GetDpnInterfaceListOutputBuilder().setInterfaces(interfaceList).build());
292 private ListenableFuture<GetDpnInterfaceListOutput> buildEmptyInterfaceListResult() {
293 GetDpnInterfaceListOutput emptyListResult =
294 new GetDpnInterfaceListOutputBuilder().setInterfaces(Collections.emptyList()).build();
295 return Futures.immediateFuture(emptyListResult);