use of org.apache.ignite.internal.table.TableImpl in project ignite-3 by apache.
the class TableManager method tableSchema.
/**
* Return table schema of certain version from history.
*
* @param tblId Table id.
* @param schemaVer Schema version.
* @return Schema descriptor.
*/
private SchemaDescriptor tableSchema(UUID tblId, int schemaVer) {
Map<UUID, TableImpl> tablesById = tablesByIdVv.latest();
TableImpl table = tablesById == null ? null : tablesById.get(tblId);
assert table != null : "Table is undefined [tblId=" + tblId + ']';
ExtendedTableConfiguration tblCfg = ((ExtendedTableConfiguration) tablesCfg.tables().get(table.name()));
if (schemaVer <= table.schemaView().lastSchemaVersion()) {
return getSchemaDescriptorLocally(schemaVer, tblCfg);
}
CompletableFuture<SchemaDescriptor> fut = new CompletableFuture<>();
var clo = new EventListener<TableEventParameters>() {
@Override
public boolean notify(@NotNull TableEventParameters parameters, @Nullable Throwable exception) {
if (tblId.equals(parameters.tableId()) && schemaVer <= parameters.table().schemaView().lastSchemaVersion()) {
fut.complete(getSchemaDescriptorLocally(schemaVer, tblCfg));
return true;
}
return false;
}
@Override
public void remove(@NotNull Throwable exception) {
fut.completeExceptionally(exception);
}
};
listen(TableEvent.ALTER, clo);
if (schemaVer <= table.schemaView().lastSchemaVersion()) {
fut.complete(getSchemaDescriptorLocally(schemaVer, tblCfg));
}
if (!isSchemaExists(tblId, schemaVer) && fut.complete(null)) {
removeListener(TableEvent.ALTER, clo);
}
return fut.join();
}
use of org.apache.ignite.internal.table.TableImpl in project ignite-3 by apache.
the class TableManager method start.
/**
* {@inheritDoc}
*/
@Override
public void start() {
tablesCfg.tables().listenElements(new ConfigurationNamedListListener<>() {
@Override
public CompletableFuture<?> onCreate(ConfigurationNotificationEvent<TableView> ctx) {
if (!busyLock.enterBusy()) {
String tblName = ctx.newValue().name();
UUID tblId = ((ExtendedTableView) ctx.newValue()).id();
fireEvent(TableEvent.CREATE, new TableEventParameters(ctx.storageRevision(), tblId, tblName), new NodeStoppingException());
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
onTableCreateInternal(ctx);
} finally {
busyLock.leaveBusy();
}
return CompletableFuture.completedFuture(null);
}
/**
* Method for handle a table configuration event.
*
* @param ctx Configuration event.
*/
private void onTableCreateInternal(ConfigurationNotificationEvent<TableView> ctx) {
String tblName = ctx.newValue().name();
UUID tblId = ((ExtendedTableView) ctx.newValue()).id();
// configuration, which is not supported now.
assert ((ExtendedTableView) ctx.newValue()).assignments() != null : IgniteStringFormatter.format("Table [id={}, name={}] has empty assignments.", tblId, tblName);
// TODO: IGNITE-16369 Listener with any placeholder should be used instead.
((ExtendedTableConfiguration) tablesCfg.tables().get(tblName)).schemas().listenElements(new ConfigurationNamedListListener<>() {
@Override
public CompletableFuture<?> onCreate(ConfigurationNotificationEvent<SchemaView> schemasCtx) {
long causalityToken = schemasCtx.storageRevision();
if (!busyLock.enterBusy()) {
fireEvent(TableEvent.ALTER, new TableEventParameters(causalityToken, tblId, tblName), new NodeStoppingException());
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
// FIXME: https://issues.apache.org/jira/browse/IGNITE-16369
if (ctx.storageRevision() != schemasCtx.storageRevision()) {
return tablesByIdVv.get(causalityToken).thenAccept(tablesById -> {
TableImpl table = tablesById.get(tblId);
((SchemaRegistryImpl) table.schemaView()).onSchemaRegistered(SchemaSerializerImpl.INSTANCE.deserialize((schemasCtx.newValue().schema())));
fireEvent(TableEvent.ALTER, new TableEventParameters(causalityToken, table), null);
});
}
return CompletableFuture.completedFuture(null);
} catch (Exception e) {
fireEvent(TableEvent.ALTER, new TableEventParameters(causalityToken, tblId, tblName), e);
return CompletableFuture.failedFuture(e);
} finally {
busyLock.leaveBusy();
}
}
});
((ExtendedTableConfiguration) tablesCfg.tables().get(tblName)).assignments().listen(assignmentsCtx -> {
if (!busyLock.enterBusy()) {
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
// FIXME: https://issues.apache.org/jira/browse/IGNITE-16369
if (ctx.storageRevision() == assignmentsCtx.storageRevision()) {
return CompletableFuture.completedFuture(null);
} else {
return updateAssignmentInternal(assignmentsCtx.storageRevision(), tblId, assignmentsCtx);
}
} finally {
busyLock.leaveBusy();
}
});
createTableLocally(ctx.storageRevision(), tblName, tblId, (List<List<ClusterNode>>) ByteUtils.fromBytes(((ExtendedTableView) ctx.newValue()).assignments()), SchemaSerializerImpl.INSTANCE.deserialize(((ExtendedTableView) ctx.newValue()).schemas().get(String.valueOf(INITIAL_SCHEMA_VERSION)).schema()));
}
private CompletableFuture<?> updateAssignmentInternal(long causalityToken, UUID tblId, ConfigurationNotificationEvent<byte[]> assignmentsCtx) {
List<List<ClusterNode>> oldAssignments = (List<List<ClusterNode>>) ByteUtils.fromBytes(assignmentsCtx.oldValue());
List<List<ClusterNode>> newAssignments = (List<List<ClusterNode>>) ByteUtils.fromBytes(assignmentsCtx.newValue());
CompletableFuture<?>[] futures = new CompletableFuture<?>[oldAssignments.size()];
// TODO: be exact same amount of partitions and replicas for both old and new assignments
for (int i = 0; i < oldAssignments.size(); i++) {
int partId = i;
List<ClusterNode> oldPartitionAssignment = oldAssignments.get(partId);
List<ClusterNode> newPartitionAssignment = newAssignments.get(partId);
var toAdd = new HashSet<>(newPartitionAssignment);
toAdd.removeAll(oldPartitionAssignment);
// Create new raft nodes according to new assignments.
futures[i] = tablesByIdVv.get(causalityToken).thenCompose(tablesById -> {
InternalTable internalTable = tablesById.get(tblId).internalTable();
try {
return raftMgr.updateRaftGroup(raftGroupName(tblId, partId), newPartitionAssignment, toAdd, () -> new PartitionListener(tblId, new VersionedRowStore(internalTable.storage().getOrCreatePartition(partId), txManager))).thenAccept(updatedRaftGroupService -> ((InternalTableImpl) internalTable).updateInternalTableRaftGroupService(partId, updatedRaftGroupService)).exceptionally(th -> {
LOG.error("Failed to update raft groups one the node", th);
return null;
});
} catch (NodeStoppingException e) {
throw new AssertionError("Loza was stopped before Table manager", e);
}
});
}
return CompletableFuture.allOf(futures);
}
@Override
public CompletableFuture<?> onRename(String oldName, String newName, ConfigurationNotificationEvent<TableView> ctx) {
return CompletableFuture.completedFuture(null);
}
@Override
public CompletableFuture<?> onDelete(ConfigurationNotificationEvent<TableView> ctx) {
if (!busyLock.enterBusy()) {
String tblName = ctx.oldValue().name();
UUID tblId = ((ExtendedTableView) ctx.oldValue()).id();
fireEvent(TableEvent.DROP, new TableEventParameters(ctx.storageRevision(), tblId, tblName), new NodeStoppingException());
return CompletableFuture.failedFuture(new NodeStoppingException());
}
try {
dropTableLocally(ctx.storageRevision(), ctx.oldValue().name(), ((ExtendedTableView) ctx.oldValue()).id(), (List<List<ClusterNode>>) ByteUtils.fromBytes(((ExtendedTableView) ctx.oldValue()).assignments()));
} finally {
busyLock.leaveBusy();
}
return CompletableFuture.completedFuture(null);
}
});
engine.start();
DataRegion defaultDataRegion = engine.createDataRegion(dataStorageCfg.defaultRegion());
dataRegions.put(DEFAULT_DATA_REGION_NAME, defaultDataRegion);
defaultDataRegion.start();
}
use of org.apache.ignite.internal.table.TableImpl in project ignite-3 by apache.
the class TableManager method dropTableLocally.
/**
* Drops local structures for a table.
*
* @param causalityToken Causality token.
* @param name Table name.
* @param tblId Table id.
* @param assignment Affinity assignment.
*/
private void dropTableLocally(long causalityToken, String name, UUID tblId, List<List<ClusterNode>> assignment) {
try {
int partitions = assignment.size();
for (int p = 0; p < partitions; p++) {
raftMgr.stopRaftGroup(raftGroupName(tblId, p));
}
tablesVv.update(causalityToken, previousVal -> {
var map = new HashMap<>(previousVal);
map.remove(name);
return map;
}, th -> {
throw new IgniteInternalException(IgniteStringFormatter.format("Cannot drop a table [name={}, id={}]", name, tblId), th);
});
Map<UUID, TableImpl> tablesByIdFut = tablesByIdVv.update(causalityToken, previousVal -> {
var map = new HashMap<>(previousVal);
map.remove(tblId);
return map;
}, th -> {
throw new IgniteInternalException(IgniteStringFormatter.format("Cannot drop a table [name={}, id={}]", name, tblId), th);
});
TableImpl table = tablesByIdFut.get(tblId);
assert table != null : "There is no table with the name specified [name=" + name + ']';
table.internalTable().storage().destroy();
fireEvent(TableEvent.DROP, new TableEventParameters(causalityToken, table), null);
} catch (Exception e) {
fireEvent(TableEvent.DROP, new TableEventParameters(causalityToken, tblId, name), e);
}
}
use of org.apache.ignite.internal.table.TableImpl in project ignite-3 by apache.
the class TableManager method alterTableAsyncInternal.
/**
* Internal method that alters a cluster table. If an appropriate table does not exist, a future will be
* completed with {@link TableNotFoundException}.
*
* @param name Table name.
* @param tableChange Table changer.
* @return Future representing pending completion of the operation.
* @throws IgniteException If an unspecified platform exception has happened internally. Is thrown when:
* <ul>
* <li>the node is stopping.</li>
* </ul>
* @see TableNotFoundException
*/
@NotNull
private CompletableFuture<Void> alterTableAsyncInternal(String name, Consumer<TableChange> tableChange) {
CompletableFuture<Void> tblFut = new CompletableFuture<>();
tableAsync(name).thenAccept(tbl -> {
if (tbl == null) {
tblFut.completeExceptionally(new TableNotFoundException(name));
} else {
TableImpl tblImpl = (TableImpl) tbl;
tablesCfg.tables().change(ch -> {
if (ch.get(name) == null) {
throw new TableNotFoundException(name);
}
ch.update(name, tblCh -> {
tableChange.accept(tblCh);
((ExtendedTableChange) tblCh).changeSchemas(schemasCh -> schemasCh.createOrUpdate(String.valueOf(schemasCh.size() + 1), schemaCh -> {
ExtendedTableView currTableView = (ExtendedTableView) tablesCfg.tables().get(name).value();
SchemaDescriptor descriptor;
// here to ensure a valid configuration passed to prepareSchemaDescriptor() method.
try {
descriptor = SchemaUtils.prepareSchemaDescriptor(((ExtendedTableView) tblCh).schemas().size(), tblCh);
descriptor.columnMapping(SchemaUtils.columnMapper(tblImpl.schemaView().schema(currTableView.schemas().size()), currTableView, descriptor, tblCh));
} catch (IllegalArgumentException ex) {
// Convert unexpected exceptions here,
// because validation actually happens later,
// when bulk configuration update is applied.
ConfigurationValidationException e = new ConfigurationValidationException(ex.getMessage());
e.addSuppressed(ex);
throw e;
}
schemaCh.changeSchema(SchemaSerializerImpl.INSTANCE.serialize(descriptor));
}));
});
}).whenComplete((res, t) -> {
if (t != null) {
Throwable ex = getRootCause(t);
if (ex instanceof TableNotFoundException) {
tblFut.completeExceptionally(ex);
} else {
LOG.error(IgniteStringFormatter.format("Table wasn't altered [name={}]", name), ex);
tblFut.completeExceptionally(ex);
}
} else {
tblFut.complete(res);
}
});
}
});
return tblFut;
}
use of org.apache.ignite.internal.table.TableImpl in project ignite-3 by apache.
the class JdbcMetadataCatalog method createPrimaryKeyMeta.
/**
* Creates primary key metadata from table object.
*
* @param tbl Table.
* @return Jdbc primary key metadata.
*/
private JdbcPrimaryKeyMeta createPrimaryKeyMeta(Table tbl) {
String schemaName = getTblSchema(tbl.name());
String tblName = getTblName(tbl.name());
final String keyName = PK + tblName;
SchemaRegistry registry = ((TableImpl) tbl).schemaView();
List<String> keyColNames = Arrays.stream(registry.schema().keyColumns().columns()).map(Column::name).collect(Collectors.toList());
return new JdbcPrimaryKeyMeta(schemaName, tblName, keyName, keyColNames);
}
Aggregations