lwm2m: Merge branch 'develop/3.3' into add-models

This commit is contained in:
nickAS21 2021-03-12 15:19:47 +02:00
commit d27c721bbf
23 changed files with 364 additions and 181 deletions

View File

@ -23,15 +23,15 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.util.List;
@Slf4j
@RestController
@TbCoreComponent
@ -61,21 +61,14 @@ public class ResourceController extends BaseController {
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/resource", method = RequestMethod.GET)
@ResponseBody
public List<Resource> getResources(@RequestParam(required = false) boolean system) throws ThingsboardException {
public PageData<Resource> getResources(@RequestParam(required = false) boolean system,
@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String sortProperty,
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
try {
return checkNotNull(resourceService.findResourcesByTenantId(system ? TenantId.SYS_TENANT_ID : getTenantId()));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/resource/{resourceType}", method = RequestMethod.GET)
@ResponseBody
public List<Resource> getResources(@RequestParam(required = false) boolean system,
@PathVariable("resourceType") ResourceType resourceType) throws ThingsboardException {
try {
return checkNotNull(resourceService.findResourcesByTenantIdResourceType(system ? TenantId.SYS_TENANT_ID : getTenantId(), resourceType));
PageLink pageLink = createPageLink(pageSize, page, null, sortProperty, sortOrder);
return checkNotNull(resourceService.findResourcesByTenantId(system ? TenantId.SYS_TENANT_ID : getTenantId(), pageLink));
} catch (Exception e) {
throw handleException(e);
}

View File

@ -22,14 +22,14 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.dashboard.DashboardService;
@ -251,7 +251,6 @@ public class InstallScripts {
}
}
public void loadDemoRuleChains(TenantId tenantId) throws Exception {
try {
createDefaultRuleChains(tenantId);

View File

@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.DeviceId;
@ -34,7 +35,6 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.queue.ServiceType;

View File

@ -19,12 +19,12 @@ import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.gen.transport.TransportProtos;

View File

@ -31,6 +31,8 @@ import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
@ -42,8 +44,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.msg.EncryptionUtil;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
@ -64,7 +64,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequ
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionResponseStatus;
import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg;
@ -81,14 +81,11 @@ import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.service.queue.TbClusterService;
import org.thingsboard.server.service.state.DeviceStateService;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
* Created by ashvayka on 05.10.18.
@ -166,8 +163,8 @@ public class DefaultTransportApiService implements TransportApiService {
} else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) {
return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()),
value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
} else if (transportApiRequestMsg.hasResourcesRequestMsg()) {
return Futures.transform(handle(transportApiRequestMsg.getResourcesRequestMsg()),
} else if (transportApiRequestMsg.hasResourceRequestMsg()) {
return Futures.transform(handle(transportApiRequestMsg.getResourceRequestMsg()),
value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
}
return Futures.transform(getEmptyTransportApiResponseFuture(),
@ -365,41 +362,22 @@ public class DefaultTransportApiService implements TransportApiService {
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setEntityProfileResponseMsg(builder).build());
}
private ListenableFuture<TransportApiResponseMsg> handle(GetResourcesRequestMsg requestMsg) {
private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) {
TenantId tenantId = new TenantId(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()));
TransportProtos.GetResourcesResponseMsg.Builder builder = TransportProtos.GetResourcesResponseMsg.newBuilder();
String resourceType = requestMsg.getResourceType();
ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType());
String resourceId = requestMsg.getResourceId();
TransportProtos.GetResourceResponseMsg.Builder builder = TransportProtos.GetResourceResponseMsg.newBuilder();
Resource resource = resourceService.getResource(tenantId, resourceType, resourceId);
List<TransportProtos.ResourceMsg> resources;
if (resourceType != null && resourceId != null && !resourceId.isEmpty()) {
resources = Collections.singletonList(toProto(
resourceService.getResource(tenantId, ResourceType.valueOf(resourceType), resourceId)));
} else if (resourceType != null && !resourceType.isEmpty()) {
resources = resourceService.findResourcesByTenantIdResourceType(tenantId, ResourceType.valueOf(resourceType))
.stream()
.map(this::toProto)
.collect(Collectors.toList());
} else {
resources = resourceService.findResourcesByTenantId(tenantId)
.stream()
.map(this::toProto)
.collect(Collectors.toList());
if (resource == null && !tenantId.equals(TenantId.SYS_TENANT_ID)) {
resource = resourceService.getResource(TenantId.SYS_TENANT_ID, resourceType, resourceId);
}
builder.addAllResources(resources);
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourcesResponseMsg(builder).build());
}
if (resource != null) {
builder.setResource(ByteString.copyFrom(dataDecodingEncodingService.encode(resource)));
}
private TransportProtos.ResourceMsg toProto(Resource resource) {
return TransportProtos.ResourceMsg.newBuilder()
.setTenantIdMSB(resource.getTenantId().getId().getMostSignificantBits())
.setTenantIdLSB(resource.getTenantId().getId().getLeastSignificantBits())
.setResourceType(resource.getResourceType().name())
.setResourceId(resource.getResourceId())
.setValue(resource.getValue())
.build();
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourceResponseMsg(builder).build());
}
private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId, DeviceCredentials credentials) {

View File

@ -15,9 +15,11 @@
*/
package org.thingsboard.server.dao.resource;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import java.util.List;
@ -27,7 +29,7 @@ public interface ResourceService {
Resource getResource(TenantId tenantId, ResourceType resourceType, String resourceId);
List<Resource> findResourcesByTenantId(TenantId tenantId);
PageData<Resource> findResourcesByTenantId(TenantId tenantId, PageLink pageLink);
List<Resource> findResourcesByTenantIdResourceType(TenantId tenantId, ResourceType resourceType);

View File

@ -0,0 +1,41 @@
/**
* Copyright © 2016-2021 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;
import lombok.Data;
import org.thingsboard.server.common.data.id.TenantId;
import java.io.Serializable;
@Data
public class Resource implements HasTenantId, Serializable {
private static final long serialVersionUID = 7379609705527272306L;
private TenantId tenantId;
private ResourceType resourceType;
private String resourceId;
private String value;
@Override
public String toString() {
return "Resource{" +
"tenantId=" + tenantId +
", resourceType=" + resourceType +
", resourceId='" + resourceId + '\'' +
'}';
}
}

View File

@ -0,0 +1,20 @@
/**
* Copyright © 2016-2021 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;
public enum ResourceType {
LWM2M_MODEL, JKS, PKCS_12
}

View File

@ -201,23 +201,15 @@ message LwM2MResponseMsg {
LwM2MRegistrationResponseMsg registrationMsg = 1;
}
message ResourceMsg {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
string resourceType = 3;
string resourceId = 4;
string value = 5;
}
message GetResourcesRequestMsg {
message GetResourceRequestMsg {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
string resourceType = 3;
string resourceId = 4;
}
message GetResourcesResponseMsg {
repeated ResourceMsg resources = 1;
message GetResourceResponseMsg {
bytes resource = 1;
}
message ValidateDeviceLwM2MCredentialsRequestMsg {
@ -558,7 +550,7 @@ message TransportApiRequestMsg {
ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 6;
ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7;
ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8;
GetResourcesRequestMsg resourcesRequestMsg = 9;
GetResourceRequestMsg resourceRequestMsg = 9;
}
/* Response from ThingsBoard Core Service to Transport Service */
@ -568,7 +560,7 @@ message TransportApiResponseMsg {
GetEntityProfileResponseMsg entityProfileResponseMsg = 3;
ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4;
LwM2MResponseMsg lwM2MResponseMsg = 6;
GetResourcesResponseMsg resourcesResponseMsg = 7;
GetResourceResponseMsg resourceResponseMsg = 7;
}
/* Messages that are handled by ThingsBoard Core Service */

View File

@ -41,8 +41,6 @@ import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
@ -51,9 +49,6 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY;
@ -147,56 +142,56 @@ public class LwM2mTransportContextServer extends TransportContext {
/**
* ResourcesRequestMsg
*
* @param resourceType
* @return
*/
public GetResourcesResponseMsg getResourceTenant (UUID tenantId, String resourceType) {
CountDownLatch latch = new CountDownLatch(1);
GetResourcesResponseMsg responseMsg =
this.getTransportService()
.getResources(GetResourcesRequestMsg.newBuilder()
.setResourceType(resourceType)
.setTenantIdLSB(tenantId.getLeastSignificantBits())
.setTenantIdMSB(tenantId.getMostSignificantBits())
.build());
latch.countDown();
try {
latch.await(this.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
log.error("Failed to await credentials!", e);
}
// /**
// * ResourcesRequestMsg
// *
// * @param resourceType
// * @return
// */
// public GetResourcesResponseMsg getResourceTenant (UUID tenantId, String resourceType) {
// CountDownLatch latch = new CountDownLatch(1);
// GetResourcesResponseMsg responseMsg =
// this.getTransportService()
// .getResources(GetResourcesRequestMsg.newBuilder()
// .setResourceType(resourceType)
// .setTenantIdLSB(tenantId.getLeastSignificantBits())
// .setTenantIdMSB(tenantId.getMostSignificantBits())
// .build());
// latch.countDown();
// try {
// latch.await(this.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
// } catch (InterruptedException e) {
// log.error("Failed to await credentials!", e);
// }
//
// return responseMsg;
// }
return responseMsg;
}
public GetResourcesResponseMsg getResourceTenantProcess (UUID tenantId, String resourceType) {
CountDownLatch latch = new CountDownLatch(2);
final GetResourcesResponseMsg[] responseMsg = {null};
this.getTransportService().process(GetResourcesRequestMsg.newBuilder()
.setResourceType(resourceType)
.setTenantIdLSB(tenantId.getLeastSignificantBits())
.setTenantIdMSB(tenantId.getMostSignificantBits())
.build(),
new TransportServiceCallback<>() {
@Override
public void onSuccess(GetResourcesResponseMsg msg) { responseMsg[0] = msg;
latch.countDown();
}
@Override
public void onError(Throwable e) {
log.trace("[{}] [{}] Failed to process credentials ", tenantId, e);
latch.countDown();
}
});
try {
latch.await(this.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
log.error("Failed to await credentials!", e);
}
return responseMsg[0];
}
// public GetResourcesResponseMsg getResourceTenantProcess (UUID tenantId, String resourceType) {
// CountDownLatch latch = new CountDownLatch(2);
// final GetResourcesResponseMsg[] responseMsg = {null};
// this.getTransportService().process(GetResourcesRequestMsg.newBuilder()
// .setResourceType(resourceType)
// .setTenantIdLSB(tenantId.getLeastSignificantBits())
// .setTenantIdMSB(tenantId.getMostSignificantBits())
// .build(),
// new TransportServiceCallback<>() {
// @Override
// public void onSuccess(GetResourcesResponseMsg msg) { responseMsg[0] = msg;
// latch.countDown();
// }
//
// @Override
// public void onError(Throwable e) {
// log.trace("[{}] [{}] Failed to process credentials ", tenantId, e);
// latch.countDown();
// }
// });
// try {
// latch.await(this.getLwM2MTransportConfigServer().getTimeout(), TimeUnit.MILLISECONDS);
// } catch (InterruptedException e) {
// log.error("Failed to await credentials!", e);
// }
// return responseMsg[0];
// }
}

View File

@ -30,9 +30,6 @@ import org.eclipse.leshan.server.security.SecurityChecker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
@ -101,7 +98,7 @@ public class LwM2mTransportServerConfiguration {
builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort));
/** Define model provider (Create Models )*/
TransportProtos.GetResourcesResponseMsg responseMsg= this.context.getResourceTenantProcess(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.context.getResourceTenantProcess(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.context.getResourceTenant(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getLwM2MTransportConfigServer().getModelsValueCommon());
LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.context.getLwM2MTransportConfigServer().getModelsValueServer(), this.lwM2mClientContext);

View File

@ -40,8 +40,6 @@ import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@ -156,7 +154,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
try {
log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
((LwM2mVersionedModelProvider)leshanServer.getModelProvider()).setRepository(this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelsValueCommon());
TransportProtos.GetResourcesResponseMsg responseMsg= this.lwM2mTransportContextServer.getResourceTenantProcess(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.lwM2mTransportContextServer.getResourceTenantProcess(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// TransportProtos.GetResourcesResponseMsg responseMsg= this.lwM2mTransportContextServer.getResourceTenant(TenantId.SYS_TENANT_ID.getId(), ResourceType.LWM2M_MODEL.name());
// (((VersionedModelProvider) (leshanServer)).modelProvider).repository;

View File

@ -0,0 +1,29 @@
/**
* Copyright © 2016-2021 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.transport;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
public interface TransportResourceCache {
Resource get(TenantId tenantId, ResourceType resourceType, String resourceId);
void update(TenantId tenantId, ResourceType resourceType, String resourceI);
void evict(TenantId tenantId, ResourceType resourceType, String resourceId);
}

View File

@ -25,8 +25,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestM
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourcesResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.LwM2MRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.LwM2MResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
@ -53,7 +53,7 @@ public interface TransportService {
GetEntityProfileResponseMsg getEntityProfile(GetEntityProfileRequestMsg msg);
GetResourcesResponseMsg getResources(GetResourcesRequestMsg msg);
GetResourceResponseMsg getResource(GetResourceRequestMsg msg);
void process(DeviceTransportType transportType, ValidateDeviceTokenRequestMsg msg,
TransportServiceCallback<ValidateDeviceCredentialsResponse> callback);
@ -75,9 +75,8 @@ public interface TransportService {
void onProfileUpdate(DeviceProfile deviceProfile);
void process(LwM2MRequestMsg msg, TransportServiceCallback<LwM2MResponseMsg> callback);
void process(GetResourcesRequestMsg msg, TransportServiceCallback<GetResourcesResponseMsg> callback);
void process(LwM2MRequestMsg msg,
TransportServiceCallback<LwM2MResponseMsg> callback);
void process(SessionInfoProto sessionInfo, SessionEventMsg msg, TransportServiceCallback<Void> callback);

View File

@ -0,0 +1,130 @@
/**
* Copyright © 2016-2021 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.transport.service;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.transport.TransportResourceCache;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
@Component
@TbTransportComponent
public class DefaultTransportResourceCache implements TransportResourceCache {
private final Lock resourceFetchLock = new ReentrantLock();
private final ConcurrentMap<ResourceKey, Resource> resources = new ConcurrentHashMap<>();
private final Set<ResourceKey> keys = ConcurrentHashMap.newKeySet();
private final DataDecodingEncodingService dataDecodingEncodingService;
private final TransportService transportService;
public DefaultTransportResourceCache(DataDecodingEncodingService dataDecodingEncodingService, @Lazy TransportService transportService) {
this.dataDecodingEncodingService = dataDecodingEncodingService;
this.transportService = transportService;
}
@Override
public Resource get(TenantId tenantId, ResourceType resourceType, String resourceId) {
ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);
Resource resource;
if (keys.contains(resourceKey)) {
resource = resources.get(resourceKey);
if (resource == null) {
resource = resources.get(resourceKey.getSystemKey());
}
} else {
resourceFetchLock.lock();
try {
if (keys.contains(resourceKey)) {
resource = resources.get(resourceKey);
if (resource == null) {
resource = resources.get(resourceKey.getSystemKey());
}
} else {
resource = fetchResource(resourceKey);
keys.add(resourceKey);
}
} finally {
resourceFetchLock.unlock();
}
}
return resource;
}
private Resource fetchResource(ResourceKey resourceKey) {
UUID tenantId = resourceKey.getTenantId().getId();
TransportProtos.GetResourceRequestMsg.Builder builder = TransportProtos.GetResourceRequestMsg.newBuilder();
builder
.setTenantIdLSB(tenantId.getLeastSignificantBits())
.setTenantIdMSB(tenantId.getMostSignificantBits())
.setResourceType(resourceKey.resourceType.name())
.setResourceId(resourceKey.resourceId);
TransportProtos.GetResourceResponseMsg responseMsg = transportService.getResource(builder.build());
Optional<Resource> optionalResource = dataDecodingEncodingService.decode(responseMsg.getResource().toByteArray());
if (optionalResource.isPresent()) {
Resource resource = optionalResource.get();
resources.put(new ResourceKey(resource.getTenantId(), resource.getResourceType(), resource.getResourceId()), resource);
return resource;
}
return null;
}
@Override
public void update(TenantId tenantId, ResourceType resourceType, String resourceId) {
ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);
if (keys.contains(resourceKey) || resources.containsKey(resourceKey)) {
fetchResource(resourceKey);
}
}
@Override
public void evict(TenantId tenantId, ResourceType resourceType, String resourceId) {
ResourceKey resourceKey = new ResourceKey(tenantId, resourceType, resourceId);
keys.remove(resourceKey);
resources.remove(resourceKey);
}
@Data
private static class ResourceKey {
private final TenantId tenantId;
private final ResourceType resourceType;
private final String resourceId;
public ResourceKey getSystemKey() {
return new ResourceKey(TenantId.SYS_TENANT_ID, resourceType, resourceId);
}
}
}

View File

@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -49,6 +50,7 @@ import org.thingsboard.server.common.stats.StatsFactory;
import org.thingsboard.server.common.stats.StatsType;
import org.thingsboard.server.common.transport.SessionMsgListener;
import org.thingsboard.server.common.transport.TransportDeviceProfileCache;
import org.thingsboard.server.common.transport.TransportResourceCache;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.TransportTenantProfileCache;
@ -130,6 +132,7 @@ public class DefaultTransportService implements TransportService {
private final TransportRateLimitService rateLimitService;
private final DataDecodingEncodingService dataDecodingEncodingService;
private final SchedulerComponent scheduler;
private final TransportResourceCache transportResourceCache;
protected TbQueueRequestTemplate<TbProtoQueueMsg<TransportApiRequestMsg>, TbProtoQueueMsg<TransportApiResponseMsg>> transportApiRequestTemplate;
protected TbQueueProducer<TbProtoQueueMsg<ToRuleEngineMsg>> ruleEngineMsgProducer;
@ -156,7 +159,7 @@ public class DefaultTransportService implements TransportService {
TransportDeviceProfileCache deviceProfileCache,
TransportTenantProfileCache tenantProfileCache,
TbApiUsageClient apiUsageClient, TransportRateLimitService rateLimitService,
DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler) {
DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler, TransportResourceCache transportResourceCache) {
this.serviceInfoProvider = serviceInfoProvider;
this.queueProvider = queueProvider;
this.producerProvider = producerProvider;
@ -168,6 +171,7 @@ public class DefaultTransportService implements TransportService {
this.rateLimitService = rateLimitService;
this.dataDecodingEncodingService = dataDecodingEncodingService;
this.scheduler = scheduler;
this.transportResourceCache = transportResourceCache;
}
@PostConstruct
@ -254,27 +258,17 @@ public class DefaultTransportService implements TransportService {
}
@Override
public TransportProtos.GetResourcesResponseMsg getResources(TransportProtos.GetResourcesRequestMsg msg) {
public TransportProtos.GetResourceResponseMsg getResource(TransportProtos.GetResourceRequestMsg msg) {
TbProtoQueueMsg<TransportProtos.TransportApiRequestMsg> protoMsg =
new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setResourcesRequestMsg(msg).build());
new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setResourceRequestMsg(msg).build());
try {
TbProtoQueueMsg<TransportApiResponseMsg> response = transportApiRequestTemplate.send(protoMsg).get();
return response.getValue().getResourcesResponseMsg();
return response.getValue().getResourceResponseMsg();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
public void process(TransportProtos.GetResourcesRequestMsg msg, TransportServiceCallback<TransportProtos.GetResourcesResponseMsg> callback) {
log.trace("Processing msg: {}", msg);
TbProtoQueueMsg<TransportProtos.TransportApiRequestMsg> protoMsg =
new TbProtoQueueMsg<>(UUID.randomUUID(), TransportProtos.TransportApiRequestMsg.newBuilder().setResourcesRequestMsg(msg).build());
AsyncCallbackTemplate.withCallback(transportApiRequestTemplate.send(protoMsg),
response -> callback.onSuccess(response.getValue().getResourcesResponseMsg()), callback::onError, transportCallbackExecutor);
}
@Override
public void process(DeviceTransportType transportType, TransportProtos.ValidateDeviceTokenRequestMsg msg,
TransportServiceCallback<ValidateDeviceCredentialsResponse> callback) {
@ -711,9 +705,17 @@ public class DefaultTransportService implements TransportService {
rateLimitService.remove(new DeviceId(entityUuid));
}
} else if (toSessionMsg.hasResourceUpdateMsg()) {
//TODO: update resource cache
TransportProtos.ResourceUpdateMsg msg = toSessionMsg.getResourceUpdateMsg();
TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
ResourceType resourceType = ResourceType.valueOf(msg.getResourceType());
String resourceId = msg.getResourceId();
transportResourceCache.update(tenantId, resourceType, resourceId);
} else if (toSessionMsg.hasResourceDeleteMsg()) {
//TODO: remove resource from cache
TransportProtos.ResourceDeleteMsg msg = toSessionMsg.getResourceDeleteMsg();
TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB()));
ResourceType resourceType = ResourceType.valueOf(msg.getResourceType());
String resourceId = msg.getResourceId();
transportResourceCache.evict(tenantId, resourceType, resourceId);
} else {
//TODO: should we notify the device actor about missed session?
log.debug("[{}] Missing session.", sessionId);

View File

@ -18,8 +18,6 @@ package org.thingsboard.server.common.transport.util;
import lombok.extern.slf4j.Slf4j;
import org.nustaq.serialization.FSTConfiguration;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
import java.util.Optional;
@ -33,8 +31,8 @@ public class ProtoWithFSTService implements DataDecodingEncodingService {
public <T> Optional<T> decode(byte[] byteArray) {
try {
@SuppressWarnings("unchecked")
T msg = (T) config.asObject(byteArray);
return Optional.of(msg);
T msg = byteArray != null && byteArray.length > 0 ? (T) config.asObject(byteArray) : null;
return Optional.ofNullable(msg);
} catch (IllegalArgumentException e) {
log.error("Error during deserialization message, [{}]", e.getMessage());
return Optional.empty();

View File

@ -18,8 +18,7 @@ package org.thingsboard.server.dao.model.sql;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.Resource;
import javax.persistence.Transient;
import java.io.Serializable;

View File

@ -16,9 +16,9 @@
package org.thingsboard.server.dao.model.sql;
import lombok.Data;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.dao.model.ToData;
import javax.persistence.Column;

View File

@ -17,9 +17,11 @@ package org.thingsboard.server.dao.resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.exception.DataValidationException;
import java.util.List;
@ -59,12 +61,13 @@ public class BaseResourceService implements ResourceService {
}
@Override
public List<Resource> findResourcesByTenantId(TenantId tenantId) {
public PageData<Resource> findResourcesByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findByTenantId [{}]", tenantId);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
return resourceDao.findAllByTenantId(tenantId);
return resourceDao.findAllByTenantId(tenantId, pageLink);
}
@Override
public List<Resource> findResourcesByTenantIdResourceType(TenantId tenantId, ResourceType resourceType) {
log.trace("Executing findByTenantId [{}]", tenantId);

View File

@ -15,9 +15,11 @@
*/
package org.thingsboard.server.dao.resource;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import java.util.List;
@ -29,7 +31,8 @@ public interface ResourceDao {
void deleteResource(TenantId tenantId, ResourceType resourceType, String resourceId);
List<Resource> findAllByTenantId(TenantId tenantId);
PageData<Resource> findAllByTenantId(TenantId tenantId, PageLink pageLink);
List<Resource> findAllByTenantIdResourceType(TenantId tenantId, ResourceType resourceType);

View File

@ -18,9 +18,11 @@ package org.thingsboard.server.dao.sql.resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.Resource;
import org.thingsboard.server.common.data.ResourceType;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.transport.resource.Resource;
import org.thingsboard.server.common.data.transport.resource.ResourceType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;
import org.thingsboard.server.dao.model.sql.ResourceEntity;
@ -66,8 +68,8 @@ public class ResourceDaoImpl implements ResourceDao {
}
@Override
public List<Resource> findAllByTenantId(TenantId tenantId) {
return DaoUtil.convertDataList(resourceRepository.findAllByTenantId(tenantId.getId()));
public PageData<Resource> findAllByTenantId(TenantId tenantId, PageLink pageLink) {
return DaoUtil.toPageData(resourceRepository.findAllByTenantId(tenantId.getId(), DaoUtil.toPageable(pageLink)));
}
@Override

View File

@ -15,6 +15,8 @@
*/
package org.thingsboard.server.dao.sql.resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;
import org.thingsboard.server.dao.model.sql.ResourceCompositeKey;
import org.thingsboard.server.dao.model.sql.ResourceEntity;
@ -24,7 +26,8 @@ import java.util.UUID;
public interface ResourceRepository extends CrudRepository<ResourceEntity, ResourceCompositeKey> {
List<ResourceEntity> findAllByTenantId(UUID tenantId);
Page<ResourceEntity> findAllByTenantId(UUID tenantId, Pageable pageable);
List<ResourceEntity> findAllByTenantIdAndResourceType(UUID tenantId, String resourceType);