Update MRI projects for Aluminium
[lispflowmapping.git] / mappingservice / neutron / src / main / java / org / opendaylight / lispflowmapping / neutron / intenthandler / util / VppNodeReader.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc.  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.lispflowmapping.neutron.intenthandler.util;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import com.google.common.util.concurrent.SettableFuture;
12 import java.util.Map;
13 import java.util.Optional;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.lispflowmapping.neutron.intenthandler.exception.RlocNotFoundOnVppNode;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.binding.api.MountPointService;
18 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.Loopback;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35
36 /**
37  * Created by Shakib Ahmed on 1/12/17.
38  */
39 public class VppNodeReader {
40     private static final Logger LOG = LoggerFactory.getLogger(VppNodeReader.class);
41
42     private final DataBroker dataBroker;
43     private final MountPointService mountService;
44
45     public VppNodeReader(DataBroker dataBroker, MountPointService mountService) {
46         this.dataBroker = dataBroker;
47         this.mountService = mountService;
48     }
49
50     public Ipv4Address rlocIpOfNode(KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifierToVppNode) {
51         try {
52             Optional<Ipv4Address> ipv4AddressOptional =
53                     readFirstAvailableIpOfVppNode(instanceIdentifierToVppNode).get();
54             if (!ipv4AddressOptional.isPresent()) {
55                 throw new RlocNotFoundOnVppNode(InfoUtil.node(instanceIdentifierToVppNode));
56             }
57
58             return ipv4AddressOptional.get();
59         } catch (final InterruptedException | ExecutionException ex) {
60             LOG.warn("Got exception while reading IP addresses from nodes {}",
61                     InfoUtil.node(instanceIdentifierToVppNode));
62             throw new RlocNotFoundOnVppNode(InfoUtil.node(instanceIdentifierToVppNode), ex);
63         }
64     }
65
66     private ListenableFuture<Optional<Ipv4Address>>
67         readFirstAvailableIpOfVppNode(final KeyedInstanceIdentifier<Node, NodeKey> instanceIdentifierToVppNode) {
68
69         final SettableFuture<Optional<Ipv4Address>> resultFuture = SettableFuture.create();
70
71         final DataBroker vppDataBroker = LispNeutronUtil.resolveDataBrokerForMountPoint(instanceIdentifierToVppNode,
72                 mountService);
73         if (vppDataBroker != null) {
74             final Optional<InterfacesState> interfacesOnVppNodeOptional = VppNetconfTrasaction.read(vppDataBroker,
75                     LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(InterfacesState.class));
76             if (interfacesOnVppNodeOptional.isPresent()) {
77
78                 for (Interface intf : interfacesOnVppNodeOptional.get().nonnullInterface().values()) {
79
80                     if (intf.getType().equals(Loopback.class)) {
81                         continue;
82                     }
83
84                     final Optional<Ipv4Address> ipv4AddressOptional = readIpAddressFromInterface(intf,
85                             instanceIdentifierToVppNode);
86
87                     if (ipv4AddressOptional.isPresent()) {
88                         resultFuture.set(ipv4AddressOptional);
89                         break;
90                     }
91                 }
92
93             }
94
95             resultFuture.set(Optional.empty());
96         } else {
97             LOG.debug("Data broker for vpp {} is missing.", instanceIdentifierToVppNode);
98         }
99         return resultFuture;
100     }
101
102     private Optional<Ipv4Address> readIpAddressFromInterface(Interface intf,
103                                                                    KeyedInstanceIdentifier iiToVpp) {
104         Interface2 augIntf = intf.augmentation(Interface2.class);
105
106         if (augIntf == null) {
107             LOG.debug("Cannot get Interface2 augmentation for intf {}");
108             return Optional.empty();
109         }
110
111         Ipv4 ipv4 = augIntf.getIpv4();
112
113         if (ipv4 == null) {
114             LOG.debug("Ipv4 address for interface {} on node {} is null!", augIntf, InfoUtil.node(iiToVpp));
115             return Optional.empty();
116         }
117
118         final Map<AddressKey, Address> addresses = ipv4.getAddress();
119         if (addresses == null || addresses.isEmpty()) {
120             LOG.debug("Ipv4 addresses list is empty for interface {} on node {}", augIntf, InfoUtil.node(iiToVpp));
121             return Optional.empty();
122         }
123
124         final Ipv4AddressNoZone ip = addresses.values().iterator().next().getIp();
125         if (ip == null) {
126             LOG.debug("Ipv4AddressNoZone is null for node {}", InfoUtil.node(iiToVpp));
127             return Optional.empty();
128         }
129
130         LOG.debug("Got ip address {} from interface {} on node {}", ip.getValue(), intf.getName(),
131                 InfoUtil.node(iiToVpp));
132         return Optional.of(ip);
133     }
134
135 }