|
|
@ -15,10 +15,13 @@ |
|
|
*/ |
|
|
*/ |
|
|
package org.thingsboard.monitoring.service; |
|
|
package org.thingsboard.monitoring.service; |
|
|
|
|
|
|
|
|
|
|
|
import com.google.common.collect.Sets; |
|
|
import jakarta.annotation.PostConstruct; |
|
|
import jakarta.annotation.PostConstruct; |
|
|
import lombok.SneakyThrows; |
|
|
import lombok.SneakyThrows; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
import org.springframework.context.ApplicationContext; |
|
|
import org.springframework.context.ApplicationContext; |
|
|
import org.thingsboard.monitoring.client.TbClient; |
|
|
import org.thingsboard.monitoring.client.TbClient; |
|
|
import org.thingsboard.monitoring.client.WsClient; |
|
|
import org.thingsboard.monitoring.client.WsClient; |
|
|
@ -27,13 +30,26 @@ import org.thingsboard.monitoring.config.MonitoringConfig; |
|
|
import org.thingsboard.monitoring.config.MonitoringTarget; |
|
|
import org.thingsboard.monitoring.config.MonitoringTarget; |
|
|
import org.thingsboard.monitoring.data.Latencies; |
|
|
import org.thingsboard.monitoring.data.Latencies; |
|
|
import org.thingsboard.monitoring.data.MonitoredServiceKey; |
|
|
import org.thingsboard.monitoring.data.MonitoredServiceKey; |
|
|
|
|
|
import org.thingsboard.monitoring.data.ServiceFailureException; |
|
|
import org.thingsboard.monitoring.service.transport.TransportHealthChecker; |
|
|
import org.thingsboard.monitoring.service.transport.TransportHealthChecker; |
|
|
import org.thingsboard.monitoring.util.TbStopWatch; |
|
|
import org.thingsboard.monitoring.util.TbStopWatch; |
|
|
|
|
|
import org.thingsboard.server.common.data.EntityType; |
|
|
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityData; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityDataPageLink; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityDataQuery; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityDataSortOrder; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityKey; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityKeyType; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.EntityTypeFilter; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.TsValue; |
|
|
|
|
|
|
|
|
import java.net.InetAddress; |
|
|
import java.net.InetAddress; |
|
|
import java.net.URI; |
|
|
import java.net.URI; |
|
|
import java.net.URISyntaxException; |
|
|
import java.net.URISyntaxException; |
|
|
import java.util.Arrays; |
|
|
import java.util.Arrays; |
|
|
|
|
|
import java.util.Collections; |
|
|
|
|
|
import java.util.HashMap; |
|
|
import java.util.HashSet; |
|
|
import java.util.HashSet; |
|
|
import java.util.LinkedList; |
|
|
import java.util.LinkedList; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
@ -41,6 +57,7 @@ import java.util.Map; |
|
|
import java.util.Set; |
|
|
import java.util.Set; |
|
|
import java.util.UUID; |
|
|
import java.util.UUID; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
|
@Slf4j |
|
|
@Slf4j |
|
|
public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T extends MonitoringTarget> { |
|
|
public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T extends MonitoringTarget> { |
|
|
@ -61,6 +78,9 @@ public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T ext |
|
|
@Autowired |
|
|
@Autowired |
|
|
protected ApplicationContext applicationContext; |
|
|
protected ApplicationContext applicationContext; |
|
|
|
|
|
|
|
|
|
|
|
@Value("${monitoring.edqs.enabled:false}") |
|
|
|
|
|
private boolean edqsMonitoringEnabled; |
|
|
|
|
|
|
|
|
@PostConstruct |
|
|
@PostConstruct |
|
|
private void init() { |
|
|
private void init() { |
|
|
if (configs == null || configs.isEmpty()) { |
|
|
if (configs == null || configs.isEmpty()) { |
|
|
@ -108,6 +128,21 @@ public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T ext |
|
|
check(healthChecker, wsClient); |
|
|
check(healthChecker, wsClient); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (edqsMonitoringEnabled) { |
|
|
|
|
|
try { |
|
|
|
|
|
stopWatch.start(); |
|
|
|
|
|
checkEdqs(); |
|
|
|
|
|
reporter.reportLatency(Latencies.EDQS_QUERY, stopWatch.getTime()); |
|
|
|
|
|
|
|
|
|
|
|
reporter.serviceIsOk(MonitoredServiceKey.EDQS); |
|
|
|
|
|
} catch (ServiceFailureException e) { |
|
|
|
|
|
reporter.serviceFailure(MonitoredServiceKey.EDQS, e); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
reporter.serviceFailure(MonitoredServiceKey.GENERAL, e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
reporter.reportLatencies(tbClient); |
|
|
reporter.reportLatencies(tbClient); |
|
|
log.debug("Finished {}", getName()); |
|
|
log.debug("Finished {}", getName()); |
|
|
} catch (Throwable error) { |
|
|
} catch (Throwable error) { |
|
|
@ -149,6 +184,39 @@ public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T ext |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void checkEdqs() { |
|
|
|
|
|
EntityTypeFilter entityTypeFilter = new EntityTypeFilter(); |
|
|
|
|
|
entityTypeFilter.setEntityType(EntityType.DEVICE); |
|
|
|
|
|
EntityDataPageLink pageLink = new EntityDataPageLink(100, 0, null, new EntityDataSortOrder(new EntityKey(EntityKeyType.ENTITY_FIELD, "name"))); |
|
|
|
|
|
EntityDataQuery entityDataQuery = new EntityDataQuery(entityTypeFilter, pageLink, |
|
|
|
|
|
List.of(new EntityKey(EntityKeyType.ENTITY_FIELD, "name"), new EntityKey(EntityKeyType.ENTITY_FIELD, "type")), |
|
|
|
|
|
List.of(new EntityKey(EntityKeyType.TIME_SERIES, "testData")), |
|
|
|
|
|
Collections.emptyList()); |
|
|
|
|
|
|
|
|
|
|
|
PageData<EntityData> result = tbClient.findEntityDataByQuery(entityDataQuery); |
|
|
|
|
|
Set<UUID> devices = result.getData().stream() |
|
|
|
|
|
.map(entityData -> entityData.getEntityId().getId()) |
|
|
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
|
Set<UUID> missing = Sets.difference(new HashSet<>(this.devices), devices); |
|
|
|
|
|
if (!missing.isEmpty()) { |
|
|
|
|
|
throw new ServiceFailureException("Missing devices in the response: " + missing); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
result.getData().stream() |
|
|
|
|
|
.filter(entityData -> this.devices.contains(entityData.getEntityId().getId())) |
|
|
|
|
|
.forEach(entityData -> { |
|
|
|
|
|
Map<String, TsValue> values = new HashMap<>(entityData.getLatest().get(EntityKeyType.ENTITY_FIELD)); |
|
|
|
|
|
values.putAll(entityData.getLatest().get(EntityKeyType.TIME_SERIES)); |
|
|
|
|
|
|
|
|
|
|
|
Stream.of("name", "type", "testData").forEach(key -> { |
|
|
|
|
|
TsValue value = values.get(key); |
|
|
|
|
|
if (value == null || StringUtils.isBlank(value.getValue())) { |
|
|
|
|
|
throw new ServiceFailureException("Missing " + key + " for device " + entityData.getEntityId()); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@SneakyThrows |
|
|
@SneakyThrows |
|
|
private Set<String> getAssociatedUrls(String baseUrl) { |
|
|
private Set<String> getAssociatedUrls(String baseUrl) { |
|
|
URI url = new URI(baseUrl); |
|
|
URI url = new URI(baseUrl); |
|
|
|