Search in sources :

Example 1 with GatewayAsset

use of org.openremote.model.asset.impl.GatewayAsset in project openremote by openremote.

the class GatewayService method start.

@Override
public void start(Container container) throws Exception {
    if (!active) {
        return;
    }
    List<GatewayAsset> gateways = assetStorageService.findAll(new AssetQuery().types(GatewayAsset.class)).stream().map(asset -> (GatewayAsset) asset).collect(Collectors.toList());
    List<String> gatewayIds = gateways.stream().map(Asset::getId).collect(Collectors.toList());
    gateways = gateways.stream().filter(gateway -> Arrays.stream(gateway.getPath()).noneMatch(p -> !p.equals(gateway.getId()) && gatewayIds.contains(p))).collect(Collectors.toList());
    if (!gateways.isEmpty()) {
        LOG.info("Directly registered gateways found = " + gateways.size());
        gateways.forEach(gateway -> {
            // Check if client has been created
            boolean hasClientId = gateway.getClientId().isPresent();
            boolean hasClientSecret = gateway.getClientSecret().isPresent();
            if (!hasClientId || !hasClientSecret) {
                createUpdateGatewayServiceUser(gateway);
            }
            // Create connector
            GatewayConnector connector = new GatewayConnector(assetStorageService, assetProcessingService, executorService, gateway);
            gatewayConnectorMap.put(gateway.getId().toLowerCase(Locale.ROOT), connector);
            // Get IDs of all assets under this gateway
            List<Asset<?>> gatewayAssets = assetStorageService.findAll(new AssetQuery().parents(gateway.getId()).select(new AssetQuery.Select().excludeAttributes()).recursive(true));
            gatewayAssets.forEach(asset -> assetIdGatewayIdMap.put(asset.getId(), gateway.getId()));
        });
    }
}
Also used : AssetStorageService(org.openremote.manager.asset.AssetStorageService) Tenant(org.openremote.model.security.Tenant) IntStream(java.util.stream.IntStream) ManagerKeycloakIdentityProvider(org.openremote.manager.security.ManagerKeycloakIdentityProvider) java.util(java.util) GATEWAY(org.openremote.model.syslog.SyslogCategory.GATEWAY) AssetProcessingException(org.openremote.manager.asset.AssetProcessingException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Exchange(org.apache.camel.Exchange) AssetProcessingService(org.openremote.manager.asset.AssetProcessingService) Level(java.util.logging.Level) Predicate(org.apache.camel.Predicate) RulesetStorageService(org.openremote.manager.rules.RulesetStorageService) RulesService(org.openremote.manager.rules.RulesService) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) SyslogCategory(org.openremote.model.syslog.SyslogCategory) TextUtil(org.openremote.model.util.TextUtil) PersistenceEvent(org.openremote.model.PersistenceEvent) MessageBrokerService(org.openremote.container.message.MessageBrokerService) User(org.openremote.model.security.User) Ruleset(org.openremote.model.rules.Ruleset) ManagerIdentityService(org.openremote.manager.security.ManagerIdentityService) Asset(org.openremote.model.asset.Asset) GatewayDisconnectEvent(org.openremote.model.gateway.GatewayDisconnectEvent) AssetQuery(org.openremote.model.query.AssetQuery) GatewayAsset(org.openremote.model.asset.impl.GatewayAsset) ContainerService(org.openremote.model.ContainerService) EntityManager(javax.persistence.EntityManager) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Container(org.openremote.model.Container) Consumer(java.util.function.Consumer) ClientEventService(org.openremote.manager.event.ClientEventService) RouteBuilder(org.apache.camel.builder.RouteBuilder) PERSISTENCE_TOPIC(org.openremote.container.persistence.PersistenceService.PERSISTENCE_TOPIC) GatewayConnector.mapAssetId(org.openremote.manager.gateway.GatewayConnector.mapAssetId) org.openremote.model.attribute(org.openremote.model.attribute) AssetUpdateProcessor(org.openremote.manager.asset.AssetUpdateProcessor) PredicateBuilder.and(org.apache.camel.builder.PredicateBuilder.and) PredicateBuilder.or(org.apache.camel.builder.PredicateBuilder.or) PersistenceService.isPersistenceEventForEntityType(org.openremote.container.persistence.PersistenceService.isPersistenceEventForEntityType) ConnectionConstants(org.openremote.container.web.ConnectionConstants) SharedEvent(org.openremote.model.event.shared.SharedEvent) AssetQuery(org.openremote.model.query.AssetQuery) Asset(org.openremote.model.asset.Asset) GatewayAsset(org.openremote.model.asset.impl.GatewayAsset) GatewayAsset(org.openremote.model.asset.impl.GatewayAsset)

Example 2 with GatewayAsset

use of org.openremote.model.asset.impl.GatewayAsset in project openremote by openremote.

the class GatewayService method processAssetUpdate.

@Override
public boolean processAssetUpdate(EntityManager em, Asset<?> asset, Attribute<?> attribute, AttributeEvent.Source source) throws AssetProcessingException {
    // If the update was generated by a gateway then we don't want to process it here
    if (source == AttributeEvent.Source.GATEWAY) {
        return false;
    }
    GatewayConnector connector = gatewayConnectorMap.get(asset.getId().toLowerCase(Locale.ROOT));
    if (connector != null) {
        LOG.fine("Attribute event for a locally registered gateway asset (Asset ID=" + asset.getId() + "): " + attribute);
        GatewayAsset gatewayAsset = (GatewayAsset) asset;
        // This is a change to a locally registered gateway
        if (GatewayAsset.DISABLED.getName().equals(attribute.getName())) {
            boolean disabled = attribute.getValueAs(Boolean.class).orElse(false);
            boolean isAlreadyDisabled = gatewayAsset.getDisabled().orElse(false);
            // Ensure we update state
            gatewayAsset.setDisabled(disabled);
            if (disabled != isAlreadyDisabled) {
                createUpdateGatewayServiceUser(gatewayAsset);
                if (disabled) {
                    connector.sendMessageToGateway(new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.DISABLED));
                }
                connector.setDisabled(disabled);
            }
        }
        if (GatewayAsset.CLIENT_SECRET.getName().equals(attribute.getName())) {
            String newSecret = attribute.getValueAs(String.class).orElse(null);
            if (!TextUtil.isNullOrEmpty(newSecret)) {
                LOG.fine("Gateway client secret attribute updated so updating gateway service user secret to match: (Gateway ID=" + asset.getId() + ")");
                User gatewayServiceUser = identityProvider.getUserByUsername(asset.getRealm(), User.SERVICE_ACCOUNT_PREFIX + ((GatewayAsset) asset).getClientId().orElse(""));
                if (gatewayServiceUser != null) {
                    identityProvider.resetSecret(asset.getRealm(), gatewayServiceUser.getId(), newSecret);
                } else {
                    LOG.info("Couldn't retrieve gateway service user to update secret: (Gateway ID=" + asset.getId() + ")");
                }
            } else {
                // Push old secret back
                assetProcessingService.sendAttributeEvent(new AttributeEvent(asset.getId(), GatewayAsset.CLIENT_SECRET, gatewayAsset.getClientSecret().orElseThrow(() -> new IllegalStateException("Gateway client secret is null which was not expected"))));
            }
        }
    } else {
        String gatewayId = assetIdGatewayIdMap.get(asset.getId());
        if (gatewayId != null) {
            LOG.fine("Attribute event for a gateway descendant asset (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + "): " + attribute);
            connector = gatewayConnectorMap.get(gatewayId.toLowerCase(Locale.ROOT));
            if (connector == null) {
                LOG.warning("Gateway not found for descendant asset, this should not happen!!! (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + ")");
            } else {
                if (!connector.isConnected()) {
                    LOG.info("Gateway is not connected so attribute event for descendant asset will be dropped (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + "): " + attribute);
                    throw new AssetProcessingException(AttributeWriteFailure.GATEWAY_DISCONNECTED, "Gateway is not connected: Gateway ID=" + connector.gatewayId);
                }
                LOG.fine("Attribute event for a gateway descendant asset being forwarded to the gateway (Asset<?> ID=" + asset.getId() + ", Gateway ID=" + gatewayId + "): " + attribute);
                connector.sendMessageToGateway(new AttributeEvent(mapAssetId(gatewayId, asset.getId(), true), attribute.getName(), attribute.getValue().orElse(null), attribute.getTimestamp().orElse(0L)).setParentId(mapAssetId(gatewayId, asset.getParentId(), true)).setRealm(asset.getRealm()));
            }
            // Consume this event as it is for a gateway descendant and we've sent it to that gateway for processing
            return true;
        }
    }
    // Don't consume event for non gateway descendant assets
    return false;
}
Also used : User(org.openremote.model.security.User) GatewayDisconnectEvent(org.openremote.model.gateway.GatewayDisconnectEvent) GatewayAsset(org.openremote.model.asset.impl.GatewayAsset) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AssetProcessingException(org.openremote.manager.asset.AssetProcessingException)

Example 3 with GatewayAsset

use of org.openremote.model.asset.impl.GatewayAsset in project openremote by openremote.

the class GatewayService method processGatewayChange.

protected void processGatewayChange(GatewayAsset gateway, PersistenceEvent<Asset<?>> persistenceEvent) {
    switch(persistenceEvent.getCause()) {
        case CREATE:
            createUpdateGatewayServiceUser(gateway);
            synchronized (gatewayConnectorMap) {
                GatewayConnector connector = new GatewayConnector(assetStorageService, assetProcessingService, executorService, gateway);
                gatewayConnectorMap.put(gateway.getId().toLowerCase(Locale.ROOT), connector);
            }
            break;
        case UPDATE:
            // Check if this gateway has a connector
            GatewayConnector connector = gatewayConnectorMap.get(gateway.getId().toLowerCase(Locale.ROOT));
            if (connector == null) {
                break;
            }
            connector.gateway = gateway;
            // Check if disabled
            boolean isNowDisabled = gateway.getDisabled().orElse(false);
            if (isNowDisabled) {
                connector.sendMessageToGateway(new GatewayDisconnectEvent(GatewayDisconnectEvent.Reason.DISABLED));
            }
            connector.setDisabled(isNowDisabled);
            int attributeIndex = persistenceEvent.getPropertyNames() != null ? IntStream.range(0, persistenceEvent.getPropertyNames().length).filter(i -> "attributes".equals(persistenceEvent.getPropertyNames()[i])).findFirst().orElse(-1) : -1;
            if (attributeIndex >= 0) {
                // Check if disabled attribute has changed
                AttributeMap oldAttributes = persistenceEvent.getPreviousState("attributes");
                boolean wasDisabled = oldAttributes.getValue(GatewayAsset.DISABLED).orElse(false);
                if (wasDisabled != isNowDisabled) {
                    createUpdateGatewayServiceUser(gateway);
                }
            }
            break;
        case DELETE:
            // Check if this gateway has a connector
            connector = gatewayConnectorMap.get(gateway.getId().toLowerCase(Locale.ROOT));
            if (connector == null) {
                break;
            }
            synchronized (gatewayConnectorMap) {
                connector = gatewayConnectorMap.remove(gateway.getId().toLowerCase(Locale.ROOT));
                if (connector != null) {
                    connector.disconnect();
                }
            }
            removeGatewayServiceUser(gateway);
            break;
    }
}
Also used : AssetStorageService(org.openremote.manager.asset.AssetStorageService) Tenant(org.openremote.model.security.Tenant) IntStream(java.util.stream.IntStream) ManagerKeycloakIdentityProvider(org.openremote.manager.security.ManagerKeycloakIdentityProvider) java.util(java.util) GATEWAY(org.openremote.model.syslog.SyslogCategory.GATEWAY) AssetProcessingException(org.openremote.manager.asset.AssetProcessingException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Exchange(org.apache.camel.Exchange) AssetProcessingService(org.openremote.manager.asset.AssetProcessingService) Level(java.util.logging.Level) Predicate(org.apache.camel.Predicate) RulesetStorageService(org.openremote.manager.rules.RulesetStorageService) RulesService(org.openremote.manager.rules.RulesService) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) SyslogCategory(org.openremote.model.syslog.SyslogCategory) TextUtil(org.openremote.model.util.TextUtil) PersistenceEvent(org.openremote.model.PersistenceEvent) MessageBrokerService(org.openremote.container.message.MessageBrokerService) User(org.openremote.model.security.User) Ruleset(org.openremote.model.rules.Ruleset) ManagerIdentityService(org.openremote.manager.security.ManagerIdentityService) Asset(org.openremote.model.asset.Asset) GatewayDisconnectEvent(org.openremote.model.gateway.GatewayDisconnectEvent) AssetQuery(org.openremote.model.query.AssetQuery) GatewayAsset(org.openremote.model.asset.impl.GatewayAsset) ContainerService(org.openremote.model.ContainerService) EntityManager(javax.persistence.EntityManager) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Container(org.openremote.model.Container) Consumer(java.util.function.Consumer) ClientEventService(org.openremote.manager.event.ClientEventService) RouteBuilder(org.apache.camel.builder.RouteBuilder) PERSISTENCE_TOPIC(org.openremote.container.persistence.PersistenceService.PERSISTENCE_TOPIC) GatewayConnector.mapAssetId(org.openremote.manager.gateway.GatewayConnector.mapAssetId) org.openremote.model.attribute(org.openremote.model.attribute) AssetUpdateProcessor(org.openremote.manager.asset.AssetUpdateProcessor) PredicateBuilder.and(org.apache.camel.builder.PredicateBuilder.and) PredicateBuilder.or(org.apache.camel.builder.PredicateBuilder.or) PersistenceService.isPersistenceEventForEntityType(org.openremote.container.persistence.PersistenceService.isPersistenceEventForEntityType) ConnectionConstants(org.openremote.container.web.ConnectionConstants) SharedEvent(org.openremote.model.event.shared.SharedEvent) GatewayDisconnectEvent(org.openremote.model.gateway.GatewayDisconnectEvent)

Aggregations

AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)3 AssetProcessingException (org.openremote.manager.asset.AssetProcessingException)3 GatewayAsset (org.openremote.model.asset.impl.GatewayAsset)3 GatewayDisconnectEvent (org.openremote.model.gateway.GatewayDisconnectEvent)3 User (org.openremote.model.security.User)3 java.util (java.util)2 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)2 Consumer (java.util.function.Consumer)2 Level (java.util.logging.Level)2 Logger (java.util.logging.Logger)2 Collectors (java.util.stream.Collectors)2 IntStream (java.util.stream.IntStream)2 EntityManager (javax.persistence.EntityManager)2 Exchange (org.apache.camel.Exchange)2 Predicate (org.apache.camel.Predicate)2 PredicateBuilder.and (org.apache.camel.builder.PredicateBuilder.and)2 PredicateBuilder.or (org.apache.camel.builder.PredicateBuilder.or)2 RouteBuilder (org.apache.camel.builder.RouteBuilder)2 MessageBrokerService (org.openremote.container.message.MessageBrokerService)2 PERSISTENCE_TOPIC (org.openremote.container.persistence.PersistenceService.PERSISTENCE_TOPIC)2