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);
}
}
}
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);
}
}
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);
}
}
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);
}
}
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;
}
}
}
Aggregations