Feature/rest client (#2347)
* refactored URLs * refactored * refactored * refactored * refactored * refactored rest client * changed executorService from RestClient * refactored rest client and JsonConverter
This commit is contained in:
		
							parent
							
								
									7d0661a826
								
							
						
					
					
						commit
						e583b0a1d3
					
				@ -31,7 +31,7 @@ import org.springframework.http.client.support.HttpRequestWrapper;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import org.springframework.web.client.HttpClientErrorException;
 | 
			
		||||
import org.springframework.web.client.RestTemplate;
 | 
			
		||||
import org.springframework.web.context.request.async.DeferredResult;
 | 
			
		||||
import org.thingsboard.client.tools.utils.RestJsonConverter;
 | 
			
		||||
import org.thingsboard.server.common.data.AdminSettings;
 | 
			
		||||
import org.thingsboard.server.common.data.ClaimRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.Customer;
 | 
			
		||||
@ -57,6 +57,8 @@ import org.thingsboard.server.common.data.id.CustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DashboardId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.TsKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TextPageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TextPageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TimePageData;
 | 
			
		||||
@ -74,6 +76,7 @@ import org.thingsboard.server.common.data.security.model.UserPasswordPolicy;
 | 
			
		||||
import org.thingsboard.server.common.data.widget.WidgetType;
 | 
			
		||||
import org.thingsboard.server.common.data.widget.WidgetsBundle;
 | 
			
		||||
 | 
			
		||||
import java.io.Closeable;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@ -81,19 +84,23 @@ import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.concurrent.ExecutorService;
 | 
			
		||||
import java.util.concurrent.Executors;
 | 
			
		||||
import java.util.concurrent.Future;
 | 
			
		||||
 | 
			
		||||
import static org.springframework.util.StringUtils.isEmpty;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Andrew Shvayka
 | 
			
		||||
 */
 | 
			
		||||
public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
public class RestClient implements ClientHttpRequestInterceptor, Closeable {
 | 
			
		||||
    private static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization";
 | 
			
		||||
    protected final RestTemplate restTemplate;
 | 
			
		||||
    protected final String baseURL;
 | 
			
		||||
    private String token;
 | 
			
		||||
    private String refreshToken;
 | 
			
		||||
    private final ObjectMapper objectMapper = new ObjectMapper();
 | 
			
		||||
    private ExecutorService service = Executors.newWorkStealingPool(10);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected static final String ACTIVATE_TOKEN_REGEX = "/api/noauth/activate?activateToken=";
 | 
			
		||||
@ -256,6 +263,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        }
 | 
			
		||||
        return restTemplate.postForEntity(baseURL + deviceCreationUrl, device, Device.class, params).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Asset createAsset(Asset asset) {
 | 
			
		||||
        return restTemplate.postForEntity(baseURL + "/api/asset", asset, Asset.class).getBody();
 | 
			
		||||
    }
 | 
			
		||||
@ -418,17 +426,17 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void ackAlarm(String alarmId) {
 | 
			
		||||
        restTemplate.postForObject(baseURL + "/api/alarm/{alarmId}/ack", new Object(), Object.class, alarmId);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/alarm/{alarmId}/ack", null, alarmId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void clearAlarm(String alarmId) {
 | 
			
		||||
        restTemplate.postForObject(baseURL + "/api/alarm/{alarmId}/clear", new Object(), Object.class, alarmId);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/alarm/{alarmId}/clear", null, alarmId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TimePageData<AlarmInfo> getAlarms(String entityType, String entityId, String searchStatus, String status, TimePageLink pageLink, Boolean fetchOriginator) {
 | 
			
		||||
    public TimePageData<AlarmInfo> getAlarms(EntityId entityId, String searchStatus, String status, TimePageLink pageLink, Boolean fetchOriginator) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("searchStatus", searchStatus);
 | 
			
		||||
        params.put("status", status);
 | 
			
		||||
        params.put("fetchOriginator", String.valueOf(fetchOriginator));
 | 
			
		||||
@ -471,10 +479,10 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        return urlParams;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<AlarmSeverity> getHighestAlarmSeverity(String entityType, String entityId, String searchStatus, String status) {
 | 
			
		||||
    public Optional<AlarmSeverity> getHighestAlarmSeverity(EntityId entityId, String searchStatus, String status) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("searchStatus", searchStatus);
 | 
			
		||||
        params.put("status", status);
 | 
			
		||||
        try {
 | 
			
		||||
@ -597,14 +605,14 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        return assets.getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Asset> getAssetsByIds(String[] assetIds) {
 | 
			
		||||
    public List<Asset> getAssetsByIds(List<String> assetIds) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/assets?assetIds={assetIds}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<List<Asset>>() {
 | 
			
		||||
                },
 | 
			
		||||
                String.join(",", assetIds)).getBody();
 | 
			
		||||
                listToString(assetIds)).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Asset> findByQuery(AssetSearchQuery query) {
 | 
			
		||||
@ -657,10 +665,10 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        return auditLog.getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TimePageData<AuditLog> getAuditLogsByEntityId(String entityType, String entityId, String actionTypes, TimePageLink pageLink) {
 | 
			
		||||
    public TimePageData<AuditLog> getAuditLogsByEntityId(EntityId entityId, String actionTypes, TimePageLink pageLink) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("actionTypes", actionTypes);
 | 
			
		||||
        addPageLinkToParam(params, pageLink);
 | 
			
		||||
 | 
			
		||||
@ -700,14 +708,14 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void logout() {
 | 
			
		||||
        restTemplate.exchange(URI.create(baseURL + "/api/auth/logout"), HttpMethod.POST, HttpEntity.EMPTY, Object.class);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/auth/logout", null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void changePassword(String currentPassword, String newPassword) {
 | 
			
		||||
        ObjectNode changePasswordRequest = objectMapper.createObjectNode();
 | 
			
		||||
        changePasswordRequest.put("currentPassword", currentPassword);
 | 
			
		||||
        changePasswordRequest.put("newPassword", newPassword);
 | 
			
		||||
        restTemplate.exchange(URI.create(baseURL + "/api/auth/changePassword"), HttpMethod.POST, new HttpEntity<>(changePasswordRequest), Object.class);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/auth/changePassword", changePasswordRequest);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<UserPasswordPolicy> getUserPasswordPolicy() {
 | 
			
		||||
@ -731,7 +739,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
    public void requestResetPasswordByEmail(String email) {
 | 
			
		||||
        ObjectNode resetPasswordByEmailRequest = objectMapper.createObjectNode();
 | 
			
		||||
        resetPasswordByEmailRequest.put("email", email);
 | 
			
		||||
        restTemplate.exchange(URI.create(baseURL + "/api/noauth/resetPasswordByEmail"), HttpMethod.POST, new HttpEntity<>(resetPasswordByEmailRequest), Object.class);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/noauth/resetPasswordByEmail", resetPasswordByEmailRequest);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<JsonNode> activateUser(String userId, String password) {
 | 
			
		||||
@ -772,14 +780,14 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
                componentType).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<ComponentDescriptor> getComponentDescriptorsByTypes(String[] componentTypes) {
 | 
			
		||||
    public List<ComponentDescriptor> getComponentDescriptorsByTypes(List<String> componentTypes) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/components?componentTypes={componentTypes}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<List<ComponentDescriptor>>() {
 | 
			
		||||
                },
 | 
			
		||||
                String.join(",", componentTypes)).getBody();
 | 
			
		||||
                listToString(componentTypes)).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<Customer> getCustomerById(String customerId) {
 | 
			
		||||
@ -915,7 +923,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<Dashboard> updateDashboardCustomers(String dashboardId, String[] customerIds) {
 | 
			
		||||
    public Optional<Dashboard> updateDashboardCustomers(String dashboardId, List<String> customerIds) {
 | 
			
		||||
        try {
 | 
			
		||||
            ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/api/dashboard/{dashboardId}/customers", customerIds, Dashboard.class, dashboardId);
 | 
			
		||||
            return Optional.ofNullable(dashboard.getBody());
 | 
			
		||||
@ -928,7 +936,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<Dashboard> addDashboardCustomers(String dashboardId, String[] customerIds) {
 | 
			
		||||
    public Optional<Dashboard> addDashboardCustomers(String dashboardId, List<String> customerIds) {
 | 
			
		||||
        try {
 | 
			
		||||
            ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/api/dashboard/{dashboardId}/customers/add", customerIds, Dashboard.class, dashboardId);
 | 
			
		||||
            return Optional.ofNullable(dashboard.getBody());
 | 
			
		||||
@ -941,7 +949,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<Dashboard> removeDashboardCustomers(String dashboardId, String[] customerIds) {
 | 
			
		||||
    public Optional<Dashboard> removeDashboardCustomers(String dashboardId, List<String> customerIds) {
 | 
			
		||||
        try {
 | 
			
		||||
            ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/api/dashboard/{dashboardId}/customers/remove", customerIds, Dashboard.class, dashboardId);
 | 
			
		||||
            return Optional.ofNullable(dashboard.getBody());
 | 
			
		||||
@ -1135,12 +1143,12 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
                .getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Device> getDevicesByIds(String[] deviceIds) {
 | 
			
		||||
    public List<Device> getDevicesByIds(List<String> deviceIds) {
 | 
			
		||||
        return restTemplate.exchange(baseURL + "/api/devices?deviceIds={deviceIds}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY, new ParameterizedTypeReference<List<Device>>() {
 | 
			
		||||
                },
 | 
			
		||||
                String.join(",", deviceIds)).getBody();
 | 
			
		||||
                listToString(deviceIds)).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Device> findByQuery(DeviceSearchQuery query) {
 | 
			
		||||
@ -1161,28 +1169,22 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
                }).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> claimDevice(String deviceName, ClaimRequest claimRequest) {
 | 
			
		||||
    public JsonNode claimDevice(String deviceName, ClaimRequest claimRequest) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/customer/device/{deviceName}/claim",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(claimRequest),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<JsonNode>() {
 | 
			
		||||
                },
 | 
			
		||||
                deviceName).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> reClaimDevice(String deviceName) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/customer/device/{deviceName}/claim",
 | 
			
		||||
                HttpMethod.DELETE,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                },
 | 
			
		||||
                deviceName).getBody();
 | 
			
		||||
    public void reClaimDevice(String deviceName) {
 | 
			
		||||
        restTemplate.delete(baseURL + "/api/customer/device/{deviceName}/claim", deviceName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void saveRelation(EntityRelation relation) {
 | 
			
		||||
        restTemplate.postForEntity(baseURL + "/api/relation", relation, Object.class);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/relation", null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void deleteRelation(String fromId, String fromType, String relationType, String relationTypeGroup, String toId, String toType) {
 | 
			
		||||
@ -1196,8 +1198,8 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        restTemplate.delete(baseURL + "/api/relation?fromId={fromId}&fromType={fromType}&relationType={relationType}&relationTypeGroup={relationTypeGroup}&toId={toId}&toType={toType}", params);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void deleteRelations(String entityId, String entityType) {
 | 
			
		||||
        restTemplate.delete(baseURL + "/api/relations?entityId={entityId}&entityType={entityType}", entityId, entityType);
 | 
			
		||||
    public void deleteRelations(EntityId entityId) {
 | 
			
		||||
        restTemplate.delete(baseURL + "/api/relations?entityId={entityId}&entityType={entityType}", entityId.getId().toString(), entityId.getEntityType().name());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<EntityRelation> getRelation(String fromId, String fromType, String relationType, String relationTypeGroup, String toId, String toType) {
 | 
			
		||||
@ -1448,10 +1450,10 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TimePageData<Event> getEvents(String entityType, String entityId, String eventType, String tenantId, TimePageLink pageLink) {
 | 
			
		||||
    public TimePageData<Event> getEvents(EntityId entityId, String eventType, String tenantId, TimePageLink pageLink) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("eventType", eventType);
 | 
			
		||||
        params.put("tenantId", tenantId);
 | 
			
		||||
        addPageLinkToParam(params, pageLink);
 | 
			
		||||
@ -1465,10 +1467,10 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
                params).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TimePageData<Event> getEvents(String entityType, String entityId, String tenantId, TimePageLink pageLink) {
 | 
			
		||||
    public TimePageData<Event> getEvents(EntityId entityId, String tenantId, TimePageLink pageLink) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("tenantId", tenantId);
 | 
			
		||||
        addPageLinkToParam(params, pageLink);
 | 
			
		||||
 | 
			
		||||
@ -1481,22 +1483,16 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
                params).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(String deviceId, String requestBody) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/rpc/oneway/{deviceId}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(requestBody),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                },
 | 
			
		||||
                deviceId).getBody();
 | 
			
		||||
    public void handleOneWayDeviceRPCRequest(String deviceId, JsonNode requestBody) {
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/plugins/rpc/oneway/{deviceId}", requestBody, deviceId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(String deviceId, String requestBody) {
 | 
			
		||||
    public JsonNode handleTwoWayDeviceRPCRequest(String deviceId, JsonNode requestBody) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/rpc/twoway/{deviceId}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(requestBody),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<JsonNode>() {
 | 
			
		||||
                },
 | 
			
		||||
                deviceId).getBody();
 | 
			
		||||
    }
 | 
			
		||||
@ -1590,206 +1586,233 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getAttributeKeys(String entityType, String entityId) {
 | 
			
		||||
    public List<String> getAttributeKeys(EntityId entityId) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/keys/attributes",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<String>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId).getBody();
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString()).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getAttributeKeysByScope(String entityType, String entityId, String scope) {
 | 
			
		||||
    public List<String> getAttributeKeysByScope(EntityId entityId, String scope) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/keys/attributes/{scope}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<String>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getAttributesResponseEntity(String entityType, String entityId, String keys) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<AttributeKvEntry> getAttributeKvEntries(EntityId entityId, List<String> keys) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/values/attributes?keys={keys}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                keys).getBody();
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId(),
 | 
			
		||||
                listToString(keys)).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getAttributesByScope(String entityType, String entityId, String scope, String keys) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public Future<List<AttributeKvEntry>> getAttributeKvEntriesAsync(EntityId entityId, List<String> keys) {
 | 
			
		||||
        return service.submit(() -> getAttributeKvEntries(entityId, keys));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<AttributeKvEntry> getAttributesByScope(EntityId entityId, String scope, List<String> keys) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/values/attributes/{scope}?keys={keys}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope,
 | 
			
		||||
                keys).getBody();
 | 
			
		||||
                listToString(keys)).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getTimeseriesKeys(String entityType, String entityId) {
 | 
			
		||||
    public List<String> getTimeseriesKeys(EntityId entityId) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/keys/timeseries",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<String>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId).getBody();
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString()).getBody();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getLatestTimeseries(String entityType, String entityId, String keys) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<TsKvEntry> getLatestTimeseries(EntityId entityId, List<String> keys) {
 | 
			
		||||
        Map<String, List<JsonNode>> timeseries = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys={keys}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<Map<String, List<JsonNode>>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                keys).getBody();
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                listToString(keys)).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toTimeseries(timeseries);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> getTimeseries(String entityType, String entityId, String keys, Long startTs, Long endTs, Long interval, Integer limit, String agg) {
 | 
			
		||||
    public List<TsKvEntry> getTimeseries(EntityId entityId, List<String> keys, Long startTs, Long endTs, Long interval, Integer limit, String agg) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("keys", keys);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("keys", listToString(keys));
 | 
			
		||||
        params.put("startTs", startTs.toString());
 | 
			
		||||
        params.put("endTs", endTs.toString());
 | 
			
		||||
        params.put("interval", interval == null ? "0" : interval.toString());
 | 
			
		||||
        params.put("limit", limit == null ? "100" : limit.toString());
 | 
			
		||||
        params.put("agg", agg == null ? "NONE" : agg);
 | 
			
		||||
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
        Map<String, List<JsonNode>> timeseries = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/values/timeseries?keys={keys}&startTs={startTs}&endTs={endTs}&interval={interval}&limit={limit}&agg={agg}",
 | 
			
		||||
                HttpMethod.GET,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<Map<String, List<JsonNode>>>() {
 | 
			
		||||
                },
 | 
			
		||||
                params).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toTimeseries(timeseries);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> saveDeviceAttributes(String deviceId, String scope, JsonNode request) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<AttributeKvEntry> saveDeviceAttributes(String deviceId, String scope, JsonNode request) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{deviceId}/{scope}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(request),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                deviceId,
 | 
			
		||||
                scope).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> saveEntityAttributesV1(String entityType, String entityId, String scope, JsonNode request) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<AttributeKvEntry> saveEntityAttributesV1(EntityId entityId, String scope, JsonNode request) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/{scope}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(request),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> saveEntityAttributesV2(String entityType, String entityId, String scope, JsonNode request) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<AttributeKvEntry> saveEntityAttributesV2(EntityId entityId, String scope, JsonNode request) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/attributes/{scope}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(request),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> saveEntityTelemetry(String entityType, String entityId, String scope, String requestBody) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<TsKvEntry> saveEntityTelemetry(EntityId entityId, String scope, String requestBody) {
 | 
			
		||||
        Map<String, List<JsonNode>> timeseries = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/timeseries/{scope}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(requestBody),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<Map<String, List<JsonNode>>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toTimeseries(timeseries);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> saveEntityTelemetryWithTTL(String entityType, String entityId, String scope, Long ttl, String requestBody) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<TsKvEntry> saveEntityTelemetryWithTTL(EntityId entityId, String scope, Long ttl, String requestBody) {
 | 
			
		||||
        Map<String, List<JsonNode>> timeseries = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/timeseries/{scope}/{ttl}",
 | 
			
		||||
                HttpMethod.POST,
 | 
			
		||||
                new HttpEntity<>(requestBody),
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<Map<String, List<JsonNode>>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope,
 | 
			
		||||
                ttl).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toTimeseries(timeseries);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> deleteEntityTimeseries(String entityType,
 | 
			
		||||
                                                                 String entityId,
 | 
			
		||||
                                                                 String keys,
 | 
			
		||||
                                                                 boolean deleteAllDataForKeys,
 | 
			
		||||
                                                                 Long startTs,
 | 
			
		||||
                                                                 Long endTs,
 | 
			
		||||
                                                                 boolean rewriteLatestIfDeleted) {
 | 
			
		||||
    public List<TsKvEntry> deleteEntityTimeseries(EntityId entityId,
 | 
			
		||||
                                                  List<String> keys,
 | 
			
		||||
                                                  boolean deleteAllDataForKeys,
 | 
			
		||||
                                                  Long startTs,
 | 
			
		||||
                                                  Long endTs,
 | 
			
		||||
                                                  boolean rewriteLatestIfDeleted) {
 | 
			
		||||
        Map<String, String> params = new HashMap<>();
 | 
			
		||||
        params.put("entityType", entityType);
 | 
			
		||||
        params.put("entityId", entityId);
 | 
			
		||||
        params.put("keys", keys);
 | 
			
		||||
        params.put("entityType", entityId.getEntityType().name());
 | 
			
		||||
        params.put("entityId", entityId.getId().toString());
 | 
			
		||||
        params.put("keys", listToString(keys));
 | 
			
		||||
        params.put("deleteAllDataForKeys", String.valueOf(deleteAllDataForKeys));
 | 
			
		||||
        params.put("startTs", startTs.toString());
 | 
			
		||||
        params.put("endTs", endTs.toString());
 | 
			
		||||
        params.put("rewriteLatestIfDeleted", String.valueOf(rewriteLatestIfDeleted));
 | 
			
		||||
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
        Map<String, List<JsonNode>> timeseries = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/timeseries/delete?keys={keys}&deleteAllDataForKeys={deleteAllDataForKeys}&startTs={startTs}&endTs={endTs}&rewriteLatestIfDeleted={rewriteLatestIfDeleted}",
 | 
			
		||||
                HttpMethod.DELETE,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<Map<String, List<JsonNode>>>() {
 | 
			
		||||
                },
 | 
			
		||||
                params).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toTimeseries(timeseries);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> deleteEntityAttributes(String deviceId, String scope, String keys) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<AttributeKvEntry> deleteEntityAttributes(String deviceId, String scope, List<String> keys) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{deviceId}/{scope}?keys={keys}",
 | 
			
		||||
                HttpMethod.DELETE,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                deviceId,
 | 
			
		||||
                scope,
 | 
			
		||||
                keys).getBody();
 | 
			
		||||
                listToString(keys)).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DeferredResult<ResponseEntity> deleteEntityAttributes(String entityType, String entityId, String scope, String keys) {
 | 
			
		||||
        return restTemplate.exchange(
 | 
			
		||||
    public List<AttributeKvEntry> deleteEntityAttributes(EntityId entityId, String scope, List<String> keys) {
 | 
			
		||||
        List<JsonNode> attributes = restTemplate.exchange(
 | 
			
		||||
                baseURL + "/api/plugins/telemetry/{entityType}/{entityId}/{scope}?keys={keys}",
 | 
			
		||||
                HttpMethod.DELETE,
 | 
			
		||||
                HttpEntity.EMPTY,
 | 
			
		||||
                new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
 | 
			
		||||
                new ParameterizedTypeReference<List<JsonNode>>() {
 | 
			
		||||
                },
 | 
			
		||||
                entityType,
 | 
			
		||||
                entityId,
 | 
			
		||||
                entityId.getEntityType().name(),
 | 
			
		||||
                entityId.getId().toString(),
 | 
			
		||||
                scope,
 | 
			
		||||
                keys).getBody();
 | 
			
		||||
                listToString(keys)).getBody();
 | 
			
		||||
 | 
			
		||||
        return RestJsonConverter.toAttributes(attributes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Optional<Tenant> getTenantById(String tenantId) {
 | 
			
		||||
@ -1860,7 +1883,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void sendActivationEmail(String email) {
 | 
			
		||||
        restTemplate.postForEntity(baseURL + "/api/user/sendActivationMail?email={email}", null, Object.class, email);
 | 
			
		||||
        restTemplate.postForLocation(baseURL + "/api/user/sendActivationMail?email={email}", null, email);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getActivationLink(String userId) {
 | 
			
		||||
@ -1900,10 +1923,9 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUserCredentialsEnabled(String userId, boolean userCredentialsEnabled) {
 | 
			
		||||
        restTemplate.postForEntity(
 | 
			
		||||
        restTemplate.postForLocation(
 | 
			
		||||
                baseURL + "/api/user/{userId}/userCredentialsEnabled?serCredentialsEnabled={serCredentialsEnabled}",
 | 
			
		||||
                null,
 | 
			
		||||
                Object.class,
 | 
			
		||||
                userId,
 | 
			
		||||
                userCredentialsEnabled);
 | 
			
		||||
    }
 | 
			
		||||
@ -2030,4 +2052,15 @@ public class RestClient implements ClientHttpRequestInterceptor {
 | 
			
		||||
            params.put("textOffset", pageLink.getTextOffset());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String listToString(List<String> list) {
 | 
			
		||||
        return String.join(",", list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void close() {
 | 
			
		||||
        if (service != null) {
 | 
			
		||||
            service.shutdown();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,87 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2020 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.client.tools.utils;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import org.springframework.util.CollectionUtils;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.BooleanDataEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.DoubleDataEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.KvEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.LongDataEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.StringDataEntry;
 | 
			
		||||
import org.thingsboard.server.common.data.kv.TsKvEntry;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
public class RestJsonConverter {
 | 
			
		||||
    private static final String KEY = "key";
 | 
			
		||||
    private static final String VALUE = "value";
 | 
			
		||||
    private static final String LAST_UPDATE_TS = "lastUpdateTs";
 | 
			
		||||
    private static final String TS = "ts";
 | 
			
		||||
 | 
			
		||||
    private static final String CAN_T_PARSE_VALUE = "Can't parse value: ";
 | 
			
		||||
 | 
			
		||||
    public static List<AttributeKvEntry> toAttributes(List<JsonNode> attributes) {
 | 
			
		||||
        if (!CollectionUtils.isEmpty(attributes)) {
 | 
			
		||||
            return attributes.stream().map(attr -> {
 | 
			
		||||
                        KvEntry entry = parseValue(attr.get(KEY).asText(), attr.get(VALUE));
 | 
			
		||||
                        return new BaseAttributeKvEntry(entry, attr.get(LAST_UPDATE_TS).asLong());
 | 
			
		||||
                    }
 | 
			
		||||
            ).collect(Collectors.toList());
 | 
			
		||||
        } else {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<TsKvEntry> toTimeseries(Map<String, List<JsonNode>> timeseries) {
 | 
			
		||||
        if (!CollectionUtils.isEmpty(timeseries)) {
 | 
			
		||||
            List<TsKvEntry> result = new ArrayList<>();
 | 
			
		||||
            timeseries.forEach((key, values) ->
 | 
			
		||||
                    result.addAll(values.stream().map(ts -> {
 | 
			
		||||
                                KvEntry entry = parseValue(key, ts.get(VALUE));
 | 
			
		||||
                                return new BasicTsKvEntry(ts.get(TS).asLong(), entry);
 | 
			
		||||
                            }
 | 
			
		||||
                    ).collect(Collectors.toList()))
 | 
			
		||||
            );
 | 
			
		||||
            return result;
 | 
			
		||||
        } else {
 | 
			
		||||
            return Collections.emptyList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static KvEntry parseValue(String key, JsonNode value) {
 | 
			
		||||
        if (!value.isObject()) {
 | 
			
		||||
            if (value.isBoolean()) {
 | 
			
		||||
                return new BooleanDataEntry(key, value.asBoolean());
 | 
			
		||||
            } else if (value.isDouble()) {
 | 
			
		||||
                return new DoubleDataEntry(key, value.asDouble());
 | 
			
		||||
            } else if (value.isLong()) {
 | 
			
		||||
                return new LongDataEntry(key, value.asLong());
 | 
			
		||||
            } else {
 | 
			
		||||
                return new StringDataEntry(key, value.asText());
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new RuntimeException(CAN_T_PARSE_VALUE + value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user