Search in sources :

Example 1 with TopicPartitionInfo

use of org.thingsboard.server.common.msg.queue.TopicPartitionInfo in project thingsboard by thingsboard.

the class DefaultSubscriptionManagerService method handleNewTelemetrySubscription.

private void handleNewTelemetrySubscription(TbTimeseriesSubscription subscription) {
    log.trace("[{}][{}][{}] Processing remote telemetry subscription for entity [{}]", serviceId, subscription.getSessionId(), subscription.getSubscriptionId(), subscription.getEntityId());
    long curTs = System.currentTimeMillis();
    if (subscription.isLatestValues()) {
        DonAsynchron.withCallback(tsService.findLatest(subscription.getTenantId(), subscription.getEntityId(), subscription.getKeyStates().keySet()), missedUpdates -> {
            if (missedUpdates != null && !missedUpdates.isEmpty()) {
                TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, subscription.getServiceId());
                toCoreNotificationsProducer.send(tpi, toProto(subscription, missedUpdates), null);
            }
        }, e -> log.error("Failed to fetch missed updates.", e), tsCallBackExecutor);
    } else {
        List<ReadTsKvQuery> queries = new ArrayList<>();
        subscription.getKeyStates().forEach((key, value) -> {
            if (curTs > value) {
                long startTs = subscription.getStartTime() > 0 ? Math.max(subscription.getStartTime(), value + 1L) : (value + 1L);
                long endTs = subscription.getEndTime() > 0 ? Math.min(subscription.getEndTime(), curTs) : curTs;
                queries.add(new BaseReadTsKvQuery(key, startTs, endTs, 0, 1000, Aggregation.NONE));
            }
        });
        if (!queries.isEmpty()) {
            DonAsynchron.withCallback(tsService.findAll(subscription.getTenantId(), subscription.getEntityId(), queries), missedUpdates -> {
                if (missedUpdates != null && !missedUpdates.isEmpty()) {
                    TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, subscription.getServiceId());
                    toCoreNotificationsProducer.send(tpi, toProto(subscription, missedUpdates), null);
                }
            }, e -> log.error("Failed to fetch missed updates.", e), tsCallBackExecutor);
        }
    }
}
Also used : TopicPartitionInfo(org.thingsboard.server.common.msg.queue.TopicPartitionInfo) BaseReadTsKvQuery(org.thingsboard.server.common.data.kv.BaseReadTsKvQuery) ReadTsKvQuery(org.thingsboard.server.common.data.kv.ReadTsKvQuery) ArrayList(java.util.ArrayList) BaseReadTsKvQuery(org.thingsboard.server.common.data.kv.BaseReadTsKvQuery)

Example 2 with TopicPartitionInfo

use of org.thingsboard.server.common.msg.queue.TopicPartitionInfo in project thingsboard by thingsboard.

the class DefaultSubscriptionManagerService method removeSubscriptionFromPartitionMap.

private void removeSubscriptionFromPartitionMap(TbSubscription sub) {
    TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, sub.getTenantId(), sub.getEntityId());
    Set<TbSubscription> subs = partitionedSubscriptions.get(tpi);
    if (subs != null) {
        subs.remove(sub);
    }
}
Also used : TopicPartitionInfo(org.thingsboard.server.common.msg.queue.TopicPartitionInfo)

Example 3 with TopicPartitionInfo

use of org.thingsboard.server.common.msg.queue.TopicPartitionInfo in project thingsboard by thingsboard.

the class DefaultSubscriptionManagerService method onLocalTelemetrySubUpdate.

private <T extends TbSubscription> void onLocalTelemetrySubUpdate(EntityId entityId, Function<TbSubscription, T> castFunction, Predicate<T> filterFunction, Function<T, List<TsKvEntry>> processFunction, boolean ignoreEmptyUpdates) {
    Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId);
    if (entitySubscriptions != null) {
        entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> {
            List<TsKvEntry> subscriptionUpdate = processFunction.apply(s);
            if (subscriptionUpdate != null && !subscriptionUpdate.isEmpty()) {
                if (serviceId.equals(s.getServiceId())) {
                    TelemetrySubscriptionUpdate update = new TelemetrySubscriptionUpdate(s.getSubscriptionId(), subscriptionUpdate);
                    localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY);
                } else {
                    TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId());
                    toCoreNotificationsProducer.send(tpi, toProto(s, subscriptionUpdate, ignoreEmptyUpdates), null);
                }
            }
        });
    } else {
        log.debug("[{}] No device subscriptions to process!", entityId);
    }
}
Also used : BasicTsKvEntry(org.thingsboard.server.common.data.kv.BasicTsKvEntry) TsKvEntry(org.thingsboard.server.common.data.kv.TsKvEntry) TelemetrySubscriptionUpdate(org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate) TopicPartitionInfo(org.thingsboard.server.common.msg.queue.TopicPartitionInfo) Objects(java.util.Objects)

Example 4 with TopicPartitionInfo

use of org.thingsboard.server.common.msg.queue.TopicPartitionInfo in project thingsboard by thingsboard.

the class DefaultSubscriptionManagerService method onLocalAlarmSubUpdate.

private void onLocalAlarmSubUpdate(EntityId entityId, Function<TbSubscription, TbAlarmsSubscription> castFunction, Predicate<TbAlarmsSubscription> filterFunction, Function<TbAlarmsSubscription, Alarm> processFunction, boolean deleted) {
    Set<TbSubscription> entitySubscriptions = subscriptionsByEntityId.get(entityId);
    if (entitySubscriptions != null) {
        entitySubscriptions.stream().map(castFunction).filter(Objects::nonNull).filter(filterFunction).forEach(s -> {
            Alarm alarm = processFunction.apply(s);
            if (alarm != null) {
                if (serviceId.equals(s.getServiceId())) {
                    AlarmSubscriptionUpdate update = new AlarmSubscriptionUpdate(s.getSubscriptionId(), alarm, deleted);
                    localSubscriptionService.onSubscriptionUpdate(s.getSessionId(), update, TbCallback.EMPTY);
                } else {
                    TopicPartitionInfo tpi = partitionService.getNotificationsTopic(ServiceType.TB_CORE, s.getServiceId());
                    toCoreNotificationsProducer.send(tpi, toProto(s, alarm, deleted), null);
                }
            }
        });
    } else {
        log.debug("[{}] No device subscriptions to process!", entityId);
    }
}
Also used : TopicPartitionInfo(org.thingsboard.server.common.msg.queue.TopicPartitionInfo) AlarmSubscriptionUpdate(org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate) Alarm(org.thingsboard.server.common.data.alarm.Alarm) Objects(java.util.Objects)

Example 5 with TopicPartitionInfo

use of org.thingsboard.server.common.msg.queue.TopicPartitionInfo in project thingsboard by thingsboard.

the class DefaultSubscriptionManagerService method addSubscription.

@Override
public void addSubscription(TbSubscription subscription, TbCallback callback) {
    log.trace("[{}][{}][{}] Registering subscription for entity [{}]", subscription.getServiceId(), subscription.getSessionId(), subscription.getSubscriptionId(), subscription.getEntityId());
    TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_CORE, subscription.getTenantId(), subscription.getEntityId());
    if (currentPartitions.contains(tpi)) {
        partitionedSubscriptions.computeIfAbsent(tpi, k -> ConcurrentHashMap.newKeySet()).add(subscription);
        callback.onSuccess();
    } else {
        log.warn("[{}][{}] Entity belongs to external partition. Probably rebalancing is in progress. Topic: {}", subscription.getTenantId(), subscription.getEntityId(), tpi.getFullTopicName());
        callback.onFailure(new RuntimeException("Entity belongs to external partition " + tpi.getFullTopicName() + "!"));
    }
    boolean newSubscription = subscriptionsByEntityId.computeIfAbsent(subscription.getEntityId(), k -> ConcurrentHashMap.newKeySet()).add(subscription);
    subscriptionsByWsSessionId.computeIfAbsent(subscription.getSessionId(), k -> new ConcurrentHashMap<>()).put(subscription.getSubscriptionId(), subscription);
    if (newSubscription) {
        switch(subscription.getType()) {
            case TIMESERIES:
                handleNewTelemetrySubscription((TbTimeseriesSubscription) subscription);
                break;
            case ATTRIBUTES:
                handleNewAttributeSubscription((TbAttributeSubscription) subscription);
                break;
            case ALARMS:
                handleNewAlarmsSubscription((TbAlarmsSubscription) subscription);
                break;
        }
    }
}
Also used : DonAsynchron(org.thingsboard.common.util.DonAsynchron) Autowired(org.springframework.beans.factory.annotation.Autowired) ToCoreNotificationMsg(org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg) AlarmSubscriptionUpdate(org.thingsboard.server.service.telemetry.sub.AlarmSubscriptionUpdate) TenantId(org.thingsboard.server.common.data.id.TenantId) BasicTsKvEntry(org.thingsboard.server.common.data.kv.BasicTsKvEntry) AttributeKvEntry(org.thingsboard.server.common.data.kv.AttributeKvEntry) PreDestroy(javax.annotation.PreDestroy) Map(java.util.Map) EntityType(org.thingsboard.server.common.data.EntityType) DeviceAttributesEventNotificationMsg(org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg) LocalSubscriptionServiceMsgProto(org.thingsboard.server.gen.transport.TransportProtos.LocalSubscriptionServiceMsgProto) TbServiceInfoProvider(org.thingsboard.server.queue.discovery.TbServiceInfoProvider) AttributesService(org.thingsboard.server.dao.attributes.AttributesService) TbQueueProducer(org.thingsboard.server.queue.TbQueueProducer) BaseReadTsKvQuery(org.thingsboard.server.common.data.kv.BaseReadTsKvQuery) DeviceId(org.thingsboard.server.common.data.id.DeviceId) Predicate(java.util.function.Predicate) DeviceStateService(org.thingsboard.server.service.state.DeviceStateService) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TimeseriesService(org.thingsboard.server.dao.timeseries.TimeseriesService) Set(java.util.Set) ThingsBoardThreadFactory(org.thingsboard.common.util.ThingsBoardThreadFactory) Executors(java.util.concurrent.Executors) Alarm(org.thingsboard.server.common.data.alarm.Alarm) TbQueueProducerProvider(org.thingsboard.server.queue.provider.TbQueueProducerProvider) Objects(java.util.Objects) TsKvEntry(org.thingsboard.server.common.data.kv.TsKvEntry) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) KvEntry(org.thingsboard.server.common.data.kv.KvEntry) PostConstruct(javax.annotation.PostConstruct) TbClusterService(org.thingsboard.server.cluster.TbClusterService) TbSubscriptionUpdateProto(org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateProto) TopicPartitionInfo(org.thingsboard.server.common.msg.queue.TopicPartitionInfo) PartitionService(org.thingsboard.server.queue.discovery.PartitionService) JacksonUtil(org.thingsboard.common.util.JacksonUtil) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) HashSet(java.util.HashSet) TbCoreComponent(org.thingsboard.server.queue.util.TbCoreComponent) ServiceType(org.thingsboard.server.common.msg.queue.ServiceType) Service(org.springframework.stereotype.Service) EntityId(org.thingsboard.server.common.data.id.EntityId) TbApplicationEventListener(org.thingsboard.server.queue.discovery.TbApplicationEventListener) TbCallback(org.thingsboard.server.common.msg.queue.TbCallback) ExecutorService(java.util.concurrent.ExecutorService) DataConstants(org.thingsboard.server.common.data.DataConstants) TbSubscriptionUpdateTsValue(org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateTsValue) DefaultDeviceStateService(org.thingsboard.server.service.state.DefaultDeviceStateService) PartitionChangeEvent(org.thingsboard.server.queue.discovery.event.PartitionChangeEvent) Aggregation(org.thingsboard.server.common.data.kv.Aggregation) TreeMap(java.util.TreeMap) TbSubscriptionUpdateValueListProto(org.thingsboard.server.gen.transport.TransportProtos.TbSubscriptionUpdateValueListProto) TbAlarmSubscriptionUpdateProto(org.thingsboard.server.gen.transport.TransportProtos.TbAlarmSubscriptionUpdateProto) TelemetrySubscriptionUpdate(org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate) ReadTsKvQuery(org.thingsboard.server.common.data.kv.ReadTsKvQuery) TbProtoQueueMsg(org.thingsboard.server.queue.common.TbProtoQueueMsg) StringDataEntry(org.thingsboard.server.common.data.kv.StringDataEntry) TopicPartitionInfo(org.thingsboard.server.common.msg.queue.TopicPartitionInfo) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Aggregations

TopicPartitionInfo (org.thingsboard.server.common.msg.queue.TopicPartitionInfo)50 ArrayList (java.util.ArrayList)10 TransportProtos (org.thingsboard.server.gen.transport.TransportProtos)10 TenantId (org.thingsboard.server.common.data.id.TenantId)7 TbProtoQueueMsg (org.thingsboard.server.queue.common.TbProtoQueueMsg)7 EntityId (org.thingsboard.server.common.data.id.EntityId)6 TsKvEntry (org.thingsboard.server.common.data.kv.TsKvEntry)6 UUID (java.util.UUID)5 BasicTsKvEntry (org.thingsboard.server.common.data.kv.BasicTsKvEntry)5 HashSet (java.util.HashSet)4 Map (java.util.Map)4 Set (java.util.Set)4 PostConstruct (javax.annotation.PostConstruct)4 Slf4j (lombok.extern.slf4j.Slf4j)4 EntityType (org.thingsboard.server.common.data.EntityType)4 DeviceId (org.thingsboard.server.common.data.id.DeviceId)4 ServiceType (org.thingsboard.server.common.msg.queue.ServiceType)4 ToCoreNotificationMsg (org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg)4 ToRuleEngineMsg (org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg)4 ByteString (com.google.protobuf.ByteString)3