24 changed files with 1470 additions and 71 deletions
@ -0,0 +1,129 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 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 com.google.common.util.concurrent.ListenableFuture; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.security.access.prepost.PreAuthorize; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
import org.thingsboard.server.common.data.Customer; |
||||
|
import org.thingsboard.server.common.data.Event; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmId; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmQuery; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
||||
|
import org.thingsboard.server.common.data.asset.Asset; |
||||
|
import org.thingsboard.server.common.data.id.*; |
||||
|
import org.thingsboard.server.common.data.page.TextPageData; |
||||
|
import org.thingsboard.server.common.data.page.TextPageLink; |
||||
|
import org.thingsboard.server.common.data.page.TimePageData; |
||||
|
import org.thingsboard.server.common.data.page.TimePageLink; |
||||
|
import org.thingsboard.server.dao.asset.AssetSearchQuery; |
||||
|
import org.thingsboard.server.dao.exception.IncorrectParameterException; |
||||
|
import org.thingsboard.server.dao.model.ModelConstants; |
||||
|
import org.thingsboard.server.exception.ThingsboardErrorCode; |
||||
|
import org.thingsboard.server.exception.ThingsboardException; |
||||
|
import org.thingsboard.server.service.security.model.SecurityUser; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@RestController |
||||
|
@RequestMapping("/api") |
||||
|
public class AlarmController extends BaseController { |
||||
|
|
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
||||
|
@RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public Alarm getAlarmById(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { |
||||
|
checkParameter("alarmId", strAlarmId); |
||||
|
try { |
||||
|
AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
||||
|
return checkAlarmId(alarmId); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
||||
|
@RequestMapping(value = "/alarm", method = RequestMethod.POST) |
||||
|
@ResponseBody |
||||
|
public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException { |
||||
|
try { |
||||
|
alarm.setTenantId(getCurrentUser().getTenantId()); |
||||
|
return checkNotNull(alarmService.createOrUpdateAlarm(alarm)); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) |
||||
|
@ResponseStatus(value = HttpStatus.OK) |
||||
|
public void ackAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { |
||||
|
checkParameter("alarmId", strAlarmId); |
||||
|
try { |
||||
|
AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
||||
|
checkAlarmId(alarmId); |
||||
|
alarmService.ackAlarm(alarmId, System.currentTimeMillis()).get(); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@PreAuthorize("hasAuthority('TENANT_ADMIN')") |
||||
|
@RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) |
||||
|
@ResponseStatus(value = HttpStatus.OK) |
||||
|
public void clearAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { |
||||
|
checkParameter("alarmId", strAlarmId); |
||||
|
try { |
||||
|
AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
||||
|
checkAlarmId(alarmId); |
||||
|
alarmService.clearAlarm(alarmId, System.currentTimeMillis()).get(); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
||||
|
@RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET) |
||||
|
@ResponseBody |
||||
|
public TimePageData<Alarm> getAlarms( |
||||
|
@PathVariable("entityType") String strEntityType, |
||||
|
@PathVariable("entityId") String strEntityId, |
||||
|
@RequestParam(required = false) String status, |
||||
|
@RequestParam int limit, |
||||
|
@RequestParam(required = false) Long startTime, |
||||
|
@RequestParam(required = false) Long endTime, |
||||
|
@RequestParam(required = false, defaultValue = "false") boolean ascOrder, |
||||
|
@RequestParam(required = false) String offset |
||||
|
) throws ThingsboardException { |
||||
|
checkParameter("EntityId", strEntityId); |
||||
|
checkParameter("EntityType", strEntityType); |
||||
|
EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); |
||||
|
AlarmStatus alarmStatus = StringUtils.isEmpty(status) ? null : AlarmStatus.valueOf(status); |
||||
|
checkEntityId(entityId); |
||||
|
try { |
||||
|
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); |
||||
|
return checkNotNull(alarmService.findAlarms(new AlarmQuery(entityId, pageLink, alarmStatus)).get()); |
||||
|
} catch (Exception e) { |
||||
|
throw handleException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,109 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.alarm; |
||||
|
|
||||
|
import com.datastax.driver.core.querybuilder.QueryBuilder; |
||||
|
import com.datastax.driver.core.querybuilder.Select; |
||||
|
import com.google.common.util.concurrent.AsyncFunction; |
||||
|
import com.google.common.util.concurrent.Futures; |
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmQuery; |
||||
|
import org.thingsboard.server.common.data.id.EntityId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
||||
|
import org.thingsboard.server.dao.AbstractModelDao; |
||||
|
import org.thingsboard.server.dao.AbstractSearchTimeDao; |
||||
|
import org.thingsboard.server.dao.model.AlarmEntity; |
||||
|
import org.thingsboard.server.dao.model.ModelConstants; |
||||
|
import org.thingsboard.server.dao.relation.RelationDao; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; |
||||
|
import static com.datastax.driver.core.querybuilder.QueryBuilder.select; |
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.*; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class AlarmDaoImpl extends AbstractModelDao<AlarmEntity> implements AlarmDao { |
||||
|
|
||||
|
@Autowired |
||||
|
private RelationDao relationDao; |
||||
|
|
||||
|
@Override |
||||
|
protected Class<AlarmEntity> getColumnFamilyClass() { |
||||
|
return AlarmEntity.class; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected String getColumnFamilyName() { |
||||
|
return ALARM_COLUMN_FAMILY_NAME; |
||||
|
} |
||||
|
|
||||
|
protected boolean isDeleteOnSave() { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public AlarmEntity save(Alarm alarm) { |
||||
|
log.debug("Save asset [{}] ", alarm); |
||||
|
return save(new AlarmEntity(alarm)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) { |
||||
|
Select select = select().from(ALARM_COLUMN_FAMILY_NAME); |
||||
|
Select.Where query = select.where(); |
||||
|
query.and(eq(ALARM_TENANT_ID_PROPERTY, tenantId.getId())); |
||||
|
query.and(eq(ALARM_ORIGINATOR_ID_PROPERTY, originator.getId())); |
||||
|
query.and(eq(ALARM_ORIGINATOR_TYPE_PROPERTY, originator.getEntityType())); |
||||
|
query.and(eq(ALARM_TYPE_PROPERTY, type)); |
||||
|
query.limit(1); |
||||
|
query.orderBy(QueryBuilder.asc(ModelConstants.ALARM_TYPE_PROPERTY), QueryBuilder.desc(ModelConstants.ID_PROPERTY)); |
||||
|
return Futures.transform(findOneByStatementAsync(query), toDataFunction()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<Alarm> findAlarmByIdAsync(UUID key) { |
||||
|
log.debug("Get alarm by id {}", key); |
||||
|
Select.Where query = select().from(ALARM_BY_ID_VIEW_NAME).where(eq(ModelConstants.ID_PROPERTY, key)); |
||||
|
query.limit(1); |
||||
|
log.trace("Execute query {}", query); |
||||
|
return Futures.transform(findOneByStatementAsync(query), toDataFunction()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ListenableFuture<List<Alarm>> findAlarms(AlarmQuery query) { |
||||
|
log.trace("Try to find alarms by entity [{}], status [{}] and pageLink [{}]", query.getAffectedEntityId(), query.getStatus(), query.getPageLink()); |
||||
|
EntityId affectedEntity = query.getAffectedEntityId(); |
||||
|
String relationType = query.getStatus() == null ? BaseAlarmService.ALARM_RELATION : BaseAlarmService.ALARM_RELATION_PREFIX + query.getStatus().name(); |
||||
|
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(affectedEntity, relationType, EntityType.ALARM, query.getPageLink()); |
||||
|
return Futures.transform(relations, (AsyncFunction<List<EntityRelation>, List<Alarm>>) input -> { |
||||
|
List<ListenableFuture<Alarm>> alarmFutures = new ArrayList<>(input.size()); |
||||
|
for (EntityRelation relation : input) { |
||||
|
alarmFutures.add(findAlarmByIdAsync(relation.getTo().getId())); |
||||
|
} |
||||
|
return Futures.successfulAsList(alarmFutures); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,236 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.model; |
||||
|
|
||||
|
import com.datastax.driver.core.utils.UUIDs; |
||||
|
import com.datastax.driver.mapping.annotations.*; |
||||
|
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmId; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
||||
|
import org.thingsboard.server.common.data.id.EntityIdFactory; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.dao.model.type.AlarmSeverityCodec; |
||||
|
import org.thingsboard.server.dao.model.type.AlarmStatusCodec; |
||||
|
import org.thingsboard.server.dao.model.type.EntityTypeCodec; |
||||
|
import org.thingsboard.server.dao.model.type.JsonCodec; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
import static org.thingsboard.server.dao.model.ModelConstants.*; |
||||
|
|
||||
|
@Table(name = ALARM_COLUMN_FAMILY_NAME) |
||||
|
public final class AlarmEntity implements BaseEntity<Alarm> { |
||||
|
|
||||
|
@Transient |
||||
|
private static final long serialVersionUID = -1265181166886910152L; |
||||
|
|
||||
|
@ClusteringColumn(value = 1) |
||||
|
@Column(name = ID_PROPERTY) |
||||
|
private UUID id; |
||||
|
|
||||
|
@PartitionKey(value = 0) |
||||
|
@Column(name = ALARM_TENANT_ID_PROPERTY) |
||||
|
private UUID tenantId; |
||||
|
|
||||
|
@PartitionKey(value = 1) |
||||
|
@Column(name = ALARM_ORIGINATOR_ID_PROPERTY) |
||||
|
private UUID originatorId; |
||||
|
|
||||
|
@PartitionKey(value = 2) |
||||
|
@Column(name = ALARM_ORIGINATOR_TYPE_PROPERTY, codec = EntityTypeCodec.class) |
||||
|
private EntityType originatorType; |
||||
|
|
||||
|
@ClusteringColumn(value = 0) |
||||
|
@Column(name = ALARM_TYPE_PROPERTY) |
||||
|
private String type; |
||||
|
|
||||
|
@Column(name = ALARM_SEVERITY_PROPERTY, codec = AlarmSeverityCodec.class) |
||||
|
private AlarmSeverity severity; |
||||
|
|
||||
|
@Column(name = ALARM_STATUS_PROPERTY, codec = AlarmStatusCodec.class) |
||||
|
private AlarmStatus status; |
||||
|
|
||||
|
@Column(name = ALARM_START_TS_PROPERTY) |
||||
|
private Long startTs; |
||||
|
|
||||
|
@Column(name = ALARM_END_TS_PROPERTY) |
||||
|
private Long endTs; |
||||
|
|
||||
|
@Column(name = ALARM_ACK_TS_PROPERTY) |
||||
|
private Long ackTs; |
||||
|
|
||||
|
@Column(name = ALARM_CLEAR_TS_PROPERTY) |
||||
|
private Long clearTs; |
||||
|
|
||||
|
@Column(name = ALARM_DETAILS_PROPERTY, codec = JsonCodec.class) |
||||
|
private JsonNode details; |
||||
|
|
||||
|
@Column(name = ALARM_PROPAGATE_PROPERTY) |
||||
|
private Boolean propagate; |
||||
|
|
||||
|
public AlarmEntity() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public AlarmEntity(Alarm alarm) { |
||||
|
if (alarm.getId() != null) { |
||||
|
this.id = alarm.getId().getId(); |
||||
|
} |
||||
|
if (alarm.getTenantId() != null) { |
||||
|
this.tenantId = alarm.getTenantId().getId(); |
||||
|
} |
||||
|
this.type = alarm.getType(); |
||||
|
this.originatorId = alarm.getOriginator().getId(); |
||||
|
this.originatorType = alarm.getOriginator().getEntityType(); |
||||
|
this.type = alarm.getType(); |
||||
|
this.severity = alarm.getSeverity(); |
||||
|
this.status = alarm.getStatus(); |
||||
|
this.propagate = alarm.isPropagate(); |
||||
|
this.startTs = alarm.getStartTs(); |
||||
|
this.endTs = alarm.getEndTs(); |
||||
|
this.ackTs = alarm.getAckTs(); |
||||
|
this.clearTs = alarm.getClearTs(); |
||||
|
this.details = alarm.getDetails(); |
||||
|
} |
||||
|
|
||||
|
public UUID getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(UUID id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public UUID getTenantId() { |
||||
|
return tenantId; |
||||
|
} |
||||
|
|
||||
|
public void setTenantId(UUID tenantId) { |
||||
|
this.tenantId = tenantId; |
||||
|
} |
||||
|
|
||||
|
public UUID getOriginatorId() { |
||||
|
return originatorId; |
||||
|
} |
||||
|
|
||||
|
public void setOriginatorId(UUID originatorId) { |
||||
|
this.originatorId = originatorId; |
||||
|
} |
||||
|
|
||||
|
public EntityType getOriginatorType() { |
||||
|
return originatorType; |
||||
|
} |
||||
|
|
||||
|
public void setOriginatorType(EntityType originatorType) { |
||||
|
this.originatorType = originatorType; |
||||
|
} |
||||
|
|
||||
|
public String getType() { |
||||
|
return type; |
||||
|
} |
||||
|
|
||||
|
public void setType(String type) { |
||||
|
this.type = type; |
||||
|
} |
||||
|
|
||||
|
public AlarmSeverity getSeverity() { |
||||
|
return severity; |
||||
|
} |
||||
|
|
||||
|
public void setSeverity(AlarmSeverity severity) { |
||||
|
this.severity = severity; |
||||
|
} |
||||
|
|
||||
|
public AlarmStatus getStatus() { |
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
public void setStatus(AlarmStatus status) { |
||||
|
this.status = status; |
||||
|
} |
||||
|
|
||||
|
public Long getStartTs() { |
||||
|
return startTs; |
||||
|
} |
||||
|
|
||||
|
public void setStartTs(Long startTs) { |
||||
|
this.startTs = startTs; |
||||
|
} |
||||
|
|
||||
|
public Long getEndTs() { |
||||
|
return endTs; |
||||
|
} |
||||
|
|
||||
|
public void setEndTs(Long endTs) { |
||||
|
this.endTs = endTs; |
||||
|
} |
||||
|
|
||||
|
public Long getAckTs() { |
||||
|
return ackTs; |
||||
|
} |
||||
|
|
||||
|
public void setAckTs(Long ackTs) { |
||||
|
this.ackTs = ackTs; |
||||
|
} |
||||
|
|
||||
|
public Long getClearTs() { |
||||
|
return clearTs; |
||||
|
} |
||||
|
|
||||
|
public void setClearTs(Long clearTs) { |
||||
|
this.clearTs = clearTs; |
||||
|
} |
||||
|
|
||||
|
public JsonNode getDetails() { |
||||
|
return details; |
||||
|
} |
||||
|
|
||||
|
public void setDetails(JsonNode details) { |
||||
|
this.details = details; |
||||
|
} |
||||
|
|
||||
|
public Boolean getPropagate() { |
||||
|
return propagate; |
||||
|
} |
||||
|
|
||||
|
public void setPropagate(Boolean propagate) { |
||||
|
this.propagate = propagate; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Alarm toData() { |
||||
|
Alarm alarm = new Alarm(new AlarmId(id)); |
||||
|
alarm.setCreatedTime(UUIDs.unixTimestamp(id)); |
||||
|
if (tenantId != null) { |
||||
|
alarm.setTenantId(new TenantId(tenantId)); |
||||
|
} |
||||
|
alarm.setOriginator(EntityIdFactory.getByTypeAndUuid(originatorType, originatorId)); |
||||
|
alarm.setType(type); |
||||
|
alarm.setSeverity(severity); |
||||
|
alarm.setStatus(status); |
||||
|
alarm.setPropagate(propagate); |
||||
|
alarm.setStartTs(startTs); |
||||
|
alarm.setEndTs(endTs); |
||||
|
alarm.setAckTs(ackTs); |
||||
|
alarm.setClearTs(clearTs); |
||||
|
alarm.setDetails(details); |
||||
|
return alarm; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.model.type; |
||||
|
|
||||
|
import com.datastax.driver.extras.codecs.enums.EnumNameCodec; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
||||
|
import org.thingsboard.server.dao.alarm.AlarmService; |
||||
|
|
||||
|
public class AlarmSeverityCodec extends EnumNameCodec<AlarmSeverity> { |
||||
|
|
||||
|
public AlarmSeverityCodec() { |
||||
|
super(AlarmSeverity.class); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.model.type; |
||||
|
|
||||
|
import com.datastax.driver.extras.codecs.enums.EnumNameCodec; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
||||
|
|
||||
|
public class AlarmStatusCodec extends EnumNameCodec<AlarmStatus> { |
||||
|
|
||||
|
public AlarmStatusCodec() { |
||||
|
super(AlarmStatus.class); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,172 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.service; |
||||
|
|
||||
|
import com.datastax.driver.core.utils.UUIDs; |
||||
|
import org.junit.After; |
||||
|
import org.junit.Assert; |
||||
|
import org.junit.Before; |
||||
|
import org.junit.Test; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.Tenant; |
||||
|
import org.thingsboard.server.common.data.alarm.Alarm; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmQuery; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
||||
|
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
||||
|
import org.thingsboard.server.common.data.id.AssetId; |
||||
|
import org.thingsboard.server.common.data.id.DeviceId; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.page.TimePageData; |
||||
|
import org.thingsboard.server.common.data.page.TimePageLink; |
||||
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
||||
|
import org.thingsboard.server.dao.exception.DataValidationException; |
||||
|
import org.thingsboard.server.dao.relation.EntityRelationsQuery; |
||||
|
import org.thingsboard.server.dao.relation.EntitySearchDirection; |
||||
|
import org.thingsboard.server.dao.relation.EntityTypeFilter; |
||||
|
import org.thingsboard.server.dao.relation.RelationsSearchParameters; |
||||
|
|
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.ExecutionException; |
||||
|
|
||||
|
public class AlarmServiceTest extends AbstractServiceTest { |
||||
|
|
||||
|
public static final String TEST_ALARM = "TEST_ALARM"; |
||||
|
private TenantId tenantId; |
||||
|
|
||||
|
@Before |
||||
|
public void before() { |
||||
|
Tenant tenant = new Tenant(); |
||||
|
tenant.setTitle("My tenant"); |
||||
|
Tenant savedTenant = tenantService.saveTenant(tenant); |
||||
|
Assert.assertNotNull(savedTenant); |
||||
|
tenantId = savedTenant.getId(); |
||||
|
} |
||||
|
|
||||
|
@After |
||||
|
public void after() { |
||||
|
tenantService.deleteTenant(tenantId); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Test |
||||
|
public void testSaveAndFetchAlarm() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childId = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
Assert.assertTrue(relationService.saveRelation(relation).get()); |
||||
|
|
||||
|
long ts = System.currentTimeMillis(); |
||||
|
Alarm alarm = Alarm.builder().tenantId(tenantId).originator(childId) |
||||
|
.type(TEST_ALARM) |
||||
|
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
||||
|
.startTs(ts).build(); |
||||
|
|
||||
|
Alarm created = alarmService.createOrUpdateAlarm(alarm); |
||||
|
|
||||
|
Assert.assertNotNull(created); |
||||
|
Assert.assertNotNull(created.getId()); |
||||
|
Assert.assertNotNull(created.getOriginator()); |
||||
|
Assert.assertNotNull(created.getSeverity()); |
||||
|
Assert.assertNotNull(created.getStatus()); |
||||
|
|
||||
|
Assert.assertEquals(tenantId, created.getTenantId()); |
||||
|
Assert.assertEquals(childId, created.getOriginator()); |
||||
|
Assert.assertEquals(TEST_ALARM, created.getType()); |
||||
|
Assert.assertEquals(AlarmSeverity.CRITICAL, created.getSeverity()); |
||||
|
Assert.assertEquals(AlarmStatus.ACTIVE_UNACK, created.getStatus()); |
||||
|
Assert.assertEquals(ts, created.getStartTs()); |
||||
|
Assert.assertEquals(ts, created.getEndTs()); |
||||
|
Assert.assertEquals(0L, created.getAckTs()); |
||||
|
Assert.assertEquals(0L, created.getClearTs()); |
||||
|
|
||||
|
Alarm fetched = alarmService.findAlarmByIdAsync(created.getId()).get(); |
||||
|
Assert.assertEquals(created, fetched); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testFindAlarm() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childId = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
Assert.assertTrue(relationService.saveRelation(relation).get()); |
||||
|
|
||||
|
long ts = System.currentTimeMillis(); |
||||
|
Alarm alarm = Alarm.builder().tenantId(tenantId).originator(childId) |
||||
|
.type(TEST_ALARM) |
||||
|
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
||||
|
.startTs(ts).build(); |
||||
|
|
||||
|
Alarm created = alarmService.createOrUpdateAlarm(alarm); |
||||
|
|
||||
|
// Check child relation
|
||||
|
TimePageData<Alarm> alarms = alarmService.findAlarms(AlarmQuery.builder() |
||||
|
.affectedEntityId(childId) |
||||
|
.status(AlarmStatus.ACTIVE_UNACK).pageLink( |
||||
|
new TimePageLink(1, 0L, System.currentTimeMillis(), false) |
||||
|
).build()).get(); |
||||
|
Assert.assertNotNull(alarms.getData()); |
||||
|
Assert.assertEquals(1, alarms.getData().size()); |
||||
|
Assert.assertEquals(created, alarms.getData().get(0)); |
||||
|
|
||||
|
// Check parent relation
|
||||
|
alarms = alarmService.findAlarms(AlarmQuery.builder() |
||||
|
.affectedEntityId(parentId) |
||||
|
.status(AlarmStatus.ACTIVE_UNACK).pageLink( |
||||
|
new TimePageLink(1, 0L, System.currentTimeMillis(), false) |
||||
|
).build()).get(); |
||||
|
Assert.assertNotNull(alarms.getData()); |
||||
|
Assert.assertEquals(1, alarms.getData().size()); |
||||
|
Assert.assertEquals(created, alarms.getData().get(0)); |
||||
|
|
||||
|
alarmService.ackAlarm(created.getId(), System.currentTimeMillis()).get(); |
||||
|
created = alarmService.findAlarmByIdAsync(created.getId()).get(); |
||||
|
|
||||
|
alarms = alarmService.findAlarms(AlarmQuery.builder() |
||||
|
.affectedEntityId(childId) |
||||
|
.status(AlarmStatus.ACTIVE_ACK).pageLink( |
||||
|
new TimePageLink(1, 0L, System.currentTimeMillis(), false) |
||||
|
).build()).get(); |
||||
|
Assert.assertNotNull(alarms.getData()); |
||||
|
Assert.assertEquals(1, alarms.getData().size()); |
||||
|
Assert.assertEquals(created, alarms.getData().get(0)); |
||||
|
|
||||
|
// Check not existing relation
|
||||
|
alarms = alarmService.findAlarms(AlarmQuery.builder() |
||||
|
.affectedEntityId(childId) |
||||
|
.status(AlarmStatus.ACTIVE_UNACK).pageLink( |
||||
|
new TimePageLink(1, 0L, System.currentTimeMillis(), false) |
||||
|
).build()).get(); |
||||
|
Assert.assertNotNull(alarms.getData()); |
||||
|
Assert.assertEquals(0, alarms.getData().size()); |
||||
|
|
||||
|
alarmService.clearAlarm(created.getId(), System.currentTimeMillis()).get(); |
||||
|
created = alarmService.findAlarmByIdAsync(created.getId()).get(); |
||||
|
|
||||
|
alarms = alarmService.findAlarms(AlarmQuery.builder() |
||||
|
.affectedEntityId(childId) |
||||
|
.status(AlarmStatus.CLEARED_ACK).pageLink( |
||||
|
new TimePageLink(1, 0L, System.currentTimeMillis(), false) |
||||
|
).build()).get(); |
||||
|
Assert.assertNotNull(alarms.getData()); |
||||
|
Assert.assertEquals(1, alarms.getData().size()); |
||||
|
Assert.assertEquals(created, alarms.getData().get(0)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,283 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.dao.service; |
||||
|
|
||||
|
import com.datastax.driver.core.utils.UUIDs; |
||||
|
import com.google.common.util.concurrent.ListenableFuture; |
||||
|
import org.junit.After; |
||||
|
import org.junit.Assert; |
||||
|
import org.junit.Before; |
||||
|
import org.junit.Test; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
import org.thingsboard.server.common.data.asset.Asset; |
||||
|
import org.thingsboard.server.common.data.id.AssetId; |
||||
|
import org.thingsboard.server.common.data.id.DeviceId; |
||||
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
||||
|
import org.thingsboard.server.dao.exception.DataValidationException; |
||||
|
import org.thingsboard.server.dao.relation.EntityRelationsQuery; |
||||
|
import org.thingsboard.server.dao.relation.EntitySearchDirection; |
||||
|
import org.thingsboard.server.dao.relation.EntityTypeFilter; |
||||
|
import org.thingsboard.server.dao.relation.RelationsSearchParameters; |
||||
|
|
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.ExecutionException; |
||||
|
|
||||
|
public class RelationServiceTest extends AbstractServiceTest { |
||||
|
|
||||
|
@Before |
||||
|
public void before() { |
||||
|
} |
||||
|
|
||||
|
@After |
||||
|
public void after() { |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testSaveRelation() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childId = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
Assert.assertTrue(saveRelation(relation)); |
||||
|
|
||||
|
Assert.assertTrue(relationService.checkRelation(parentId, childId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
|
||||
|
Assert.assertFalse(relationService.checkRelation(parentId, childId, "NOT_EXISTING_TYPE").get()); |
||||
|
|
||||
|
Assert.assertFalse(relationService.checkRelation(childId, parentId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
|
||||
|
Assert.assertFalse(relationService.checkRelation(childId, parentId, "NOT_EXISTING_TYPE").get()); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testDeleteRelation() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId subChildId = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relationA = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationB = new EntityRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
saveRelation(relationA); |
||||
|
saveRelation(relationB); |
||||
|
|
||||
|
Assert.assertTrue(relationService.deleteRelation(relationA).get()); |
||||
|
|
||||
|
Assert.assertFalse(relationService.checkRelation(parentId, childId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
|
||||
|
Assert.assertTrue(relationService.checkRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
|
||||
|
Assert.assertTrue(relationService.deleteRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testDeleteEntityRelations() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childId = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId subChildId = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relationA = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationB = new EntityRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
saveRelation(relationA); |
||||
|
saveRelation(relationB); |
||||
|
|
||||
|
Assert.assertTrue(relationService.deleteEntityRelations(childId).get()); |
||||
|
|
||||
|
Assert.assertFalse(relationService.checkRelation(parentId, childId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
|
||||
|
Assert.assertFalse(relationService.checkRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE).get()); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testFindFrom() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentA = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId parentB = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childA = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childB = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relationA1 = new EntityRelation(parentA, childA, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationA2 = new EntityRelation(parentA, childB, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
EntityRelation relationB1 = new EntityRelation(parentB, childA, EntityRelation.MANAGES_TYPE); |
||||
|
EntityRelation relationB2 = new EntityRelation(parentB, childB, EntityRelation.MANAGES_TYPE); |
||||
|
|
||||
|
saveRelation(relationA1); |
||||
|
saveRelation(relationA2); |
||||
|
|
||||
|
saveRelation(relationB1); |
||||
|
saveRelation(relationB2); |
||||
|
|
||||
|
List<EntityRelation> relations = relationService.findByFrom(parentA).get(); |
||||
|
Assert.assertEquals(2, relations.size()); |
||||
|
for (EntityRelation relation : relations) { |
||||
|
Assert.assertEquals(EntityRelation.CONTAINS_TYPE, relation.getType()); |
||||
|
Assert.assertEquals(parentA, relation.getFrom()); |
||||
|
Assert.assertTrue(childA.equals(relation.getTo()) || childB.equals(relation.getTo())); |
||||
|
} |
||||
|
|
||||
|
relations = relationService.findByFromAndType(parentA, EntityRelation.CONTAINS_TYPE).get(); |
||||
|
Assert.assertEquals(2, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByFromAndType(parentA, EntityRelation.MANAGES_TYPE).get(); |
||||
|
Assert.assertEquals(0, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByFrom(parentB).get(); |
||||
|
Assert.assertEquals(2, relations.size()); |
||||
|
for (EntityRelation relation : relations) { |
||||
|
Assert.assertEquals(EntityRelation.MANAGES_TYPE, relation.getType()); |
||||
|
Assert.assertEquals(parentB, relation.getFrom()); |
||||
|
Assert.assertTrue(childA.equals(relation.getTo()) || childB.equals(relation.getTo())); |
||||
|
} |
||||
|
|
||||
|
relations = relationService.findByFromAndType(parentB, EntityRelation.CONTAINS_TYPE).get(); |
||||
|
Assert.assertEquals(0, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByFromAndType(parentB, EntityRelation.CONTAINS_TYPE).get(); |
||||
|
Assert.assertEquals(0, relations.size()); |
||||
|
} |
||||
|
|
||||
|
private Boolean saveRelation(EntityRelation relationA1) throws ExecutionException, InterruptedException { |
||||
|
return relationService.saveRelation(relationA1).get(); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testFindTo() throws ExecutionException, InterruptedException { |
||||
|
AssetId parentA = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId parentB = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childA = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId childB = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relationA1 = new EntityRelation(parentA, childA, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationA2 = new EntityRelation(parentA, childB, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
EntityRelation relationB1 = new EntityRelation(parentB, childA, EntityRelation.MANAGES_TYPE); |
||||
|
EntityRelation relationB2 = new EntityRelation(parentB, childB, EntityRelation.MANAGES_TYPE); |
||||
|
|
||||
|
saveRelation(relationA1); |
||||
|
saveRelation(relationA2); |
||||
|
|
||||
|
saveRelation(relationB1); |
||||
|
saveRelation(relationB2); |
||||
|
|
||||
|
// Data propagation to views is async
|
||||
|
Thread.sleep(3000); |
||||
|
|
||||
|
List<EntityRelation> relations = relationService.findByTo(childA).get(); |
||||
|
Assert.assertEquals(2, relations.size()); |
||||
|
for (EntityRelation relation : relations) { |
||||
|
Assert.assertEquals(childA, relation.getTo()); |
||||
|
Assert.assertTrue(parentA.equals(relation.getFrom()) || parentB.equals(relation.getFrom())); |
||||
|
} |
||||
|
|
||||
|
relations = relationService.findByToAndType(childA, EntityRelation.CONTAINS_TYPE).get(); |
||||
|
Assert.assertEquals(1, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByToAndType(childB, EntityRelation.MANAGES_TYPE).get(); |
||||
|
Assert.assertEquals(1, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByToAndType(parentA, EntityRelation.MANAGES_TYPE).get(); |
||||
|
Assert.assertEquals(0, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByToAndType(parentB, EntityRelation.MANAGES_TYPE).get(); |
||||
|
Assert.assertEquals(0, relations.size()); |
||||
|
|
||||
|
relations = relationService.findByTo(childB).get(); |
||||
|
Assert.assertEquals(2, relations.size()); |
||||
|
for (EntityRelation relation : relations) { |
||||
|
Assert.assertEquals(childB, relation.getTo()); |
||||
|
Assert.assertTrue(parentA.equals(relation.getFrom()) || parentB.equals(relation.getFrom())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testCyclicRecursiveRelation() throws ExecutionException, InterruptedException { |
||||
|
// A -> B -> C -> A
|
||||
|
AssetId assetA = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId assetB = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId assetC = new AssetId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relationA = new EntityRelation(assetA, assetB, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationB = new EntityRelation(assetB, assetC, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationC = new EntityRelation(assetC, assetA, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
saveRelation(relationA); |
||||
|
saveRelation(relationB); |
||||
|
saveRelation(relationC); |
||||
|
|
||||
|
EntityRelationsQuery query = new EntityRelationsQuery(); |
||||
|
query.setParameters(new RelationsSearchParameters(assetA, EntitySearchDirection.FROM, -1)); |
||||
|
query.setFilters(Collections.singletonList(new EntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.singletonList(EntityType.ASSET)))); |
||||
|
List<EntityRelation> relations = relationService.findByQuery(query).get(); |
||||
|
Assert.assertEquals(3, relations.size()); |
||||
|
Assert.assertTrue(relations.contains(relationA)); |
||||
|
Assert.assertTrue(relations.contains(relationB)); |
||||
|
Assert.assertTrue(relations.contains(relationC)); |
||||
|
} |
||||
|
|
||||
|
@Test |
||||
|
public void testRecursiveRelation() throws ExecutionException, InterruptedException { |
||||
|
// A -> B -> [C,D]
|
||||
|
AssetId assetA = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId assetB = new AssetId(UUIDs.timeBased()); |
||||
|
AssetId assetC = new AssetId(UUIDs.timeBased()); |
||||
|
DeviceId deviceD = new DeviceId(UUIDs.timeBased()); |
||||
|
|
||||
|
EntityRelation relationAB = new EntityRelation(assetA, assetB, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationBC = new EntityRelation(assetB, assetC, EntityRelation.CONTAINS_TYPE); |
||||
|
EntityRelation relationBD = new EntityRelation(assetB, deviceD, EntityRelation.CONTAINS_TYPE); |
||||
|
|
||||
|
|
||||
|
saveRelation(relationAB); |
||||
|
saveRelation(relationBC); |
||||
|
saveRelation(relationBD); |
||||
|
|
||||
|
EntityRelationsQuery query = new EntityRelationsQuery(); |
||||
|
query.setParameters(new RelationsSearchParameters(assetA, EntitySearchDirection.FROM, -1)); |
||||
|
query.setFilters(Collections.singletonList(new EntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.singletonList(EntityType.ASSET)))); |
||||
|
List<EntityRelation> relations = relationService.findByQuery(query).get(); |
||||
|
Assert.assertEquals(2, relations.size()); |
||||
|
Assert.assertTrue(relations.contains(relationAB)); |
||||
|
Assert.assertTrue(relations.contains(relationBC)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Test(expected = DataValidationException.class) |
||||
|
public void testSaveRelationWithEmptyFrom() throws ExecutionException, InterruptedException { |
||||
|
EntityRelation relation = new EntityRelation(); |
||||
|
relation.setTo(new AssetId(UUIDs.timeBased())); |
||||
|
relation.setType(EntityRelation.CONTAINS_TYPE); |
||||
|
Assert.assertTrue(saveRelation(relation)); |
||||
|
} |
||||
|
|
||||
|
@Test(expected = DataValidationException.class) |
||||
|
public void testSaveRelationWithEmptyTo() throws ExecutionException, InterruptedException { |
||||
|
EntityRelation relation = new EntityRelation(); |
||||
|
relation.setFrom(new AssetId(UUIDs.timeBased())); |
||||
|
relation.setType(EntityRelation.CONTAINS_TYPE); |
||||
|
Assert.assertTrue(saveRelation(relation)); |
||||
|
} |
||||
|
|
||||
|
@Test(expected = DataValidationException.class) |
||||
|
public void testSaveRelationWithEmptyType() throws ExecutionException, InterruptedException { |
||||
|
EntityRelation relation = new EntityRelation(); |
||||
|
relation.setFrom(new AssetId(UUIDs.timeBased())); |
||||
|
relation.setTo(new AssetId(UUIDs.timeBased())); |
||||
|
Assert.assertTrue(saveRelation(relation)); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue