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 com.google.common.collect.Lists;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.Optional;
19 import java.util.concurrent.ExecutionException;
20 import java.util.function.Function;
21 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 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
63 public class HwvtepTableReader {
65 private static final Logger LOG = LoggerFactory.getLogger(HwvtepTableReader.class);
67 private final Class alltables[] = new Class[] {
70 ArpSourcesLocal.class,
72 ArpSourcesRemote.class,
77 PhysicalLocator.class,
78 McastMacsRemote.class,
81 PhysicalLocatorSet.class,
87 private final Map<Class, Function<InstanceIdentifier, List<Condition>>> whereClauseGetterMap = new HashMap();
88 private final Map<Class, Class> tableMap = new HashMap();
89 private final Map<Class, TypedBaseTable> tables = new HashMap<>();
91 private final HwvtepConnectionInstance connectionInstance;
93 public HwvtepTableReader(HwvtepConnectionInstance connectionInstance) {
94 this.connectionInstance = connectionInstance;
95 DatabaseSchema dbSchema = null;
97 dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.HARDWARE_VTEP).get();
98 } catch (InterruptedException | ExecutionException e) {
99 LOG.warn("Not able to fetch schema for database {} from device {}",
100 HwvtepSchemaConstants.HARDWARE_VTEP, connectionInstance.getConnectionInfo(), e);
103 tableMap.put(RemoteMcastMacs.class, McastMacsRemote.class);
104 tableMap.put(RemoteUcastMacs.class, UcastMacsRemote.class);
105 tableMap.put(LogicalSwitches.class, LogicalSwitch.class);
106 tableMap.put(TerminationPoint.class, PhysicalLocator.class);
108 whereClauseGetterMap.put(RemoteMcastMacs.class, new RemoteMcastMacWhereClauseGetter());
109 whereClauseGetterMap.put(RemoteUcastMacs.class, new RemoteUcastMacWhereClauseGetter());
110 whereClauseGetterMap.put(LogicalSwitches.class, new LogicalSwitchWhereClauseGetter());
111 whereClauseGetterMap.put(TerminationPoint.class, new LocatorWhereClauseGetter());
113 tables.put(McastMacsRemote.class, TyperUtils.getTypedRowWrapper(dbSchema, McastMacsRemote.class, null));
114 tables.put(UcastMacsRemote.class, TyperUtils.getTypedRowWrapper(dbSchema, UcastMacsRemote.class, null));
115 tables.put(LogicalSwitch.class, TyperUtils.getTypedRowWrapper(dbSchema, LogicalSwitch.class, null));
116 tables.put(PhysicalLocator.class, TyperUtils.getTypedRowWrapper(dbSchema, PhysicalLocator.class, null));
119 class RemoteMcastMacWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
121 public List<Condition> apply(InstanceIdentifier iid) {
122 InstanceIdentifier<RemoteMcastMacs> macIid = iid;
123 String mac = macIid.firstKeyOf(RemoteMcastMacs.class).getMacEntryKey().getValue();
124 InstanceIdentifier<LogicalSwitches> lsIid = (InstanceIdentifier<LogicalSwitches>) macIid.firstKeyOf(
125 RemoteMcastMacs.class).getLogicalSwitchRef().getValue();
126 UUID lsUUID = connectionInstance.getDeviceInfo().getUUID(LogicalSwitches.class, lsIid);
127 if (lsUUID == null) {
128 LOG.error("Could not find uuid for ls key {}", lsIid);
132 McastMacsRemote macTable = (McastMacsRemote) tables.get(McastMacsRemote.class);
133 ArrayList<Condition> conditions = new ArrayList<>();
134 conditions.add(macTable.getLogicalSwitchColumn().getSchema().opEqual(lsUUID));
135 conditions.add(macTable.getMacColumn().getSchema().opEqual(mac));
140 class RemoteUcastMacWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
142 public List<Condition> apply(InstanceIdentifier iid) {
143 InstanceIdentifier<RemoteUcastMacs> macIid = iid;
144 String mac = macIid.firstKeyOf(RemoteUcastMacs.class).getMacEntryKey().getValue();
145 InstanceIdentifier<LogicalSwitches> lsIid = (InstanceIdentifier<LogicalSwitches>) macIid.firstKeyOf(
146 RemoteUcastMacs.class).getLogicalSwitchRef().getValue();
147 UUID lsUUID = connectionInstance.getDeviceInfo().getUUID(LogicalSwitches.class, lsIid);
148 if (lsUUID == null) {
149 LOG.error("Could not find uuid for ls key {}", lsIid);
153 UcastMacsRemote macTable = (UcastMacsRemote) tables.get(UcastMacsRemote.class);
154 ArrayList<Condition> conditions = new ArrayList<>();
155 conditions.add(macTable.getLogicalSwitchColumn().getSchema().opEqual(lsUUID));
156 conditions.add(macTable.getMacColumn().getSchema().opEqual(mac));
161 class LogicalSwitchWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
163 public List<Condition> apply(InstanceIdentifier iid) {
164 InstanceIdentifier<LogicalSwitches> lsIid = iid;
165 String lsName = lsIid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue();
166 LogicalSwitch logicalSwitch = (LogicalSwitch) tables.get(LogicalSwitch.class);
167 return Lists.newArrayList(logicalSwitch.getNameColumn().getSchema().opEqual(lsName));
171 class LocatorWhereClauseGetter implements Function<InstanceIdentifier, List<Condition>> {
173 public List<Condition> apply(InstanceIdentifier iid) {
174 InstanceIdentifier<TerminationPoint> tepIid = iid;
175 String locatorIp = tepIid.firstKeyOf(TerminationPoint.class).getTpId().getValue();
176 locatorIp = locatorIp.substring(locatorIp.indexOf(":") + 1);
177 LOG.info("Locator ip to look for {}", locatorIp);
178 PhysicalLocator locatorTable = (PhysicalLocator) tables.get(PhysicalLocator.class);
179 return Lists.newArrayList(locatorTable.getDstIpColumn().getSchema().opEqual(locatorIp));
183 public Optional<TypedBaseTable> getHwvtepTableEntryUUID(Class<? extends Identifiable> cls,
184 InstanceIdentifier iid,
187 DatabaseSchema dbSchema = null;
188 TypedBaseTable globalRow = null;
189 Class<TypedBaseTable> tableClass = tableMap.get(cls);
191 dbSchema = connectionInstance.getSchema(HwvtepSchemaConstants.HARDWARE_VTEP).get();
192 } catch (InterruptedException | ExecutionException e) {
193 LOG.warn("Not able to fetch schema for database {} from device {}",
194 HwvtepSchemaConstants.HARDWARE_VTEP, connectionInstance.getConnectionInfo(), e);
197 if (dbSchema != null) {
198 GenericTableSchema hwvtepSchema = TyperUtils.getTableSchema(dbSchema, tableClass);
200 List<String> hwvtepTableColumn = new ArrayList<>();
201 hwvtepTableColumn.addAll(hwvtepSchema.getColumns());
202 Select<GenericTableSchema> selectOperation = op.select(hwvtepSchema);
203 selectOperation.setColumns(hwvtepTableColumn);
205 if (existingUUID != null) {
206 TypedBaseTable table = tables.get(tableClass);
207 LOG.info("Setting uuid condition {} ", existingUUID);
208 selectOperation.where(table.getUuidColumn().getSchema().opEqual(existingUUID));
210 if (whereClauseGetterMap.get(cls) != null) {
211 List<Condition> conditions = whereClauseGetterMap.get(cls).apply(iid);
212 if (conditions != null) {
213 if (conditions.size() == 2) {
214 selectOperation.where(conditions.get(0)).and(conditions.get(1));
216 selectOperation.where(conditions.get(0));
219 LOG.error("Could not get where conditions for cls {} key {}", cls, iid);
220 return Optional.empty();
223 LOG.error("Could not get where class for cls {} ", cls);
224 return Optional.empty();
227 ArrayList<Operation> operations = new ArrayList<>();
228 operations.add(selectOperation);
230 List<OperationResult> results = connectionInstance.transact(dbSchema, operations).get();
231 if (results != null && !results.isEmpty()) {
232 OperationResult selectResult = results.get(0);
233 if (selectResult.getRows() != null && !selectResult.getRows().isEmpty()) {
234 globalRow = TyperUtils.getTypedRowWrapper(
235 dbSchema, tableClass, selectResult.getRows().get(0));
238 } catch (InterruptedException | ExecutionException e) {
239 LOG.warn("Not able to fetch hardware_vtep table row from device {}",
240 connectionInstance.getConnectionInfo(), e);
243 LOG.trace("Fetched {} from hardware_vtep schema", globalRow);
244 if (globalRow != null && globalRow.getUuid() != null) {
245 return Optional.of(globalRow);
247 return Optional.empty();
248 } catch (Throwable e) {
249 LOG.error("Failed to get the hwvtep row for iid {} {} ", iid, e);
250 return Optional.empty();
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 (Throwable 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"));