2 * Copyright (c) 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.ovsdb.hwvtepsouthbound;
10 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
12 import com.google.common.collect.Lists;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.Optional;
20 import java.util.concurrent.ExecutionException;
21 import java.util.function.Function;
22 import java.util.stream.Collectors;
23 import org.opendaylight.ovsdb.lib.message.TableUpdate;
24 import org.opendaylight.ovsdb.lib.message.TableUpdates;
25 import org.opendaylight.ovsdb.lib.notation.Condition;
26 import org.opendaylight.ovsdb.lib.notation.Row;
27 import org.opendaylight.ovsdb.lib.notation.UUID;
28 import org.opendaylight.ovsdb.lib.operations.Operation;
29 import org.opendaylight.ovsdb.lib.operations.OperationResult;
30 import org.opendaylight.ovsdb.lib.operations.Select;
31 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
32 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
33 import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
34 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
35 import org.opendaylight.ovsdb.schema.hardwarevtep.ACL;
36 import org.opendaylight.ovsdb.schema.hardwarevtep.ACLEntry;
37 import org.opendaylight.ovsdb.schema.hardwarevtep.ArpSourcesLocal;
38 import org.opendaylight.ovsdb.schema.hardwarevtep.ArpSourcesRemote;
39 import org.opendaylight.ovsdb.schema.hardwarevtep.Global;
40 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalRouter;
41 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
42 import org.opendaylight.ovsdb.schema.hardwarevtep.Manager;
43 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsLocal;
44 import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
45 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocator;
46 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalLocatorSet;
47 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
48 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
49 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
50 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsLocal;
51 import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
56 import org.opendaylight.yangtools.yang.binding.Identifiable;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
61 public class HwvtepTableReader {
63 private static final Logger LOG = LoggerFactory.getLogger(HwvtepTableReader.class);
65 private final Class[] alltables = new Class[] {
68 ArpSourcesLocal.class,
70 ArpSourcesRemote.class,
75 PhysicalLocator.class,
76 McastMacsRemote.class,
79 PhysicalLocatorSet.class,
85 private final Map<Class, Function<InstanceIdentifier, List<Condition>>> whereClauseGetterMap = new HashMap();
86 private final Map<Class, Class> tableMap = new HashMap();
87 private final Map<Class, TypedBaseTable> tables = new HashMap<>();
89 private final HwvtepConnectionInstance connectionInstance;
91 public HwvtepTableReader(HwvtepConnectionInstance connectionInstance) {
92 this.connectionInstance = connectionInstance;
93 DatabaseSchema dbSchema = null;
95 dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.HARDWARE_VTEP).get();
96 } catch (InterruptedException | ExecutionException e) {
97 LOG.warn("Not able to fetch schema for database {} from device {}",
98 HwvtepSchemaConstants.HARDWARE_VTEP, connectionInstance.getConnectionInfo(), e);
101 tableMap.put(RemoteMcastMacs.class, McastMacsRemote.class);
102 tableMap.put(RemoteUcastMacs.class, UcastMacsRemote.class);
103 tableMap.put(LogicalSwitches.class, LogicalSwitch.class);
104 tableMap.put(TerminationPoint.class, PhysicalLocator.class);
106 whereClauseGetterMap.put(RemoteMcastMacs.class, new RemoteMcastMacWhereClauseGetter());
107 whereClauseGetterMap.put(RemoteUcastMacs.class, new RemoteUcastMacWhereClauseGetter());
108 whereClauseGetterMap.put(LogicalSwitches.class, new LogicalSwitchWhereClauseGetter());
109 whereClauseGetterMap.put(TerminationPoint.class, new LocatorWhereClauseGetter());
111 tables.put(McastMacsRemote.class, TyperUtils.getTypedRowWrapper(dbSchema, McastMacsRemote.class, null));
112 tables.put(UcastMacsRemote.class, TyperUtils.getTypedRowWrapper(dbSchema, UcastMacsRemote.class, null));
113 tables.put(LogicalSwitch.class, TyperUtils.getTypedRowWrapper(dbSchema, LogicalSwitch.class, null));
114 tables.put(PhysicalLocator.class, TyperUtils.getTypedRowWrapper(dbSchema, PhysicalLocator.class, null));
117 class RemoteMcastMacWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
119 public List<Condition> apply(InstanceIdentifier iid) {
120 InstanceIdentifier<RemoteMcastMacs> macIid = iid;
121 String mac = macIid.firstKeyOf(RemoteMcastMacs.class).getMacEntryKey().getValue();
122 InstanceIdentifier<LogicalSwitches> lsIid = (InstanceIdentifier<LogicalSwitches>) macIid.firstKeyOf(
123 RemoteMcastMacs.class).getLogicalSwitchRef().getValue();
124 UUID lsUUID = connectionInstance.getDeviceInfo().getUUID(LogicalSwitches.class, lsIid);
125 if (lsUUID == null) {
126 LOG.error("Could not find uuid for ls key {}", lsIid);
130 McastMacsRemote macTable = (McastMacsRemote) tables.get(McastMacsRemote.class);
131 ArrayList<Condition> conditions = new ArrayList<>();
132 conditions.add(macTable.getLogicalSwitchColumn().getSchema().opEqual(lsUUID));
133 conditions.add(macTable.getMacColumn().getSchema().opEqual(mac));
138 class RemoteUcastMacWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
140 public List<Condition> apply(InstanceIdentifier iid) {
141 InstanceIdentifier<RemoteUcastMacs> macIid = iid;
142 String mac = macIid.firstKeyOf(RemoteUcastMacs.class).getMacEntryKey().getValue();
143 InstanceIdentifier<LogicalSwitches> lsIid = (InstanceIdentifier<LogicalSwitches>) macIid.firstKeyOf(
144 RemoteUcastMacs.class).getLogicalSwitchRef().getValue();
145 UUID lsUUID = connectionInstance.getDeviceInfo().getUUID(LogicalSwitches.class, lsIid);
146 if (lsUUID == null) {
147 LOG.error("Could not find uuid for ls key {}", lsIid);
151 UcastMacsRemote macTable = (UcastMacsRemote) tables.get(UcastMacsRemote.class);
152 ArrayList<Condition> conditions = new ArrayList<>();
153 conditions.add(macTable.getLogicalSwitchColumn().getSchema().opEqual(lsUUID));
154 conditions.add(macTable.getMacColumn().getSchema().opEqual(mac));
159 class LogicalSwitchWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
161 public List<Condition> apply(InstanceIdentifier iid) {
162 InstanceIdentifier<LogicalSwitches> lsIid = iid;
163 String lsName = lsIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue();
164 LogicalSwitch logicalSwitch = (LogicalSwitch) tables.get(LogicalSwitch.class);
165 return Lists.newArrayList(logicalSwitch.getNameColumn().getSchema().opEqual(lsName));
169 class LocatorWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
171 public List<Condition> apply(InstanceIdentifier iid) {
172 InstanceIdentifier<TerminationPoint> tepIid = iid;
173 String locatorIp = tepIid.firstKeyOf(TerminationPoint.class).getTpId().getValue();
174 locatorIp = locatorIp.substring(locatorIp.indexOf(":") + 1);
175 LOG.info("Locator ip to look for {}", locatorIp);
176 PhysicalLocator locatorTable = (PhysicalLocator) tables.get(PhysicalLocator.class);
177 return Lists.newArrayList(locatorTable.getDstIpColumn().getSchema().opEqual(locatorIp));
181 @SuppressWarnings("checkstyle:IllegalCatch")
182 public Optional<TypedBaseTable> getHwvtepTableEntryUUID(Class<? extends Identifiable> cls,
183 InstanceIdentifier iid,
186 DatabaseSchema dbSchema = null;
187 TypedBaseTable globalRow = null;
188 Class<TypedBaseTable> tableClass = tableMap.get(cls);
190 dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.HARDWARE_VTEP).get();
191 } catch (InterruptedException | ExecutionException e) {
192 LOG.warn("Not able to fetch schema for database {} from device {}",
193 HwvtepSchemaConstants.HARDWARE_VTEP, connectionInstance.getConnectionInfo(), e);
196 if (dbSchema != null) {
197 GenericTableSchema hwvtepSchema = TyperUtils.getTableSchema(dbSchema, tableClass);
199 List<String> hwvtepTableColumn = new ArrayList<>();
200 hwvtepTableColumn.addAll(hwvtepSchema.getColumns());
201 Select<GenericTableSchema> selectOperation = op.select(hwvtepSchema);
202 selectOperation.setColumns(hwvtepTableColumn);
204 if (existingUUID != null) {
205 TypedBaseTable table = tables.get(tableClass);
206 LOG.info("Setting uuid condition {} ", existingUUID);
207 selectOperation.where(table.getUuidColumn().getSchema().opEqual(existingUUID));
209 if (whereClauseGetterMap.get(cls) != null) {
210 List<Condition> conditions = whereClauseGetterMap.get(cls).apply(iid);
211 if (conditions != null) {
212 if (conditions.size() == 2) {
213 selectOperation.where(conditions.get(0)).and(conditions.get(1));
215 selectOperation.where(conditions.get(0));
218 LOG.error("Could not get where conditions for cls {} key {}", cls, iid);
219 return Optional.empty();
222 LOG.error("Could not get where class for cls {} ", cls);
223 return Optional.empty();
226 ArrayList<Operation> operations = new ArrayList<>();
227 operations.add(selectOperation);
229 List<OperationResult> results = connectionInstance.transact(dbSchema, operations).get();
230 if (results != null && !results.isEmpty()) {
231 OperationResult selectResult = results.get(0);
232 if (selectResult.getRows() != null && !selectResult.getRows().isEmpty()) {
233 globalRow = TyperUtils.getTypedRowWrapper(
234 dbSchema, tableClass, selectResult.getRows().get(0));
237 } catch (InterruptedException | ExecutionException e) {
238 LOG.warn("Not able to fetch hardware_vtep table row from device {}",
239 connectionInstance.getConnectionInfo(), e);
242 LOG.trace("Fetched {} from hardware_vtep schema", globalRow);
243 if (globalRow != null && globalRow.getUuid() != null) {
244 return Optional.of(globalRow);
246 return Optional.empty();
247 } catch (RuntimeException e) {
248 LOG.error("Failed to get the hwvtep row for iid {}", iid, e);
249 return Optional.empty();
253 @SuppressWarnings("checkstyle:IllegalCatch")
254 public List<TypedBaseTable> getHwvtepTableEntries(Class<? extends Identifiable> cls) {
256 List<TypedBaseTable> tableRows = new ArrayList<>();
257 DatabaseSchema dbSchema = null;
258 TypedBaseTable globalRow = null;
259 Class<TypedBaseTable> tableClass = tableMap.get(cls);
261 dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.HARDWARE_VTEP).get();
262 } catch (InterruptedException | ExecutionException e) {
263 LOG.error("Not able to fetch schema for database {} from device {}",
264 HwvtepSchemaConstants.HARDWARE_VTEP, connectionInstance.getConnectionInfo(), e);
267 if (dbSchema != null) {
268 GenericTableSchema hwvtepSchema = TyperUtils.getTableSchema(dbSchema, tableClass);
270 List<String> hwvtepTableColumn = new ArrayList<>();
271 hwvtepTableColumn.addAll(hwvtepSchema.getColumns());
272 Select<GenericTableSchema> selectOperation = op.select(hwvtepSchema);
273 selectOperation.setColumns(hwvtepTableColumn);
275 ArrayList<Operation> operations = Lists.newArrayList(selectOperation);
277 List<OperationResult> results = connectionInstance.transact(dbSchema, operations).get();
278 if (results != null && !results.isEmpty()) {
279 for (OperationResult selectResult : results) {
280 if (selectResult.getRows() != null && !selectResult.getRows().isEmpty()) {
281 for (Row<GenericTableSchema> row : selectResult.getRows()) {
282 tableRows.add(TyperUtils.getTypedRowWrapper(dbSchema, tableClass, row));
287 } catch (InterruptedException | ExecutionException e) {
288 LOG.error("Not able to fetch hardware_vtep table row from device {}",
289 connectionInstance.getConnectionInfo(), e);
293 } catch (RuntimeException e) {
294 LOG.error("Failed to get the hwvtep ", e);
296 return Collections.emptyList();
299 public TableUpdates readAllTables() throws ExecutionException, InterruptedException {
300 Map<String, TableUpdate> tableUpdates = new HashMap<>();
301 DatabaseSchema dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.HARDWARE_VTEP).get();
303 List<Operation> operations = Arrays.asList(alltables).stream()
304 .map(tableClass -> TyperUtils.getTableSchema(dbSchema, tableClass))
305 .map(tableSchema -> buildSelectOperationFor(tableSchema))
306 .collect(Collectors.toList());
308 List<OperationResult> results = connectionInstance.transact(dbSchema, operations).get();
309 if (results != null && !results.isEmpty()) {
311 .filter(result -> result.getRows() != null)
312 .flatMap(result -> result.getRows().stream())
314 tableUpdates.compute(row.getTableSchema().getName(), (tableName, tableUpdate) -> {
315 if (tableUpdate == null) {
316 tableUpdate = new TableUpdate();
318 tableUpdate.addRow(getRowUuid(row), null, row);
323 return new TableUpdates(tableUpdates);
326 private Select<GenericTableSchema> buildSelectOperationFor(GenericTableSchema tableSchema) {
327 Select<GenericTableSchema> selectOpearation = op.select(tableSchema);
328 selectOpearation.setColumns(new ArrayList<>(tableSchema.getColumns()));
329 return selectOpearation;
332 private UUID getRowUuid(Row<GenericTableSchema> row) {
333 return row.getColumns().stream()
334 .filter(column -> column.getSchema().getName().equals("_uuid"))
335 .map(column -> (UUID) column.getData())
336 .findFirst().orElse(new UUID("test"));