Use Topology Node in place of Inventory Node
[ovsdb.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / impl / VlanConfigurationCacheImpl.java
1 /*
2  * Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Authors: Dave Tucker
10 */
11
12 package org.opendaylight.ovsdb.openstack.netvirt.impl;
13
14 import org.opendaylight.ovsdb.lib.notation.Row;
15 import org.opendaylight.ovsdb.lib.notation.UUID;
16 import org.opendaylight.ovsdb.openstack.netvirt.NodeConfiguration;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.MdsalConsumer;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbConfigurationService;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
21 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
22 import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
23 import org.opendaylight.ovsdb.schema.openvswitch.Port;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
25
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.Maps;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import java.util.Map;
32 import java.util.Set;
33
34 public class VlanConfigurationCacheImpl implements VlanConfigurationCache {
35     static final Logger logger = LoggerFactory.getLogger(VlanConfigurationCacheImpl.class);
36
37     private Map<String, NodeConfiguration> configurationCache = Maps.newConcurrentMap();
38
39     private volatile TenantNetworkManager tenantNetworkManager;
40     /* TODO SB_MIGRATION */
41     private volatile OvsdbConfigurationService ovsdbConfigurationService;
42
43     private NodeConfiguration getNodeConfiguration(Node node){
44         String nodeUuid = getNodeUUID(node);
45         if (configurationCache.get(nodeUuid) != null) {
46             return configurationCache.get(nodeUuid);
47         }
48
49         // Cache miss
50         initializeNodeConfiguration(nodeUuid, node);
51
52         return configurationCache.get(nodeUuid);
53     }
54
55     private String getNodeUUID(Node node) {
56         //String nodeUuid = mdsalConsumer.getNodeUUID(node);
57         /* TODO SB_MIGRATION */
58         Preconditions.checkNotNull(ovsdbConfigurationService);
59         String nodeUuid = new String();
60
61         try {
62             Map<String, Row> ovsTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
63             nodeUuid = (String)ovsTable.keySet().toArray()[0];
64         }
65         catch (Exception e) {
66             logger.error("Unable to get the Open_vSwitch table for Node {}", node, e);
67         }
68
69         return nodeUuid;
70     }
71
72     private void initializeNodeConfiguration(String nodeUuid, Node node) {
73         /* TODO SB_MIGRATION */
74         NodeConfiguration nodeConfiguration = new NodeConfiguration();
75         Integer vlan;
76         String networkId = null;
77
78         try {
79             Map<String, Row> portRows = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Port.class));
80
81             if (portRows == null){
82                 logger.debug("Port table is null for Node {}", node);
83                 return;
84             }
85
86             for (Row row : portRows.values()) {
87                 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, row);
88
89                 if (port.getTagColumn() == null) continue;
90                 Set<Long> tags = port.getTagColumn().getData();
91                 if (tags.size() == 1)
92                 {
93                     //There is only one tag here
94                     vlan = tags.iterator().next().intValue();
95                 }
96                 else {
97                    logger.debug("This port ({}) has {} tags", port.getName(), tags.size());
98                    continue;
99                 }
100
101                 for (UUID ifaceId : port.getInterfacesColumn().getData()) {
102                     Row ifaceRow = ovsdbConfigurationService
103                             .getRow(node, ovsdbConfigurationService.getTableName(node, Interface.class),
104                                     ifaceId.toString());
105                     Interface iface = ovsdbConfigurationService.getTypedRow(node, Interface.class, ifaceRow);
106
107                     if (iface == null) {
108                         logger.debug("Interface table is null");
109                         continue;
110                     }
111
112                     networkId = tenantNetworkManager.getTenantNetwork(iface).getNetworkUUID();
113
114                     if (networkId != null) break;
115                 }
116
117                 if (vlan != 0 && networkId != null) {
118
119                     this.internalVlanInUse(nodeConfiguration, vlan);
120                     nodeConfiguration.getTenantVlanMap().put(networkId, vlan);
121
122                 } else {
123                     logger.debug("Node: {} initialized without a vlan", node);
124                 }
125             }
126
127             configurationCache.put(nodeUuid, nodeConfiguration);
128         }
129         catch (Exception e) {
130             logger.debug("Error getting Port table for Node {}", node, e);
131         }
132     }
133
134     /*
135      * Return the currently mapped internal vlan or get the next
136      * free internal vlan from the available pool and map it to the networkId.
137      */
138     @Override
139     public Integer assignInternalVlan (Node node, String networkId) {
140         NodeConfiguration nodeConfiguration = getNodeConfiguration(node);
141         Integer mappedVlan = nodeConfiguration.getTenantVlanMap().get(networkId);
142         if (mappedVlan != null) {
143             return mappedVlan;
144         }
145         mappedVlan = nodeConfiguration.getInternalVlans().poll();
146         if (mappedVlan != null) {
147             nodeConfiguration.getTenantVlanMap().put(networkId, mappedVlan);
148         }
149         return mappedVlan;
150     }
151
152     /*
153      * Return the mapped internal vlan to the available pool.
154      */
155     @Override
156     public Integer reclaimInternalVlan (Node node, String networkId) {
157         NodeConfiguration nodeConfiguration = getNodeConfiguration(node);
158         Integer mappedVlan = nodeConfiguration.getTenantVlanMap().get(networkId);
159         if (mappedVlan != null) {
160             nodeConfiguration.getTenantVlanMap().remove(networkId);
161             nodeConfiguration.getInternalVlans().add(mappedVlan);
162             return mappedVlan;
163         }
164         return 0;
165     }
166
167     private void internalVlanInUse (NodeConfiguration nodeConfiguration, Integer vlan) {
168         nodeConfiguration.getInternalVlans().remove(vlan);
169     }
170
171     @Override
172     public Integer getInternalVlan (Node node, String networkId) {
173         NodeConfiguration nodeConfiguration = getNodeConfiguration(node);
174         Integer vlan = nodeConfiguration.getTenantVlanMap().get(networkId);
175         if (vlan == null) return 0;
176         return vlan;
177     }
178
179 }