use of software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable in project openhab-addons by openhab.
the class DynamoDBPersistenceService method getTable.
private <T extends DynamoDBItem<?>> DynamoDbAsyncTable<T> getTable(Class<T> dtoClass) {
DynamoDbEnhancedAsyncClient localClient = client;
DynamoDBTableNameResolver localTableNameResolver = tableNameResolver;
if (!ensureClient() || localClient == null || localTableNameResolver == null) {
throw new IllegalStateException("Client not ready");
}
ExpectedTableSchema expectedTableSchemaRevision = localTableNameResolver.getTableSchema();
String tableName = localTableNameResolver.fromClass(dtoClass);
final TableSchema<T> schema = getDynamoDBTableSchema(dtoClass, expectedTableSchemaRevision);
// OK since this is the only place tableCache is populated
@SuppressWarnings("unchecked") DynamoDbAsyncTable<T> table = (DynamoDbAsyncTable<T>) tableCache.computeIfAbsent(dtoClass, clz -> {
return localClient.table(tableName, schema);
});
if (table == null) {
// Invariant. To make null checker happy
throw new IllegalStateException();
}
return table;
}
use of software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable in project openhab-addons by openhab.
the class DynamoDBPersistenceService method query.
@Override
public Iterable<HistoricItem> query(FilterCriteria filter) {
logIfManyQueuedTasks();
Instant start = Instant.now();
String filterDescription = filterToString(filter);
logger.trace("Got a query with filter {}", filterDescription);
DynamoDbEnhancedAsyncClient localClient = client;
DynamoDBTableNameResolver localTableNameResolver = tableNameResolver;
if (!isProperlyConfigured) {
logger.debug("Configuration for dynamodb not yet loaded or broken. Returning empty query results.");
return Collections.emptyList();
}
if (!ensureClient() || localClient == null || localTableNameResolver == null) {
logger.warn("DynamoDB not connected. Returning empty query results.");
return Collections.emptyList();
}
//
try {
Boolean resolved = resolveTableSchema().get();
if (!resolved) {
logger.warn("Table schema not resolved, cannot query data.");
return Collections.emptyList();
}
} catch (InterruptedException e) {
logger.warn("Table schema resolution interrupted, cannot query data");
return Collections.emptyList();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
logger.warn("Table schema resolution errored, cannot query data: {} {}", cause == null ? e.getClass().getSimpleName() : cause.getClass().getSimpleName(), cause == null ? e.getMessage() : cause.getMessage());
return Collections.emptyList();
}
try {
//
// Proceed with query
//
String itemName = filter.getItemName();
Item item = getItemFromRegistry(itemName);
if (item == null) {
logger.warn("Could not get item {} from registry! Returning empty query results.", itemName);
return Collections.emptyList();
}
if (item instanceof GroupItem) {
item = ((GroupItem) item).getBaseItem();
logger.debug("Item is instanceof GroupItem '{}'", itemName);
if (item == null) {
logger.debug("BaseItem of GroupItem is null. Ignore and give up!");
return Collections.emptyList();
}
if (item instanceof GroupItem) {
logger.debug("BaseItem of GroupItem is a GroupItem too. Ignore and give up!");
return Collections.emptyList();
}
}
boolean legacy = localTableNameResolver.getTableSchema() == ExpectedTableSchema.LEGACY;
Class<? extends DynamoDBItem<?>> dtoClass = AbstractDynamoDBItem.getDynamoItemClass(item.getClass(), legacy);
String tableName = localTableNameResolver.fromClass(dtoClass);
DynamoDbAsyncTable<? extends DynamoDBItem<?>> table = getTable(dtoClass);
logger.debug("Item {} (of type {}) will be tried to query using DTO class {} from table {}", itemName, item.getClass().getSimpleName(), dtoClass.getSimpleName(), tableName);
QueryEnhancedRequest queryExpression = DynamoDBQueryUtils.createQueryExpression(dtoClass, localTableNameResolver.getTableSchema(), item, filter);
CompletableFuture<List<DynamoDBItem<?>>> itemsFuture = new CompletableFuture<>();
final SdkPublisher<? extends DynamoDBItem<?>> itemPublisher = table.query(queryExpression).items();
Subscriber<DynamoDBItem<?>> pageSubscriber = new PageOfInterestSubscriber<DynamoDBItem<?>>(itemsFuture, filter.getPageNumber(), filter.getPageSize());
itemPublisher.subscribe(pageSubscriber);
// NumberItem.getUnit() is expensive, we avoid calling it in the loop
// by fetching the unit here.
final Item localItem = item;
final Unit<?> itemUnit = localItem instanceof NumberItem ? ((NumberItem) localItem).getUnit() : null;
try {
@SuppressWarnings("null") List<HistoricItem> results = itemsFuture.get().stream().map(dynamoItem -> {
HistoricItem historicItem = dynamoItem.asHistoricItem(localItem, itemUnit);
if (historicItem == null) {
logger.warn("Dynamo item {} serialized state '{}' cannot be converted to item {} {}. Item type changed since persistence. Ignoring", dynamoItem.getClass().getSimpleName(), dynamoItem.getState(), localItem.getClass().getSimpleName(), localItem.getName());
return null;
}
logger.trace("Dynamo item {} converted to historic item: {}", localItem, historicItem);
return historicItem;
}).filter(value -> value != null).collect(Collectors.toList());
logger.debug("Query completed in {} ms. Filter was {}", Duration.between(start, Instant.now()).toMillis(), filterDescription);
return results;
} catch (InterruptedException e) {
logger.warn("Query interrupted. Filter was {}", filterDescription);
return Collections.emptyList();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof ResourceNotFoundException) {
logger.trace("Query failed since the DynamoDB table '{}' does not exist. Filter was {}", tableName, filterDescription);
} else if (logger.isTraceEnabled()) {
logger.trace("Query failed. Filter was {}", filterDescription, e);
} else {
logger.warn("Query failed {} {}. Filter was {}", cause == null ? e.getClass().getSimpleName() : cause.getClass().getSimpleName(), cause == null ? e.getMessage() : cause.getMessage(), filterDescription);
}
return Collections.emptyList();
}
} catch (Exception e) {
logger.error("Unexpected error with query having filter {}: {} {}. Returning empty query results.", filterDescription, e.getClass().getSimpleName(), e.getMessage());
return Collections.emptyList();
}
}
Aggregations