Search in sources :

Example 1 with DynamoDbAsyncTable

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;
}
Also used : Unit(javax.measure.Unit) Constants(org.osgi.framework.Constants) ZonedDateTime(java.time.ZonedDateTime) LoggerFactory(org.slf4j.LoggerFactory) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) PersistenceStrategy(org.openhab.core.persistence.strategy.PersistenceStrategy) NettyNioAsyncHttpClient(software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient) Nullable(org.eclipse.jdt.annotation.Nullable) GenericItem(org.openhab.core.items.GenericItem) Locale(java.util.Locale) Duration(java.time.Duration) Map(java.util.Map) DynamoDbAsyncTable(software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable) URI(java.net.URI) NumberItem(org.openhab.core.library.items.NumberItem) ClientAsyncConfiguration(software.amazon.awssdk.core.client.config.ClientAsyncConfiguration) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Deactivate(org.osgi.service.component.annotations.Deactivate) UnDefType(org.openhab.core.types.UnDefType) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) TableSchema(software.amazon.awssdk.enhanced.dynamodb.TableSchema) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) BundleContext(org.osgi.framework.BundleContext) InvocationTargetException(java.lang.reflect.InvocationTargetException) List(java.util.List) PersistenceService(org.openhab.core.persistence.PersistenceService) SdkAdvancedAsyncClientOption(software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption) QueryEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest) AwsRequestOverrideConfiguration(software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration) FilterCriteria(org.openhab.core.persistence.FilterCriteria) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) CompletableFuture(java.util.concurrent.CompletableFuture) DynamoDbEnhancedAsyncClient(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedAsyncClient) StaticCredentialsProvider(software.amazon.awssdk.auth.credentials.StaticCredentialsProvider) HistoricItem(org.openhab.core.persistence.HistoricItem) Component(org.osgi.service.component.annotations.Component) DefaultsMode(software.amazon.awssdk.awscore.defaultsmode.DefaultsMode) QueryablePersistenceService(org.openhab.core.persistence.QueryablePersistenceService) Activate(org.osgi.service.component.annotations.Activate) Subscriber(org.reactivestreams.Subscriber) ExecutorService(java.util.concurrent.ExecutorService) DynamoDbAsyncClientBuilder(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClientBuilder) QuantityType(org.openhab.core.library.types.QuantityType) ThreadPoolManager(org.openhab.core.common.ThreadPoolManager) GroupItem(org.openhab.core.items.GroupItem) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) ConfigurableService(org.openhab.core.config.core.ConfigurableService) State(org.openhab.core.types.State) ItemNotFoundException(org.openhab.core.items.ItemNotFoundException) SdkPublisher(software.amazon.awssdk.core.async.SdkPublisher) PersistenceItemInfo(org.openhab.core.persistence.PersistenceItemInfo) Item(org.openhab.core.items.Item) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) ExecutionException(java.util.concurrent.ExecutionException) ItemRegistry(org.openhab.core.items.ItemRegistry) Reference(org.osgi.service.component.annotations.Reference) Collections(java.util.Collections) ClientOverrideConfiguration(software.amazon.awssdk.core.client.config.ClientOverrideConfiguration) DynamoDbAsyncTable(software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable) DynamoDbEnhancedAsyncClient(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedAsyncClient)

Example 2 with DynamoDbAsyncTable

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();
    }
}
Also used : Unit(javax.measure.Unit) Constants(org.osgi.framework.Constants) ZonedDateTime(java.time.ZonedDateTime) LoggerFactory(org.slf4j.LoggerFactory) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) PersistenceStrategy(org.openhab.core.persistence.strategy.PersistenceStrategy) NettyNioAsyncHttpClient(software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient) Nullable(org.eclipse.jdt.annotation.Nullable) GenericItem(org.openhab.core.items.GenericItem) Locale(java.util.Locale) Duration(java.time.Duration) Map(java.util.Map) DynamoDbAsyncTable(software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable) URI(java.net.URI) NumberItem(org.openhab.core.library.items.NumberItem) ClientAsyncConfiguration(software.amazon.awssdk.core.client.config.ClientAsyncConfiguration) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Deactivate(org.osgi.service.component.annotations.Deactivate) UnDefType(org.openhab.core.types.UnDefType) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) TableSchema(software.amazon.awssdk.enhanced.dynamodb.TableSchema) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) BundleContext(org.osgi.framework.BundleContext) InvocationTargetException(java.lang.reflect.InvocationTargetException) List(java.util.List) PersistenceService(org.openhab.core.persistence.PersistenceService) SdkAdvancedAsyncClientOption(software.amazon.awssdk.core.client.config.SdkAdvancedAsyncClientOption) QueryEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest) AwsRequestOverrideConfiguration(software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration) FilterCriteria(org.openhab.core.persistence.FilterCriteria) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) CompletableFuture(java.util.concurrent.CompletableFuture) DynamoDbEnhancedAsyncClient(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedAsyncClient) StaticCredentialsProvider(software.amazon.awssdk.auth.credentials.StaticCredentialsProvider) HistoricItem(org.openhab.core.persistence.HistoricItem) Component(org.osgi.service.component.annotations.Component) DefaultsMode(software.amazon.awssdk.awscore.defaultsmode.DefaultsMode) QueryablePersistenceService(org.openhab.core.persistence.QueryablePersistenceService) Activate(org.osgi.service.component.annotations.Activate) Subscriber(org.reactivestreams.Subscriber) ExecutorService(java.util.concurrent.ExecutorService) DynamoDbAsyncClientBuilder(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClientBuilder) QuantityType(org.openhab.core.library.types.QuantityType) ThreadPoolManager(org.openhab.core.common.ThreadPoolManager) GroupItem(org.openhab.core.items.GroupItem) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) ConfigurableService(org.openhab.core.config.core.ConfigurableService) State(org.openhab.core.types.State) ItemNotFoundException(org.openhab.core.items.ItemNotFoundException) SdkPublisher(software.amazon.awssdk.core.async.SdkPublisher) PersistenceItemInfo(org.openhab.core.persistence.PersistenceItemInfo) Item(org.openhab.core.items.Item) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) ExecutionException(java.util.concurrent.ExecutionException) ItemRegistry(org.openhab.core.items.ItemRegistry) Reference(org.osgi.service.component.annotations.Reference) Collections(java.util.Collections) ClientOverrideConfiguration(software.amazon.awssdk.core.client.config.ClientOverrideConfiguration) GenericItem(org.openhab.core.items.GenericItem) NumberItem(org.openhab.core.library.items.NumberItem) HistoricItem(org.openhab.core.persistence.HistoricItem) GroupItem(org.openhab.core.items.GroupItem) Item(org.openhab.core.items.Item) CompletableFuture(java.util.concurrent.CompletableFuture) GroupItem(org.openhab.core.items.GroupItem) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) HistoricItem(org.openhab.core.persistence.HistoricItem) Instant(java.time.Instant) QueryEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest) InvocationTargetException(java.lang.reflect.InvocationTargetException) ItemNotFoundException(org.openhab.core.items.ItemNotFoundException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) ExecutionException(java.util.concurrent.ExecutionException) NumberItem(org.openhab.core.library.items.NumberItem) DynamoDbEnhancedAsyncClient(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedAsyncClient)

Aggregations

InvocationTargetException (java.lang.reflect.InvocationTargetException)2 URI (java.net.URI)2 Duration (java.time.Duration)2 Instant (java.time.Instant)2 ZonedDateTime (java.time.ZonedDateTime)2 Collections (java.util.Collections)2 Iterator (java.util.Iterator)2 List (java.util.List)2 Locale (java.util.Locale)2 Map (java.util.Map)2 Set (java.util.Set)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ExecutionException (java.util.concurrent.ExecutionException)2 ExecutorService (java.util.concurrent.ExecutorService)2 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)2 Collectors (java.util.stream.Collectors)2 Unit (javax.measure.Unit)2 NonNullByDefault (org.eclipse.jdt.annotation.NonNullByDefault)2 Nullable (org.eclipse.jdt.annotation.Nullable)2