Fix logs in how it should use exceptions.
[netvirt.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.controller.sal.core.Node;
15 import org.opendaylight.ovsdb.lib.notation.Row;
16 import org.opendaylight.ovsdb.lib.notation.UUID;
17 import org.opendaylight.ovsdb.openstack.netvirt.NodeConfiguration;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
20 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
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
25 import com.google.common.base.Preconditions;
26 import com.google.common.collect.Maps;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.util.Map;
31 import java.util.Set;
32
33 public class VlanConfigurationCacheImpl implements VlanConfigurationCache {
34     static final Logger logger = LoggerFactory.getLogger(VlanConfigurationCacheImpl.class);
35
36     private Map<String, NodeConfiguration> configurationCache = Maps.newConcurrentMap();
37
38     private volatile TenantNetworkManager tenantNetworkManager;
39     private volatile OvsdbConfigurationService ovsdbConfigurationService;
40
41     private NodeConfiguration getNodeConfiguration(Node node){
42         String nodeUuid = getNodeUUID(node);
43         if (configurationCache.get(nodeUuid) != null) {
44             return configurationCache.get(nodeUuid);
45         }
46
47         // Cache miss
48         initializeNodeConfiguration(nodeUuid, node);
49
50         return configurationCache.get(nodeUuid);
51     }
52
53     private String getNodeUUID(Node node) {
54         Preconditions.checkNotNull(ovsdbConfigurationService);
55         String nodeUuid = new String();
56         try {
57             Map<String, Row> ovsTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, OpenVSwitch.class));
58             nodeUuid = (String)ovsTable.keySet().toArray()[0];
59         }
60         catch (Exception e) {
61             logger.error("Unable to get the Open_vSwitch table for Node {}", node, e);
62         }
63
64         return nodeUuid;
65     }
66
67     private void initializeNodeConfiguration(String nodeUuid, Node node) {
68
69         NodeConfiguration nodeConfiguration = new NodeConfiguration();
70         Integer vlan;
71         String networkId = null;
72
73         try {
74             Map<String, Row> portRows = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Port.class));
75
76             if (portRows == null){
77                 logger.debug("Port table is null for Node {}", node);
78                 return;
79             }
80
81             for (Row row : portRows.values()) {
82                 Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, row);
83
84                 if (port.getTagColumn() == null) continue;
85                 Set<Long> tags = port.getTagColumn().getData();
86                 if (tags.size() == 1)
87                 {
88                     //There is only one tag here
89                     vlan = tags.iterator().next().intValue();
90                 }
91                 else {
92                    logger.debug("This port ({}) has {} tags", port.getName(), tags.size());
93                    continue;
94                 }
95
96                 for (UUID ifaceId : port.getInterfacesColumn().getData()) {
97                     Row ifaceRow = ovsdbConfigurationService
98                             .getRow(node, ovsdbConfigurationService.getTableName(node, Interface.class),
99                                     ifaceId.toString());
100                     Interface iface = ovsdbConfigurationService.getTypedRow(node, Interface.class, ifaceRow);
101
102                     if (iface == null) {
103                         logger.debug("Interface table is null");
104                         continue;
105                     }
106
107                     networkId = tenantNetworkManager.getTenantNetwork(iface).getNetworkUUID();
108
109                     if (networkId != null) break;
110                 }
111
112                 if (vlan != 0 && networkId != null) {
113
114                     this.internalVlanInUse(nodeConfiguration, vlan);
115                     nodeConfiguration.getTenantVlanMap().put(networkId, vlan);
116
117                 } else {
118                     logger.debug("Node: {} initialized without a vlan", node);
119                 }
120             }
121
122             configurationCache.put(nodeUuid, nodeConfiguration);
123         }
124         catch (Exception e) {
125             logger.debug("Error getting Port table for Node {}", node, e);
126         }
127     }
128
129     /*
130      * Return the currently mapped internal vlan or get the next
131      * free internal vlan from the available pool and map it to the networkId.
132      */
133     @Override
134     public Integer assignInternalVlan (Node node, String networkId) {
135         NodeConfiguration nodeConfiguration = getNodeConfiguration(node);
136         Integer mappedVlan = nodeConfiguration.getTenantVlanMap().get(networkId);
137         if (mappedVlan != null) {
138             return mappedVlan;
139         }
140         mappedVlan = nodeConfiguration.getInternalVlans().poll();
141         if (mappedVlan != null) {
142             nodeConfiguration.getTenantVlanMap().put(networkId, mappedVlan);
143         }
144         return mappedVlan;
145     }
146
147     /*
148      * Return the mapped internal vlan to the available pool.
149      */
150     @Override
151     public Integer reclaimInternalVlan (Node node, String networkId) {
152         NodeConfiguration nodeConfiguration = getNodeConfiguration(node);
153         Integer mappedVlan = nodeConfiguration.getTenantVlanMap().get(networkId);
154         if (mappedVlan != null) {
155             nodeConfiguration.getTenantVlanMap().remove(networkId);
156             nodeConfiguration.getInternalVlans().add(mappedVlan);
157             return mappedVlan;
158         }
159         return 0;
160     }
161
162     private void internalVlanInUse (NodeConfiguration nodeConfiguration, Integer vlan) {
163         nodeConfiguration.getInternalVlans().remove(vlan);
164     }
165
166     @Override
167     public Integer getInternalVlan (Node node, String networkId) {
168         NodeConfiguration nodeConfiguration = getNodeConfiguration(node);
169         Integer vlan = nodeConfiguration.getTenantVlanMap().get(networkId);
170         if (vlan == null) return 0;
171         return vlan;
172     }
173
174 }