import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
import org.opendaylight.ovsdb.lib.schema.TableSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedDatabaseSchema;
import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
-import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger LOG = LoggerFactory.getLogger(OvsdbClientImpl.class);
private ExecutorService executorService;
private OvsdbRPC rpc;
- private final Map<String, DatabaseSchema> schemas = new HashMap<>();
+ private final Map<String, TypedDatabaseSchema> schemas = new HashMap<>();
private final Map<String, CallbackContext> monitorCallbacks = new HashMap<>();
private OvsdbRPC.Callback rpcCallback;
private OvsdbConnectionInfo connectionInfo;
@Override
public ListenableFuture<DatabaseSchema> getSchema(final String database) {
- final DatabaseSchema existing = schemas.get(database);
+ final TypedDatabaseSchema existing = schemas.get(database);
if (existing != null) {
return Futures.immediateFuture(existing);
}
return Futures.transform(getSchemaFromDevice(Collections.singletonList(database)), result -> {
- DatabaseSchema dbSchema = result.get(database);
+ final DatabaseSchema dbSchema = result.get(database);
if (dbSchema == null) {
return null;
}
- dbSchema = dbSchema.withInternallyGeneratedColumns();
- final DatabaseSchema raced = schemas.putIfAbsent(database, dbSchema);
- return raced != null ? raced : dbSchema;
+ final TypedDatabaseSchema typedSchema = TypedDatabaseSchema.of(dbSchema.withInternallyGeneratedColumns());
+ final TypedDatabaseSchema raced = schemas.putIfAbsent(database, typedSchema);
+ return raced != null ? raced : typedSchema;
}, executorService);
}
}
@Override
- public DatabaseSchema getDatabaseSchema(final String dbName) {
+ public TypedDatabaseSchema getDatabaseSchema(final String dbName) {
return schemas.get(dbName);
}
* @param klazz Typed Class that represents a Table
* @return DatabaseSchema that matches a Typed Table Class
*/
- private <T> DatabaseSchema getDatabaseSchemaForTypedTable(final Class<T> klazz) {
+ private <T> TypedDatabaseSchema getDatabaseSchemaForTypedTable(final Class<T> klazz) {
TypedTable typedTable = klazz.getAnnotation(TypedTable.class);
if (typedTable != null) {
return this.getDatabaseSchema(typedTable.database());
*/
@Override
public <T extends TypedBaseTable<?>> T createTypedRowWrapper(final Class<T> klazz) {
- DatabaseSchema dbSchema = getDatabaseSchemaForTypedTable(klazz);
- return this.createTypedRowWrapper(dbSchema, klazz);
+ return getTypedRowWrapper(klazz, new Row<>());
}
/**
*/
@Override
public <T extends TypedBaseTable<?>> T createTypedRowWrapper(final DatabaseSchema dbSchema, final Class<T> klazz) {
- return TyperUtils.getTypedRowWrapper(dbSchema, klazz, new Row<>());
+ return dbSchema == null ? null : TypedDatabaseSchema.of(dbSchema).getTypedRowWrapper(klazz, new Row<>());
}
/**
@Override
public <T extends TypedBaseTable<?>> T getTypedRowWrapper(final Class<T> klazz, final Row<GenericTableSchema> row) {
- DatabaseSchema dbSchema = getDatabaseSchemaForTypedTable(klazz);
- return TyperUtils.getTypedRowWrapper(dbSchema, klazz, row);
+ final TypedDatabaseSchema dbSchema = getDatabaseSchemaForTypedTable(klazz);
+ return dbSchema == null ? null : dbSchema.getTypedRowWrapper(klazz, row);
}
@Override
--- /dev/null
+/*
+ * Copyright © 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.lib.schema;
+
+import com.google.common.collect.ForwardingObject;
+import java.util.Set;
+import org.opendaylight.ovsdb.lib.notation.Version;
+
+public abstract class ForwardingDatabaseSchema extends ForwardingObject implements DatabaseSchema {
+ @Override
+ protected abstract DatabaseSchema delegate();
+
+ @Override
+ public Set<String> getTables() {
+ return delegate().getTables();
+ }
+
+ @Override
+ public boolean hasTable(final String table) {
+ return delegate().hasTable(table);
+ }
+
+ @Override
+ public <E extends TableSchema<E>> E table(final String tableName, final Class<E> clazz) {
+ return delegate().table(tableName, clazz);
+ }
+
+ @Override
+ public String getName() {
+ return delegate().getName();
+ }
+
+ @Override
+ public Version getVersion() {
+ return delegate().getVersion();
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.lib.schema.typed;
+
+import java.util.Map;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+
+public interface TypedDatabaseSchema extends DatabaseSchema {
+
+ static TypedDatabaseSchema of(final DatabaseSchema delegate) {
+ return delegate instanceof TypedDatabaseSchema ? (TypedDatabaseSchema) delegate
+ : new TypedDatabaseSchemaImpl(delegate);
+ }
+
+ @Override
+ TypedDatabaseSchema withInternallyGeneratedColumns();
+
+ /**
+ * Retrieve the table schema for the given table in the given database schema.
+ *
+ * @param klazz The class whose table schema should be retrieved. Classes are matched in the database schema either
+ * using their {@link TypedTable} annotation, if they have one, or by name.
+ * @return the table schema.
+ */
+ GenericTableSchema getTableSchema(Class<?> klazz);
+
+ /**
+ * Returns a Typed Proxy implementation for the klazz passed as a parameter.
+ * Per design choice, the Typed Proxy implementation is just a Wrapper on top of the actual
+ * Row which is untyped.
+ *
+ * <p>Being just a wrapper, it is state-less and more of a convenience functionality to
+ * provide a type-safe infrastructure for the applications to built on top of.
+ * And this Typed infra is completely optional.
+ *
+ * <p>It is the applications responsibility to pass on the raw Row parameter and this method will
+ * return the appropriate Proxy wrapper for the passed klazz Type.
+ * The raw Row parameter may be null if the caller is interested in just the ColumnSchema.
+ * But that is not a very common use-case.
+ *
+ * @param klazz Typed Class that represents a Table
+ */
+ <T> T getTypedRowWrapper(Class<T> klazz);
+
+ /**
+ * Returns a Typed Proxy implementation for the klazz passed as a parameter.
+ * Per design choice, the Typed Proxy implementation is just a Wrapper on top of the actual
+ * Row which is untyped.
+ *
+ * <p>Being just a wrapper, it is state-less and more of a convenience functionality
+ * to provide a type-safe infrastructure for the applications to built on top of.
+ * And this Typed infra is completely optional.
+ *
+ * <p>It is the applications responsibility to pass on the raw Row parameter and this method
+ * will return the appropriate Proxy wrapper for the passed klazz Type.
+ * The raw Row parameter may be null if the caller is interested in just the
+ * ColumnSchema. But that is not a very common use-case.
+ *
+ * @param klazz Typed Class that represents a Table
+ * @param row The actual Row that the wrapper is operating on. It can be null if the caller
+ * is just interested in getting ColumnSchema.
+ */
+ <T> T getTypedRowWrapper(Class<T> klazz, Row<GenericTableSchema> row);
+
+ /**
+ * This method extracts all row updates of Class<T> klazz from a TableUpdates
+ * that correspond to old version of rows of type klazz that have been updated.
+ * Example:
+ * <code>
+ * Map<UUID,Bridge> oldBridges = extractRowsOld(Bridge.class,updates,dbSchema)
+ * </code>
+ *
+ * @param klazz Class for row type to be extracted
+ * @param updates TableUpdates from which to extract rowUpdates
+ * @return Map<UUID,T> for the type of things being sought
+ */
+ <T> Map<UUID, T> extractRowsOld(Class<T> klazz, TableUpdates updates);
+
+ /**
+ * This method extracts all row updates of Class<T> klazz from a TableUpdates
+ * that correspond to removal of rows of type klazz.
+ * Example:
+ * <code>
+ * Map<UUID,Bridge> updatedBridges = extractRowsRemoved(Bridge.class,updates,dbSchema)
+ * </code>
+ *
+ * @param klazz Class for row type to be extracted
+ * @param updates TableUpdates from which to extract rowUpdates
+ * @return Map<UUID,T> for the type of things being sought
+ */
+ <T> Map<UUID,T> extractRowsRemoved(Class<T> klazz, TableUpdates updates);
+
+ /**
+ * This method extracts all row updates of Class<T> klazz from a TableUpdates
+ * that correspond to insertion or updates of rows of type klazz.
+ * Example:
+ * <code>
+ * Map<UUID,Bridge> updatedBridges = extractRowsUpdated(Bridge.class,updates,dbSchema)
+ * </code>
+ *
+ * @param klazz Class for row type to be extracted
+ * @param updates TableUpdates from which to extract rowUpdates
+ * @return Map<UUID,T> for the type of things being sought
+ */
+ <T> Map<UUID, T> extractRowsUpdated(Class<T> klazz, TableUpdates updates);
+}
--- /dev/null
+/*
+ * Copyright © 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.lib.schema.typed;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.Map;
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.notation.Row;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.ForwardingDatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
+
+final class TypedDatabaseSchemaImpl extends ForwardingDatabaseSchema implements TypedDatabaseSchema {
+ private final DatabaseSchema delegate;
+
+ TypedDatabaseSchemaImpl(final DatabaseSchema delegate) {
+ this.delegate = requireNonNull(delegate);
+ }
+
+ @Override
+ protected DatabaseSchema delegate() {
+ return delegate;
+ }
+
+ @Override
+ public TypedDatabaseSchema withInternallyGeneratedColumns() {
+ final DatabaseSchema newDelegate = delegate.withInternallyGeneratedColumns();
+ return newDelegate == delegate ? this : new TypedDatabaseSchemaImpl(newDelegate);
+ }
+
+ @Override
+ public GenericTableSchema getTableSchema(final Class<?> klazz) {
+ return TyperUtils.getTableSchema(this, klazz);
+ }
+
+ @Override
+ public <T> T getTypedRowWrapper(final Class<T> klazz) {
+ return TyperUtils.getTypedRowWrapper(this, klazz);
+ }
+
+ @Override
+ public <T> T getTypedRowWrapper(final Class<T> klazz, final Row<GenericTableSchema> row) {
+ return TyperUtils.getTypedRowWrapper(this, klazz, row);
+ }
+
+ @Override
+ public <T> Map<UUID, T> extractRowsOld(final Class<T> klazz, final TableUpdates updates) {
+ return TyperUtils.extractRowsOld(klazz, updates, this);
+ }
+
+ @Override
+ public <T> Map<UUID, T> extractRowsUpdated(final Class<T> klazz, final TableUpdates updates) {
+ return TyperUtils.extractRowsUpdated(klazz, updates, this);
+ }
+
+ @Override
+ public <T> Map<UUID, T> extractRowsRemoved(final Class<T> klazz, final TableUpdates updates) {
+ return TyperUtils.extractRowsRemoved(klazz, updates, this);
+ }
+}