设备模块单元测试
This commit is contained in:
parent
8691833c97
commit
d96c9a54e2
|
|
@ -0,0 +1,45 @@
|
|||
#!/bin/bash
|
||||
#set -x
|
||||
#******************************************************************************
|
||||
# @file : entrypoint.sh
|
||||
# @author : wangyubin
|
||||
# @date : 2018-08- 1 10:18:43
|
||||
#
|
||||
# @brief : entry point for manage service start order
|
||||
# history : init
|
||||
#******************************************************************************
|
||||
|
||||
: ${SLEEP_SECOND:=2}
|
||||
|
||||
wait_for() {
|
||||
echo Waiting for $1 to listen on $2...
|
||||
while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
|
||||
}
|
||||
|
||||
declare DEPENDS
|
||||
declare CMD
|
||||
|
||||
while getopts "d:c:" arg
|
||||
do
|
||||
case $arg in
|
||||
d)
|
||||
DEPENDS=$OPTARG
|
||||
;;
|
||||
c)
|
||||
CMD=$OPTARG
|
||||
;;
|
||||
?)
|
||||
echo "unkonw argument"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for var in ${DEPENDS//,/ }
|
||||
do
|
||||
host=${var%:*}
|
||||
port=${var#*:}
|
||||
wait_for $host $port
|
||||
done
|
||||
|
||||
eval $CMD
|
||||
|
|
@ -4,12 +4,14 @@ import io.micrometer.core.instrument.Clock;
|
|||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
|
||||
import lombok.Setter;
|
||||
import org.jetlinks.core.metadata.DataType;
|
||||
import org.jetlinks.core.metadata.types.StringType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -23,17 +25,33 @@ public class MeterRegistryManager {
|
|||
|
||||
private Map<String, MeterRegistry> meterRegistryMap = new ConcurrentHashMap<>();
|
||||
|
||||
private List<MeterRegistrySupplier> suppliers;
|
||||
private final List<MeterRegistrySupplier> suppliers;
|
||||
|
||||
private MeterRegistry createMeterRegistry(String metric, String... tagKeys) {
|
||||
return new CompositeMeterRegistry(Clock.SYSTEM,
|
||||
suppliers.stream()
|
||||
.map(supplier -> supplier.getMeterRegistry(metric, tagKeys))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
public MeterRegistryManager(@Autowired(required = false) List<MeterRegistrySupplier> suppliers) {
|
||||
this.suppliers = suppliers == null ? new ArrayList<>() : suppliers;
|
||||
}
|
||||
|
||||
|
||||
private MeterRegistry createMeterRegistry(String metric, Map<String, DataType> tagDefine) {
|
||||
Map<String, DataType> tags = new HashMap<>(tagDefine);
|
||||
MeterRegistrySettings settings = tags::put;
|
||||
return new CompositeMeterRegistry(Clock.SYSTEM, suppliers
|
||||
.stream()
|
||||
.map(supplier -> supplier.getMeterRegistry(metric))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public MeterRegistry getMeterRegister(String metric, String... tagKeys) {
|
||||
return meterRegistryMap.computeIfAbsent(metric, _metric -> createMeterRegistry(_metric, tagKeys));
|
||||
|
||||
return meterRegistryMap.computeIfAbsent(metric, _metric -> {
|
||||
if (tagKeys.length == 0) {
|
||||
return createMeterRegistry(metric, Collections.emptyMap());
|
||||
}
|
||||
return createMeterRegistry(metric, Arrays
|
||||
.stream(tagKeys)
|
||||
.collect(Collectors.toMap(Function.identity(), key -> StringType.GLOBAL)));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,58 +29,58 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnBean(ProtocolSupports.class)
|
||||
public class DeviceClusterConfiguration {
|
||||
|
||||
@Bean
|
||||
public ClusterDeviceRegistry deviceRegistry(ProtocolSupports supports,
|
||||
ClusterManager manager,
|
||||
ConfigStorageManager storageManager,
|
||||
DeviceOperationBroker handler) {
|
||||
|
||||
return new ClusterDeviceRegistry(supports,
|
||||
storageManager,
|
||||
manager,
|
||||
handler,
|
||||
CaffeinatedGuava.build(Caffeine.newBuilder()));
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(ClusterDeviceRegistry.class)
|
||||
public BeanPostProcessor interceptorRegister(ClusterDeviceRegistry registry) {
|
||||
return new BeanPostProcessor() {
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof DeviceMessageSenderInterceptor) {
|
||||
registry.addInterceptor(((DeviceMessageSenderInterceptor) bean));
|
||||
}
|
||||
if (bean instanceof DeviceStateChecker) {
|
||||
registry.addStateChecker(((DeviceStateChecker) bean));
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "shutdown")
|
||||
@ConditionalOnBean(RpcManager.class)
|
||||
public PersistenceDeviceSessionManager deviceSessionManager(RpcManager rpcManager) {
|
||||
|
||||
return new PersistenceDeviceSessionManager(rpcManager);
|
||||
}
|
||||
|
||||
@ConditionalOnBean(DecodedClientMessageHandler.class)
|
||||
@Bean
|
||||
public ClusterSendToDeviceMessageHandler defaultSendToDeviceMessageHandler(DeviceSessionManager sessionManager,
|
||||
DeviceRegistry registry,
|
||||
MessageHandler messageHandler,
|
||||
DecodedClientMessageHandler clientMessageHandler) {
|
||||
return new ClusterSendToDeviceMessageHandler(sessionManager, messageHandler, registry, clientMessageHandler);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RpcDeviceOperationBroker rpcDeviceOperationBroker(RpcManager rpcManager,
|
||||
DeviceSessionManager sessionManager) {
|
||||
return new RpcDeviceOperationBroker(rpcManager, sessionManager);
|
||||
}
|
||||
// @Bean
|
||||
// public ClusterDeviceRegistry deviceRegistry(ProtocolSupports supports,
|
||||
// ClusterManager manager,
|
||||
// ConfigStorageManager storageManager,
|
||||
// DeviceOperationBroker handler) {
|
||||
//
|
||||
// return new ClusterDeviceRegistry(supports,
|
||||
// storageManager,
|
||||
// manager,
|
||||
// handler,
|
||||
// CaffeinatedGuava.build(Caffeine.newBuilder()));
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Bean
|
||||
// @ConditionalOnBean(ClusterDeviceRegistry.class)
|
||||
// public BeanPostProcessor interceptorRegister(ClusterDeviceRegistry registry) {
|
||||
// return new BeanPostProcessor() {
|
||||
// @Override
|
||||
// public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
// if (bean instanceof DeviceMessageSenderInterceptor) {
|
||||
// registry.addInterceptor(((DeviceMessageSenderInterceptor) bean));
|
||||
// }
|
||||
// if (bean instanceof DeviceStateChecker) {
|
||||
// registry.addStateChecker(((DeviceStateChecker) bean));
|
||||
// }
|
||||
// return bean;
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// @Bean(initMethod = "init", destroyMethod = "shutdown")
|
||||
// @ConditionalOnBean(RpcManager.class)
|
||||
// public PersistenceDeviceSessionManager deviceSessionManager(RpcManager rpcManager) {
|
||||
//
|
||||
// return new PersistenceDeviceSessionManager(rpcManager);
|
||||
// }
|
||||
//
|
||||
// @ConditionalOnBean(DecodedClientMessageHandler.class)
|
||||
// @Bean
|
||||
// public ClusterSendToDeviceMessageHandler defaultSendToDeviceMessageHandler(DeviceSessionManager sessionManager,
|
||||
// DeviceRegistry registry,
|
||||
// MessageHandler messageHandler,
|
||||
// DecodedClientMessageHandler clientMessageHandler) {
|
||||
// return new ClusterSendToDeviceMessageHandler(sessionManager, messageHandler, registry, clientMessageHandler);
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public RpcDeviceOperationBroker rpcDeviceOperationBroker(RpcManager rpcManager,
|
||||
// DeviceSessionManager sessionManager) {
|
||||
// return new RpcDeviceOperationBroker(rpcManager, sessionManager);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.jetlinks.community.elastic.search.service.ElasticSearchService;
|
|||
import org.jetlinks.community.elastic.search.things.ElasticSearchColumnModeStrategy;
|
||||
import org.jetlinks.community.elastic.search.things.ElasticSearchRowModeStrategy;
|
||||
import org.jetlinks.community.things.data.ThingsDataRepositoryStrategy;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
|
@ -16,6 +17,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
public class ElasticSearchThingDataConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(ElasticSearchService.class)
|
||||
public ElasticSearchColumnModeStrategy elasticSearchColumnModThingDataPolicy(
|
||||
ThingsRegistry registry,
|
||||
ElasticSearchService searchService,
|
||||
|
|
@ -26,6 +28,7 @@ public class ElasticSearchThingDataConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(ElasticSearchService.class)
|
||||
public ElasticSearchRowModeStrategy elasticSearchRowModThingDataPolicy(
|
||||
ThingsRegistry registry,
|
||||
ElasticSearchService searchService,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.jetlinks.community.elastic.search.index.strategies;
|
|||
import org.hswebframework.utils.time.DateFormatter;
|
||||
import org.jetlinks.community.elastic.search.index.ElasticSearchIndexProperties;
|
||||
import org.jetlinks.community.elastic.search.service.reactive.ReactiveElasticsearchClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
|
@ -15,6 +16,7 @@ import java.util.Date;
|
|||
* @since 1.0
|
||||
*/
|
||||
@Component
|
||||
@ConditionalOnBean(ReactiveElasticsearchClient.class)
|
||||
public class TimeByDayElasticSearchIndexStrategy extends TemplateElasticSearchIndexStrategy {
|
||||
|
||||
public TimeByDayElasticSearchIndexStrategy(ReactiveElasticsearchClient client, ElasticSearchIndexProperties properties) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.jetlinks.community.gateway.external.socket;
|
|||
import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
|
||||
import org.hswebframework.web.authorization.token.UserTokenManager;
|
||||
import org.jetlinks.community.gateway.external.MessagingManager;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
|
@ -16,10 +17,10 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
//@ConditionalOnBean({
|
||||
// ReactiveAuthenticationManager.class,
|
||||
// UserTokenManager.class
|
||||
//})
|
||||
@ConditionalOnBean({
|
||||
ReactiveAuthenticationManager.class,
|
||||
UserTokenManager.class
|
||||
})
|
||||
public class WebSocketMessagingHandlerConfiguration {
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.jetlinks.core.event.Subscription;
|
|||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -30,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@ConditionalOnBean(NetworkConfigManager.class)
|
||||
public class DefaultNetworkManager implements NetworkManager, BeanPostProcessor, CommandLineRunner {
|
||||
|
||||
private final NetworkConfigManager configManager;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.jetlinks.community.elastic.search.index.ElasticSearchIndexManager;
|
|||
import org.jetlinks.community.rule.engine.event.handler.RuleEngineLoggerIndexProvider;
|
||||
import org.jetlinks.core.metadata.types.DateTimeType;
|
||||
import org.jetlinks.core.metadata.types.StringType;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ import org.springframework.stereotype.Component;
|
|||
@Component
|
||||
@Order(1)
|
||||
@Slf4j
|
||||
@ConditionalOnBean(DefaultElasticSearchIndexMetadata.class)
|
||||
public class RuleEngineLogIndexInitialize {
|
||||
|
||||
public RuleEngineLogIndexInitialize(ElasticSearchIndexManager indexManager) {
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ package org.jetlinks.community.rule.engine.event.handler;
|
|||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetlinks.community.elastic.search.service.ElasticSearchService;
|
||||
import org.jetlinks.community.elastic.search.service.reactive.ReactiveElasticsearchClient;
|
||||
import org.jetlinks.community.gateway.annotation.Subscribe;
|
||||
import org.jetlinks.community.rule.engine.entity.RuleEngineExecuteEventInfo;
|
||||
import org.jetlinks.core.event.TopicPayload;
|
||||
import org.jetlinks.rule.engine.defaults.LogEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -14,6 +16,7 @@ import reactor.core.publisher.Mono;
|
|||
@Component
|
||||
@Slf4j
|
||||
@Order(3)
|
||||
@ConditionalOnBean(ElasticSearchService.class)
|
||||
public class RuleLogHandler {
|
||||
|
||||
@Autowired
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
package org.jetlinks.community.timeseries;
|
||||
|
||||
import org.hswebframework.ezorm.core.param.QueryParam;
|
||||
import org.jetlinks.community.timeseries.query.AggregationData;
|
||||
import org.jetlinks.community.timeseries.query.AggregationQueryParam;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class NoneTimeSeriesManager implements TimeSeriesManager {
|
||||
public static final NoneTimeSeriesService NONE = new NoneTimeSeriesService();
|
||||
|
||||
@Override
|
||||
public TimeSeriesService getService(TimeSeriesMetric metric) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSeriesService getServices(TimeSeriesMetric... metric) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSeriesService getServices(String... metric) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSeriesService getService(String metric) {
|
||||
return NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> registerMetadata(TimeSeriesMetadata metadata) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
static class NoneTimeSeriesService implements TimeSeriesService {
|
||||
@Override
|
||||
public Flux<TimeSeriesData> query(QueryParam queryParam) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<TimeSeriesData> multiQuery(Collection<QueryParam> query) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Integer> count(QueryParam queryParam) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<AggregationData> aggregation(AggregationQueryParam queryParam) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> commit(Publisher<TimeSeriesData> data) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> commit(TimeSeriesData data) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> save(Publisher<TimeSeriesData> data) {
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.jetlinks.community.timeseries;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class TimeSeriesManagerConfiguration {
|
||||
|
||||
@ConditionalOnMissingBean(TimeSeriesManager.class)
|
||||
@Bean
|
||||
public NoneTimeSeriesManager timeSeriesManager() {
|
||||
return new NoneTimeSeriesManager();
|
||||
}
|
||||
}
|
||||
|
|
@ -99,6 +99,13 @@
|
|||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>test-component</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
package org.jetlinks.community.device;
|
||||
|
||||
import org.hswebframework.web.authorization.token.DefaultUserTokenManager;
|
||||
import org.hswebframework.web.authorization.token.UserTokenManager;
|
||||
import org.hswebframework.web.starter.jackson.CustomCodecsAutoConfiguration;
|
||||
import org.jetlinks.community.configure.cluster.ClusterConfiguration;
|
||||
import org.jetlinks.community.configure.device.DeviceClusterConfiguration;
|
||||
import org.jetlinks.community.elastic.search.configuration.ElasticSearchConfiguration;
|
||||
import org.jetlinks.core.ProtocolSupports;
|
||||
import org.jetlinks.core.device.DeviceRegistry;
|
||||
import org.jetlinks.core.device.StandaloneDeviceMessageBroker;
|
||||
import org.jetlinks.core.device.session.DeviceSessionManager;
|
||||
import org.jetlinks.core.server.MessageHandler;
|
||||
import org.jetlinks.supports.device.session.LocalDeviceSessionManager;
|
||||
import org.jetlinks.supports.official.JetLinksDeviceMetadataCodec;
|
||||
import org.jetlinks.supports.test.InMemoryDeviceRegistry;
|
||||
import org.jetlinks.supports.test.MockProtocolSupport;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ImportAutoConfiguration({
|
||||
CodecsAutoConfiguration.class,
|
||||
JacksonAutoConfiguration.class,
|
||||
CustomCodecsAutoConfiguration.class,
|
||||
ClusterConfiguration.class,
|
||||
DeviceClusterConfiguration.class
|
||||
})
|
||||
public class DeviceTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public ProtocolSupports mockProtocolSupport(){
|
||||
return new MockProtocolSupport();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserTokenManager userTokenManager(){
|
||||
return new DefaultUserTokenManager();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DeviceRegistry deviceRegistry() {
|
||||
|
||||
return new InMemoryDeviceRegistry();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageHandler messageHandler() {
|
||||
|
||||
return new StandaloneDeviceMessageBroker();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DeviceSessionManager deviceSessionManager() {
|
||||
|
||||
return LocalDeviceSessionManager.create();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ElasticSearchConfiguration searchConfiguration() {
|
||||
|
||||
return new ElasticSearchConfiguration();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JetLinksDeviceMetadataCodec jetLinksDeviceMetadataCodec(){
|
||||
return new JetLinksDeviceMetadataCodec();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,695 @@
|
|||
package org.jetlinks.community.device.web;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.SneakyThrows;
|
||||
import org.jetlinks.community.test.spring.TestJetLinksController;
|
||||
import org.jetlinks.core.metadata.SimplePropertyMetadata;
|
||||
import org.jetlinks.core.metadata.types.FloatType;
|
||||
import org.jetlinks.community.PropertyMetadataConstants;
|
||||
import org.jetlinks.community.PropertyMetric;
|
||||
import org.jetlinks.community.device.entity.DeviceInstanceEntity;
|
||||
import org.jetlinks.community.device.entity.DeviceProductEntity;
|
||||
import org.jetlinks.community.device.entity.DeviceTagEntity;
|
||||
import org.jetlinks.community.device.service.LocalDeviceInstanceService;
|
||||
import org.jetlinks.community.device.service.LocalDeviceProductService;
|
||||
import org.jetlinks.community.device.service.data.DeviceDataService;
|
||||
import org.jetlinks.community.device.web.request.AggRequest;
|
||||
import org.jetlinks.community.relation.entity.RelationEntity;
|
||||
import org.jetlinks.community.relation.service.RelatedObjectInfo;
|
||||
import org.jetlinks.community.relation.service.RelationService;
|
||||
import org.jetlinks.community.relation.service.request.SaveRelationRequest;
|
||||
import org.jetlinks.community.timeseries.query.Aggregation;
|
||||
import org.jetlinks.supports.official.JetLinksDeviceMetadata;
|
||||
import org.jetlinks.supports.official.JetLinksDeviceMetadataCodec;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@WebFluxTest(value = DeviceInstanceController.class, properties = {
|
||||
"spring.reactor.debug-agent.enabled=true"
|
||||
})
|
||||
class DeviceInstanceControllerTest extends TestJetLinksController {
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("all")
|
||||
private LocalDeviceInstanceService deviceService;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("all")
|
||||
private LocalDeviceProductService productService;
|
||||
|
||||
private String deviceId;
|
||||
private String productId;
|
||||
|
||||
private String metadata;
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
DeviceProductEntity product = new DeviceProductEntity();
|
||||
product.setMetadata("{}");
|
||||
product.setTransportProtocol("MQTT");
|
||||
product.setMessageProtocol("test");
|
||||
product.setId(productId = "deviceinstancecontrollertest_product");
|
||||
product.setName("DeviceInstanceControllerTest");
|
||||
|
||||
JetLinksDeviceMetadata metadata = new JetLinksDeviceMetadata("Test", "Test");
|
||||
{
|
||||
SimplePropertyMetadata metric = SimplePropertyMetadata.of(
|
||||
"metric", "Metric", FloatType.GLOBAL
|
||||
);
|
||||
metric.setExpands(
|
||||
PropertyMetadataConstants.Metrics
|
||||
.metricsToExpands(Arrays.asList(
|
||||
PropertyMetric.of("max", "最大值", 100),
|
||||
PropertyMetric.of("min", "最小值", -100)
|
||||
))
|
||||
);
|
||||
metadata.addProperty(metric);
|
||||
}
|
||||
|
||||
product.setMetadata(this.metadata=JetLinksDeviceMetadataCodec.getInstance().doEncode(metadata));
|
||||
|
||||
productService
|
||||
.save(product)
|
||||
.then(productService.deploy(productId))
|
||||
.then()
|
||||
.as(StepVerifier::create)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
|
||||
DeviceInstanceEntity device = new DeviceInstanceEntity();
|
||||
device.setId(deviceId = "deviceinstancecontrollertest_device");
|
||||
device.setName("DeviceInstanceControllerTest");
|
||||
device.setProductId(product.getId());
|
||||
device.setProductName(device.getName());
|
||||
|
||||
client
|
||||
.patch()
|
||||
.uri("/device/instance")
|
||||
.bodyValue(device)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/batch/_deploy")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Arrays.asList(deviceId))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void shutdown() {
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/batch/_unDeploy")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Arrays.asList(deviceId))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/batch/_delete")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Arrays.asList(deviceId))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testCommon() {
|
||||
// {
|
||||
// DeviceInstanceEntity device = new DeviceInstanceEntity();
|
||||
// device.setId(deviceId);
|
||||
// device.setName("DeviceInstanceControllerTest");
|
||||
// device.setProductId(productId);
|
||||
// device.setProductName(device.getName());
|
||||
// //重复创建
|
||||
// client
|
||||
// .post()
|
||||
// .uri("/device/instance")
|
||||
// .bodyValue(device)
|
||||
// .exchange()
|
||||
// .expectStatus()
|
||||
// .is4xxClientError();
|
||||
// }
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{id:.+}/detail", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/bind-providers")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId}/state", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/state/_sync")
|
||||
.accept(MediaType.TEXT_EVENT_STREAM)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId}/deploy", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId}/undeploy", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId}/disconnect", deviceId)
|
||||
.exchange();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testProperties() {
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/properties/_query?where=property is test", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/properties/_query", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is4xxClientError();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/properties/latest", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/properties", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/properties/_top/{numberOfTop}", deviceId, 1)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/property/{property}/_query", deviceId, "test")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/property/{property}/_query", deviceId, "test")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/properties/_query", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{}")
|
||||
.exchange();
|
||||
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/property/{property:.+}", deviceId, "test")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
AggRequest request = new AggRequest();
|
||||
|
||||
request.setColumns(Arrays.asList(
|
||||
new DeviceDataService.DevicePropertyAggregation("test", "alias", Aggregation.AVG)
|
||||
));
|
||||
request.setQuery(DeviceDataService.AggregationRequest
|
||||
.builder()
|
||||
.build());
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/agg/_query", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(request)
|
||||
.exchange();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEvent() {
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/event/{eventId}", deviceId, "test")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/event/{eventId}", deviceId, "test")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLog() {
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/logs", deviceId, "test")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/logs", deviceId, "test")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTag() {
|
||||
DeviceTagEntity tag = new DeviceTagEntity();
|
||||
tag.setKey("test");
|
||||
tag.setValue("value");
|
||||
|
||||
client
|
||||
.patch()
|
||||
.uri("/device/instance/{deviceId}/tag", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(tag)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
List<DeviceTagEntity> tags = client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId}/tags", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBodyList(DeviceTagEntity.class)
|
||||
.returnResult()
|
||||
.getResponseBody();
|
||||
|
||||
assertNotNull(tags);
|
||||
assertFalse(tags.isEmpty());
|
||||
|
||||
client
|
||||
.delete()
|
||||
.uri("/device/instance/{deviceId}/tag/{tagId}", deviceId, tags.get(0).getId())
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testMetadata() {
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{id:.+}/config-metadata", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{id:.+}/config-metadata/{metadataType}/{metadataId}/{typeId}",
|
||||
deviceId,
|
||||
"property",
|
||||
"temp",
|
||||
"test")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
|
||||
String metadata = client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId}/property-metadata/import?fileUrl=" + new ClassPathResource("property-metadata.csv")
|
||||
.getFile()
|
||||
.getAbsolutePath(), deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody(String.class)
|
||||
.returnResult()
|
||||
.getResponseBody();
|
||||
assertNotNull(metadata);
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/{id:.+}/metadata", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(metadata)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
deviceService.findById(deviceId)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextMatches(device -> Objects.equals(
|
||||
device.getDeriveMetadata(),
|
||||
metadata
|
||||
))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/{id}/metadata/merge-product", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.delete()
|
||||
.uri("/device/instance/{id}/metadata", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
deviceService
|
||||
.findById(deviceId)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextMatches(device -> StringUtils.isEmpty(device.getDeriveMetadata()))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConfiguration() {
|
||||
|
||||
deviceService.deploy(deviceId)
|
||||
.then()
|
||||
.as(StepVerifier::create)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/configuration/_write", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{\"test\":\"123\"}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/configuration/_read", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("[\"test\"]")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody(Map.class)
|
||||
.isEqualTo(Collections.singletonMap("test", "123"));
|
||||
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/{deviceId:.+}/configuration/_reset", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/{deviceId:.+}/shadow", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{\"test\":\"123\"}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId:.+}/shadow", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody(String.class)
|
||||
.isEqualTo("{\"test\":\"123\"}");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCommand() {
|
||||
client
|
||||
.put()
|
||||
.uri("/device/instance/{deviceId:.+}/property", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Collections.singletonMap("test", "value"))
|
||||
.exchange();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/property/_read", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Collections.singleton("test"))
|
||||
.exchange();
|
||||
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/function/test", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Collections.singletonMap("test", "value"))
|
||||
.exchange();
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/{deviceId:.+}/message", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Collections.singletonMap("properties", Collections.singletonList("test")))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("deviceId", "test");
|
||||
data.put("properties", Collections.singletonList("test"));
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/instance/messages", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(data)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutoChangeProductInfo() {
|
||||
client.post()
|
||||
.uri("/device/instance")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{\"id\":\"testAutoChangeProductInfo\",\"name\":\"Test\",\"productId\":\"" + productId + "\"}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private RelationService relationService;
|
||||
|
||||
@Test
|
||||
void testRelation() {
|
||||
RelationEntity entity = new RelationEntity();
|
||||
entity.setRelation("manager");
|
||||
entity.setObjectType("device");
|
||||
entity.setObjectTypeName("设备");
|
||||
entity.setTargetType("user");
|
||||
entity.setTargetTypeName("用户");
|
||||
entity.setName("管理员");
|
||||
relationService
|
||||
.save(entity).block();
|
||||
|
||||
|
||||
client.get()
|
||||
.uri("/device/instance/{deviceId}/detail", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("$.relations[0].relation").isEqualTo("manager")
|
||||
.jsonPath("$.relations[0].related").isEmpty();
|
||||
|
||||
|
||||
client.patch()
|
||||
.uri("/device/instance/{deviceId}/relations", deviceId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(SaveRelationRequest.of(
|
||||
"user",
|
||||
"manager",
|
||||
Arrays.asList(RelatedObjectInfo.of("admin", "管理员")),
|
||||
null
|
||||
))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client.get()
|
||||
.uri("/device/instance/{deviceId}/detail", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("$.relations[0].relation").isEqualTo("manager")
|
||||
.jsonPath("$.relations[0].related[0].id").isEqualTo("admin")
|
||||
.jsonPath("$.relations[0].related[0].name").isEqualTo("管理员");
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMetric() {
|
||||
client.get()
|
||||
.uri("/device/instance/{deviceId}/metric/property/{property}", deviceId, "metric")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("[0].id").isEqualTo("max")
|
||||
.jsonPath("[0].value").isEqualTo(100)
|
||||
.jsonPath("[1].id").isEqualTo("min")
|
||||
.jsonPath("[1].value").isEqualTo(-100);
|
||||
|
||||
|
||||
client.patch()
|
||||
.uri("/device/instance/{deviceId}/metric/property/{property}", deviceId, "metric")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(PropertyMetric.of("max", "最大值", 110))
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client.get()
|
||||
.uri("/device/instance/{deviceId}/metric/property/{property}", deviceId, "metric")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("[0].id").isEqualTo("max")
|
||||
.jsonPath("[0].value").isEqualTo(110)
|
||||
.jsonPath("[1].id").isEqualTo("min")
|
||||
.jsonPath("[1].value").isEqualTo(-100);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDetail(){
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId}/detail", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("$.metadata").isEqualTo(metadata);
|
||||
|
||||
String newMetadata="{\"properties\":[]}";
|
||||
|
||||
client
|
||||
.put()
|
||||
.uri("/device/product/{productId}", productId)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue("{\"metadata\":"+ JSON.toJSONString(newMetadata)+"}")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
//仅保存 未发布
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId}/detail", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("$.metadata").isEqualTo(metadata);
|
||||
|
||||
client
|
||||
.post()
|
||||
.uri("/device/product/{productId}/deploy", productId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful();
|
||||
|
||||
client
|
||||
.get()
|
||||
.uri("/device/instance/{deviceId}/detail", deviceId)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.is2xxSuccessful()
|
||||
.expectBody()
|
||||
.jsonPath("$.metadata").isEqualTo(newMetadata);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -11,5 +11,7 @@ COPY --from=builder application/snapshot-dependencies/ ./
|
|||
COPY --from=builder application/spring-boot-loader/ ./
|
||||
COPY --from=builder application/application/ ./
|
||||
COPY docker-entrypoint.sh ./
|
||||
COPY entrypoint.sh ./
|
||||
RUN chmod +x docker-entrypoint.sh
|
||||
RUN chmod +x entrypoint.sh
|
||||
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||
Loading…
Reference in New Issue