254 changed files with 7598 additions and 4402 deletions
@ -1,48 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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; |
|
||||
|
|
||||
import com.fasterxml.jackson.databind.JsonNode; |
|
||||
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.EdgeId; |
|
||||
import org.thingsboard.server.common.data.id.EntityId; |
|
||||
import org.thingsboard.server.common.data.id.TenantId; |
|
||||
|
|
||||
public final class EdgeEventUtils { |
|
||||
|
|
||||
private EdgeEventUtils() { |
|
||||
} |
|
||||
|
|
||||
public static EdgeEvent constructEdgeEvent(TenantId tenantId, |
|
||||
EdgeId edgeId, |
|
||||
EdgeEventType type, |
|
||||
EdgeEventActionType action, |
|
||||
EntityId entityId, |
|
||||
JsonNode body) { |
|
||||
EdgeEvent edgeEvent = new EdgeEvent(); |
|
||||
edgeEvent.setTenantId(tenantId); |
|
||||
edgeEvent.setEdgeId(edgeId); |
|
||||
edgeEvent.setType(type); |
|
||||
edgeEvent.setAction(action); |
|
||||
if (entityId != null) { |
|
||||
edgeEvent.setEntityId(entityId.getId()); |
|
||||
} |
|
||||
edgeEvent.setBody(body); |
|
||||
return edgeEvent; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,201 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy; |
||||
|
|
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import com.google.common.util.concurrent.Futures; |
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import lombok.Getter; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.thingsboard.server.cluster.TbClusterService; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.HasName; |
||||
|
import org.thingsboard.server.common.data.User; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmInfo; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmQuery; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.AlarmId; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
import org.thingsboard.server.common.data.id.EntityId; |
||||
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.PageData; |
||||
|
import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; |
||||
|
import org.thingsboard.server.common.data.page.TimePageLink; |
||||
|
import org.thingsboard.server.dao.alarm.AlarmService; |
||||
|
import org.thingsboard.server.dao.asset.AssetService; |
||||
|
import org.thingsboard.server.dao.customer.CustomerService; |
||||
|
import org.thingsboard.server.dao.device.ClaimDevicesService; |
||||
|
import org.thingsboard.server.dao.device.DeviceCredentialsService; |
||||
|
import org.thingsboard.server.dao.device.DeviceService; |
||||
|
import org.thingsboard.server.dao.edge.EdgeService; |
||||
|
import org.thingsboard.server.dao.exception.DataValidationException; |
||||
|
import org.thingsboard.server.dao.exception.IncorrectParameterException; |
||||
|
import org.thingsboard.server.dao.model.ModelConstants; |
||||
|
import org.thingsboard.server.dao.rule.RuleChainService; |
||||
|
import org.thingsboard.server.dao.tenant.TbTenantProfileCache; |
||||
|
import org.thingsboard.server.dao.tenant.TenantService; |
||||
|
import org.thingsboard.server.service.action.EntityActionService; |
||||
|
import org.thingsboard.server.service.edge.EdgeNotificationService; |
||||
|
import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
||||
|
|
||||
|
import javax.mail.MessagingException; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
import java.util.Optional; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Slf4j |
||||
|
public abstract class AbstractTbEntityService { |
||||
|
|
||||
|
protected static final int DEFAULT_PAGE_SIZE = 1000; |
||||
|
|
||||
|
private static final ObjectMapper json = new ObjectMapper(); |
||||
|
|
||||
|
@Value("${server.log_controller_error_stack_trace}") |
||||
|
@Getter |
||||
|
private boolean logControllerErrorStackTrace; |
||||
|
@Value("${edges.enabled}") |
||||
|
@Getter |
||||
|
protected boolean edgesEnabled; |
||||
|
|
||||
|
@Autowired |
||||
|
protected DbCallbackExecutorService dbExecutor; |
||||
|
@Autowired |
||||
|
protected TbNotificationEntityService notificationEntityService; |
||||
|
@Autowired(required = false) |
||||
|
protected EdgeService edgeService; |
||||
|
@Autowired |
||||
|
protected AlarmService alarmService; |
||||
|
@Autowired |
||||
|
protected EntityActionService entityActionService; |
||||
|
@Autowired |
||||
|
protected DeviceService deviceService; |
||||
|
@Autowired |
||||
|
protected AssetService assetService; |
||||
|
@Autowired |
||||
|
protected DeviceCredentialsService deviceCredentialsService; |
||||
|
@Autowired |
||||
|
protected TenantService tenantService; |
||||
|
@Autowired |
||||
|
protected CustomerService customerService; |
||||
|
@Autowired |
||||
|
protected ClaimDevicesService claimDevicesService; |
||||
|
@Autowired |
||||
|
protected TbTenantProfileCache tenantProfileCache; |
||||
|
@Autowired |
||||
|
protected RuleChainService ruleChainService; |
||||
|
@Autowired |
||||
|
protected EdgeNotificationService edgeNotificationService; |
||||
|
|
||||
|
protected ListenableFuture<Void> removeAlarmsByEntityId(TenantId tenantId, EntityId entityId) { |
||||
|
ListenableFuture<PageData<AlarmInfo>> alarmsFuture = |
||||
|
alarmService.findAlarms(tenantId, new AlarmQuery(entityId, new TimePageLink(Integer.MAX_VALUE), null, null, false)); |
||||
|
|
||||
|
ListenableFuture<List<AlarmId>> alarmIdsFuture = Futures.transform(alarmsFuture, page -> |
||||
|
page.getData().stream().map(AlarmInfo::getId).collect(Collectors.toList()), dbExecutor); |
||||
|
|
||||
|
return Futures.transform(alarmIdsFuture, ids -> { |
||||
|
ids.stream().map(alarmId -> alarmService.deleteAlarm(tenantId, alarmId)).collect(Collectors.toList()); |
||||
|
return null; |
||||
|
}, dbExecutor); |
||||
|
} |
||||
|
|
||||
|
protected <E extends HasName, I extends EntityId> void logEntityAction(User user, TenantId tenantId, I entityId, E entity, CustomerId customerId, |
||||
|
ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException { |
||||
|
if (user != null) { |
||||
|
entityActionService.logEntityAction(user, entityId, entity, customerId, actionType, e, additionalInfo); |
||||
|
} else if (e == null) { |
||||
|
entityActionService.pushEntityActionToRuleEngine(entityId, entity, tenantId, customerId, actionType, null, additionalInfo); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected <T> T checkNotNull(T reference) throws ThingsboardException { |
||||
|
return checkNotNull(reference, "Requested item wasn't found!"); |
||||
|
} |
||||
|
|
||||
|
protected <T> T checkNotNull(T reference, String notFoundMessage) throws ThingsboardException { |
||||
|
if (reference == null) { |
||||
|
throw new ThingsboardException(notFoundMessage, ThingsboardErrorCode.ITEM_NOT_FOUND); |
||||
|
} |
||||
|
return reference; |
||||
|
} |
||||
|
|
||||
|
protected <T> T checkNotNull(Optional<T> reference) throws ThingsboardException { |
||||
|
return checkNotNull(reference, "Requested item wasn't found!"); |
||||
|
} |
||||
|
|
||||
|
protected <T> T checkNotNull(Optional<T> reference, String notFoundMessage) throws ThingsboardException { |
||||
|
if (reference.isPresent()) { |
||||
|
return reference.get(); |
||||
|
} else { |
||||
|
throw new ThingsboardException(notFoundMessage, ThingsboardErrorCode.ITEM_NOT_FOUND); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected ThingsboardException handleException(Exception exception) { |
||||
|
return handleException(exception, true); |
||||
|
} |
||||
|
|
||||
|
protected ThingsboardException handleException(Exception exception, boolean logException) { |
||||
|
if (logException && logControllerErrorStackTrace) { |
||||
|
log.error("Error [{}]", exception.getMessage(), exception); |
||||
|
} |
||||
|
|
||||
|
String cause = ""; |
||||
|
if (exception.getCause() != null) { |
||||
|
cause = exception.getCause().getClass().getCanonicalName(); |
||||
|
} |
||||
|
|
||||
|
if (exception instanceof ThingsboardException) { |
||||
|
return (ThingsboardException) exception; |
||||
|
} else if (exception instanceof IllegalArgumentException || exception instanceof IncorrectParameterException |
||||
|
|| exception instanceof DataValidationException || cause.contains("IncorrectParameterException")) { |
||||
|
return new ThingsboardException(exception.getMessage(), ThingsboardErrorCode.BAD_REQUEST_PARAMS); |
||||
|
} else if (exception instanceof MessagingException) { |
||||
|
return new ThingsboardException("Unable to send mail: " + exception.getMessage(), ThingsboardErrorCode.GENERAL); |
||||
|
} else { |
||||
|
return new ThingsboardException(exception.getMessage(), exception, ThingsboardErrorCode.GENERAL); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@SuppressWarnings("unchecked") |
||||
|
protected <I extends EntityId> I emptyId(EntityType entityType) { |
||||
|
return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID); |
||||
|
} |
||||
|
|
||||
|
protected List<EdgeId> findRelatedEdgeIds(TenantId tenantId, EntityId entityId) { |
||||
|
if (!edgesEnabled) { |
||||
|
return null; |
||||
|
} |
||||
|
if (EntityType.EDGE.equals(entityId.getEntityType())) { |
||||
|
return Collections.singletonList(new EdgeId(entityId.getId())); |
||||
|
} |
||||
|
PageDataIterableByTenantIdEntityId<EdgeId> relatedEdgeIdsIterator = |
||||
|
new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); |
||||
|
List<EdgeId> result = new ArrayList<>(); |
||||
|
for (EdgeId edgeId : relatedEdgeIdsIterator) { |
||||
|
result.add(edgeId); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,299 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy; |
||||
|
|
||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg; |
||||
|
import org.thingsboard.server.cluster.TbClusterService; |
||||
|
import org.thingsboard.server.common.data.DataConstants; |
||||
|
import org.thingsboard.server.common.data.Device; |
||||
|
import org.thingsboard.server.common.data.HasName; |
||||
|
import org.thingsboard.server.common.data.Tenant; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.asset.Asset; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventType; |
||||
|
import org.thingsboard.server.common.data.id.AssetId; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.DeviceId; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
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.security.DeviceCredentials; |
||||
|
import org.thingsboard.server.common.msg.TbMsg; |
||||
|
import org.thingsboard.server.common.msg.TbMsgDataType; |
||||
|
import org.thingsboard.server.common.msg.TbMsgMetaData; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.action.EntityActionService; |
||||
|
import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Service |
||||
|
@TbCoreComponent |
||||
|
@RequiredArgsConstructor |
||||
|
public class DefaultTbNotificationEntityService implements TbNotificationEntityService { |
||||
|
private static final ObjectMapper json = new ObjectMapper(); |
||||
|
|
||||
|
private final EntityActionService entityActionService; |
||||
|
private final TbClusterService tbClusterService; |
||||
|
private final GatewayNotificationsService gatewayNotificationsService; |
||||
|
|
||||
|
@Override |
||||
|
public <E extends HasName, I extends EntityId> void notifyEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, |
||||
|
ActionType actionType, SecurityUser user, Exception e, |
||||
|
Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, e, additionalInfo); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public <E extends HasName, I extends EntityId> void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, |
||||
|
CustomerId customerId, List<EdgeId> relatedEdgeIds, |
||||
|
SecurityUser user, Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, entityId, entity, customerId, ActionType.DELETED, user, additionalInfo); |
||||
|
sendDeleteNotificationMsg(tenantId, entityId, relatedEdgeIds); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public <E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, |
||||
|
CustomerId customerId, E entity, |
||||
|
ActionType actionType, |
||||
|
EdgeEventActionType edgeActionType, |
||||
|
SecurityUser user, boolean sendToEdge, |
||||
|
Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); |
||||
|
|
||||
|
if (sendToEdge) { |
||||
|
sendEntityAssignToCustomerNotificationMsg(tenantId, entityId, customerId, edgeActionType); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public <E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToEdge(TenantId tenantId, I entityId, |
||||
|
CustomerId customerId, EdgeId edgeId, |
||||
|
E entity, ActionType actionType, |
||||
|
EdgeEventActionType edgeActionType, |
||||
|
SecurityUser user, Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, additionalInfo); |
||||
|
sendEntityAssignToEdgeNotificationMsg(tenantId, edgeId, entityId, edgeActionType); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyCreateOruUpdateTenant(Tenant tenant, ComponentLifecycleEvent event) { |
||||
|
tbClusterService.onTenantChange(tenant, null); |
||||
|
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), event); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyDeleteTenant(Tenant tenant) { |
||||
|
tbClusterService.onTenantDelete(tenant, null); |
||||
|
tbClusterService.broadcastEntityStateChangeEvent(tenant.getId(), tenant.getId(), ComponentLifecycleEvent.DELETED); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyCreateOrUpdateDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, |
||||
|
Device device, Device oldDevice, ActionType actionType, |
||||
|
SecurityUser user, Object... additionalInfo) { |
||||
|
tbClusterService.onDeviceUpdated(device, oldDevice); |
||||
|
logEntityAction(tenantId, deviceId, device, customerId, actionType, user, additionalInfo); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, |
||||
|
List<EdgeId> relatedEdgeIds, SecurityUser user, Object... additionalInfo) { |
||||
|
gatewayNotificationsService.onDeviceDeleted(device); |
||||
|
tbClusterService.onDeviceDeleted(device, null); |
||||
|
|
||||
|
notifyDeleteEntity(tenantId, deviceId, device, customerId, relatedEdgeIds, user, additionalInfo); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, |
||||
|
DeviceCredentials deviceCredentials, SecurityUser user) { |
||||
|
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(tenantId, deviceCredentials.getDeviceId(), deviceCredentials), null); |
||||
|
sendEntityNotificationMsg(tenantId, deviceId, EdgeEventActionType.CREDENTIALS_UPDATED); |
||||
|
logEntityAction(tenantId, deviceId, device, customerId, ActionType.CREDENTIALS_UPDATED, user, deviceCredentials); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId, |
||||
|
Device device, Tenant tenant, SecurityUser user, Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, deviceId, device, customerId, ActionType.ASSIGNED_TO_TENANT, user, additionalInfo); |
||||
|
pushAssignedFromNotification(tenant, newTenantId, device); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyCreateOrUpdateAsset(TenantId tenantId, AssetId assetId, CustomerId customerId, Asset asset, |
||||
|
ActionType actionType, SecurityUser user, Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, assetId, asset, customerId, actionType, user, additionalInfo); |
||||
|
|
||||
|
if (actionType == ActionType.UPDATED) { |
||||
|
sendEntityNotificationMsg(asset.getTenantId(), asset.getId(), EdgeEventActionType.UPDATED); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType, |
||||
|
SecurityUser user, Object... additionalInfo) { |
||||
|
ComponentLifecycleEvent lifecycleEvent; |
||||
|
EdgeEventActionType edgeEventActionType = null; |
||||
|
switch (actionType) { |
||||
|
case ADDED: |
||||
|
lifecycleEvent = ComponentLifecycleEvent.CREATED; |
||||
|
break; |
||||
|
case UPDATED: |
||||
|
lifecycleEvent = ComponentLifecycleEvent.UPDATED; |
||||
|
break; |
||||
|
case ASSIGNED_TO_CUSTOMER: |
||||
|
lifecycleEvent = ComponentLifecycleEvent.UPDATED; |
||||
|
edgeEventActionType = EdgeEventActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
break; |
||||
|
case UNASSIGNED_FROM_CUSTOMER: |
||||
|
lifecycleEvent = ComponentLifecycleEvent.UPDATED; |
||||
|
edgeEventActionType = EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER; |
||||
|
break; |
||||
|
case DELETED: |
||||
|
lifecycleEvent = ComponentLifecycleEvent.DELETED; |
||||
|
break; |
||||
|
default: |
||||
|
throw new IllegalArgumentException("Unknown actionType: " + actionType); |
||||
|
} |
||||
|
|
||||
|
tbClusterService.broadcastEntityStateChangeEvent(tenantId, edgeId, lifecycleEvent); |
||||
|
logEntityAction(tenantId, edgeId, edge, customerId, actionType, user, additionalInfo); |
||||
|
|
||||
|
//Send notification to edge
|
||||
|
if (edgeEventActionType != null) { |
||||
|
sendEntityAssignToCustomerNotificationMsg(tenantId, edgeId, customerId, edgeEventActionType); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyCreateOrUpdateAlarm(Alarm alarm, ActionType actionType, SecurityUser user, Object... additionalInfo) { |
||||
|
logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarm, alarm.getCustomerId(), actionType, user, additionalInfo); |
||||
|
sendEntityNotificationMsg(alarm.getTenantId(), alarm.getId(), edgeTypeByActionType (actionType)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void notifyDeleteAlarm(Alarm alarm, SecurityUser user, List<EdgeId> relatedEdgeIds) { |
||||
|
logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarm, alarm.getCustomerId(), ActionType.ALARM_DELETE, user, null); |
||||
|
sendAlarmDeleteNotificationMsg(alarm, relatedEdgeIds); |
||||
|
} |
||||
|
|
||||
|
private <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId, |
||||
|
ActionType actionType, SecurityUser user, Object... additionalInfo) { |
||||
|
logEntityAction(tenantId, entityId, entity, customerId, actionType, user, null, additionalInfo); |
||||
|
} |
||||
|
|
||||
|
private <E extends HasName, I extends EntityId> void logEntityAction(TenantId tenantId, I entityId, E entity, CustomerId customerId, |
||||
|
ActionType actionType, SecurityUser user, Exception e, Object... additionalInfo) { |
||||
|
if (user != null) { |
||||
|
entityActionService.logEntityAction(user, entityId, entity, customerId, actionType, e, additionalInfo); |
||||
|
} else if (e == null) { |
||||
|
entityActionService.pushEntityActionToRuleEngine(entityId, entity, tenantId, customerId, actionType, null, additionalInfo); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void sendEntityNotificationMsg(TenantId tenantId, EntityId entityId, EdgeEventActionType action) { |
||||
|
sendNotificationMsgToEdgeService(tenantId, null, entityId, null, null, action); |
||||
|
} |
||||
|
|
||||
|
private void sendEntityAssignToCustomerNotificationMsg(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) { |
||||
|
try { |
||||
|
sendNotificationMsgToEdgeService(tenantId, null, entityId, json.writeValueAsString(customerId), null, action); |
||||
|
} catch (Exception e) { |
||||
|
log.warn("Failed to push assign/unassign to/from customer to core: {}", customerId, e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds) { |
||||
|
sendDeleteNotificationMsg(tenantId, entityId, edgeIds, null); |
||||
|
} |
||||
|
|
||||
|
protected void sendAlarmDeleteNotificationMsg(Alarm alarm, List<EdgeId> relatedEdgeIds) { |
||||
|
try { |
||||
|
sendDeleteNotificationMsg(alarm.getTenantId(), alarm.getId(), relatedEdgeIds, json.writeValueAsString(alarm)); |
||||
|
} catch (Exception e) { |
||||
|
log.warn("Failed to push delete alarm msg to core: {}", alarm, e); |
||||
|
} |
||||
|
} |
||||
|
private void sendDeleteNotificationMsg(TenantId tenantId, EntityId entityId, List<EdgeId> edgeIds, String body) { |
||||
|
if (edgeIds != null && !edgeIds.isEmpty()) { |
||||
|
for (EdgeId edgeId : edgeIds) { |
||||
|
sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, null, EdgeEventActionType.DELETED); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void sendEntityAssignToEdgeNotificationMsg(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) { |
||||
|
sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, null, action); |
||||
|
} |
||||
|
|
||||
|
private void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, String body, EdgeEventType type, EdgeEventActionType action) { |
||||
|
tbClusterService.sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, body, type, action); |
||||
|
} |
||||
|
|
||||
|
private void pushAssignedFromNotification(Tenant currentTenant, TenantId newTenantId, Device assignedDevice) { |
||||
|
String data = entityToStr(assignedDevice); |
||||
|
if (data != null) { |
||||
|
TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_ASSIGNED_FROM_TENANT, assignedDevice.getId(), assignedDevice.getCustomerId(), getMetaDataForAssignedFrom(currentTenant), TbMsgDataType.JSON, data); |
||||
|
tbClusterService.pushMsgToRuleEngine(newTenantId, assignedDevice.getId(), tbMsg, null); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private TbMsgMetaData getMetaDataForAssignedFrom(Tenant tenant) { |
||||
|
TbMsgMetaData metaData = new TbMsgMetaData(); |
||||
|
metaData.putValue("assignedFromTenantId", tenant.getId().getId().toString()); |
||||
|
metaData.putValue("assignedFromTenantName", tenant.getName()); |
||||
|
return metaData; |
||||
|
} |
||||
|
|
||||
|
private <E extends HasName> String entityToStr(E entity) { |
||||
|
try { |
||||
|
return json.writeValueAsString(json.valueToTree(entity)); |
||||
|
} catch (JsonProcessingException e) { |
||||
|
log.warn("[{}] Failed to convert entity to string!", entity, e); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
private EdgeEventActionType edgeTypeByActionType (ActionType actionType) { |
||||
|
switch (actionType) { |
||||
|
case ADDED: |
||||
|
return EdgeEventActionType.ADDED; |
||||
|
case UPDATED: |
||||
|
return EdgeEventActionType.UPDATED; |
||||
|
case ALARM_ACK: |
||||
|
return EdgeEventActionType.ALARM_ACK; |
||||
|
case ALARM_CLEAR: |
||||
|
return EdgeEventActionType.ALARM_CLEAR; |
||||
|
case DELETED: |
||||
|
return EdgeEventActionType.DELETED; |
||||
|
default: |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.Device; |
||||
|
import org.thingsboard.server.common.data.HasName; |
||||
|
import org.thingsboard.server.common.data.Tenant; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.asset.Asset; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.id.AssetId; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.DeviceId; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
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.security.DeviceCredentials; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface TbNotificationEntityService { |
||||
|
|
||||
|
<E extends HasName, I extends EntityId> void notifyEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, |
||||
|
ActionType actionType, SecurityUser user, Exception e, |
||||
|
Object... additionalInfo); |
||||
|
|
||||
|
<E extends HasName, I extends EntityId> void notifyDeleteEntity(TenantId tenantId, I entityId, E entity, CustomerId customerId, |
||||
|
List<EdgeId> relatedEdgeIds, SecurityUser user, |
||||
|
Object... additionalInfo); |
||||
|
|
||||
|
<E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToCustomer(TenantId tenantId, I entityId, |
||||
|
CustomerId customerId, E entity, |
||||
|
ActionType actionType, |
||||
|
EdgeEventActionType edgeActionType, |
||||
|
SecurityUser user, boolean sendToEdge, |
||||
|
Object... additionalInfo); |
||||
|
|
||||
|
<E extends HasName, I extends EntityId> void notifyAssignOrUnassignEntityToEdge(TenantId tenantId, I entityId, |
||||
|
CustomerId customerId, EdgeId edgeId, |
||||
|
E entity, ActionType actionType, |
||||
|
EdgeEventActionType edgeActionType, |
||||
|
SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyCreateOruUpdateTenant(Tenant tenant, ComponentLifecycleEvent event); |
||||
|
|
||||
|
void notifyDeleteTenant(Tenant tenant); |
||||
|
|
||||
|
void notifyCreateOrUpdateDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, |
||||
|
Device oldDevice, ActionType actionType, SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyDeleteDevice(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, |
||||
|
List<EdgeId> relatedEdgeIds, SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyUpdateDeviceCredentials(TenantId tenantId, DeviceId deviceId, CustomerId customerId, Device device, |
||||
|
DeviceCredentials deviceCredentials, SecurityUser user); |
||||
|
|
||||
|
void notifyAssignDeviceToTenant(TenantId tenantId, TenantId newTenantId, DeviceId deviceId, CustomerId customerId, |
||||
|
Device device, Tenant tenant, SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyCreateOrUpdateAsset(TenantId tenantId, AssetId assetId, CustomerId customerId, Asset asset, |
||||
|
ActionType actionType, SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyEdge(TenantId tenantId, EdgeId edgeId, CustomerId customerId, Edge edge, ActionType actionType, SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyCreateOrUpdateAlarm(Alarm alarm, |
||||
|
ActionType actionType, SecurityUser user, Object... additionalInfo); |
||||
|
|
||||
|
void notifyDeleteAlarm(Alarm alarm, SecurityUser user, List<EdgeId> relatedEdgeIds); |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.alarm; |
||||
|
|
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Service |
||||
|
@TbCoreComponent |
||||
|
@AllArgsConstructor |
||||
|
public class DefaultTbAlarmService extends AbstractTbEntityService implements TbAlarmService { |
||||
|
|
||||
|
@Override |
||||
|
public Alarm save(Alarm alarm, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
||||
|
TenantId tenantId = alarm.getTenantId(); |
||||
|
try { |
||||
|
Alarm savedAlarm = checkNotNull(alarmService.createOrUpdateAlarm(alarm).getAlarm()); |
||||
|
notificationEntityService.notifyCreateOrUpdateAlarm(savedAlarm, actionType, user); |
||||
|
return savedAlarm; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ALARM), alarm, null, actionType, user, e); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void ack(Alarm alarm, SecurityUser user) throws ThingsboardException { |
||||
|
try { |
||||
|
long ackTs = System.currentTimeMillis(); |
||||
|
alarmService.ackAlarm(user.getTenantId(), alarm.getId(), ackTs).get(); |
||||
|
alarm.setAckTs(ackTs); |
||||
|
alarm.setStatus(alarm.getStatus().isCleared() ? AlarmStatus.CLEARED_ACK : AlarmStatus.ACTIVE_ACK); |
||||
|
notificationEntityService.notifyCreateOrUpdateAlarm(alarm, ActionType.ALARM_ACK, user); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void clear(Alarm alarm, SecurityUser user) throws ThingsboardException { |
||||
|
try { |
||||
|
long clearTs = System.currentTimeMillis(); |
||||
|
alarmService.clearAlarm(user.getTenantId(), alarm.getId(), null, clearTs).get(); |
||||
|
alarm.setClearTs(clearTs); |
||||
|
alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK); |
||||
|
notificationEntityService.notifyCreateOrUpdateAlarm(alarm, ActionType.ALARM_CLEAR, user); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { |
||||
|
List<EdgeId> relatedEdgeIds = findRelatedEdgeIds(alarm.getTenantId(), alarm.getOriginator()); |
||||
|
notificationEntityService.notifyDeleteAlarm(alarm, user, relatedEdgeIds); |
||||
|
return alarmService.deleteAlarm(alarm.getTenantId(), alarm.getId()).isSuccessful(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,163 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.asset; |
||||
|
|
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.asset.Asset; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.AssetId; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@Service |
||||
|
@TbCoreComponent |
||||
|
@AllArgsConstructor |
||||
|
public class DefaultTbAssetService extends AbstractTbEntityService implements TbAssetService { |
||||
|
@Override |
||||
|
public Asset save(Asset asset, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
||||
|
TenantId tenantId = asset.getTenantId(); |
||||
|
try { |
||||
|
Asset savedAsset = checkNotNull(assetService.saveAsset(asset)); |
||||
|
notificationEntityService.notifyCreateOrUpdateAsset(tenantId, savedAsset.getId(), savedAsset.getCustomerId(), asset, actionType, user); |
||||
|
return savedAsset; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), asset, null, actionType, user, e); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<Void> delete(Asset asset, SecurityUser user) throws ThingsboardException { |
||||
|
TenantId tenantId = asset.getTenantId(); |
||||
|
AssetId assetId = asset.getId(); |
||||
|
try { |
||||
|
List<EdgeId> relatedEdgeIds = findRelatedEdgeIds(tenantId, assetId); |
||||
|
assetService.deleteAsset(tenantId, assetId); |
||||
|
notificationEntityService.notifyDeleteEntity(tenantId, assetId, asset, asset.getCustomerId(), relatedEdgeIds, user, asset.toString()); |
||||
|
|
||||
|
return removeAlarmsByEntityId(tenantId, assetId); |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, |
||||
|
ActionType.DELETED, user, e, asset.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
CustomerId customerId = customer.getId(); |
||||
|
try { |
||||
|
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(tenantId, assetId, customerId)); |
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, assetId, customerId, savedAsset, |
||||
|
actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerId.toString(), customer.getName()); |
||||
|
|
||||
|
return savedAsset; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, |
||||
|
actionType, user, e, assetId.toString(), customerId.toString()); |
||||
|
|
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Asset unassignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; |
||||
|
try { |
||||
|
Asset savedAsset = checkNotNull(assetService.unassignAssetFromCustomer(tenantId, assetId)); |
||||
|
CustomerId customerId = customer.getId(); |
||||
|
|
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, assetId, customerId, savedAsset, |
||||
|
actionType, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER, user, |
||||
|
true, customerId.toString(), customer.getName()); |
||||
|
|
||||
|
return savedAsset; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, |
||||
|
actionType, user, e, assetId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Asset assignAssetToPublicCustomer(TenantId tenantId, AssetId assetId, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
try { |
||||
|
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); |
||||
|
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(tenantId, assetId, publicCustomer.getId())); |
||||
|
|
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, assetId, savedAsset.getCustomerId(), savedAsset, |
||||
|
actionType, null, user, false, actionType.toString(), |
||||
|
publicCustomer.getId().toString(), publicCustomer.getName()); |
||||
|
|
||||
|
return savedAsset; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, |
||||
|
actionType, user, e, assetId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, Edge edge, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_EDGE; |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
try { |
||||
|
Asset savedAsset = checkNotNull(assetService.assignAssetToEdge(tenantId, assetId, edgeId)); |
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, assetId, savedAsset.getCustomerId(), |
||||
|
edgeId, savedAsset, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, assetId.toString(), edgeId.toString(), edge.getName()); |
||||
|
|
||||
|
return savedAsset; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, |
||||
|
actionType, user, e, assetId.toString(), edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Asset unassignAssetFromEdge(TenantId tenantId, Asset asset, Edge edge, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE; |
||||
|
AssetId assetId = asset.getId(); |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
try { |
||||
|
Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(tenantId, assetId, edgeId)); |
||||
|
|
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, assetId, asset.getCustomerId(), |
||||
|
edgeId, asset, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, assetId.toString(), edgeId.toString(), edge.getName()); |
||||
|
return savedAsset; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.ASSET), null, null, |
||||
|
actionType, user, e, assetId.toString(), edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.asset; |
||||
|
|
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.asset.Asset; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.AssetId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
public interface TbAssetService { |
||||
|
Asset save(Asset asset, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
ListenableFuture<Void> delete(Asset asset, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Asset unassignAssetToCustomer(TenantId tenantId, AssetId assetId, Customer customer, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Asset assignAssetToPublicCustomer(TenantId tenantId, AssetId assetId, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, Edge edge, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Asset unassignAssetFromEdge(TenantId tenantId, Asset asset, Edge edge, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,279 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.device; |
||||
|
|
||||
|
import com.google.common.util.concurrent.Futures; |
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import com.google.common.util.concurrent.MoreExecutors; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.Device; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.Tenant; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.edge.EdgeEventActionType; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.DeviceId; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.security.DeviceCredentials; |
||||
|
import org.thingsboard.server.dao.device.claim.ClaimResponse; |
||||
|
import org.thingsboard.server.dao.device.claim.ClaimResult; |
||||
|
import org.thingsboard.server.dao.device.claim.ReclaimResult; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
@AllArgsConstructor |
||||
|
@TbCoreComponent |
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class DefaultTbDeviceService extends AbstractTbEntityService implements TbDeviceService { |
||||
|
|
||||
|
@Override |
||||
|
public Device save(TenantId tenantId, Device device, Device oldDevice, String accessToken, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
||||
|
try { |
||||
|
Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken)); |
||||
|
notificationEntityService.notifyCreateOrUpdateDevice(tenantId, savedDevice.getId(), savedDevice.getCustomerId(), |
||||
|
savedDevice, oldDevice, actionType, user); |
||||
|
|
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), device, null, actionType, user, e); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device saveDeviceWithCredentials(TenantId tenantId, Device device, DeviceCredentials credentials, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = device.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
||||
|
try { |
||||
|
Device savedDevice = checkNotNull(deviceService.saveDeviceWithCredentials(device, credentials)); |
||||
|
notificationEntityService.notifyCreateOrUpdateDevice(tenantId, savedDevice.getId(), savedDevice.getCustomerId(), |
||||
|
savedDevice, device, actionType, user); |
||||
|
|
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), device, null, actionType, user, e); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<Void> deleteDevice(Device device, SecurityUser user) throws ThingsboardException { |
||||
|
TenantId tenantId = device.getTenantId(); |
||||
|
DeviceId deviceId = device.getId(); |
||||
|
try { |
||||
|
List<EdgeId> relatedEdgeIds = findRelatedEdgeIds(tenantId, deviceId); |
||||
|
deviceService.deleteDevice(tenantId, deviceId); |
||||
|
notificationEntityService.notifyDeleteDevice(tenantId, deviceId, device.getCustomerId(), device, |
||||
|
relatedEdgeIds, user, deviceId.toString()); |
||||
|
|
||||
|
return removeAlarmsByEntityId(tenantId, deviceId); |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
ActionType.DELETED, user, e, deviceId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, Customer customer, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
CustomerId customerId = customer.getId(); |
||||
|
try { |
||||
|
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(user.getTenantId(), deviceId, customerId)); |
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, customerId, savedDevice, |
||||
|
actionType, EdgeEventActionType.ASSIGNED_TO_CUSTOMER, user, true, customerId.toString(), customer.getName()); |
||||
|
|
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
actionType, user, e, deviceId.toString(), customerId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device unassignDeviceFromCustomer(Device device, Customer customer, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; |
||||
|
TenantId tenantId = device.getTenantId(); |
||||
|
DeviceId deviceId = device.getId(); |
||||
|
try { |
||||
|
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(tenantId, deviceId)); |
||||
|
CustomerId customerId = customer.getId(); |
||||
|
|
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, customerId, savedDevice, |
||||
|
actionType, EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER, user, |
||||
|
true, customerId.toString(), customer.getName()); |
||||
|
|
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
actionType, user, e, deviceId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device assignDeviceToPublicCustomer(TenantId tenantId, DeviceId deviceId, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
try { |
||||
|
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); |
||||
|
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(tenantId, deviceId, publicCustomer.getId())); |
||||
|
|
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToCustomer(tenantId, deviceId, savedDevice.getCustomerId(), savedDevice, |
||||
|
actionType, null, user, false, deviceId.toString(), |
||||
|
publicCustomer.getId().toString(), publicCustomer.getName()); |
||||
|
|
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
actionType, user, e, deviceId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public DeviceCredentials getDeviceCredentialsByDeviceId(Device device, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.CREDENTIALS_READ; |
||||
|
TenantId tenantId = device.getTenantId(); |
||||
|
DeviceId deviceId = device.getId(); |
||||
|
try { |
||||
|
DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId)); |
||||
|
notificationEntityService.notifyEntity(tenantId, deviceId, device, device.getCustomerId(), |
||||
|
actionType, user, null, deviceId.toString()); |
||||
|
return deviceCredentials; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
actionType, user, e, deviceId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public DeviceCredentials updateDeviceCredentials(Device device, DeviceCredentials deviceCredentials, SecurityUser user) throws ThingsboardException { |
||||
|
TenantId tenantId = device.getTenantId(); |
||||
|
DeviceId deviceId = device.getId(); |
||||
|
try { |
||||
|
DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(tenantId, deviceCredentials)); |
||||
|
notificationEntityService.notifyUpdateDeviceCredentials(tenantId, deviceId, device.getCustomerId(), device, result, user); |
||||
|
return result; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
ActionType.CREDENTIALS_UPDATED, user, e, deviceCredentials); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<ClaimResult> claimDevice(TenantId tenantId, Device device, CustomerId customerId, String secretKey, SecurityUser user) throws ThingsboardException { |
||||
|
try { |
||||
|
ListenableFuture<ClaimResult> future = claimDevicesService.claimDevice(device, customerId, secretKey); |
||||
|
|
||||
|
return Futures.transform(future, result -> { |
||||
|
if (result != null && result.getResponse().equals(ClaimResponse.SUCCESS)) { |
||||
|
notificationEntityService.notifyEntity(tenantId, device.getId(), result.getDevice(), customerId, |
||||
|
ActionType.ASSIGNED_TO_CUSTOMER, user, null, device.getId().toString(), customerId.toString(), |
||||
|
customerService.findCustomerById(tenantId, customerId).getName()); |
||||
|
} |
||||
|
return result; |
||||
|
}, MoreExecutors.directExecutor()); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<ReclaimResult> reclaimDevice(TenantId tenantId, Device device, SecurityUser user) throws ThingsboardException { |
||||
|
try { |
||||
|
ListenableFuture<ReclaimResult> future = claimDevicesService.reClaimDevice(tenantId, device); |
||||
|
|
||||
|
return Futures.transform(future, result -> { |
||||
|
Customer unassignedCustomer = result.getUnassignedCustomer(); |
||||
|
if (unassignedCustomer != null) { |
||||
|
notificationEntityService.notifyEntity(tenantId, device.getId(), device, device.getCustomerId(), ActionType.UNASSIGNED_FROM_CUSTOMER, user, null, |
||||
|
device.getId().toString(), unassignedCustomer.getId().toString(), unassignedCustomer.getName()); |
||||
|
} |
||||
|
return result; |
||||
|
}, MoreExecutors.directExecutor()); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device assignDeviceToTenant(Device device, Tenant newTenant, SecurityUser user) throws ThingsboardException { |
||||
|
TenantId tenantId = device.getTenantId(); |
||||
|
TenantId newTenantId = newTenant.getId(); |
||||
|
try { |
||||
|
Tenant tenant = tenantService.findTenantById(tenantId); |
||||
|
Device assignedDevice = deviceService.assignDeviceToTenant(newTenantId, device); |
||||
|
|
||||
|
notificationEntityService.notifyAssignDeviceToTenant(tenantId, newTenantId, device.getId(), |
||||
|
assignedDevice.getCustomerId(), assignedDevice, tenant, user, newTenantId.toString(), newTenant.getName()); |
||||
|
|
||||
|
return assignedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
ActionType.ASSIGNED_TO_TENANT, user, e, newTenantId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, Edge edge, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_EDGE; |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
try { |
||||
|
Device savedDevice = checkNotNull(deviceService.assignDeviceToEdge(tenantId, deviceId, edgeId)); |
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, deviceId, savedDevice.getCustomerId(), |
||||
|
edgeId, savedDevice, actionType, EdgeEventActionType.ASSIGNED_TO_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName()); |
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
actionType, user, e, deviceId.toString(), edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Device unassignDeviceFromEdge(Device device, Edge edge, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.UNASSIGNED_FROM_EDGE; |
||||
|
TenantId tenantId = device.getTenantId(); |
||||
|
DeviceId deviceId = device.getId(); |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
try { |
||||
|
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(tenantId, deviceId, edgeId)); |
||||
|
|
||||
|
notificationEntityService.notifyAssignOrUnassignEntityToEdge(tenantId, deviceId, device.getCustomerId(), |
||||
|
edgeId, device, actionType, EdgeEventActionType.UNASSIGNED_FROM_EDGE, user, deviceId.toString(), edgeId.toString(), edge.getName()); |
||||
|
return savedDevice; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.DEVICE), null, null, |
||||
|
actionType, user, e, deviceId.toString(), edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.device; |
||||
|
|
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.Device; |
||||
|
import org.thingsboard.server.common.data.Tenant; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.DeviceId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.security.DeviceCredentials; |
||||
|
import org.thingsboard.server.dao.device.claim.ClaimResult; |
||||
|
import org.thingsboard.server.dao.device.claim.ReclaimResult; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
public interface TbDeviceService { |
||||
|
|
||||
|
Device save(TenantId tenantId, Device device, Device oldDevice, String accessToken, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device saveDeviceWithCredentials(TenantId tenantId, Device device, DeviceCredentials deviceCredentials, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
ListenableFuture<Void> deleteDevice(Device device, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, Customer customer, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device unassignDeviceFromCustomer(Device device, Customer customer, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device assignDeviceToPublicCustomer(TenantId tenantId, DeviceId deviceId, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
DeviceCredentials getDeviceCredentialsByDeviceId(Device device, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
DeviceCredentials updateDeviceCredentials(Device device, DeviceCredentials deviceCredentials, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
ListenableFuture<ClaimResult> claimDevice(TenantId tenantId, Device device, CustomerId customerId, String secretKey, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
ListenableFuture<ReclaimResult> reclaimDevice(TenantId tenantId, Device device, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device assignDeviceToTenant(Device device, Tenant newTenant, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, Edge edge, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Device unassignDeviceFromEdge(Device device, Edge edge, SecurityUser user) throws ThingsboardException; |
||||
|
} |
||||
@ -0,0 +1,150 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.edge; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.audit.ActionType; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
import org.thingsboard.server.common.data.id.RuleChainId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.rule.RuleChain; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
@AllArgsConstructor |
||||
|
@TbCoreComponent |
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class DefaultTbEdgeService extends AbstractTbEntityService implements TbEdgeService { |
||||
|
|
||||
|
@Override |
||||
|
public Edge saveEdge(Edge edge, RuleChain edgeTemplateRootRuleChain, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = edge.getId() == null ? ActionType.ADDED : ActionType.UPDATED; |
||||
|
TenantId tenantId = edge.getTenantId(); |
||||
|
try { |
||||
|
Edge savedEdge = checkNotNull(edgeService.saveEdge(edge)); |
||||
|
EdgeId edgeId = savedEdge.getId(); |
||||
|
|
||||
|
if (actionType == ActionType.ADDED) { |
||||
|
ruleChainService.assignRuleChainToEdge(tenantId, edgeTemplateRootRuleChain.getId(), edgeId); |
||||
|
edgeNotificationService.setEdgeRootRuleChain(tenantId, savedEdge, edgeTemplateRootRuleChain.getId()); |
||||
|
edgeService.assignDefaultRuleChainsToEdge(tenantId, edgeId); |
||||
|
} |
||||
|
|
||||
|
notificationEntityService.notifyEdge(tenantId, edgeId, savedEdge.getCustomerId(), savedEdge, actionType, user); |
||||
|
|
||||
|
return savedEdge; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), edge, null, actionType, user, e); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteEdge(Edge edge, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.DELETED; |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
TenantId tenantId = edge.getTenantId(); |
||||
|
try { |
||||
|
edgeService.deleteEdge(tenantId, edgeId); |
||||
|
notificationEntityService.notifyEdge(tenantId, edgeId, edge.getCustomerId(), edge, actionType, user, edgeId.toString()); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), edge, null, actionType, user, e); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, Customer customer, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
CustomerId customerId = customer.getId(); |
||||
|
try { |
||||
|
Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(tenantId, edgeId, customerId)); |
||||
|
|
||||
|
notificationEntityService.notifyEdge(tenantId, edgeId, customerId, savedEdge, actionType, user, |
||||
|
edgeId.toString(), customerId.toString(), customer.getName()); |
||||
|
|
||||
|
return savedEdge; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), null, null, |
||||
|
actionType, user, e, edgeId.toString(), customerId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Edge unassignEdgeFromCustomer(Edge edge, Customer customer, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.UNASSIGNED_FROM_CUSTOMER; |
||||
|
TenantId tenantId = edge.getTenantId(); |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
CustomerId customerId = customer.getId(); |
||||
|
try { |
||||
|
Edge savedEdge = checkNotNull(edgeService.unassignEdgeFromCustomer(tenantId, edgeId)); |
||||
|
|
||||
|
notificationEntityService.notifyEdge(tenantId, edgeId, customerId, savedEdge, actionType, user, |
||||
|
edgeId.toString(), customerId.toString(), customer.getName()); |
||||
|
return savedEdge; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), null, null, |
||||
|
actionType, user, e, edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Edge assignEdgeToPublicCustomer(TenantId tenantId, EdgeId edgeId, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.ASSIGNED_TO_CUSTOMER; |
||||
|
try { |
||||
|
Customer publicCustomer = customerService.findOrCreatePublicCustomer(tenantId); |
||||
|
CustomerId customerId = publicCustomer.getId(); |
||||
|
Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(tenantId, edgeId, customerId)); |
||||
|
|
||||
|
notificationEntityService.notifyEdge(tenantId, edgeId, customerId, savedEdge, actionType, user, |
||||
|
edgeId.toString(), customerId.toString(), publicCustomer.getName()); |
||||
|
|
||||
|
return savedEdge; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), null, null, |
||||
|
actionType, user, e, edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Edge setEdgeRootRuleChain(Edge edge, RuleChainId ruleChainId, SecurityUser user) throws ThingsboardException { |
||||
|
ActionType actionType = ActionType.UPDATED; |
||||
|
TenantId tenantId = edge.getTenantId(); |
||||
|
EdgeId edgeId = edge.getId(); |
||||
|
try { |
||||
|
Edge updatedEdge = edgeNotificationService.setEdgeRootRuleChain(tenantId, edge, ruleChainId); |
||||
|
notificationEntityService.notifyEdge(tenantId, edgeId, null, updatedEdge, actionType, user); |
||||
|
return updatedEdge; |
||||
|
} catch (Exception e) { |
||||
|
notificationEntityService.notifyEntity(tenantId, emptyId(EntityType.EDGE), null, null, |
||||
|
actionType, user, e, edgeId.toString()); |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.edge; |
||||
|
|
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.edge.Edge; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.EdgeId; |
||||
|
import org.thingsboard.server.common.data.id.RuleChainId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.rule.RuleChain; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
public interface TbEdgeService { |
||||
|
Edge saveEdge(Edge edge, RuleChain edgeTemplateRootRuleChain, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
void deleteEdge(Edge edge, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Edge assignEdgeToCustomer(TenantId tenantId, EdgeId edgeId, Customer customer, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Edge unassignEdgeFromCustomer(Edge edge, Customer customer, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Edge assignEdgeToPublicCustomer(TenantId tenantId, EdgeId edgeId, SecurityUser user) throws ThingsboardException; |
||||
|
|
||||
|
Edge setEdgeRootRuleChain(Edge edge, RuleChainId ruleChainId, SecurityUser user) throws ThingsboardException; |
||||
|
} |
||||
@ -0,0 +1,66 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.entitiy.tenant; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.Tenant; |
||||
|
import org.thingsboard.server.common.data.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
||||
|
import org.thingsboard.server.queue.util.TbCoreComponent; |
||||
|
import org.thingsboard.server.service.entitiy.AbstractTbEntityService; |
||||
|
import org.thingsboard.server.service.install.InstallScripts; |
||||
|
|
||||
|
@Service |
||||
|
@TbCoreComponent |
||||
|
@AllArgsConstructor |
||||
|
public class DefaultTbTenantService extends AbstractTbEntityService implements TbTenantService { |
||||
|
|
||||
|
@Autowired |
||||
|
private InstallScripts installScripts; |
||||
|
|
||||
|
@Override |
||||
|
public Tenant save(Tenant tenant) throws ThingsboardException { |
||||
|
try { |
||||
|
boolean newTenant = tenant.getId() == null; |
||||
|
Tenant savedTenant = checkNotNull(tenantService.saveTenant(tenant)); |
||||
|
if (newTenant) { |
||||
|
installScripts.createDefaultRuleChains(savedTenant.getId()); |
||||
|
installScripts.createDefaultEdgeRuleChains(savedTenant.getId()); |
||||
|
} |
||||
|
tenantProfileCache.evict(savedTenant.getId()); |
||||
|
notificationEntityService.notifyCreateOruUpdateTenant(savedTenant, newTenant ? |
||||
|
ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED); |
||||
|
return savedTenant; |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void delete(Tenant tenant) throws ThingsboardException { |
||||
|
try { |
||||
|
TenantId tenantId = tenant.getId(); |
||||
|
tenantService.deleteTenant(tenantId); |
||||
|
tenantProfileCache.evict(tenantId); |
||||
|
notificationEntityService.notifyDeleteTenant(tenant); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,186 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.sms.smpp; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.apache.commons.lang3.exception.ExceptionUtils; |
||||
|
import org.smpp.Connection; |
||||
|
import org.smpp.Data; |
||||
|
import org.smpp.Session; |
||||
|
import org.smpp.TCPIPConnection; |
||||
|
import org.smpp.TimeoutException; |
||||
|
import org.smpp.WrongSessionStateException; |
||||
|
import org.smpp.pdu.Address; |
||||
|
import org.smpp.pdu.BindReceiver; |
||||
|
import org.smpp.pdu.BindRequest; |
||||
|
import org.smpp.pdu.BindResponse; |
||||
|
import org.smpp.pdu.BindTransciever; |
||||
|
import org.smpp.pdu.BindTransmitter; |
||||
|
import org.smpp.pdu.PDUException; |
||||
|
import org.smpp.pdu.SubmitSM; |
||||
|
import org.smpp.pdu.SubmitSMResp; |
||||
|
import org.thingsboard.rule.engine.api.sms.exception.SmsException; |
||||
|
import org.thingsboard.server.common.data.sms.config.SmppSmsProviderConfiguration; |
||||
|
import org.thingsboard.server.service.sms.AbstractSmsSender; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.util.Optional; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class SmppSmsSender extends AbstractSmsSender { |
||||
|
protected SmppSmsProviderConfiguration config; |
||||
|
|
||||
|
protected Session smppSession; |
||||
|
|
||||
|
public SmppSmsSender(SmppSmsProviderConfiguration config) { |
||||
|
if (config.getBindType() == null) { |
||||
|
config.setBindType(SmppSmsProviderConfiguration.SmppBindType.TX); |
||||
|
} |
||||
|
if (StringUtils.isNotEmpty(config.getSourceAddress())) { |
||||
|
if (config.getSourceTon() == null) { |
||||
|
config.setSourceTon((byte) 5); |
||||
|
} |
||||
|
if (config.getSourceNpi() == null) { |
||||
|
config.setSourceNpi((byte) 0); |
||||
|
} |
||||
|
} |
||||
|
if (config.getDestinationTon() == null) { |
||||
|
config.setDestinationTon((byte) 5); |
||||
|
} |
||||
|
if (config.getDestinationNpi() == null) { |
||||
|
config.setDestinationNpi((byte) 0); |
||||
|
} |
||||
|
|
||||
|
this.config = config; |
||||
|
this.smppSession = initSmppSession(); |
||||
|
} |
||||
|
|
||||
|
private SmppSmsSender() {} // for testing purposes
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public int sendSms(String numberTo, String message) throws SmsException { |
||||
|
try { |
||||
|
checkSmppSession(); |
||||
|
|
||||
|
SubmitSM request = new SubmitSM(); |
||||
|
if (StringUtils.isNotEmpty(config.getServiceType())) { |
||||
|
request.setServiceType(config.getServiceType()); |
||||
|
} |
||||
|
if (StringUtils.isNotEmpty(config.getSourceAddress())) { |
||||
|
request.setSourceAddr(new Address(config.getSourceTon(), config.getSourceNpi(), config.getSourceAddress())); |
||||
|
} |
||||
|
request.setDestAddr(new Address(config.getDestinationTon(), config.getDestinationNpi(), prepareNumber(numberTo))); |
||||
|
request.setShortMessage(message); |
||||
|
request.setDataCoding(Optional.ofNullable(config.getCodingScheme()).orElse((byte) 0)); |
||||
|
request.setReplaceIfPresentFlag((byte) 0); |
||||
|
request.setEsmClass((byte) 0); |
||||
|
request.setProtocolId((byte) 0); |
||||
|
request.setPriorityFlag((byte) 0); |
||||
|
request.setRegisteredDelivery((byte) 0); |
||||
|
request.setSmDefaultMsgId((byte) 0); |
||||
|
|
||||
|
SubmitSMResp response = smppSession.submit(request); |
||||
|
|
||||
|
log.debug("SMPP submit command status: {}", response.getCommandStatus()); |
||||
|
} catch (Exception e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
|
||||
|
return countMessageSegments(message); |
||||
|
} |
||||
|
|
||||
|
private synchronized void checkSmppSession() { |
||||
|
if (smppSession == null || !smppSession.isOpened()) { |
||||
|
smppSession = initSmppSession(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected Session initSmppSession() { |
||||
|
try { |
||||
|
Connection connection = new TCPIPConnection(config.getHost(), config.getPort()); |
||||
|
Session session = new Session(connection); |
||||
|
|
||||
|
BindRequest bindRequest; |
||||
|
switch (config.getBindType()) { |
||||
|
case TX: |
||||
|
bindRequest = new BindTransmitter(); |
||||
|
break; |
||||
|
case RX: |
||||
|
bindRequest = new BindReceiver(); |
||||
|
break; |
||||
|
case TRX: |
||||
|
bindRequest = new BindTransciever(); |
||||
|
break; |
||||
|
default: |
||||
|
throw new UnsupportedOperationException("Unsupported bind type " + config.getBindType()); |
||||
|
} |
||||
|
|
||||
|
bindRequest.setSystemId(config.getSystemId()); |
||||
|
bindRequest.setPassword(config.getPassword()); |
||||
|
|
||||
|
byte interfaceVersion; |
||||
|
switch (config.getProtocolVersion()) { |
||||
|
case "3.3": |
||||
|
interfaceVersion = Data.SMPP_V33; |
||||
|
break; |
||||
|
case "3.4": |
||||
|
interfaceVersion = Data.SMPP_V34; |
||||
|
break; |
||||
|
default: |
||||
|
throw new UnsupportedOperationException("Unsupported SMPP version: " + config.getProtocolVersion()); |
||||
|
} |
||||
|
bindRequest.setInterfaceVersion(interfaceVersion); |
||||
|
|
||||
|
if (StringUtils.isNotEmpty(config.getSystemType())) { |
||||
|
bindRequest.setSystemType(config.getSystemType()); |
||||
|
} |
||||
|
if (StringUtils.isNotEmpty(config.getAddressRange())) { |
||||
|
bindRequest.setAddressRange(config.getDestinationTon(), config.getDestinationNpi(), config.getAddressRange()); |
||||
|
} |
||||
|
|
||||
|
BindResponse bindResponse = session.bind(bindRequest); |
||||
|
log.debug("SMPP bind response: {}", bindResponse.debugString()); |
||||
|
|
||||
|
if (bindResponse.getCommandStatus() != 0) { |
||||
|
throw new IllegalStateException("Error status when binding: " + bindResponse.getCommandStatus()); |
||||
|
} |
||||
|
|
||||
|
return session; |
||||
|
} catch (Exception e) { |
||||
|
throw new IllegalArgumentException("Failed to establish SMPP session: " + ExceptionUtils.getRootCauseMessage(e), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private String prepareNumber(String number) { |
||||
|
if (config.getDestinationTon() == Data.GSM_TON_INTERNATIONAL) { |
||||
|
return StringUtils.removeStart(number, "+"); |
||||
|
} |
||||
|
return number; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void destroy() { |
||||
|
try { |
||||
|
smppSession.unbind(); |
||||
|
smppSession.close(); |
||||
|
} catch (TimeoutException | PDUException | IOException | WrongSessionStateException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -1,54 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.controller; |
|
||||
|
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.junit.Assert; |
|
||||
import org.junit.runner.RunWith; |
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader; |
|
||||
import org.springframework.boot.test.context.SpringBootTest; |
|
||||
import org.springframework.boot.web.server.LocalServerPort; |
|
||||
import org.springframework.context.annotation.ComponentScan; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
import org.springframework.test.annotation.DirtiesContext; |
|
||||
import org.springframework.test.context.ActiveProfiles; |
|
||||
import org.springframework.test.context.ContextConfiguration; |
|
||||
import org.springframework.test.context.junit4.SpringRunner; |
|
||||
import java.net.URI; |
|
||||
import java.net.URISyntaxException; |
|
||||
|
|
||||
@ActiveProfiles("test") |
|
||||
@RunWith(SpringRunner.class) |
|
||||
@ContextConfiguration(classes = AbstractControllerTest.class, loader = SpringBootContextLoader.class) |
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) |
|
||||
@Configuration |
|
||||
@ComponentScan({"org.thingsboard.server"}) |
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) |
|
||||
@Slf4j |
|
||||
public abstract class AbstractWebsocketTest extends AbstractWebTest { |
|
||||
|
|
||||
protected static final String WS_URL = "ws://localhost:"; |
|
||||
|
|
||||
@LocalServerPort |
|
||||
protected int wsPort; |
|
||||
|
|
||||
protected TbTestWebSocketClient buildAndConnectWebSocketClient() throws URISyntaxException, InterruptedException { |
|
||||
TbTestWebSocketClient wsClient = new TbTestWebSocketClient(new URI(WS_URL + wsPort + "/api/ws/plugins/telemetry?token=" + token)); |
|
||||
Assert.assertTrue(wsClient.connectBlocking()); |
|
||||
return wsClient; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -0,0 +1,50 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.script; |
||||
|
|
||||
|
import com.google.common.util.concurrent.Futures; |
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.thingsboard.server.common.data.id.CustomerId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Service |
||||
|
@ConditionalOnProperty(prefix = "js", value = "evaluator", havingValue = "mock") |
||||
|
public class MockJsInvokeService implements JsInvokeService { |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<UUID> eval(TenantId tenantId, JsScriptType scriptType, String scriptBody, String... argNames) { |
||||
|
log.warn("eval {} {} {} {}", tenantId, scriptType, scriptBody, argNames); |
||||
|
return Futures.immediateFuture(UUID.randomUUID()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<Object> invokeFunction(TenantId tenantId, CustomerId customerId, UUID scriptId, Object... args) { |
||||
|
log.warn("invokeFunction {} {} {} {}", tenantId, customerId, scriptId, args); |
||||
|
return Futures.immediateFuture("{}"); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<Void> release(UUID scriptId) { |
||||
|
log.warn("release {}", scriptId); |
||||
|
return Futures.immediateFuture(null); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,121 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.sms.smpp; |
||||
|
|
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.assertj.core.api.Assertions; |
||||
|
import org.junit.Before; |
||||
|
import org.junit.Ignore; |
||||
|
import org.junit.Test; |
||||
|
import org.junit.runner.RunWith; |
||||
|
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
import org.smpp.Session; |
||||
|
import org.smpp.pdu.SubmitSMResp; |
||||
|
import org.thingsboard.server.common.data.sms.config.SmppSmsProviderConfiguration; |
||||
|
|
||||
|
import java.lang.reflect.Constructor; |
||||
|
import java.net.UnknownHostException; |
||||
|
|
||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
import static org.junit.Assert.fail; |
||||
|
import static org.mockito.ArgumentMatchers.any; |
||||
|
import static org.mockito.ArgumentMatchers.argThat; |
||||
|
import static org.mockito.Mockito.mock; |
||||
|
import static org.mockito.Mockito.never; |
||||
|
import static org.mockito.Mockito.spy; |
||||
|
import static org.mockito.Mockito.times; |
||||
|
import static org.mockito.Mockito.verify; |
||||
|
import static org.mockito.Mockito.when; |
||||
|
|
||||
|
@RunWith(MockitoJUnitRunner.class) |
||||
|
public class SmppSmsSenderTest { |
||||
|
|
||||
|
SmppSmsSender smppSmsSender; |
||||
|
SmppSmsProviderConfiguration smppConfig; |
||||
|
Session smppSession; |
||||
|
|
||||
|
@Before |
||||
|
public void beforeEach() throws Exception { |
||||
|
Constructor<SmppSmsSender> constructor = SmppSmsSender.class.getDeclaredConstructor(); |
||||
|
constructor.setAccessible(true); |
||||
|
smppSmsSender = spy(constructor.newInstance()); |
||||
|
|
||||
|
smppSession = mock(Session.class); |
||||
|
smppSmsSender.smppSession = smppSession; |
||||
|
|
||||
|
smppConfig = new SmppSmsProviderConfiguration(); |
||||
|
smppSmsSender.config = smppConfig; |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSendSms() throws Exception { |
||||
|
when(smppSession.isOpened()).thenReturn(true); |
||||
|
when(smppSession.submit(any())).thenReturn(new SubmitSMResp()); |
||||
|
setDefaultSmppConfig(); |
||||
|
|
||||
|
String number = "123545"; |
||||
|
String message = "message"; |
||||
|
smppSmsSender.sendSms(number, message); |
||||
|
|
||||
|
verify(smppSmsSender, never()).initSmppSession(); |
||||
|
verify(smppSession).submit(argThat(submitRequest -> { |
||||
|
try { |
||||
|
return submitRequest.getShortMessage().equals(message) && |
||||
|
submitRequest.getDestAddr().getAddress().equals(number) && |
||||
|
submitRequest.getServiceType().equals(smppConfig.getServiceType()) && |
||||
|
(StringUtils.isEmpty(smppConfig.getSourceAddress()) ? submitRequest.getSourceAddr().getAddress().equals("") |
||||
|
: submitRequest.getSourceAddr().getAddress().equals(smppConfig.getSourceAddress()) && |
||||
|
submitRequest.getSourceAddr().getTon() == smppConfig.getSourceTon() && |
||||
|
submitRequest.getSourceAddr().getNpi() == smppConfig.getSourceNpi()) && |
||||
|
submitRequest.getDestAddr().getTon() == smppConfig.getDestinationTon() && |
||||
|
submitRequest.getDestAddr().getNpi() == smppConfig.getDestinationNpi() && |
||||
|
submitRequest.getDataCoding() == smppConfig.getCodingScheme() && |
||||
|
submitRequest.getReplaceIfPresentFlag() == 0 && |
||||
|
submitRequest.getEsmClass() == 0 && |
||||
|
submitRequest.getProtocolId() == 0 && |
||||
|
submitRequest.getPriorityFlag() == 0 && |
||||
|
submitRequest.getRegisteredDelivery() == 0 && |
||||
|
submitRequest.getSmDefaultMsgId() == 0; |
||||
|
} catch (Exception e) { |
||||
|
fail(e.getMessage()); |
||||
|
return false; |
||||
|
} |
||||
|
})); |
||||
|
} |
||||
|
|
||||
|
private void setDefaultSmppConfig() { |
||||
|
smppConfig.setProtocolVersion("3.3"); |
||||
|
smppConfig.setHost("smpphost"); |
||||
|
smppConfig.setPort(5687); |
||||
|
smppConfig.setSystemId("213131"); |
||||
|
smppConfig.setPassword("35125q"); |
||||
|
|
||||
|
smppConfig.setSystemType(""); |
||||
|
smppConfig.setBindType(SmppSmsProviderConfiguration.SmppBindType.TX); |
||||
|
smppConfig.setServiceType(""); |
||||
|
|
||||
|
smppConfig.setSourceAddress(""); |
||||
|
smppConfig.setSourceTon((byte) 5); |
||||
|
smppConfig.setSourceNpi((byte) 0); |
||||
|
|
||||
|
smppConfig.setDestinationTon((byte) 5); |
||||
|
smppConfig.setDestinationNpi((byte) 0); |
||||
|
|
||||
|
smppConfig.setAddressRange(""); |
||||
|
smppConfig.setCodingScheme((byte) 0); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2022 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.coap; |
||||
|
|
||||
|
import lombok.Builder; |
||||
|
import lombok.Data; |
||||
|
import org.thingsboard.server.common.data.CoapDeviceType; |
||||
|
import org.thingsboard.server.common.data.DeviceProfileProvisionType; |
||||
|
import org.thingsboard.server.common.data.TransportPayloadType; |
||||
|
|
||||
|
@Data |
||||
|
@Builder |
||||
|
public class CoapTestConfigProperties { |
||||
|
|
||||
|
String deviceName; |
||||
|
|
||||
|
CoapDeviceType coapDeviceType; |
||||
|
|
||||
|
TransportPayloadType transportPayloadType; |
||||
|
|
||||
|
String telemetryTopicFilter; |
||||
|
String attributesTopicFilter; |
||||
|
|
||||
|
String telemetryProtoSchema; |
||||
|
String attributesProtoSchema; |
||||
|
String rpcResponseProtoSchema; |
||||
|
String rpcRequestProtoSchema; |
||||
|
|
||||
|
DeviceProfileProvisionType provisionType; |
||||
|
String provisionKey; |
||||
|
String provisionSecret; |
||||
|
|
||||
|
} |
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.coap.attributes.request.sql; |
|
||||
|
|
||||
import org.thingsboard.server.transport.coap.attributes.request.AbstractCoapAttributesRequestJsonIntegrationTest; |
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class CoapAttributesRequestJsonSqlIntegrationTest extends AbstractCoapAttributesRequestJsonIntegrationTest { |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.coap.attributes.request.sql; |
|
||||
|
|
||||
import org.thingsboard.server.transport.coap.attributes.request.AbstractCoapAttributesRequestProtoIntegrationTest; |
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class CoapAttributesRequestProtoSqlIntegrationTest extends AbstractCoapAttributesRequestProtoIntegrationTest { |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.coap.attributes.request.sql; |
|
||||
|
|
||||
import org.thingsboard.server.transport.coap.attributes.request.AbstractCoapAttributesRequestIntegrationTest; |
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class CoapAttributesRequestSqlIntegrationTest extends AbstractCoapAttributesRequestIntegrationTest { |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.coap.attributes.updates.sql; |
|
||||
|
|
||||
import org.thingsboard.server.transport.coap.attributes.updates.AbstractCoapAttributesUpdatesIntegrationTest; |
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class CoapAttributesUpdatesSqlIntegrationTest extends AbstractCoapAttributesUpdatesIntegrationTest { |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.coap.attributes.updates.sql; |
|
||||
|
|
||||
import org.thingsboard.server.transport.coap.attributes.updates.AbstractCoapAttributesUpdatesJsonIntegrationTest; |
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class CoapAttributesUpdatesSqlJsonIntegrationTest extends AbstractCoapAttributesUpdatesJsonIntegrationTest { |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
/** |
|
||||
* Copyright © 2016-2022 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.coap.attributes.updates.sql; |
|
||||
|
|
||||
import org.thingsboard.server.transport.coap.attributes.updates.AbstractCoapAttributesUpdatesProtoIntegrationTest; |
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|
||||
|
|
||||
@DaoSqlTest |
|
||||
public class CoapAttributesUpdatesSqlProtoIntegrationTest extends AbstractCoapAttributesUpdatesProtoIntegrationTest { |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue