Search in sources :

Example 31 with Asset

use of org.openremote.model.asset.Asset in project openremote by openremote.

the class JsonRulesBuilder method buildRuleActionExecution.

protected static RuleActionExecution buildRuleActionExecution(JsonRule rule, RuleAction ruleAction, String actionsName, int index, boolean useUnmatched, RulesFacts facts, RuleState ruleState, Assets assetsFacade, Users usersFacade, Notifications notificationsFacade, PredictedDatapoints predictedDatapointsFacade) {
    if (ruleAction instanceof RuleActionNotification) {
        RuleActionNotification notificationAction = (RuleActionNotification) ruleAction;
        if (notificationAction.notification != null) {
            Notification notification = notificationAction.notification;
            if (notification.getMessage() != null) {
                String body = null;
                boolean isEmail = Objects.equals(notification.getMessage().getType(), EmailNotificationMessage.TYPE);
                boolean isPush = Objects.equals(notification.getMessage().getType(), PushNotificationMessage.TYPE);
                boolean isHtml = false;
                if (isEmail) {
                    EmailNotificationMessage email = (EmailNotificationMessage) notification.getMessage();
                    isHtml = !TextUtil.isNullOrEmpty(email.getHtml());
                    body = isHtml ? email.getHtml() : email.getText();
                } else if (isPush) {
                    PushNotificationMessage pushNotificationMessage = (PushNotificationMessage) notification.getMessage();
                    body = pushNotificationMessage.getBody();
                }
                if (!TextUtil.isNullOrEmpty(body)) {
                    if (body.contains(PLACEHOLDER_TRIGGER_ASSETS)) {
                        // Need to clone the notification
                        notification = ValueUtil.clone(notification);
                        String triggeredAssetInfo = buildTriggeredAssetInfo(useUnmatched, ruleState, isHtml);
                        body = body.replace(PLACEHOLDER_TRIGGER_ASSETS, triggeredAssetInfo);
                        if (isEmail) {
                            EmailNotificationMessage email = (EmailNotificationMessage) notification.getMessage();
                            if (isHtml) {
                                email.setHtml(body);
                            } else {
                                email.setText(body);
                            }
                        } else if (isPush) {
                            PushNotificationMessage pushNotificationMessage = (PushNotificationMessage) notification.getMessage();
                            pushNotificationMessage.setBody(body);
                        }
                    }
                }
            }
            // Transfer the rule action target into notification targets
            Notification.TargetType targetType = Notification.TargetType.ASSET;
            if (ruleAction.target != null) {
                if (ruleAction.target.users != null && ruleAction.target.conditionAssets == null && ruleAction.target.assets == null && ruleAction.target.matchedAssets == null) {
                    targetType = Notification.TargetType.USER;
                } else if (ruleAction.target.custom != null && ruleAction.target.conditionAssets == null && ruleAction.target.assets == null && ruleAction.target.matchedAssets == null) {
                    targetType = Notification.TargetType.CUSTOM;
                }
            }
            Collection<String> ids = getRuleActionTargetIds(ruleAction.target, useUnmatched, ruleState, assetsFacade, usersFacade, facts);
            if (ids == null) {
                notification.setTargets((List<Notification.Target>) null);
            } else {
                Notification.TargetType finalTargetType = targetType;
                notification.setTargets(ids.stream().map(id -> new Notification.Target(finalTargetType, id)).collect(Collectors.toList()));
            }
            log(Level.FINE, "Sending notification for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
            Notification finalNotification = notification;
            return new RuleActionExecution(() -> notificationsFacade.send(finalNotification), 0);
        }
    }
    if (ruleAction instanceof RuleActionWriteAttribute) {
        if (targetIsNotAssets(ruleAction.target)) {
            return null;
        }
        RuleActionWriteAttribute attributeAction = (RuleActionWriteAttribute) ruleAction;
        if (TextUtil.isNullOrEmpty(attributeAction.attributeName)) {
            log(Level.WARNING, "Attribute name is missing for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        Collection<String> ids = getRuleActionTargetIds(ruleAction.target, useUnmatched, ruleState, assetsFacade, usersFacade, facts);
        if (ids == null || ids.isEmpty()) {
            log(Level.INFO, "No targets for write attribute rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        log(Level.FINE, "Writing attribute '" + attributeAction.attributeName + "' for " + ids.size() + " asset(s) for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
        return new RuleActionExecution(() -> ids.forEach(id -> assetsFacade.dispatch(id, attributeAction.attributeName, attributeAction.value)), 0);
    }
    if (ruleAction instanceof RuleActionWait) {
        long millis = ((RuleActionWait) ruleAction).millis;
        if (millis > 0) {
            return new RuleActionExecution(null, millis);
        }
        log(Level.FINEST, "Invalid delay for wait rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
    }
    if (ruleAction instanceof RuleActionUpdateAttribute) {
        if (targetIsNotAssets(ruleAction.target)) {
            log(Level.FINEST, "Invalid target update attribute rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        RuleActionUpdateAttribute attributeUpdateAction = (RuleActionUpdateAttribute) ruleAction;
        if (TextUtil.isNullOrEmpty(attributeUpdateAction.attributeName)) {
            log(Level.WARNING, "Attribute name is missing for rule action: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        List<String> matchingAssetIds;
        if (ruleAction.target == null || ruleAction.target.assets == null) {
            if (ruleAction.target != null && ruleAction.target.users != null) {
                throw new IllegalStateException("Cannot use action type '" + RuleActionUpdateAttribute.class.getSimpleName() + "' with user target");
            }
            matchingAssetIds = new ArrayList<>(getRuleActionTargetIds(ruleAction.target, useUnmatched, ruleState, assetsFacade, usersFacade, facts));
        } else {
            matchingAssetIds = facts.matchAssetState(ruleAction.target.assets).map(AssetState::getId).distinct().collect(Collectors.toList());
        }
        if (matchingAssetIds.isEmpty()) {
            log(Level.INFO, "No targets for update attribute rule action so skipping: " + rule.name + " '" + actionsName + "' action index " + index);
            return null;
        }
        // Look for the current value within the asset state facts (asset/attribute has to be in scope of this rule engine and have a rule state meta item)
        List<AssetState<?>> matchingAssetStates = matchingAssetIds.stream().map(assetId -> facts.getAssetStates().stream().filter(state -> state.getId().equals(assetId) && state.getName().equals(attributeUpdateAction.attributeName)).findFirst().orElseGet(() -> {
            log(Level.WARNING, "Failed to find attribute in rule states for attribute update: " + new AttributeRef(assetId, attributeUpdateAction.attributeName));
            return null;
        })).filter(Objects::nonNull).collect(Collectors.toList());
        if (matchingAssetStates.isEmpty()) {
            log(Level.WARNING, "No asset states matched to apply update attribute action to");
            return null;
        }
        return new RuleActionExecution(() -> matchingAssetStates.forEach(assetState -> {
            Object value = assetState.getValue().orElse(null);
            Class<?> valueType = assetState.getType().getType();
            boolean isArray = ValueUtil.isArray(valueType);
            if (!isArray && !ValueUtil.isObject(valueType)) {
                log(Level.WARNING, "Rule action target asset cannot determine value type or incompatible value type for attribute: " + assetState);
            } else {
                // Convert value to JSON Node to easily manipulate it
                value = isArray ? ValueUtil.convert(value, ArrayNode.class) : ValueUtil.convert(value, ObjectNode.class);
                switch(attributeUpdateAction.updateAction) {
                    case ADD:
                        if (isArray) {
                            value = value == null ? ValueUtil.JSON.createArrayNode() : value;
                            ((ArrayNode) value).add(ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                        } else {
                            value = value == null ? ValueUtil.JSON.createObjectNode() : value;
                            ((ObjectNode) value).set(attributeUpdateAction.key, ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                        }
                        break;
                    case ADD_OR_REPLACE:
                    case REPLACE:
                        if (isArray) {
                            value = value == null ? ValueUtil.JSON.createArrayNode() : value;
                            ArrayNode arrayValue = (ArrayNode) value;
                            if (attributeUpdateAction.index != null && arrayValue.size() >= attributeUpdateAction.index) {
                                arrayValue.set(attributeUpdateAction.index, ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                            } else {
                                arrayValue.add(ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                            }
                        } else {
                            value = value == null ? ValueUtil.JSON.createObjectNode() : value;
                            if (!TextUtil.isNullOrEmpty(attributeUpdateAction.key)) {
                                ((ObjectNode) value).set(attributeUpdateAction.key, ValueUtil.convert(attributeUpdateAction.value, JsonNode.class));
                            } else {
                                log(Level.WARNING, "JSON Rule: Rule action missing required 'key': " + ValueUtil.asJSON(attributeUpdateAction));
                            }
                        }
                        break;
                    case DELETE:
                        if (value != null) {
                            if (isArray) {
                                ((ArrayNode) value).remove(attributeUpdateAction.index);
                            } else {
                                ((ObjectNode) value).remove(attributeUpdateAction.key);
                            }
                        }
                        break;
                    case CLEAR:
                        if (isArray) {
                            value = ValueUtil.JSON.createArrayNode();
                        } else {
                            value = ValueUtil.JSON.createObjectNode();
                        }
                        break;
                }
                log(Level.FINE, "Updating attribute for rule action: " + rule.name + " '" + actionsName + "' action index " + index + ": " + assetState);
                assetsFacade.dispatch(assetState.getId(), attributeUpdateAction.attributeName, value);
            }
        }), 0);
    }
    log(Level.FINE, "Unsupported rule action: " + rule.name + " '" + actionsName + "' action index " + index);
    return null;
}
Also used : AssetStorageService(org.openremote.manager.asset.AssetStorageService) java.util(java.util) AttributeRef(org.openremote.model.attribute.AttributeRef) CronExpression(org.quartz.CronExpression) LocationAttributePredicate.getLocationPredicates(org.openremote.model.query.filter.LocationAttributePredicate.getLocationPredicates) ValueUtil(org.openremote.model.util.ValueUtil) Supplier(java.util.function.Supplier) ValueUtil.distinctByKey(org.openremote.model.util.ValueUtil.distinctByKey) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Level(java.util.logging.Level) Notification(org.openremote.model.notification.Notification) UserQuery(org.openremote.model.query.UserQuery) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) EmailNotificationMessage(org.openremote.model.notification.EmailNotificationMessage) JsonNode(com.fasterxml.jackson.databind.JsonNode) TextUtil(org.openremote.model.util.TextUtil) PersistenceEvent(org.openremote.model.PersistenceEvent) LogicGroup(org.openremote.model.query.LogicGroup) org.openremote.model.rules(org.openremote.model.rules) Asset(org.openremote.model.asset.Asset) MetaItemType(org.openremote.model.value.MetaItemType) Predicate(java.util.function.Predicate) AssetQuery(org.openremote.model.query.AssetQuery) AttributePredicate(org.openremote.model.query.filter.AttributePredicate) Collectors(java.util.stream.Collectors) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) AtomicLong(java.util.concurrent.atomic.AtomicLong) PushNotificationMessage(org.openremote.model.notification.PushNotificationMessage) Stream(java.util.stream.Stream) org.openremote.model.rules.json(org.openremote.model.rules.json) TimerService(org.openremote.container.timer.TimerService) TimeUtil(org.openremote.model.util.TimeUtil) AssetQueryPredicate.groupIsEmpty(org.openremote.manager.rules.AssetQueryPredicate.groupIsEmpty) AttributeRef(org.openremote.model.attribute.AttributeRef) Notification(org.openremote.model.notification.Notification) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) EmailNotificationMessage(org.openremote.model.notification.EmailNotificationMessage) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) PushNotificationMessage(org.openremote.model.notification.PushNotificationMessage)

Example 32 with Asset

use of org.openremote.model.asset.Asset in project openremote by openremote.

the class AgentResourceImpl method getParentAssetAndRealmId.

/**
 * Parent takes priority over realm ID (only super user can add to other realms)
 */
protected Pair<Asset, String> getParentAssetAndRealmId(String parentId, String realmId) {
    if (isRestrictedUser()) {
        throw new ForbiddenException("User is restricted");
    }
    // Assets must be added in the same realm as the user (unless super user)
    Asset parentAsset = isNullOrEmpty(parentId) ? null : assetStorageService.find(parentId);
    if (parentAsset == null && !isNullOrEmpty(parentId)) {
        // Either invalid asset or user doesn't have access to it
        LOG.info("User is trying to import with an invalid or inaccessible parent");
        throw new BadRequestException("Parent either doesn't exist or is not accessible");
    }
    Tenant tenant = parentAsset != null ? identityService.getIdentityProvider().getTenantForRealmId(parentAsset.getRealmId()) : !isNullOrEmpty(realmId) ? identityService.getIdentityProvider().getTenantForRealmId(realmId) : getAuthenticatedTenant();
    if (!isTenantActiveAndAccessible(tenant)) {
        String msg = "The requested parent asset or realm is inaccessible";
        LOG.fine(msg);
        throw new ForbiddenException(msg);
    }
    return new Pair<>(parentAsset, tenant.getId());
}
Also used : Tenant(org.openremote.model.security.Tenant) ServerAsset(org.openremote.manager.asset.ServerAsset) Asset(org.openremote.model.asset.Asset) Pair(org.openremote.model.util.Pair)

Example 33 with Asset

use of org.openremote.model.asset.Asset in project openremote by openremote.

the class AgentResourceImpl method searchForLinkedAttributes.

@Override
public Asset[] searchForLinkedAttributes(RequestParams requestParams, String agentId, String protocolConfigurationName, String parentId, String realmId) {
    AttributeRef protocolConfigRef = new AttributeRef(agentId, protocolConfigurationName);
    Pair<Asset, String> parentAndRealmId = getParentAssetAndRealmId(parentId, realmId);
    // TODO: Allow user to select which assets/attributes are actually added to the DB
    Asset[] assets = withAgentConnector(agentId, agentConnector -> {
        LOG.finer("Asking connector '" + agentConnector.value.getClass().getSimpleName() + "' to do linked attribute discovery for protocol configuration: " + protocolConfigRef);
        return agentConnector.value.getDiscoveredLinkedAttributes(protocolConfigRef);
    });
    try {
        persistAssets(assets, parentAndRealmId.key, parentAndRealmId.value);
        return assets;
    } catch (IllegalArgumentException e) {
        LOG.log(Level.WARNING, e.getMessage(), e);
        throw new NotFoundException(e.getMessage());
    } catch (UnsupportedOperationException e) {
        LOG.log(Level.WARNING, e.getMessage(), e);
        throw new NotSupportedException(e.getMessage());
    }
}
Also used : AttributeRef(org.openremote.model.attribute.AttributeRef) ServerAsset(org.openremote.manager.asset.ServerAsset) Asset(org.openremote.model.asset.Asset)

Example 34 with Asset

use of org.openremote.model.asset.Asset in project openremote by openremote.

the class AssetProcessingService method configure.

@Override
public void configure() throws Exception {
    // A client wants to write attribute state through event bus
    from(CLIENT_EVENT_TOPIC).routeId("FromClientUpdates").filter(body().isInstanceOf(AttributeEvent.class)).setHeader(HEADER_SOURCE, () -> CLIENT).to(ASSET_QUEUE);
    // Process attribute events
    /* TODO This message consumer should be transactionally consistent with the database, this is currently not the case

         Our "if I have not processed this message before" duplicate detection:

          - discard events with source time greater than server processing time (future events)
          - discard events with source time less than last applied/stored event source time
          - allow the rest (also events with same source time, order of application undefined)

         Possible improvements moving towards at-least-once:

         - Make AssetUpdateProcessor transactional with a two-phase commit API
         - Replace at-most-once ClientEventService with at-least-once capable, embeddable message broker/protocol
         - See pseudocode here: http://activemq.apache.org/should-i-use-xa.html
         - Do we want JMS/AMQP/WSS or SOME_API/MQTT/WSS? ActiveMQ or Moquette?
        */
    from(ASSET_QUEUE).routeId("AssetQueueProcessor").filter(body().isInstanceOf(AttributeEvent.class)).doTry().process(exchange -> withLock(getClass().getSimpleName() + "::processFromAssetQueue", () -> {
        AttributeEvent event = exchange.getIn().getBody(AttributeEvent.class);
        LOG.finest("Processing: " + event);
        if (event.getEntityId() == null || event.getEntityId().isEmpty())
            return;
        if (event.getAttributeName() == null || event.getAttributeName().isEmpty())
            return;
        Source source = exchange.getIn().getHeader(HEADER_SOURCE, () -> null, Source.class);
        if (source == null) {
            throw new AssetProcessingException(MISSING_SOURCE);
        }
        // Process the asset update in a database transaction, this ensures that processors
        // will see consistent database state and we only commit if no processor failed. This
        // still won't make this procedure consistent with the message queue from which we consume!
        persistenceService.doTransaction(em -> {
            ServerAsset asset = assetStorageService.find(em, event.getEntityId(), true);
            if (asset == null)
                throw new AssetProcessingException(ASSET_NOT_FOUND);
            AssetAttribute oldAttribute = asset.getAttribute(event.getAttributeName()).orElse(null);
            if (oldAttribute == null)
                throw new AssetProcessingException(ATTRIBUTE_NOT_FOUND);
            // Agent attributes can't be updated with events
            if (asset.getWellKnownType() == AssetType.AGENT) {
                throw new AssetProcessingException(ILLEGAL_AGENT_UPDATE);
            }
            // For executable attributes, non-sensor sources can set a writable attribute execute status
            if (oldAttribute.isExecutable() && source != SENSOR) {
                Optional<AttributeExecuteStatus> status = event.getValue().flatMap(Values::getString).flatMap(AttributeExecuteStatus::fromString);
                if (status.isPresent() && !status.get().isWrite()) {
                    throw new AssetProcessingException(INVALID_ATTRIBUTE_EXECUTE_STATUS);
                }
            }
            switch(source) {
                case CLIENT:
                    AuthContext authContext = exchange.getIn().getHeader(Constants.AUTH_CONTEXT, AuthContext.class);
                    if (authContext == null) {
                        throw new AssetProcessingException(NO_AUTH_CONTEXT);
                    }
                    // Check realm, must be accessible
                    if (!identityService.getIdentityProvider().isTenantActiveAndAccessible(authContext, asset)) {
                        throw new AssetProcessingException(INSUFFICIENT_ACCESS);
                    }
                    // Check read-only
                    if (oldAttribute.isReadOnly() && !authContext.isSuperUser()) {
                        throw new AssetProcessingException(INSUFFICIENT_ACCESS);
                    }
                    // Regular user must have write assets role
                    if (!authContext.hasResourceRoleOrIsSuperUser(ClientRole.WRITE_ASSETS.getValue(), Constants.KEYCLOAK_CLIENT_ID)) {
                        throw new AssetProcessingException(INSUFFICIENT_ACCESS);
                    }
                    // Check restricted user
                    if (identityService.getIdentityProvider().isRestrictedUser(authContext.getUserId())) {
                        // Must be asset linked to user
                        if (!assetStorageService.isUserAsset(authContext.getUserId(), event.getEntityId())) {
                            throw new AssetProcessingException(INSUFFICIENT_ACCESS);
                        }
                        // Must be writable by restricted client
                        if (!oldAttribute.isAccessRestrictedWrite()) {
                            throw new AssetProcessingException(INSUFFICIENT_ACCESS);
                        }
                    }
                    break;
                case SENSOR:
                    Optional<AssetAttribute> protocolConfiguration = getAgentLink(oldAttribute).flatMap(agentService::getProtocolConfiguration);
                    // Sensor event must be for an attribute linked to a protocol configuration
                    if (!protocolConfiguration.isPresent()) {
                        throw new AssetProcessingException(INVALID_AGENT_LINK);
                    }
                    break;
            }
            // Either use the timestamp of the event or set event time to processing time
            long processingTime = timerService.getCurrentTimeMillis();
            long eventTime = event.getTimestamp() > 0 ? event.getTimestamp() : processingTime;
            // the attribute until after that time (maybe that is desirable behaviour)
            if (eventTime - processingTime > 0) {
                // TODO: Decide how to handle update events in the future - ignore or change timestamp
                throw new AssetProcessingException(EVENT_IN_FUTURE, "current time: " + new Date(processingTime) + "/" + processingTime + ", event time: " + new Date(eventTime) + "/" + eventTime);
            }
            // Check the last update timestamp of the attribute, ignoring any event that is older than last update
            // TODO This means we drop out-of-sequence events but accept events with the same source timestamp
            // TODO Several attribute events can occur in the same millisecond, then order of application is undefined
            oldAttribute.getValueTimestamp().filter(t -> t >= 0 && eventTime < t).ifPresent(lastStateTime -> {
                throw new AssetProcessingException(EVENT_OUTDATED, "last asset state time: " + new Date(lastStateTime) + "/" + lastStateTime + ", event time: " + new Date(eventTime) + "/" + eventTime);
            });
            // Create a copy of the attribute and set the new value and timestamp
            AssetAttribute updatedAttribute = oldAttribute.deepCopy();
            updatedAttribute.setValue(event.getValue().orElse(null), eventTime);
            // Validate constraints of attribute
            List<ValidationFailure> validationFailures = updatedAttribute.getValidationFailures();
            if (!validationFailures.isEmpty()) {
                throw new AssetProcessingException(ATTRIBUTE_VALIDATION_FAILURE, validationFailures.toString());
            }
            // Push through all processors
            boolean consumedCompletely = processAssetUpdate(em, asset, updatedAttribute, source);
            // Publish a new event for clients if no processor consumed the update completely
            if (!consumedCompletely) {
                publishClientEvent(asset, updatedAttribute);
            }
        });
    })).endDoTry().doCatch(AssetProcessingException.class).process(handleAssetProcessingException(LOG));
}
Also used : ClientRole(org.openremote.model.security.ClientRole) AuthContext(org.openremote.container.security.AuthContext) AssetDatapointService(org.openremote.manager.datapoint.AssetDatapointService) Date(java.util.Date) CLIENT_EVENT_TOPIC(org.openremote.manager.event.ClientEventService.CLIENT_EVENT_TOPIC) ValidationFailure(org.openremote.model.ValidationFailure) Exchange(org.apache.camel.Exchange) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) Processor(org.apache.camel.Processor) Container(org.openremote.container.Container) ContainerService(org.openremote.container.ContainerService) RulesService(org.openremote.manager.rules.RulesService) AttributeEvent(org.openremote.model.attribute.AttributeEvent) PersistenceService(org.openremote.container.persistence.PersistenceService) AgentService(org.openremote.manager.agent.AgentService) AgentLink.getAgentLink(org.openremote.model.asset.agent.AgentLink.getAgentLink) MessageBrokerService(org.openremote.container.message.MessageBrokerService) ManagerIdentityService(org.openremote.manager.security.ManagerIdentityService) Asset(org.openremote.model.asset.Asset) AssetType(org.openremote.model.asset.AssetType) EntityManager(javax.persistence.EntityManager) Constants(org.openremote.model.Constants) Logger(java.util.logging.Logger) MessageBrokerSetupService(org.openremote.container.message.MessageBrokerSetupService) Collectors(java.util.stream.Collectors) Reason(org.openremote.manager.asset.AssetProcessingException.Reason) AssetResource(org.openremote.model.asset.AssetResource) HEADER_SOURCE(org.openremote.model.attribute.AttributeEvent.HEADER_SOURCE) Value(org.openremote.model.value.Value) ClientEventService(org.openremote.manager.event.ClientEventService) List(java.util.List) RouteBuilder(org.apache.camel.builder.RouteBuilder) TimerService(org.openremote.container.timer.TimerService) Optional(java.util.Optional) Source(org.openremote.model.attribute.AttributeEvent.Source) Values(org.openremote.model.value.Values) AssetAttribute(org.openremote.model.asset.AssetAttribute) Protocol(org.openremote.agent.protocol.Protocol) AttributeExecuteStatus(org.openremote.model.attribute.AttributeExecuteStatus) GlobalLock.withLock(org.openremote.container.concurrent.GlobalLock.withLock) AuthContext(org.openremote.container.security.AuthContext) AttributeEvent(org.openremote.model.attribute.AttributeEvent) Source(org.openremote.model.attribute.AttributeEvent.Source) Date(java.util.Date) ValidationFailure(org.openremote.model.ValidationFailure) AttributeExecuteStatus(org.openremote.model.attribute.AttributeExecuteStatus) AssetAttribute(org.openremote.model.asset.AssetAttribute)

Example 35 with Asset

use of org.openremote.model.asset.Asset in project openremote by openremote.

the class AssetBrowserPresenter method loadAssets.

protected void loadAssets(BrowserTreeNode parent, HasData<BrowserTreeNode> display) {
    // TODO Pagination?
    // final Range range = display.getVisibleRange();
    environment.getApp().getRequests().sendWithAndReturn(assetArrayMapper, assetQueryMapper, requestParams -> {
        if (parent instanceof TenantTreeNode) {
            assetResource.queryAssets(requestParams, new AssetQuery().tenant(new AssetQuery.TenantPredicate(parent.getId())).parent(new AssetQuery.ParentPredicate(true)));
        } else if (parent instanceof RootTreeNode) {
            assetResource.getCurrentUserAssets(requestParams);
        } else {
            assetResource.queryAssets(requestParams, new AssetQuery().parent(parent.getId()));
        }
    }, 200, assets -> {
        List<BrowserTreeNode> treeNodes = new ArrayList<>();
        for (Asset asset : assets) {
            treeNodes.add(new AssetTreeNode(asset));
        }
        display.setRowData(0, treeNodes);
        display.setRowCount(assets.length, true);
        afterNodeLoadChildren(treeNodes);
    });
}
Also used : AssetQuery(org.openremote.model.asset.AssetQuery) ArrayList(java.util.ArrayList) Asset(org.openremote.model.asset.Asset)

Aggregations

Asset (org.openremote.model.asset.Asset)45 Logger (java.util.logging.Logger)20 java.util (java.util)18 Level (java.util.logging.Level)18 Collectors (java.util.stream.Collectors)18 AssetQuery (org.openremote.model.query.AssetQuery)15 AssetStorageService (org.openremote.manager.asset.AssetStorageService)14 ManagerIdentityService (org.openremote.manager.security.ManagerIdentityService)14 MessageBrokerService (org.openremote.container.message.MessageBrokerService)13 TimerService (org.openremote.container.timer.TimerService)13 Container (org.openremote.model.Container)13 RouteBuilder (org.apache.camel.builder.RouteBuilder)12 ContainerService (org.openremote.model.ContainerService)11 PersistenceEvent (org.openremote.model.PersistenceEvent)11 Attribute (org.openremote.model.attribute.Attribute)11 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)10 ClientEventService (org.openremote.manager.event.ClientEventService)10 EntityManager (javax.persistence.EntityManager)9 Tenant (org.openremote.model.security.Tenant)9 Pair (org.openremote.model.util.Pair)9