committed by
GitHub
202 changed files with 5397 additions and 2397 deletions
@ -0,0 +1,32 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.edge.rpc.constructor.oauth2; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|||
import org.thingsboard.server.gen.edge.v1.OAuth2UpdateMsg; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
|
|||
@Component |
|||
@TbCoreComponent |
|||
public class OAuth2MsgConstructor { |
|||
|
|||
public OAuth2UpdateMsg constructOAuth2UpdateMsg(OAuth2Info oAuth2Info) { |
|||
return OAuth2UpdateMsg.newBuilder().setEntity(JacksonUtil.toString(oAuth2Info)).build(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.edge.rpc.fetch; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.EdgeUtils; |
|||
import org.thingsboard.server.common.data.edge.Edge; |
|||
import org.thingsboard.server.common.data.edge.EdgeEvent; |
|||
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
|||
import org.thingsboard.server.common.data.edge.EdgeEventType; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.oauth2.OAuth2Service; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
@AllArgsConstructor |
|||
@Slf4j |
|||
public class OAuth2EdgeEventFetcher implements EdgeEventFetcher { |
|||
|
|||
private final OAuth2Service oAuth2Service; |
|||
|
|||
@Override |
|||
public PageLink getPageLink(int pageSize) { |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public PageData<EdgeEvent> fetchEdgeEvents(TenantId tenantId, Edge edge, PageLink pageLink) { |
|||
List<EdgeEvent> result = new ArrayList<>(); |
|||
OAuth2Info oAuth2Info = oAuth2Service.findOAuth2Info(); |
|||
result.add(EdgeUtils.constructEdgeEvent(tenantId, edge.getId(), EdgeEventType.OAUTH2, |
|||
EdgeEventActionType.ADDED, null, JacksonUtil.valueToTree(oAuth2Info))); |
|||
// returns PageData object to be in sync with other fetchers
|
|||
return new PageData<>(result, 1, result.size(), false); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.edge.rpc.processor.oauth2; |
|||
|
|||
import com.google.common.util.concurrent.Futures; |
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.EdgeUtils; |
|||
import org.thingsboard.server.common.data.edge.EdgeEvent; |
|||
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
|||
import org.thingsboard.server.common.data.edge.EdgeEventType; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|||
import org.thingsboard.server.gen.edge.v1.DownlinkMsg; |
|||
import org.thingsboard.server.gen.edge.v1.OAuth2UpdateMsg; |
|||
import org.thingsboard.server.gen.transport.TransportProtos; |
|||
import org.thingsboard.server.queue.util.TbCoreComponent; |
|||
import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
@TbCoreComponent |
|||
public class OAuth2EdgeProcessor extends BaseEdgeProcessor { |
|||
|
|||
public DownlinkMsg convertOAuth2EventToDownlink(EdgeEvent edgeEvent) { |
|||
DownlinkMsg downlinkMsg = null; |
|||
OAuth2Info oAuth2Info = JacksonUtil.convertValue(edgeEvent.getBody(), OAuth2Info.class); |
|||
if (oAuth2Info != null) { |
|||
OAuth2UpdateMsg oAuth2UpdateMsg = oAuth2MsgConstructor.constructOAuth2UpdateMsg(oAuth2Info); |
|||
downlinkMsg = DownlinkMsg.newBuilder() |
|||
.setDownlinkMsgId(EdgeUtils.nextPositiveInt()) |
|||
.addOAuth2UpdateMsg(oAuth2UpdateMsg) |
|||
.build(); |
|||
} |
|||
return downlinkMsg; |
|||
} |
|||
|
|||
public ListenableFuture<Void> processOAuth2Notification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { |
|||
OAuth2Info oAuth2Info = JacksonUtil.fromString(edgeNotificationMsg.getBody(), OAuth2Info.class); |
|||
if (oAuth2Info == null) { |
|||
return Futures.immediateFuture(null); |
|||
} |
|||
EdgeEventType type = EdgeEventType.valueOf(edgeNotificationMsg.getType()); |
|||
EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); |
|||
return processActionForAllEdges(tenantId, type, actionType, null, JacksonUtil.toJsonNode(edgeNotificationMsg.getBody()), null); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.edge; |
|||
|
|||
import com.google.common.collect.Lists; |
|||
import com.google.protobuf.AbstractMessage; |
|||
import org.junit.Assert; |
|||
import org.junit.Test; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.oauth2.MapperType; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2DomainInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2Info; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2ParamsInfo; |
|||
import org.thingsboard.server.common.data.oauth2.OAuth2RegistrationInfo; |
|||
import org.thingsboard.server.common.data.oauth2.SchemeType; |
|||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|||
import org.thingsboard.server.gen.edge.v1.OAuth2UpdateMsg; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.UUID; |
|||
|
|||
@DaoSqlTest |
|||
public class OAuth2EdgeTest extends AbstractEdgeTest { |
|||
|
|||
@Test |
|||
public void testOAuth2Support() throws Exception { |
|||
loginSysAdmin(); |
|||
|
|||
// enable oauth
|
|||
edgeImitator.allowIgnoredTypes(); |
|||
edgeImitator.expectMessageAmount(1); |
|||
OAuth2Info oAuth2Info = createDefaultOAuth2Info(); |
|||
oAuth2Info = doPost("/api/oauth2/config", oAuth2Info, OAuth2Info.class); |
|||
Assert.assertTrue(edgeImitator.waitForMessages()); |
|||
AbstractMessage latestMessage = edgeImitator.getLatestMessage(); |
|||
Assert.assertTrue(latestMessage instanceof OAuth2UpdateMsg); |
|||
OAuth2UpdateMsg oAuth2UpdateMsg = (OAuth2UpdateMsg) latestMessage; |
|||
OAuth2Info result = JacksonUtil.fromString(oAuth2UpdateMsg.getEntity(), OAuth2Info.class, true); |
|||
Assert.assertEquals(oAuth2Info, result); |
|||
|
|||
// disable oauth support
|
|||
edgeImitator.expectMessageAmount(1); |
|||
oAuth2Info.setEnabled(false); |
|||
oAuth2Info.setEdgeEnabled(false); |
|||
doPost("/api/oauth2/config", oAuth2Info, OAuth2Info.class); |
|||
Assert.assertTrue(edgeImitator.waitForMessages()); |
|||
latestMessage = edgeImitator.getLatestMessage(); |
|||
Assert.assertTrue(latestMessage instanceof OAuth2UpdateMsg); |
|||
oAuth2UpdateMsg = (OAuth2UpdateMsg) latestMessage; |
|||
result = JacksonUtil.fromString(oAuth2UpdateMsg.getEntity(), OAuth2Info.class, true); |
|||
Assert.assertEquals(oAuth2Info, result); |
|||
|
|||
edgeImitator.ignoreType(OAuth2UpdateMsg.class); |
|||
loginTenantAdmin(); |
|||
} |
|||
|
|||
private OAuth2Info createDefaultOAuth2Info() { |
|||
return new OAuth2Info(true, true, Lists.newArrayList( |
|||
OAuth2ParamsInfo.builder() |
|||
.domainInfos(Lists.newArrayList( |
|||
OAuth2DomainInfo.builder().name("domain").scheme(SchemeType.MIXED).build() |
|||
)) |
|||
.mobileInfos(Collections.emptyList()) |
|||
.clientRegistrations(Lists.newArrayList( |
|||
validRegistrationInfo() |
|||
)) |
|||
.build() |
|||
)); |
|||
} |
|||
|
|||
private OAuth2RegistrationInfo validRegistrationInfo() { |
|||
return OAuth2RegistrationInfo.builder() |
|||
.clientId(UUID.randomUUID().toString()) |
|||
.clientSecret(UUID.randomUUID().toString()) |
|||
.authorizationUri(UUID.randomUUID().toString()) |
|||
.accessTokenUri(UUID.randomUUID().toString()) |
|||
.scope(Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString())) |
|||
.platforms(Collections.emptyList()) |
|||
.userInfoUri(UUID.randomUUID().toString()) |
|||
.userNameAttributeName(UUID.randomUUID().toString()) |
|||
.jwkSetUri(UUID.randomUUID().toString()) |
|||
.clientAuthenticationMethod(UUID.randomUUID().toString()) |
|||
.loginButtonLabel(UUID.randomUUID().toString()) |
|||
.mapperConfig( |
|||
OAuth2MapperConfig.builder() |
|||
.type(MapperType.CUSTOM) |
|||
.custom( |
|||
OAuth2CustomMapperConfig.builder() |
|||
.url(UUID.randomUUID().toString()) |
|||
.build() |
|||
) |
|||
.build() |
|||
) |
|||
.build(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.queue; |
|||
|
|||
import org.thingsboard.server.common.data.id.QueueStatsId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.queue.QueueStats; |
|||
import org.thingsboard.server.dao.entity.EntityDaoService; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface QueueStatsService extends EntityDaoService { |
|||
|
|||
QueueStats save(TenantId tenantId, QueueStats queueStats); |
|||
|
|||
QueueStats findQueueStatsById(TenantId tenantId, QueueStatsId queueStatsId); |
|||
|
|||
QueueStats findByTenantIdAndNameAndServiceId(TenantId tenantId, String queueName, String serviceId); |
|||
|
|||
List<QueueStats> findByTenantId(TenantId tenantId); |
|||
|
|||
void deleteByTenantId(TenantId tenantId); |
|||
|
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.id; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
public class QueueStatsId extends UUIDBased implements EntityId { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
@JsonCreator |
|||
public QueueStatsId(@JsonProperty("id") UUID id) { |
|||
super(id); |
|||
} |
|||
|
|||
public static QueueStatsId fromString(String queueId) { |
|||
return new QueueStatsId(UUID.fromString(queueId)); |
|||
} |
|||
|
|||
@Schema(required = true, description = "string", example = "QUEUE_STATS", allowableValues = "QUEUE_STATS") |
|||
@Override |
|||
public EntityType getEntityType() { |
|||
return EntityType.QUEUE_STATS; |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.queue; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.BaseData; |
|||
import org.thingsboard.server.common.data.HasTenantId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.id.QueueStatsId; |
|||
|
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Data |
|||
public class QueueStats extends BaseData<QueueStatsId> implements HasTenantId { |
|||
private TenantId tenantId; |
|||
private String queueName; |
|||
private String serviceId; |
|||
|
|||
public QueueStats() { |
|||
} |
|||
|
|||
public QueueStats(QueueStatsId id) { |
|||
super(id); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.util; |
|||
|
|||
import org.junit.jupiter.params.ParameterizedTest; |
|||
import org.junit.jupiter.params.provider.EnumSource; |
|||
import org.junit.jupiter.params.provider.MethodSource; |
|||
import org.junit.jupiter.params.provider.ValueSource; |
|||
import org.thingsboard.server.common.data.kv.AggTsKvEntry; |
|||
import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
|||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; |
|||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry; |
|||
import org.thingsboard.server.common.data.kv.BooleanDataEntry; |
|||
import org.thingsboard.server.common.data.kv.DataType; |
|||
import org.thingsboard.server.common.data.kv.DoubleDataEntry; |
|||
import org.thingsboard.server.common.data.kv.JsonDataEntry; |
|||
import org.thingsboard.server.common.data.kv.KvEntry; |
|||
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|||
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|||
import org.thingsboard.server.common.data.kv.TsKvEntry; |
|||
|
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
import java.util.stream.Stream; |
|||
|
|||
import static org.assertj.core.api.Assertions.assertThat; |
|||
|
|||
class KvProtoUtilTest { |
|||
|
|||
private static final long TS = System.currentTimeMillis(); |
|||
|
|||
private static Stream<KvEntry> kvEntryData() { |
|||
String key = "key"; |
|||
return Stream.of( |
|||
new BooleanDataEntry(key, true), |
|||
new LongDataEntry(key, 23L), |
|||
new DoubleDataEntry(key, 23.0), |
|||
new StringDataEntry(key, "stringValue"), |
|||
new JsonDataEntry(key, "jsonValue") |
|||
); |
|||
} |
|||
|
|||
private static Stream<KvEntry> basicTsKvEntryData() { |
|||
return kvEntryData().map(kvEntry -> new BasicTsKvEntry(TS, kvEntry)); |
|||
} |
|||
|
|||
private static Stream<List<BaseAttributeKvEntry>> attributeKvEntryData() { |
|||
return Stream.of(kvEntryData().map(kvEntry -> new BaseAttributeKvEntry(TS, kvEntry)).toList()); |
|||
} |
|||
|
|||
private static List<TsKvEntry> createTsKvEntryList(boolean withAggregation) { |
|||
return kvEntryData().map(kvEntry -> { |
|||
if (withAggregation) { |
|||
return new AggTsKvEntry(TS, kvEntry, 0); |
|||
} else { |
|||
return new BasicTsKvEntry(TS, kvEntry); |
|||
} |
|||
}).collect(Collectors.toList()); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@EnumSource(DataType.class) |
|||
void protoDataTypeSerialization(DataType dataType) { |
|||
assertThat(KvProtoUtil.fromKeyValueTypeProto(KvProtoUtil.toKeyValueTypeProto(dataType))) |
|||
.as(dataType.name()).isEqualTo(dataType); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("kvEntryData") |
|||
void protoKeyValueProtoSerialization(KvEntry kvEntry) { |
|||
assertThat(KvProtoUtil.fromTsKvProto(KvProtoUtil.toKeyValueTypeProto(kvEntry))) |
|||
.as("deserialized").isEqualTo(kvEntry); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("basicTsKvEntryData") |
|||
void protoTsKvEntrySerialization(KvEntry kvEntry) { |
|||
assertThat(KvProtoUtil.fromTsKvProto(KvProtoUtil.toTsKvProto(TS, kvEntry))) |
|||
.as("deserialized").isEqualTo(kvEntry); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("kvEntryData") |
|||
void protoTsValueSerialization(KvEntry kvEntry) { |
|||
assertThat(KvProtoUtil.fromTsValueProto(kvEntry.getKey(), KvProtoUtil.toTsValueProto(TS, kvEntry))) |
|||
.as("deserialized").isEqualTo(kvEntry); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@ValueSource(booleans = {true, false}) |
|||
void protoListTsKvEntrySerialization(boolean withAggregation) { |
|||
List<TsKvEntry> tsKvEntries = createTsKvEntryList(withAggregation); |
|||
assertThat(KvProtoUtil.fromTsKvProtoList(KvProtoUtil.toTsKvProtoList(tsKvEntries))) |
|||
.as("deserialized").isEqualTo(tsKvEntries); |
|||
} |
|||
|
|||
@ParameterizedTest |
|||
@MethodSource("attributeKvEntryData") |
|||
void protoListAttributeKvSerialization(List<AttributeKvEntry> attributeKvEntries) { |
|||
assertThat(KvProtoUtil.toAttributeKvList(KvProtoUtil.attrToTsKvProtos(attributeKvEntries))) |
|||
.as("deserialized") |
|||
.isEqualTo(attributeKvEntries); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.transport.http; |
|||
|
|||
import com.google.gson.JsonParseException; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.Mockito; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.http.converter.HttpMessageNotReadableException; |
|||
import org.springframework.web.context.request.async.DeferredResult; |
|||
import org.thingsboard.server.common.transport.TransportContext; |
|||
import org.thingsboard.server.gen.transport.TransportProtos; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.function.Consumer; |
|||
|
|||
class DeviceApiControllerTest { |
|||
|
|||
@Test |
|||
void deviceAuthCallbackTest() { |
|||
TransportContext transportContext = Mockito.mock(TransportContext.class); |
|||
DeferredResult<ResponseEntity> responseWriter = Mockito.mock(DeferredResult.class); |
|||
Consumer<TransportProtos.SessionInfoProto> onSuccess = x -> { |
|||
}; |
|||
var callback = new DeviceApiController.DeviceAuthCallback(transportContext, responseWriter, onSuccess); |
|||
|
|||
callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); |
|||
|
|||
callback.onError(new JsonParseException("Json ; expected")); |
|||
|
|||
callback.onError(new IOException("not found")); |
|||
|
|||
callback.onError(new RuntimeException("oops it is run time error")); |
|||
} |
|||
|
|||
@Test |
|||
void deviceProvisionCallbackTest() { |
|||
DeferredResult<ResponseEntity> responseWriter = Mockito.mock(DeferredResult.class); |
|||
var callback = new DeviceApiController.DeviceProvisionCallback(responseWriter); |
|||
|
|||
callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); |
|||
|
|||
callback.onError(new JsonParseException("Json ; expected")); |
|||
|
|||
callback.onError(new IOException("not found")); |
|||
|
|||
callback.onError(new RuntimeException("oops it is run time error")); |
|||
} |
|||
|
|||
@Test |
|||
void getOtaPackageCallback() { |
|||
TransportContext transportContext = Mockito.mock(TransportContext.class); |
|||
DeferredResult<ResponseEntity> responseWriter = Mockito.mock(DeferredResult.class); |
|||
String title = "Title"; |
|||
String version = "version"; |
|||
int chunkSize = 11; |
|||
int chunk = 3; |
|||
|
|||
var callback = new DeviceApiController.GetOtaPackageCallback(transportContext, responseWriter, title, version, chunkSize, chunk); |
|||
|
|||
callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax")); |
|||
|
|||
callback.onError(new JsonParseException("Json ; expected")); |
|||
|
|||
callback.onError(new IOException("not found")); |
|||
|
|||
callback.onError(new RuntimeException("oops it is run time error")); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
|
|||
<configuration> |
|||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
|||
<encoder> |
|||
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> |
|||
</encoder> |
|||
</appender> |
|||
|
|||
logger name="org.thingsboard.server.transport.http.DeviceApiController" level="DEBUG" /> |
|||
|
|||
<root level="INFO"> |
|||
<appender-ref ref="console"/> |
|||
</root> |
|||
|
|||
</configuration> |
|||
@ -0,0 +1,69 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.model.sql; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.thingsboard.server.common.data.id.QueueStatsId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.queue.QueueStats; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.BaseSqlEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import jakarta.persistence.Column; |
|||
import jakarta.persistence.Entity; |
|||
import jakarta.persistence.Table; |
|||
import java.util.UUID; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@Entity |
|||
@Table(name = ModelConstants.QUEUE_STATS_TABLE_NAME) |
|||
public class QueueStatsEntity extends BaseSqlEntity<QueueStats> { |
|||
|
|||
@Column(name = ModelConstants.QUEUE_STATS_TENANT_ID_PROPERTY) |
|||
private UUID tenantId; |
|||
|
|||
@Column(name = ModelConstants.QUEUE_STATS_QUEUE_NAME_PROPERTY) |
|||
private String queueName; |
|||
|
|||
@Column(name = ModelConstants.QUEUE_STATS_SERVICE_ID_PROPERTY) |
|||
private String serviceId; |
|||
|
|||
public QueueStatsEntity() { |
|||
} |
|||
|
|||
public QueueStatsEntity(QueueStats queueStats) { |
|||
if (queueStats.getId() != null) { |
|||
this.setId(queueStats.getId().getId()); |
|||
} |
|||
this.setCreatedTime(queueStats.getCreatedTime()); |
|||
this.tenantId = DaoUtil.getId(queueStats.getTenantId()); |
|||
this.queueName = queueStats.getQueueName(); |
|||
this.serviceId = queueStats.getServiceId(); |
|||
} |
|||
|
|||
@Override |
|||
public QueueStats toData() { |
|||
QueueStats queueStats = new QueueStats(new QueueStatsId(getUuid())); |
|||
queueStats.setCreatedTime(createdTime); |
|||
queueStats.setTenantId(new TenantId(tenantId)); |
|||
queueStats.setQueueName(queueName); |
|||
queueStats.setServiceId(serviceId); |
|||
return queueStats; |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue