Commit 866d7c4a2ca72be75822fbfc81e74f2332194406

Authored by YevhenBondarenko
Committed by Andrew Shvayka
1 parent 5c972575

[WIP] Feature/rest-client (#2208)

* added methods from admin-controller, alarm-controller, asset-controller, audit-log-controller

* refactored rest client and added methods from auth controller

* added methods from component-descriptor-controller

* added methods from customer controller

* added methods from dashboard controller

* added methods from device controller

* refactored url pageLink params

* added methods from entity relation controller

* added methods from entity view controller

* refactored

* added methods from event controller

* added methods from rpc controller

* added methods from rule chain controller

* added methods from telemetry controller

* added methods from tenant controller

* added methods from user controller

* added methods from widgets bundle controller

* added methods from widget type controller
... ... @@ -18,6 +18,7 @@ package org.thingsboard.client.tools;
18 18 import com.fasterxml.jackson.databind.JsonNode;
19 19 import lombok.RequiredArgsConstructor;
20 20 import org.springframework.core.ParameterizedTypeReference;
  21 +import org.springframework.http.HttpEntity;
21 22 import org.springframework.http.HttpMethod;
22 23 import org.springframework.http.HttpRequest;
23 24 import org.springframework.http.HttpStatus;
... ... @@ -28,23 +29,47 @@ import org.springframework.http.client.ClientHttpResponse;
28 29 import org.springframework.http.client.support.HttpRequestWrapper;
29 30 import org.springframework.web.client.HttpClientErrorException;
30 31 import org.springframework.web.client.RestTemplate;
  32 +import org.springframework.web.context.request.async.DeferredResult;
  33 +import org.thingsboard.server.common.data.AdminSettings;
31 34 import org.thingsboard.server.common.data.Customer;
32 35 import org.thingsboard.server.common.data.Dashboard;
33 36 import org.thingsboard.server.common.data.DashboardInfo;
34 37 import org.thingsboard.server.common.data.Device;
  38 +import org.thingsboard.server.common.data.EntitySubtype;
  39 +import org.thingsboard.server.common.data.EntityView;
  40 +import org.thingsboard.server.common.data.Event;
  41 +import org.thingsboard.server.common.data.Tenant;
  42 +import org.thingsboard.server.common.data.User;
35 43 import org.thingsboard.server.common.data.alarm.Alarm;
  44 +import org.thingsboard.server.common.data.alarm.AlarmInfo;
  45 +import org.thingsboard.server.common.data.alarm.AlarmSeverity;
36 46 import org.thingsboard.server.common.data.asset.Asset;
  47 +import org.thingsboard.server.common.data.asset.AssetSearchQuery;
  48 +import org.thingsboard.server.common.data.audit.AuditLog;
  49 +import org.thingsboard.server.common.data.device.DeviceSearchQuery;
  50 +import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
37 51 import org.thingsboard.server.common.data.id.AssetId;
38 52 import org.thingsboard.server.common.data.id.CustomerId;
39 53 import org.thingsboard.server.common.data.id.DashboardId;
40 54 import org.thingsboard.server.common.data.id.DeviceId;
41 55 import org.thingsboard.server.common.data.id.EntityId;
42 56 import org.thingsboard.server.common.data.page.TextPageData;
  57 +import org.thingsboard.server.common.data.page.TextPageLink;
  58 +import org.thingsboard.server.common.data.page.TimePageData;
  59 +import org.thingsboard.server.common.data.page.TimePageLink;
  60 +import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
43 61 import org.thingsboard.server.common.data.relation.EntityRelation;
  62 +import org.thingsboard.server.common.data.relation.EntityRelationInfo;
  63 +import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
  64 +import org.thingsboard.server.common.data.rule.RuleChain;
  65 +import org.thingsboard.server.common.data.rule.RuleChainMetaData;
44 66 import org.thingsboard.server.common.data.security.DeviceCredentials;
45 67 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
  68 +import org.thingsboard.server.common.data.widget.WidgetType;
  69 +import org.thingsboard.server.common.data.widget.WidgetsBundle;
46 70
47 71 import java.io.IOException;
  72 +import java.net.URI;
48 73 import java.util.Collections;
49 74 import java.util.HashMap;
50 75 import java.util.List;
... ... @@ -61,6 +86,16 @@ public class RestClient implements ClientHttpRequestInterceptor {
61 86 protected final String baseURL;
62 87 private String token;
63 88
  89 + private final static String TIME_PAGE_LINK_URL_PARAMS = "limit={limit}&startTime={startTime}&endTime={endTime}&ascOrder={ascOrder}&offset={offset}";
  90 + private final static String TEXT_PAGE_LINK_URL_PARAMS = "limit={limit}&textSearch{textSearch}&idOffset={idOffset}&textOffset{textOffset}";
  91 +
  92 + @Override
  93 + public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
  94 + HttpRequest wrapper = new HttpRequestWrapper(request);
  95 + wrapper.getHeaders().set(JWT_TOKEN_HEADER_PARAM, "Bearer " + token);
  96 + return execution.execute(wrapper, bytes);
  97 + }
  98 +
64 99 public void login(String username, String password) {
65 100 Map<String, String> loginRequest = new HashMap<>();
66 101 loginRequest.put("username", username);
... ... @@ -156,10 +191,6 @@ public class RestClient implements ClientHttpRequestInterceptor {
156 191 return saveDeviceCredentials(deviceCredentials);
157 192 }
158 193
159   - public DeviceCredentials saveDeviceCredentials(DeviceCredentials deviceCredentials) {
160   - return restTemplate.postForEntity(baseURL + "/api/device/credentials", deviceCredentials, DeviceCredentials.class).getBody();
161   - }
162   -
163 194 public Device createDevice(Device device) {
164 195 return restTemplate.postForEntity(baseURL + "/api/device", device, Device.class).getBody();
165 196 }
... ... @@ -197,7 +228,7 @@ public class RestClient implements ClientHttpRequestInterceptor {
197 228 }
198 229
199 230 public Asset assignAsset(CustomerId customerId, AssetId assetId) {
200   - return restTemplate.postForEntity(baseURL + "/api/customer/{customerId}/asset/{assetId}", null, Asset.class,
  231 + return restTemplate.postForEntity(baseURL + "/api/customer/{customerId}/asset/{assetId}", HttpEntity.EMPTY, Asset.class,
201 232 customerId.toString(), assetId.toString()).getBody();
202 233 }
203 234
... ... @@ -244,10 +275,1650 @@ public class RestClient implements ClientHttpRequestInterceptor {
244 275 return token;
245 276 }
246 277
247   - @Override
248   - public ClientHttpResponse intercept(HttpRequest request, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
249   - HttpRequest wrapper = new HttpRequestWrapper(request);
250   - wrapper.getHeaders().set(JWT_TOKEN_HEADER_PARAM, "Bearer " + token);
251   - return execution.execute(wrapper, bytes);
  278 + public Optional<AdminSettings> getAdminSettings(String key) {
  279 + try {
  280 + ResponseEntity<AdminSettings> adminSettings = restTemplate.getForEntity(baseURL + "/api/admin/settings/{key}", AdminSettings.class, key);
  281 + return Optional.ofNullable(adminSettings.getBody());
  282 + } catch (HttpClientErrorException exception) {
  283 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  284 + return Optional.empty();
  285 + } else {
  286 + throw exception;
  287 + }
  288 + }
  289 + }
  290 +
  291 + public AdminSettings saveAdminSettings(AdminSettings adminSettings) {
  292 + return restTemplate.postForEntity(baseURL + "/api/settings", adminSettings, AdminSettings.class).getBody();
  293 + }
  294 +
  295 + public void sendTestMail(AdminSettings adminSettings) {
  296 + restTemplate.postForEntity(baseURL + "/api/settings/testMail", adminSettings, AdminSettings.class);
  297 + }
  298 +
  299 + //TODO:
  300 +// @RequestMapping(value = "/securitySettings", method = RequestMethod.GET)
  301 +// public SecuritySettings getSecuritySettings() {
  302 +//
  303 +// }
  304 + //TODO:
  305 +// @RequestMapping(value = "/securitySettings", method = RequestMethod.POST)
  306 +// public SecuritySettings saveSecuritySettings(SecuritySettings securitySettings) {
  307 +//
  308 +// }
  309 + //TODO:
  310 +// @RequestMapping(value = "/updates", method = RequestMethod.GET)
  311 +// public UpdateMessage checkUpdates() {
  312 +//
  313 +// }
  314 +
  315 + public Optional<Alarm> getAlarmById(String alarmId) {
  316 + try {
  317 + ResponseEntity<Alarm> alarm = restTemplate.getForEntity(baseURL + "/api/alarm/{alarmId}", Alarm.class, alarmId);
  318 + return Optional.ofNullable(alarm.getBody());
  319 + } catch (HttpClientErrorException exception) {
  320 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  321 + return Optional.empty();
  322 + } else {
  323 + throw exception;
  324 + }
  325 + }
  326 + }
  327 +
  328 + public Optional<AlarmInfo> getAlarmInfoById(String alarmId) {
  329 + try {
  330 + ResponseEntity<AlarmInfo> alarmInfo = restTemplate.getForEntity(baseURL + "/api/alarm/info/{alarmId}", AlarmInfo.class, alarmId);
  331 + return Optional.ofNullable(alarmInfo.getBody());
  332 + } catch (HttpClientErrorException exception) {
  333 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  334 + return Optional.empty();
  335 + } else {
  336 + throw exception;
  337 + }
  338 + }
  339 + }
  340 +
  341 + public Alarm saveAlarm(Alarm alarm) {
  342 + return restTemplate.postForEntity(baseURL + "/api/alarm", alarm, Alarm.class).getBody();
  343 + }
  344 +
  345 + public void deleteAlarm(String alarmId) {
  346 + restTemplate.delete(baseURL + "/api/alarm/{alarmId}", alarmId);
  347 + }
  348 +
  349 + public void ackAlarm(String alarmId) {
  350 + restTemplate.postForObject(baseURL + "/api/alarm/{alarmId}/ack", new Object(), Object.class, alarmId);
  351 + }
  352 +
  353 + public void clearAlarm(String alarmId) {
  354 + restTemplate.postForObject(baseURL + "/api/alarm/{alarmId}/clear", new Object(), Object.class, alarmId);
  355 + }
  356 +
  357 + public TimePageData<AlarmInfo> getAlarms(String entityType, String entityId, String searchStatus, String status, TimePageLink pageLink, Boolean fetchOriginator) {
  358 + Map<String, String> params = new HashMap<>();
  359 + params.put("entityType", entityType);
  360 + params.put("entityId", entityId);
  361 + params.put("searchStatus", searchStatus);
  362 + params.put("status", status);
  363 + params.put("fetchOriginator", String.valueOf(fetchOriginator));
  364 + addPageLinkToParam(params, pageLink);
  365 +
  366 + return restTemplate.exchange(
  367 + baseURL + "/api/alarm/{entityType}/{entityId}?searchStatus={searchStatus}&status={status}&fetchOriginator={fetchOriginator}&" + TIME_PAGE_LINK_URL_PARAMS,
  368 + HttpMethod.GET,
  369 + HttpEntity.EMPTY,
  370 + new ParameterizedTypeReference<TimePageData<AlarmInfo>>() {
  371 + }, params).getBody();
  372 + }
  373 +
  374 + public Optional<AlarmSeverity> getHighestAlarmSeverity(String entityType, String entityId, String searchStatus, String status) {
  375 + Map<String, String> params = new HashMap<>();
  376 + params.put("entityType", entityType);
  377 + params.put("entityId", entityId);
  378 + params.put("searchStatus", searchStatus);
  379 + params.put("status", status);
  380 + try {
  381 + ResponseEntity<AlarmSeverity> alarmSeverity = restTemplate.getForEntity(baseURL + "/api/alarm/highestSeverity/{entityType}/{entityId}?searchStatus={searchStatus}&status={status}", AlarmSeverity.class, params);
  382 + return Optional.ofNullable(alarmSeverity.getBody());
  383 + } catch (HttpClientErrorException exception) {
  384 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  385 + return Optional.empty();
  386 + } else {
  387 + throw exception;
  388 + }
  389 + }
  390 + }
  391 +
  392 + public Optional<Asset> getAssetById(String assetId) {
  393 + try {
  394 + ResponseEntity<Asset> asset = restTemplate.getForEntity(baseURL + "/api/asset/{assetId}", Asset.class, assetId);
  395 + return Optional.ofNullable(asset.getBody());
  396 + } catch (HttpClientErrorException exception) {
  397 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  398 + return Optional.empty();
  399 + } else {
  400 + throw exception;
  401 + }
  402 + }
  403 + }
  404 +
  405 + public Asset saveAsset(Asset asset) {
  406 + return restTemplate.postForEntity(baseURL + "/api/asset", asset, Asset.class).getBody();
  407 + }
  408 +
  409 + public void deleteAsset(String assetId) {
  410 + restTemplate.delete(baseURL + "/api/asset/{assetId}", assetId);
  411 + }
  412 +
  413 + public Optional<Asset> assignAssetToCustomer(String customerId,
  414 + String assetId) {
  415 + Map<String, String> params = new HashMap<>();
  416 + params.put("customerId", customerId);
  417 + params.put("assetId", assetId);
  418 +
  419 + try {
  420 + ResponseEntity<Asset> asset = restTemplate.postForEntity(baseURL + "/api/customer/{customerId}/asset/{assetId}", null, Asset.class, params);
  421 + return Optional.ofNullable(asset.getBody());
  422 + } catch (HttpClientErrorException exception) {
  423 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  424 + return Optional.empty();
  425 + } else {
  426 + throw exception;
  427 + }
  428 + }
  429 + }
  430 +
  431 + public Optional<Asset> unassignAssetFromCustomer(String assetId) {
  432 + try {
  433 + ResponseEntity<Asset> asset = restTemplate.exchange(baseURL + "/api/customer/asset/{assetId}", HttpMethod.DELETE, HttpEntity.EMPTY, Asset.class, assetId);
  434 + return Optional.ofNullable(asset.getBody());
  435 + } catch (HttpClientErrorException exception) {
  436 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  437 + return Optional.empty();
  438 + } else {
  439 + throw exception;
  440 + }
  441 + }
  442 + }
  443 +
  444 + public Optional<Asset> assignAssetToPublicCustomer(String assetId) {
  445 + try {
  446 + ResponseEntity<Asset> asset = restTemplate.postForEntity(baseURL + "/api/customer/public/asset/{assetId}", null, Asset.class, assetId);
  447 + return Optional.ofNullable(asset.getBody());
  448 + } catch (HttpClientErrorException exception) {
  449 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  450 + return Optional.empty();
  451 + } else {
  452 + throw exception;
  453 + }
  454 + }
  455 + }
  456 +
  457 + public TextPageData<Asset> getTenantAssets(TextPageLink pageLink, String type) {
  458 + Map<String, String> params = new HashMap<>();
  459 + params.put("type", type);
  460 + addPageLinkToParam(params, pageLink);
  461 +
  462 + ResponseEntity<TextPageData<Asset>> assets = restTemplate.exchange(
  463 + baseURL + "/tenant/assets?type={type}&" + TEXT_PAGE_LINK_URL_PARAMS,
  464 + HttpMethod.GET, HttpEntity.EMPTY,
  465 + new ParameterizedTypeReference<TextPageData<Asset>>() {
  466 + },
  467 + params);
  468 + return assets.getBody();
  469 + }
  470 +
  471 + public Optional<Asset> getTenantAsset(String assetName) {
  472 + try {
  473 + ResponseEntity<Asset> asset = restTemplate.getForEntity(baseURL + "/api/tenant/assets?assetName={assetName}", Asset.class, assetName);
  474 + return Optional.ofNullable(asset.getBody());
  475 + } catch (HttpClientErrorException exception) {
  476 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  477 + return Optional.empty();
  478 + } else {
  479 + throw exception;
  480 + }
  481 + }
  482 + }
  483 +
  484 + public TextPageData<Asset> getCustomerAssets(String customerId, TextPageLink pageLink, String type) {
  485 + Map<String, String> params = new HashMap<>();
  486 + params.put("customerId", customerId);
  487 + params.put("type", type);
  488 + addPageLinkToParam(params, pageLink);
  489 +
  490 + ResponseEntity<TextPageData<Asset>> assets = restTemplate.exchange(
  491 + baseURL + "/customer/{customerId}/assets?type={type}&" + TEXT_PAGE_LINK_URL_PARAMS,
  492 + HttpMethod.GET,
  493 + HttpEntity.EMPTY,
  494 + new ParameterizedTypeReference<TextPageData<Asset>>() {
  495 + },
  496 + params);
  497 + return assets.getBody();
  498 + }
  499 +
  500 + public List<Asset> getAssetsByIds(String[] assetIds) {
  501 + return restTemplate.exchange(
  502 + baseURL + "/api/assets?assetIds={assetIds}",
  503 + HttpMethod.GET,
  504 + HttpEntity.EMPTY,
  505 + new ParameterizedTypeReference<List<Asset>>() {
  506 + },
  507 + assetIds).getBody();
  508 + }
  509 +
  510 + public List<Asset> findByQuery(AssetSearchQuery query) {
  511 + return restTemplate.exchange(
  512 + URI.create(baseURL + "/api/assets"),
  513 + HttpMethod.POST,
  514 + new HttpEntity<>(query),
  515 + new ParameterizedTypeReference<List<Asset>>() {
  516 + }).getBody();
  517 + }
  518 +
  519 + public List<EntitySubtype> getAssetTypes() {
  520 + return restTemplate.exchange(URI.create(
  521 + baseURL + "/api/asset/types"),
  522 + HttpMethod.GET,
  523 + HttpEntity.EMPTY,
  524 + new ParameterizedTypeReference<List<EntitySubtype>>() {
  525 + }).getBody();
  526 + }
  527 +
  528 + public TimePageData<AuditLog> getAuditLogsByCustomerId(String customerId, TimePageLink pageLink, String actionTypes) {
  529 + Map<String, String> params = new HashMap<>();
  530 + params.put("customerId", customerId);
  531 + params.put("actionTypes", actionTypes);
  532 + addPageLinkToParam(params, pageLink);
  533 +
  534 + ResponseEntity<TimePageData<AuditLog>> auditLog = restTemplate.exchange(
  535 + baseURL + "/audit/logs/customer/{customerId}?actionTypes={actionTypes}&" + TIME_PAGE_LINK_URL_PARAMS,
  536 + HttpMethod.GET,
  537 + HttpEntity.EMPTY,
  538 + new ParameterizedTypeReference<TimePageData<AuditLog>>() {
  539 + },
  540 + params);
  541 + return auditLog.getBody();
  542 + }
  543 +
  544 + public TimePageData<AuditLog> getAuditLogsByUserId(String userId, TimePageLink pageLink, String actionTypes) {
  545 + Map<String, String> params = new HashMap<>();
  546 + params.put("userId", userId);
  547 + params.put("actionTypes", actionTypes);
  548 + addPageLinkToParam(params, pageLink);
  549 +
  550 + ResponseEntity<TimePageData<AuditLog>> auditLog = restTemplate.exchange(
  551 + baseURL + "/audit/logs/user/{userId}?actionTypes={actionTypes}&" + TIME_PAGE_LINK_URL_PARAMS,
  552 + HttpMethod.GET,
  553 + HttpEntity.EMPTY,
  554 + new ParameterizedTypeReference<TimePageData<AuditLog>>() {
  555 + },
  556 + params);
  557 + return auditLog.getBody();
  558 + }
  559 +
  560 + public TimePageData<AuditLog> getAuditLogsByEntityId(String entityType, String entityId, String actionTypes, TimePageLink pageLink) {
  561 + Map<String, String> params = new HashMap<>();
  562 + params.put("entityType", entityType);
  563 + params.put("entityId", entityId);
  564 + params.put("actionTypes", actionTypes);
  565 + addPageLinkToParam(params, pageLink);
  566 +
  567 + ResponseEntity<TimePageData<AuditLog>> auditLog = restTemplate.exchange(
  568 + baseURL + "/audit/logs/entity/{entityType}/{entityId}?actionTypes={actionTypes}&" + TIME_PAGE_LINK_URL_PARAMS,
  569 + HttpMethod.GET,
  570 + HttpEntity.EMPTY,
  571 + new ParameterizedTypeReference<TimePageData<AuditLog>>() {
  572 + },
  573 + params);
  574 + return auditLog.getBody();
  575 + }
  576 +
  577 + public TimePageData<AuditLog> getAuditLogs(TimePageLink pageLink, String actionTypes) {
  578 + Map<String, String> params = new HashMap<>();
  579 + params.put("actionTypes", actionTypes);
  580 + addPageLinkToParam(params, pageLink);
  581 +
  582 + ResponseEntity<TimePageData<AuditLog>> auditLog = restTemplate.exchange(
  583 + baseURL + "/audit/logs?actionTypes={actionTypes}&" + TIME_PAGE_LINK_URL_PARAMS,
  584 + HttpMethod.GET,
  585 + HttpEntity.EMPTY,
  586 + new ParameterizedTypeReference<TimePageData<AuditLog>>() {
  587 + },
  588 + params);
  589 + return auditLog.getBody();
  590 + }
  591 +
  592 + public Optional<User> getUser() {
  593 + ResponseEntity<User> user = restTemplate.getForEntity(baseURL + "/auth/user", User.class);
  594 + return Optional.ofNullable(user.getBody());
  595 + }
  596 +
  597 + public void logout() {
  598 + restTemplate.exchange(URI.create(baseURL + "/auth/logout"), HttpMethod.POST, HttpEntity.EMPTY, Object.class);
  599 + }
  600 +
  601 + public void changePassword(JsonNode changePasswordRequest) {
  602 + restTemplate.exchange(URI.create(baseURL + "/auth/changePassword"), HttpMethod.POST, new HttpEntity<>(changePasswordRequest), Object.class);
  603 + }
  604 +
  605 + //TODO:
  606 +// @RequestMapping(value = "/noauth/userPasswordPolicy", method = RequestMethod.GET)
  607 +// public UserPasswordPolicy getUserPasswordPolicy() {
  608 +//
  609 +// }
  610 +
  611 +
  612 + public ResponseEntity<String> checkActivateToken(String activateToken) {
  613 + return restTemplate.getForEntity(baseURL + "/noauth/activate?activateToken={activateToken}", String.class, activateToken);
  614 + }
  615 +
  616 + public void requestResetPasswordByEmail(JsonNode resetPasswordByEmailRequest) {
  617 + restTemplate.exchange(URI.create(baseURL + "/noauth/resetPasswordByEmail"), HttpMethod.POST, new HttpEntity<>(resetPasswordByEmailRequest), Object.class);
  618 + }
  619 +
  620 + public ResponseEntity<String> checkResetToken(String resetToken) {
  621 + return restTemplate.getForEntity(baseURL + "noauth/resetPassword?resetToken={resetToken}", String.class, resetToken);
  622 + }
  623 +
  624 + public Optional<JsonNode> activateUser(JsonNode activateRequest) {
  625 + try {
  626 + ResponseEntity<JsonNode> jsonNode = restTemplate.postForEntity(baseURL + "/noauth/activate", activateRequest, JsonNode.class);
  627 + return Optional.ofNullable(jsonNode.getBody());
  628 + } catch (HttpClientErrorException exception) {
  629 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  630 + return Optional.empty();
  631 + } else {
  632 + throw exception;
  633 + }
  634 + }
  635 + }
  636 +
  637 + public Optional<JsonNode> resetPassword(JsonNode resetPasswordRequest) {
  638 + try {
  639 + ResponseEntity<JsonNode> jsonNode = restTemplate.postForEntity(baseURL + "/noauth/resetPassword", resetPasswordRequest, JsonNode.class);
  640 + return Optional.ofNullable(jsonNode.getBody());
  641 + } catch (HttpClientErrorException exception) {
  642 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  643 + return Optional.empty();
  644 + } else {
  645 + throw exception;
  646 + }
  647 + }
  648 + }
  649 +
  650 + public Optional<ComponentDescriptor> getComponentDescriptorByClazz(String componentDescriptorClazz) {
  651 + try {
  652 + ResponseEntity<ComponentDescriptor> componentDescriptor = restTemplate.getForEntity(baseURL + "/component/{componentDescriptorClazz}", ComponentDescriptor.class);
  653 + return Optional.ofNullable(componentDescriptor.getBody());
  654 + } catch (HttpClientErrorException exception) {
  655 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  656 + return Optional.empty();
  657 + } else {
  658 + throw exception;
  659 + }
  660 + }
  661 + }
  662 +
  663 + public List<ComponentDescriptor> getComponentDescriptorsByType(String componentType) {
  664 + return restTemplate.exchange(
  665 + baseURL + "/components?componentType={componentType}",
  666 + HttpMethod.GET, HttpEntity.EMPTY,
  667 + new ParameterizedTypeReference<List<ComponentDescriptor>>() {
  668 + },
  669 + componentType).getBody();
  670 + }
  671 +
  672 + public List<ComponentDescriptor> getComponentDescriptorsByTypes(String[] componentTypes) {
  673 + return restTemplate.exchange(
  674 + baseURL + "/components?componentTypes={componentTypes}",
  675 + HttpMethod.GET,
  676 + HttpEntity.EMPTY,
  677 + new ParameterizedTypeReference<List<ComponentDescriptor>>() {
  678 + },
  679 + componentTypes).getBody();
  680 + }
  681 +
  682 + public Optional<Customer> getCustomerById(String customerId) {
  683 + try {
  684 + ResponseEntity<Customer> customer = restTemplate.getForEntity(baseURL + "/customer/{customerId}", Customer.class, customerId);
  685 + return Optional.ofNullable(customer.getBody());
  686 + } catch (HttpClientErrorException exception) {
  687 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  688 + return Optional.empty();
  689 + } else {
  690 + throw exception;
  691 + }
  692 + }
  693 + }
  694 +
  695 + public Optional<JsonNode> getShortCustomerInfoById(String customerId) {
  696 + try {
  697 + ResponseEntity<JsonNode> customerInfo = restTemplate.getForEntity(baseURL + "/customer/{customerId}/shortInfo", JsonNode.class, customerId);
  698 + return Optional.ofNullable(customerInfo.getBody());
  699 + } catch (HttpClientErrorException exception) {
  700 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  701 + return Optional.empty();
  702 + } else {
  703 + throw exception;
  704 + }
  705 + }
  706 + }
  707 +
  708 + public String getCustomerTitleById(String customerId) {
  709 + return restTemplate.getForObject(baseURL + "/customer/{customerId}/title", String.class, customerId);
  710 + }
  711 +
  712 + public Customer saveCustomer(Customer customer) {
  713 + return restTemplate.postForEntity(baseURL + "/customer", customer, Customer.class).getBody();
  714 + }
  715 +
  716 + public void deleteCustomer(String customerId) {
  717 + restTemplate.delete(baseURL + "/customer/{customerId}", customerId);
  718 + }
  719 +
  720 + public TextPageData<Customer> getCustomers(TextPageLink pageLink) {
  721 + Map<String, String> params = new HashMap<>();
  722 + addPageLinkToParam(params, pageLink);
  723 +
  724 + ResponseEntity<TextPageData<Customer>> customer = restTemplate.exchange(
  725 + baseURL + "/customers?" + TEXT_PAGE_LINK_URL_PARAMS,
  726 + HttpMethod.GET,
  727 + HttpEntity.EMPTY,
  728 + new ParameterizedTypeReference<TextPageData<Customer>>() {
  729 + },
  730 + params);
  731 + return customer.getBody();
  732 + }
  733 +
  734 + public Optional<Customer> getTenantCustomer(String customerTitle) {
  735 + try {
  736 + ResponseEntity<Customer> customer = restTemplate.getForEntity(baseURL + "/tenant/customers?customerTitle={customerTitle}", Customer.class, customerTitle);
  737 + return Optional.ofNullable(customer.getBody());
  738 + } catch (HttpClientErrorException exception) {
  739 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  740 + return Optional.empty();
  741 + } else {
  742 + throw exception;
  743 + }
  744 + }
  745 + }
  746 +
  747 + public Long getServerTime() {
  748 + return restTemplate.getForObject(baseURL + "/dashboard/serverTime", Long.class);
  749 + }
  750 +
  751 + public Long getMaxDatapointsLimit() {
  752 + return restTemplate.getForObject(baseURL + "/dashboard/maxDatapointsLimit", Long.class);
  753 + }
  754 +
  755 + public Optional<DashboardInfo> getDashboardInfoById(String dashboardId) {
  756 + try {
  757 + ResponseEntity<DashboardInfo> dashboardInfo = restTemplate.getForEntity(baseURL + "/dashboard/info/{dashboardId}", DashboardInfo.class, dashboardId);
  758 + return Optional.ofNullable(dashboardInfo.getBody());
  759 + } catch (HttpClientErrorException exception) {
  760 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  761 + return Optional.empty();
  762 + } else {
  763 + throw exception;
  764 + }
  765 + }
  766 + }
  767 +
  768 + public Optional<Dashboard> getDashboardById(String dashboardId) {
  769 + try {
  770 + ResponseEntity<Dashboard> dashboard = restTemplate.getForEntity(baseURL + "/dashboard/{dashboardId}", Dashboard.class, dashboardId);
  771 + return Optional.ofNullable(dashboard.getBody());
  772 + } catch (HttpClientErrorException exception) {
  773 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  774 + return Optional.empty();
  775 + } else {
  776 + throw exception;
  777 + }
  778 + }
  779 + }
  780 +
  781 + public Dashboard saveDashboard(Dashboard dashboard) {
  782 + return restTemplate.postForEntity(baseURL + "/dashboard", dashboard, Dashboard.class).getBody();
  783 + }
  784 +
  785 + public void deleteDashboard(String dashboardId) {
  786 + restTemplate.delete(baseURL + "/dashboard/{dashboardId}", dashboardId);
  787 + }
  788 +
  789 + public Optional<Dashboard> assignDashboardToCustomer(String customerId, String dashboardId) {
  790 + try {
  791 + ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/customer/{customerId}/dashboard/{dashboardId}", null, Dashboard.class, customerId, dashboardId);
  792 + return Optional.ofNullable(dashboard.getBody());
  793 + } catch (HttpClientErrorException exception) {
  794 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  795 + return Optional.empty();
  796 + } else {
  797 + throw exception;
  798 + }
  799 + }
  800 + }
  801 +
  802 + public Optional<Dashboard> unassignDashboardFromCustomer(String customerId, String dashboardId) {
  803 + try {
  804 + ResponseEntity<Dashboard> dashboard = restTemplate.exchange(baseURL + "/customer/{customerId}/dashboard/{dashboardId}", HttpMethod.DELETE, HttpEntity.EMPTY, Dashboard.class, customerId, dashboardId);
  805 + return Optional.ofNullable(dashboard.getBody());
  806 + } catch (HttpClientErrorException exception) {
  807 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  808 + return Optional.empty();
  809 + } else {
  810 + throw exception;
  811 + }
  812 + }
  813 + }
  814 +
  815 + public Optional<Dashboard> updateDashboardCustomers(String dashboardId, String[] customerIds) {
  816 + try {
  817 + ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/dashboard/{dashboardId}/customers", customerIds, Dashboard.class, dashboardId);
  818 + return Optional.ofNullable(dashboard.getBody());
  819 + } catch (HttpClientErrorException exception) {
  820 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  821 + return Optional.empty();
  822 + } else {
  823 + throw exception;
  824 + }
  825 + }
  826 + }
  827 +
  828 + public Optional<Dashboard> addDashboardCustomers(String dashboardId, String[] customerIds) {
  829 + try {
  830 + ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/dashboard/{dashboardId}/customers/add", customerIds, Dashboard.class, dashboardId);
  831 + return Optional.ofNullable(dashboard.getBody());
  832 + } catch (HttpClientErrorException exception) {
  833 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  834 + return Optional.empty();
  835 + } else {
  836 + throw exception;
  837 + }
  838 + }
  839 + }
  840 +
  841 + public Optional<Dashboard> removeDashboardCustomers(String dashboardId, String[] customerIds) {
  842 + try {
  843 + ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/dashboard/{dashboardId}/customers/remove", customerIds, Dashboard.class, dashboardId);
  844 + return Optional.ofNullable(dashboard.getBody());
  845 + } catch (HttpClientErrorException exception) {
  846 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  847 + return Optional.empty();
  848 + } else {
  849 + throw exception;
  850 + }
  851 + }
  852 + }
  853 +
  854 + public Optional<Dashboard> assignDashboardToPublicCustomer(String dashboardId) {
  855 + try {
  856 + ResponseEntity<Dashboard> dashboard = restTemplate.postForEntity(baseURL + "/customer/public/dashboard/{dashboardId}", null, Dashboard.class, dashboardId);
  857 + return Optional.ofNullable(dashboard.getBody());
  858 + } catch (HttpClientErrorException exception) {
  859 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  860 + return Optional.empty();
  861 + } else {
  862 + throw exception;
  863 + }
  864 + }
  865 + }
  866 +
  867 + public Optional<Dashboard> unassignDashboardFromPublicCustomer(String dashboardId) {
  868 + try {
  869 + ResponseEntity<Dashboard> dashboard = restTemplate.exchange(baseURL + "/customer/public/dashboard/{dashboardId}", HttpMethod.DELETE, HttpEntity.EMPTY, Dashboard.class, dashboardId);
  870 + return Optional.ofNullable(dashboard.getBody());
  871 + } catch (HttpClientErrorException exception) {
  872 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  873 + return Optional.empty();
  874 + } else {
  875 + throw exception;
  876 + }
  877 + }
  878 + }
  879 +
  880 + public TextPageData<DashboardInfo> getTenantDashboards(String tenantId, TextPageLink pageLink) {
  881 + Map<String, String> params = new HashMap<>();
  882 + params.put("tenantId", tenantId);
  883 + addPageLinkToParam(params, pageLink);
  884 + return restTemplate.exchange(
  885 + baseURL + "/tenant/{tenantId}/dashboards?" + TEXT_PAGE_LINK_URL_PARAMS,
  886 + HttpMethod.GET, HttpEntity.EMPTY,
  887 + new ParameterizedTypeReference<TextPageData<DashboardInfo>>() {
  888 + },
  889 + params
  890 + ).getBody();
  891 + }
  892 +
  893 + public TextPageData<DashboardInfo> getTenantDashboards(TextPageLink pageLink) {
  894 + Map<String, String> params = new HashMap<>();
  895 + addPageLinkToParam(params, pageLink);
  896 + return restTemplate.exchange(
  897 + baseURL + "/tenant/dashboards?" + TEXT_PAGE_LINK_URL_PARAMS,
  898 + HttpMethod.GET, HttpEntity.EMPTY,
  899 + new ParameterizedTypeReference<TextPageData<DashboardInfo>>() {
  900 + },
  901 + params
  902 + ).getBody();
  903 + }
  904 +
  905 + public TimePageData<DashboardInfo> getCustomerDashboards(String customerId, TimePageLink pageLink) {
  906 + Map<String, String> params = new HashMap<>();
  907 + params.put("customerId", customerId);
  908 + addPageLinkToParam(params, pageLink);
  909 + return restTemplate.exchange(
  910 + baseURL + "/customer/{customerId}/dashboards?" + TEXT_PAGE_LINK_URL_PARAMS,
  911 + HttpMethod.GET, HttpEntity.EMPTY,
  912 + new ParameterizedTypeReference<TimePageData<DashboardInfo>>() {
  913 + },
  914 + params
  915 + ).getBody();
  916 + }
  917 +
  918 + public Optional<Device> getDeviceById(String deviceId) {
  919 + try {
  920 + ResponseEntity<Device> device = restTemplate.getForEntity(baseURL + "/device/{deviceId}", Device.class, deviceId);
  921 + return Optional.ofNullable(device.getBody());
  922 + } catch (HttpClientErrorException exception) {
  923 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  924 + return Optional.empty();
  925 + } else {
  926 + throw exception;
  927 + }
  928 + }
  929 + }
  930 +
  931 + public Device saveDevice(Device device) {
  932 + return restTemplate.postForEntity(baseURL + "/device", device, Device.class).getBody();
  933 + }
  934 +
  935 + public void deleteDevice(String deviceId) {
  936 + restTemplate.delete(baseURL + "/device/{deviceId}", deviceId);
  937 + }
  938 +
  939 + public Optional<Device> assignDeviceToCustomer(String customerId, String deviceId) {
  940 + try {
  941 + ResponseEntity<Device> device = restTemplate.postForEntity(baseURL + "/customer/{customerId}/device/{deviceId}", null, Device.class, customerId, deviceId);
  942 + return Optional.ofNullable(device.getBody());
  943 + } catch (HttpClientErrorException exception) {
  944 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  945 + return Optional.empty();
  946 + } else {
  947 + throw exception;
  948 + }
  949 + }
  950 + }
  951 +
  952 + public Optional<Device> unassignDeviceFromCustomer(String deviceId) {
  953 + try {
  954 + ResponseEntity<Device> device = restTemplate.exchange(baseURL + "/customer/device/{deviceId}", HttpMethod.DELETE, HttpEntity.EMPTY, Device.class, deviceId);
  955 + return Optional.ofNullable(device.getBody());
  956 + } catch (HttpClientErrorException exception) {
  957 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  958 + return Optional.empty();
  959 + } else {
  960 + throw exception;
  961 + }
  962 + }
  963 + }
  964 +
  965 + public Optional<Device> assignDeviceToPublicCustomer(String deviceId) {
  966 + try {
  967 + ResponseEntity<Device> device = restTemplate.postForEntity(baseURL + "/customer/public/device/{deviceId}", null, Device.class, deviceId);
  968 + return Optional.ofNullable(device.getBody());
  969 + } catch (HttpClientErrorException exception) {
  970 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  971 + return Optional.empty();
  972 + } else {
  973 + throw exception;
  974 + }
  975 + }
  976 + }
  977 +
  978 + public Optional<DeviceCredentials> getDeviceCredentialsByDeviceId(String deviceId) {
  979 + try {
  980 + ResponseEntity<DeviceCredentials> deviceCredentials = restTemplate.getForEntity(baseURL + "/device/{deviceId}/credentials", DeviceCredentials.class, deviceId);
  981 + return Optional.ofNullable(deviceCredentials.getBody());
  982 + } catch (HttpClientErrorException exception) {
  983 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  984 + return Optional.empty();
  985 + } else {
  986 + throw exception;
  987 + }
  988 + }
  989 + }
  990 +
  991 + public DeviceCredentials saveDeviceCredentials(DeviceCredentials deviceCredentials) {
  992 + return restTemplate.postForEntity(baseURL + "/api/device/credentials", deviceCredentials, DeviceCredentials.class).getBody();
  993 + }
  994 +
  995 + public TextPageData<Device> getTenantDevices(String type, TextPageLink pageLink) {
  996 + Map<String, String> params = new HashMap<>();
  997 + params.put("type", type);
  998 + addPageLinkToParam(params, pageLink);
  999 + return restTemplate.exchange(
  1000 + baseURL + "/tenant/devices?type={type}&" + TEXT_PAGE_LINK_URL_PARAMS,
  1001 + HttpMethod.GET, HttpEntity.EMPTY,
  1002 + new ParameterizedTypeReference<TextPageData<Device>>() {
  1003 + },
  1004 + params)
  1005 + .getBody();
  1006 + }
  1007 +
  1008 + public Optional<Device> getTenantDevice(String deviceName) {
  1009 + try {
  1010 + ResponseEntity<Device> device = restTemplate.getForEntity(baseURL + "/tenant/devices?deviceName={deviceName}", Device.class, deviceName);
  1011 + return Optional.ofNullable(device.getBody());
  1012 + } catch (HttpClientErrorException exception) {
  1013 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1014 + return Optional.empty();
  1015 + } else {
  1016 + throw exception;
  1017 + }
  1018 + }
  1019 + }
  1020 +
  1021 + public TextPageData<Device> getCustomerDevices(String customerId, String type, TextPageLink pageLink) {
  1022 + Map<String, String> params = new HashMap<>();
  1023 + params.put("customerId", customerId);
  1024 + params.put("type", type);
  1025 + addPageLinkToParam(params, pageLink);
  1026 + return restTemplate.exchange(
  1027 + baseURL + "/customer/{customerId}/devices?type={type}&" + TEXT_PAGE_LINK_URL_PARAMS,
  1028 + HttpMethod.GET, HttpEntity.EMPTY,
  1029 + new ParameterizedTypeReference<TextPageData<Device>>() {
  1030 + },
  1031 + params)
  1032 + .getBody();
  1033 + }
  1034 +
  1035 + public List<Device> getDevicesByIds(String[] deviceIds) {
  1036 + return restTemplate.exchange(baseURL + "/devices?deviceIds={deviceIds}",
  1037 + HttpMethod.GET,
  1038 + HttpEntity.EMPTY, new ParameterizedTypeReference<List<Device>>() {
  1039 + },
  1040 + deviceIds).getBody();
  1041 + }
  1042 +
  1043 + public List<Device> findByQuery(DeviceSearchQuery query) {
  1044 + return restTemplate.exchange(
  1045 + baseURL + "/devices",
  1046 + HttpMethod.POST,
  1047 + new HttpEntity<>(query),
  1048 + new ParameterizedTypeReference<List<Device>>() {
  1049 + }).getBody();
  1050 + }
  1051 +
  1052 + public List<EntitySubtype> getDeviceTypes() {
  1053 + return restTemplate.exchange(
  1054 + baseURL + "/devices",
  1055 + HttpMethod.GET,
  1056 + HttpEntity.EMPTY,
  1057 + new ParameterizedTypeReference<List<EntitySubtype>>() {
  1058 + }).getBody();
  1059 + }
  1060 +
  1061 + //TODO: ClaimRequest class
  1062 +// @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.POST)
  1063 +// public DeferredResult<ResponseEntity> claimDevice(String deviceName, ClaimRequest claimRequest) {
  1064 +// return restTemplate.exchange(baseURL + "/customer/device/{deviceName}/claim", HttpMethod.POST, new HttpEntity<>(claimRequest), new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1065 +// }, deviceName).getBody();
  1066 +// }
  1067 +
  1068 + public DeferredResult<ResponseEntity> reClaimDevice(String deviceName) {
  1069 + return restTemplate.exchange(
  1070 + baseURL + "/customer/device/{deviceName}/claim",
  1071 + HttpMethod.DELETE,
  1072 + HttpEntity.EMPTY,
  1073 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1074 + },
  1075 + deviceName).getBody();
  1076 + }
  1077 +
  1078 + public void saveRelation(EntityRelation relation) {
  1079 + restTemplate.postForEntity(baseURL + "/relation", relation, Object.class);
  1080 + }
  1081 +
  1082 + public void deleteRelation(String fromId, String fromType, String relationType, String relationTypeGroup, String toId, String toType) {
  1083 + Map<String, String> params = new HashMap<>();
  1084 + params.put("fromId", fromId);
  1085 + params.put("fromType", fromType);
  1086 + params.put("relationType", relationType);
  1087 + params.put("relationTypeGroup", relationTypeGroup);
  1088 + params.put("toId", toId);
  1089 + params.put("toType", toType);
  1090 + restTemplate.delete(baseURL + "/relation?fromId={fromId}&fromType={fromType}&relationType={relationType}&relationTypeGroup={relationTypeGroup}&toId={toId}&toType={toType}", params);
  1091 + }
  1092 +
  1093 + public void deleteRelations(String entityId, String entityType) {
  1094 + restTemplate.delete(baseURL + "/relations?entityId={entityId}&entityType={entityType}", entityId, entityType);
  1095 + }
  1096 +
  1097 + public Optional<EntityRelation> getRelation(String fromId, String fromType, String relationType, String relationTypeGroup, String toId, String toType) {
  1098 + Map<String, String> params = new HashMap<>();
  1099 + params.put("fromId", fromId);
  1100 + params.put("fromType", fromType);
  1101 + params.put("relationType", relationType);
  1102 + params.put("relationTypeGroup", relationTypeGroup);
  1103 + params.put("toId", toId);
  1104 + params.put("toType", toType);
  1105 +
  1106 + try {
  1107 + ResponseEntity<EntityRelation> entityRelation = restTemplate.getForEntity(
  1108 + baseURL + "/relation?fromId={fromId}&fromType={fromType}&relationType={relationType}&relationTypeGroup={relationTypeGroup}&toId={toId}&toType={toType}",
  1109 + EntityRelation.class,
  1110 + params);
  1111 + return Optional.ofNullable(entityRelation.getBody());
  1112 + } catch (HttpClientErrorException exception) {
  1113 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1114 + return Optional.empty();
  1115 + } else {
  1116 + throw exception;
  1117 + }
  1118 + }
  1119 + }
  1120 +
  1121 + public List<EntityRelation> findByFrom(String fromId, String fromType, String relationTypeGroup) {
  1122 + Map<String, String> params = new HashMap<>();
  1123 + params.put("fromId", fromId);
  1124 + params.put("fromType", fromType);
  1125 + params.put("relationTypeGroup", relationTypeGroup);
  1126 +
  1127 + return restTemplate.exchange(
  1128 + baseURL + "/relations?fromId={fromId}&fromType={fromType}&relationTypeGroup={relationTypeGroup}",
  1129 + HttpMethod.GET,
  1130 + HttpEntity.EMPTY,
  1131 + new ParameterizedTypeReference<List<EntityRelation>>() {
  1132 + },
  1133 + params).getBody();
  1134 + }
  1135 +
  1136 + public List<EntityRelationInfo> findInfoByFrom(String fromId, String fromType, String relationTypeGroup) {
  1137 +
  1138 + Map<String, String> params = new HashMap<>();
  1139 + params.put("fromId", fromId);
  1140 + params.put("fromType", fromType);
  1141 + params.put("relationTypeGroup", relationTypeGroup);
  1142 +
  1143 + return restTemplate.exchange(
  1144 + baseURL + "/relations/info?fromId={fromId}&fromType={fromType}&relationTypeGroup={relationTypeGroup}",
  1145 + HttpMethod.GET,
  1146 + HttpEntity.EMPTY,
  1147 + new ParameterizedTypeReference<List<EntityRelationInfo>>() {
  1148 + },
  1149 + params).getBody();
  1150 + }
  1151 +
  1152 + public List<EntityRelation> findByFrom(String fromId, String fromType, String relationType, String relationTypeGroup) {
  1153 + Map<String, String> params = new HashMap<>();
  1154 + params.put("fromId", fromId);
  1155 + params.put("fromType", fromType);
  1156 + params.put("relationType", relationType);
  1157 + params.put("relationTypeGroup", relationTypeGroup);
  1158 +
  1159 + return restTemplate.exchange(
  1160 + baseURL + "/relations?fromId={fromId}&fromType={fromType}&relationType={relationType}&relationTypeGroup={relationTypeGroup}",
  1161 + HttpMethod.GET,
  1162 + HttpEntity.EMPTY,
  1163 + new ParameterizedTypeReference<List<EntityRelation>>() {
  1164 + },
  1165 + params).getBody();
  1166 + }
  1167 +
  1168 + public List<EntityRelation> findByTo(String toId, String toType, String relationTypeGroup) {
  1169 + Map<String, String> params = new HashMap<>();
  1170 + params.put("toId", toId);
  1171 + params.put("toType", toType);
  1172 + params.put("relationTypeGroup", relationTypeGroup);
  1173 +
  1174 + return restTemplate.exchange(
  1175 + baseURL + "/relations?toId={toId}&toType={toType}&relationTypeGroup={relationTypeGroup}",
  1176 + HttpMethod.GET,
  1177 + HttpEntity.EMPTY,
  1178 + new ParameterizedTypeReference<List<EntityRelation>>() {
  1179 + },
  1180 + params).getBody();
  1181 + }
  1182 +
  1183 + public List<EntityRelationInfo> findInfoByTo(String toId, String toType, String relationTypeGroup) {
  1184 + Map<String, String> params = new HashMap<>();
  1185 + params.put("toId", toId);
  1186 + params.put("toType", toType);
  1187 + params.put("relationTypeGroup", relationTypeGroup);
  1188 +
  1189 + return restTemplate.exchange(
  1190 + baseURL + "/relations?toId={toId}&toType={toType}&relationTypeGroup={relationTypeGroup}",
  1191 + HttpMethod.GET,
  1192 + HttpEntity.EMPTY,
  1193 + new ParameterizedTypeReference<List<EntityRelationInfo>>() {
  1194 + },
  1195 + params).getBody();
  1196 + }
  1197 +
  1198 + public List<EntityRelation> findByTo(String toId, String toType, String relationType, String relationTypeGroup) {
  1199 + Map<String, String> params = new HashMap<>();
  1200 + params.put("toId", toId);
  1201 + params.put("toType", toType);
  1202 + params.put("relationType", relationType);
  1203 + params.put("relationTypeGroup", relationTypeGroup);
  1204 +
  1205 + return restTemplate.exchange(
  1206 + baseURL + "/relations?toId={toId}&toType={toType}&relationType={relationType}&relationTypeGroup={relationTypeGroup}",
  1207 + HttpMethod.GET,
  1208 + HttpEntity.EMPTY,
  1209 + new ParameterizedTypeReference<List<EntityRelation>>() {
  1210 + },
  1211 + params).getBody();
  1212 + }
  1213 +
  1214 + public List<EntityRelation> findByQuery(EntityRelationsQuery query) {
  1215 + return restTemplate.exchange(
  1216 + baseURL + "/relations",
  1217 + HttpMethod.POST,
  1218 + new HttpEntity<>(query),
  1219 + new ParameterizedTypeReference<List<EntityRelation>>() {
  1220 + }).getBody();
  1221 + }
  1222 +
  1223 + public List<EntityRelationInfo> findInfoByQuery(EntityRelationsQuery query) {
  1224 + return restTemplate.exchange(
  1225 + baseURL + "/relations",
  1226 + HttpMethod.POST,
  1227 + new HttpEntity<>(query),
  1228 + new ParameterizedTypeReference<List<EntityRelationInfo>>() {
  1229 + }).getBody();
  1230 + }
  1231 +
  1232 + public Optional<EntityView> getEntityViewById(String entityViewId) {
  1233 + try {
  1234 + ResponseEntity<EntityView> entityView = restTemplate.getForEntity(baseURL + "/entityView/{entityViewId}", EntityView.class, entityViewId);
  1235 + return Optional.ofNullable(entityView.getBody());
  1236 + } catch (HttpClientErrorException exception) {
  1237 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1238 + return Optional.empty();
  1239 + } else {
  1240 + throw exception;
  1241 + }
  1242 + }
  1243 + }
  1244 +
  1245 + public EntityView saveEntityView(EntityView entityView) {
  1246 + return restTemplate.postForEntity(baseURL + "entityView", entityView, EntityView.class).getBody();
  1247 + }
  1248 +
  1249 + public void deleteEntityView(String entityViewId) {
  1250 + restTemplate.delete(baseURL + "/entityView/{entityViewId}", entityViewId);
  1251 + }
  1252 +
  1253 + public Optional<EntityView> getTenantEntityView(String entityViewName) {
  1254 + try {
  1255 + ResponseEntity<EntityView> entityView = restTemplate.getForEntity(baseURL + "/tenant/entityViews?entityViewName={entityViewName}", EntityView.class, entityViewName);
  1256 + return Optional.ofNullable(entityView.getBody());
  1257 + } catch (HttpClientErrorException exception) {
  1258 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1259 + return Optional.empty();
  1260 + } else {
  1261 + throw exception;
  1262 + }
  1263 + }
  1264 + }
  1265 +
  1266 + public Optional<EntityView> assignEntityViewToCustomer(String customerId, String entityViewId) {
  1267 + try {
  1268 + ResponseEntity<EntityView> entityView = restTemplate.postForEntity(baseURL + "/customer/{customerId}/entityView/{entityViewId}", null, EntityView.class, customerId, entityViewId);
  1269 + return Optional.ofNullable(entityView.getBody());
  1270 + } catch (HttpClientErrorException exception) {
  1271 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1272 + return Optional.empty();
  1273 + } else {
  1274 + throw exception;
  1275 + }
  1276 + }
  1277 + }
  1278 +
  1279 + public Optional<EntityView> unassignEntityViewFromCustomer(String entityViewId) {
  1280 + try {
  1281 + ResponseEntity<EntityView> entityView = restTemplate.exchange(
  1282 + baseURL + "/customer/entityView/{entityViewId}",
  1283 + HttpMethod.DELETE,
  1284 + HttpEntity.EMPTY,
  1285 + EntityView.class, entityViewId);
  1286 + return Optional.ofNullable(entityView.getBody());
  1287 + } catch (HttpClientErrorException exception) {
  1288 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1289 + return Optional.empty();
  1290 + } else {
  1291 + throw exception;
  1292 + }
  1293 + }
  1294 + }
  1295 +
  1296 + public TextPageData<EntityView> getCustomerEntityViews(String customerId, String type, TextPageLink pageLink) {
  1297 + Map<String, String> params = new HashMap<>();
  1298 + params.put("customerId", customerId);
  1299 + params.put("type", type);
  1300 + addPageLinkToParam(params, pageLink);
  1301 + return restTemplate.exchange(
  1302 + baseURL + "/customer/{customerId}/entityViews?type={type}&" + TEXT_PAGE_LINK_URL_PARAMS,
  1303 + HttpMethod.GET,
  1304 + HttpEntity.EMPTY,
  1305 + new ParameterizedTypeReference<TextPageData<EntityView>>() {
  1306 + },
  1307 + params).getBody();
  1308 + }
  1309 +
  1310 + public TextPageData<EntityView> getTenantEntityViews(String type, TextPageLink pageLink) {
  1311 + Map<String, String> params = new HashMap<>();
  1312 + params.put("type", type);
  1313 + addPageLinkToParam(params, pageLink);
  1314 + return restTemplate.exchange(
  1315 + baseURL + "/tenant/entityViews?type={type}&" + TEXT_PAGE_LINK_URL_PARAMS,
  1316 + HttpMethod.GET,
  1317 + HttpEntity.EMPTY,
  1318 + new ParameterizedTypeReference<TextPageData<EntityView>>() {
  1319 + },
  1320 + params).getBody();
  1321 + }
  1322 +
  1323 + public List<EntityView> findByQuery(EntityViewSearchQuery query) {
  1324 + return restTemplate.exchange(baseURL + "/entityViews", HttpMethod.POST, new HttpEntity<>(query), new ParameterizedTypeReference<List<EntityView>>() {
  1325 + }).getBody();
  1326 + }
  1327 +
  1328 + public List<EntitySubtype> getEntityViewTypes() {
  1329 + return restTemplate.exchange(baseURL + "/entityView/types", HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<List<EntitySubtype>>() {
  1330 + }).getBody();
  1331 + }
  1332 +
  1333 + public Optional<EntityView> assignEntityViewToPublicCustomer(String entityViewId) {
  1334 + try {
  1335 + ResponseEntity<EntityView> entityView = restTemplate.postForEntity(baseURL + "customer/public/entityView/{entityViewId}", null, EntityView.class, entityViewId);
  1336 + return Optional.ofNullable(entityView.getBody());
  1337 + } catch (HttpClientErrorException exception) {
  1338 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1339 + return Optional.empty();
  1340 + } else {
  1341 + throw exception;
  1342 + }
  1343 + }
  1344 + }
  1345 +
  1346 + public TimePageData<Event> getEvents(String entityType, String entityId, String eventType, String tenantId, TimePageLink pageLink) {
  1347 + Map<String, String> params = new HashMap<>();
  1348 + params.put("entityType", entityType);
  1349 + params.put("entityId", entityId);
  1350 + params.put("eventType", eventType);
  1351 + params.put("tenantId", tenantId);
  1352 + addPageLinkToParam(params, pageLink);
  1353 +
  1354 + return restTemplate.exchange(
  1355 + baseURL + "/events/{entityType}/{entityId}/{eventType}?tenantId={tenantId}&" + TIME_PAGE_LINK_URL_PARAMS,
  1356 + HttpMethod.GET,
  1357 + HttpEntity.EMPTY,
  1358 + new ParameterizedTypeReference<TimePageData<Event>>() {
  1359 + },
  1360 + params).getBody();
  1361 + }
  1362 +
  1363 + public TimePageData<Event> getEvents(String entityType, String entityId, String tenantId, TimePageLink pageLink) {
  1364 + Map<String, String> params = new HashMap<>();
  1365 + params.put("entityType", entityType);
  1366 + params.put("entityId", entityId);
  1367 + params.put("tenantId", tenantId);
  1368 + addPageLinkToParam(params, pageLink);
  1369 +
  1370 + return restTemplate.exchange(
  1371 + baseURL + "/events/{entityType}/{entityId}?tenantId={tenantId}&" + TIME_PAGE_LINK_URL_PARAMS,
  1372 + HttpMethod.GET,
  1373 + HttpEntity.EMPTY,
  1374 + new ParameterizedTypeReference<TimePageData<Event>>() {
  1375 + },
  1376 + params).getBody();
  1377 + }
  1378 +
  1379 + public DeferredResult<ResponseEntity> handleOneWayDeviceRPCRequest(String deviceId, String requestBody) {
  1380 + return restTemplate.exchange(
  1381 + baseURL + "/oneway/{deviceId}",
  1382 + HttpMethod.POST,
  1383 + new HttpEntity<>(requestBody),
  1384 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1385 + },
  1386 + deviceId).getBody();
  1387 + }
  1388 +
  1389 + public DeferredResult<ResponseEntity> handleTwoWayDeviceRPCRequest(String deviceId, String requestBody) {
  1390 + return restTemplate.exchange(
  1391 + baseURL + "/twoway/{deviceId}",
  1392 + HttpMethod.POST,
  1393 + new HttpEntity<>(requestBody),
  1394 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1395 + },
  1396 + deviceId).getBody();
  1397 + }
  1398 +
  1399 + public Optional<RuleChain> getRuleChainById(String ruleChainId) {
  1400 + try {
  1401 + ResponseEntity<RuleChain> ruleChain = restTemplate.getForEntity(baseURL + "/ruleChain/{ruleChainId}", RuleChain.class, ruleChainId);
  1402 + return Optional.ofNullable(ruleChain.getBody());
  1403 + } catch (HttpClientErrorException exception) {
  1404 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1405 + return Optional.empty();
  1406 + } else {
  1407 + throw exception;
  1408 + }
  1409 + }
  1410 + }
  1411 +
  1412 + public Optional<RuleChainMetaData> getRuleChainMetaData(String ruleChainId) {
  1413 + try {
  1414 + ResponseEntity<RuleChainMetaData> ruleChainMetaData = restTemplate.getForEntity(baseURL + "/ruleChain/{ruleChainId}/metadata", RuleChainMetaData.class, ruleChainId);
  1415 + return Optional.ofNullable(ruleChainMetaData.getBody());
  1416 + } catch (HttpClientErrorException exception) {
  1417 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1418 + return Optional.empty();
  1419 + } else {
  1420 + throw exception;
  1421 + }
  1422 + }
  1423 + }
  1424 +
  1425 + public RuleChain saveRuleChain(RuleChain ruleChain) {
  1426 + return restTemplate.postForEntity(baseURL + "/ruleChain", ruleChain, RuleChain.class).getBody();
  1427 + }
  1428 +
  1429 + public Optional<RuleChain> setRootRuleChain(String ruleChainId) {
  1430 + try {
  1431 + ResponseEntity<RuleChain> ruleChain = restTemplate.postForEntity(baseURL + "/ruleChain/{ruleChainId}/root", null, RuleChain.class, ruleChainId);
  1432 + return Optional.ofNullable(ruleChain.getBody());
  1433 + } catch (HttpClientErrorException exception) {
  1434 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1435 + return Optional.empty();
  1436 + } else {
  1437 + throw exception;
  1438 + }
  1439 + }
  1440 + }
  1441 +
  1442 + public RuleChainMetaData saveRuleChainMetaData(RuleChainMetaData ruleChainMetaData) {
  1443 + return restTemplate.postForEntity(baseURL + "/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class).getBody();
  1444 + }
  1445 +
  1446 + public TextPageData<RuleChain> getRuleChains(TextPageLink pageLink) {
  1447 + Map<String, String> params = new HashMap<>();
  1448 + addPageLinkToParam(params, pageLink);
  1449 + return restTemplate.exchange(
  1450 + baseURL + "/ruleChains" + TEXT_PAGE_LINK_URL_PARAMS,
  1451 + HttpMethod.GET,
  1452 + HttpEntity.EMPTY,
  1453 + new ParameterizedTypeReference<TextPageData<RuleChain>>() {
  1454 + }
  1455 + ).getBody();
  1456 + }
  1457 +
  1458 + public void deleteRuleChain(String ruleChainId) {
  1459 + restTemplate.delete(baseURL + "/ruleChain/{ruleChainId}", ruleChainId);
  1460 + }
  1461 +
  1462 + public Optional<JsonNode> getLatestRuleNodeDebugInput(String ruleNodeId) {
  1463 + try {
  1464 + ResponseEntity<JsonNode> jsonNode = restTemplate.getForEntity(baseURL + "/ruleNode/{ruleNodeId}/debugIn", JsonNode.class, ruleNodeId);
  1465 + return Optional.ofNullable(jsonNode.getBody());
  1466 + } catch (HttpClientErrorException exception) {
  1467 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1468 + return Optional.empty();
  1469 + } else {
  1470 + throw exception;
  1471 + }
  1472 + }
  1473 + }
  1474 +
  1475 + public Optional<JsonNode> testScript(JsonNode inputParams) {
  1476 + try {
  1477 + ResponseEntity<JsonNode> jsonNode = restTemplate.postForEntity(baseURL + "/ruleChain/testScript", inputParams, JsonNode.class);
  1478 + return Optional.ofNullable(jsonNode.getBody());
  1479 + } catch (HttpClientErrorException exception) {
  1480 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1481 + return Optional.empty();
  1482 + } else {
  1483 + throw exception;
  1484 + }
  1485 + }
  1486 + }
  1487 +
  1488 + public DeferredResult<ResponseEntity> getAttributeKeys(String entityType, String entityId) {
  1489 + return restTemplate.exchange(
  1490 + baseURL + "/{entityType}/{entityId}/keys/attributes",
  1491 + HttpMethod.GET,
  1492 + HttpEntity.EMPTY,
  1493 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1494 + },
  1495 + entityType,
  1496 + entityId).getBody();
  1497 + }
  1498 +
  1499 + public DeferredResult<ResponseEntity> getAttributeKeysByScope(String entityType, String entityId, String scope) {
  1500 + return restTemplate.exchange(
  1501 + baseURL + "/{entityType}/{entityId}/keys/attributes/{scope}",
  1502 + HttpMethod.GET,
  1503 + HttpEntity.EMPTY,
  1504 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1505 + },
  1506 + entityType,
  1507 + entityId,
  1508 + scope).getBody();
  1509 + }
  1510 +
  1511 + public DeferredResult<ResponseEntity> getAttributesResponseEntity(String entityType, String entityId, String keys) {
  1512 + return restTemplate.exchange(
  1513 + baseURL + "/{entityType}/{entityId}/values/attributes?keys={keys}",
  1514 + HttpMethod.GET,
  1515 + HttpEntity.EMPTY,
  1516 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1517 + },
  1518 + entityType,
  1519 + entityId,
  1520 + keys).getBody();
  1521 + }
  1522 +
  1523 + public DeferredResult<ResponseEntity> getAttributesByScope(String entityType, String entityId, String scope, String keys) {
  1524 + return restTemplate.exchange(
  1525 + baseURL + "/{entityType}/{entityId}/values/attributes/{scope}?keys={keys}",
  1526 + HttpMethod.GET,
  1527 + HttpEntity.EMPTY,
  1528 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1529 + },
  1530 + entityType,
  1531 + entityId,
  1532 + scope,
  1533 + keys).getBody();
  1534 + }
  1535 +
  1536 + public DeferredResult<ResponseEntity> getTimeseriesKeys(String entityType, String entityId) {
  1537 + return restTemplate.exchange(
  1538 + baseURL + "/{entityType}/{entityId}/keys/timeseries",
  1539 + HttpMethod.GET,
  1540 + HttpEntity.EMPTY,
  1541 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1542 + },
  1543 + entityType,
  1544 + entityId).getBody();
  1545 + }
  1546 +
  1547 + public DeferredResult<ResponseEntity> getLatestTimeseries(String entityType, String entityId, String keys) {
  1548 + return restTemplate.exchange(
  1549 + baseURL + "/{entityType}/{entityId}/values/timeseries?keys={keys}",
  1550 + HttpMethod.GET,
  1551 + HttpEntity.EMPTY,
  1552 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1553 + },
  1554 + entityType,
  1555 + entityId,
  1556 + keys).getBody();
  1557 + }
  1558 +
  1559 +
  1560 + public DeferredResult<ResponseEntity> getTimeseries(String entityType, String entityId, String keys, Long startTs, Long endTs, Long interval, Integer limit, String agg) {
  1561 + Map<String, String> params = new HashMap<>();
  1562 + params.put("entityType", entityType);
  1563 + params.put("entityId", entityId);
  1564 + params.put("keys", keys);
  1565 + params.put("startTs", startTs.toString());
  1566 + params.put("endTs", endTs.toString());
  1567 + params.put("interval", interval == null ? "0" : interval.toString());
  1568 + params.put("limit", limit == null ? "100" : limit.toString());
  1569 + params.put("agg", agg == null ? "NONE" : agg);
  1570 +
  1571 + return restTemplate.exchange(
  1572 + baseURL + "/{entityType}/{entityId}/values/timeseries?keys={keys}&startTs={startTs}&endTs={endTs}&interval={interval}&limit={limit}&agg={agg}",
  1573 + HttpMethod.GET,
  1574 + HttpEntity.EMPTY,
  1575 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1576 + },
  1577 + params).getBody();
  1578 + }
  1579 +
  1580 + public DeferredResult<ResponseEntity> saveDeviceAttributes(String deviceId, String scope, JsonNode request) {
  1581 + return restTemplate.exchange(
  1582 + baseURL + "/{deviceId}/{scope}",
  1583 + HttpMethod.POST,
  1584 + new HttpEntity<>(request),
  1585 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1586 + },
  1587 + deviceId,
  1588 + scope).getBody();
  1589 + }
  1590 +
  1591 + public DeferredResult<ResponseEntity> saveEntityAttributesV1(String entityType, String entityId, String scope, JsonNode request) {
  1592 + return restTemplate.exchange(
  1593 + baseURL + "/{entityType}/{entityId}/{scope}",
  1594 + HttpMethod.POST,
  1595 + new HttpEntity<>(request),
  1596 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1597 + },
  1598 + entityType,
  1599 + entityId,
  1600 + scope).getBody();
  1601 + }
  1602 +
  1603 + public DeferredResult<ResponseEntity> saveEntityAttributesV2(String entityType, String entityId, String scope, JsonNode request) {
  1604 + return restTemplate.exchange(
  1605 + baseURL + "/{entityType}/{entityId}/attributes/{scope}",
  1606 + HttpMethod.POST,
  1607 + new HttpEntity<>(request),
  1608 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1609 + },
  1610 + entityType,
  1611 + entityId,
  1612 + scope).getBody();
  1613 + }
  1614 +
  1615 + public DeferredResult<ResponseEntity> saveEntityTelemetry(String entityType, String entityId, String scope, String requestBody) {
  1616 + return restTemplate.exchange(
  1617 + baseURL + "/{entityType}/{entityId}/timeseries/{scope}",
  1618 + HttpMethod.POST,
  1619 + new HttpEntity<>(requestBody),
  1620 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1621 + },
  1622 + entityType,
  1623 + entityId,
  1624 + scope).getBody();
  1625 + }
  1626 +
  1627 + public DeferredResult<ResponseEntity> saveEntityTelemetryWithTTL(String entityType, String entityId, String scope, Long ttl, String requestBody) {
  1628 + return restTemplate.exchange(
  1629 + baseURL + "/{entityType}/{entityId}/timeseries/{scope}/{ttl}",
  1630 + HttpMethod.POST,
  1631 + new HttpEntity<>(requestBody),
  1632 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1633 + },
  1634 + entityType,
  1635 + entityId,
  1636 + scope,
  1637 + ttl).getBody();
  1638 + }
  1639 +
  1640 + public DeferredResult<ResponseEntity> deleteEntityTimeseries(String entityType,
  1641 + String entityId,
  1642 + String keys,
  1643 + boolean deleteAllDataForKeys,
  1644 + Long startTs,
  1645 + Long endTs,
  1646 + boolean rewriteLatestIfDeleted) {
  1647 + Map<String, String> params = new HashMap<>();
  1648 + params.put("entityType", entityType);
  1649 + params.put("entityId", entityId);
  1650 + params.put("keys", keys);
  1651 + params.put("deleteAllDataForKeys", String.valueOf(deleteAllDataForKeys));
  1652 + params.put("startTs", startTs.toString());
  1653 + params.put("endTs", endTs.toString());
  1654 + params.put("rewriteLatestIfDeleted", String.valueOf(rewriteLatestIfDeleted));
  1655 +
  1656 + return restTemplate.exchange(
  1657 + baseURL + "/{entityType}/{entityId}/timeseries/delete?keys={keys}&deleteAllDataForKeys={deleteAllDataForKeys}&startTs={startTs}&endTs={endTs}&rewriteLatestIfDeleted={rewriteLatestIfDeleted}",
  1658 + HttpMethod.DELETE,
  1659 + HttpEntity.EMPTY,
  1660 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1661 + },
  1662 + params).getBody();
  1663 + }
  1664 +
  1665 + public DeferredResult<ResponseEntity> deleteEntityAttributes(String deviceId, String scope, String keys) {
  1666 + return restTemplate.exchange(
  1667 + baseURL + "/{deviceId}/{scope}?keys={keys}",
  1668 + HttpMethod.DELETE,
  1669 + HttpEntity.EMPTY,
  1670 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1671 + },
  1672 + deviceId,
  1673 + scope,
  1674 + keys).getBody();
  1675 + }
  1676 +
  1677 + public DeferredResult<ResponseEntity> deleteEntityAttributes(String entityType, String entityId, String scope, String keys) {
  1678 + return restTemplate.exchange(
  1679 + baseURL + "/{entityType}/{entityId}/{scope}?keys={keys}",
  1680 + HttpMethod.DELETE,
  1681 + HttpEntity.EMPTY,
  1682 + new ParameterizedTypeReference<DeferredResult<ResponseEntity>>() {
  1683 + },
  1684 + entityType,
  1685 + entityId,
  1686 + scope,
  1687 + keys).getBody();
  1688 + }
  1689 +
  1690 + public Optional<Tenant> getTenantById(String tenantId) {
  1691 + try {
  1692 + ResponseEntity<Tenant> tenant = restTemplate.getForEntity(baseURL + "/tenant/{tenantId}", Tenant.class, tenantId);
  1693 + return Optional.ofNullable(tenant.getBody());
  1694 + } catch (HttpClientErrorException exception) {
  1695 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1696 + return Optional.empty();
  1697 + } else {
  1698 + throw exception;
  1699 + }
  1700 + }
  1701 + }
  1702 +
  1703 + public Tenant saveTenant(Tenant tenant) {
  1704 + return restTemplate.postForEntity(baseURL + "/tenant", tenant, Tenant.class).getBody();
  1705 + }
  1706 +
  1707 + public void deleteTenant(String tenantId) {
  1708 + restTemplate.delete(baseURL + "/tenant/{tenantId}", tenantId);
  1709 + }
  1710 +
  1711 + public TextPageData<Tenant> getTenants(TextPageLink pageLink) {
  1712 + Map<String, String> params = new HashMap<>();
  1713 + addPageLinkToParam(params, pageLink);
  1714 + return restTemplate.exchange(
  1715 + baseURL + "/tenants?" + TEXT_PAGE_LINK_URL_PARAMS,
  1716 + HttpMethod.GET,
  1717 + HttpEntity.EMPTY,
  1718 + new ParameterizedTypeReference<TextPageData<Tenant>>() {
  1719 + },
  1720 + params).getBody();
  1721 + }
  1722 +
  1723 + public Optional<User> getUserById(String userId) {
  1724 + try {
  1725 + ResponseEntity<User> user = restTemplate.getForEntity(baseURL + "/user/{userId}", User.class, userId);
  1726 + return Optional.ofNullable(user.getBody());
  1727 + } catch (HttpClientErrorException exception) {
  1728 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1729 + return Optional.empty();
  1730 + } else {
  1731 + throw exception;
  1732 + }
  1733 + }
  1734 + }
  1735 +
  1736 + public Boolean isUserTokenAccessEnabled() {
  1737 + return restTemplate.getForEntity(baseURL + "/user/tokenAccessEnabled", Boolean.class).getBody();
  1738 + }
  1739 +
  1740 + public Optional<JsonNode> getUserToken(String userId) {
  1741 + try {
  1742 + ResponseEntity<JsonNode> userToken = restTemplate.getForEntity(baseURL + "/user/{userId}/token", JsonNode.class, userId);
  1743 + return Optional.ofNullable(userToken.getBody());
  1744 + } catch (HttpClientErrorException exception) {
  1745 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1746 + return Optional.empty();
  1747 + } else {
  1748 + throw exception;
  1749 + }
  1750 + }
  1751 + }
  1752 +
  1753 + public User saveUser(User user, boolean sendActivationMail) {
  1754 + return restTemplate.postForEntity(baseURL + "/user?sendActivationMail={sendActivationMail}", user, User.class, sendActivationMail).getBody();
  1755 + }
  1756 +
  1757 + public void sendActivationEmail(String email) {
  1758 + restTemplate.postForEntity(baseURL + "/user/sendActivationMail?email={email}", null, Object.class, email);
  1759 + }
  1760 +
  1761 + public Optional<String> getActivationLink(String userId) {
  1762 + try {
  1763 + ResponseEntity<String> activationLink = restTemplate.getForEntity(baseURL + "/user/{userId}/activationLink", String.class, userId);
  1764 + return Optional.ofNullable(activationLink.getBody());
  1765 + } catch (HttpClientErrorException exception) {
  1766 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1767 + return Optional.empty();
  1768 + } else {
  1769 + throw exception;
  1770 + }
  1771 + }
  1772 + }
  1773 +
  1774 + public void deleteUser(String userId) {
  1775 + restTemplate.delete(baseURL + "/user/{userId}", userId);
  1776 + }
  1777 +
  1778 + // @RequestMapping(value = "/tenant/{tenantId}/users", params = {"limit"}, method = RequestMethod.GET)
  1779 + public TextPageData<User> getTenantAdmins(String tenantId, TextPageLink pageLink) {
  1780 + Map<String, String> params = new HashMap<>();
  1781 + params.put("tenantId", tenantId);
  1782 + addPageLinkToParam(params, pageLink);
  1783 +
  1784 + return restTemplate.exchange(
  1785 + baseURL + "/tenant/{tenantId}/users?" + TEXT_PAGE_LINK_URL_PARAMS,
  1786 + HttpMethod.GET,
  1787 + HttpEntity.EMPTY,
  1788 + new ParameterizedTypeReference<TextPageData<User>>() {
  1789 + },
  1790 + params).getBody();
  1791 + }
  1792 +
  1793 + public TextPageData<User> getCustomerUsers(String customerId, TextPageLink pageLink) {
  1794 + Map<String, String> params = new HashMap<>();
  1795 + params.put("customerId", customerId);
  1796 + addPageLinkToParam(params, pageLink);
  1797 +
  1798 + return restTemplate.exchange(
  1799 + baseURL + "/customer/{customerId}/users?" + TEXT_PAGE_LINK_URL_PARAMS,
  1800 + HttpMethod.GET,
  1801 + HttpEntity.EMPTY,
  1802 + new ParameterizedTypeReference<TextPageData<User>>() {
  1803 + },
  1804 + params).getBody();
  1805 + }
  1806 +
  1807 + public void setUserCredentialsEnabled(String userId, boolean userCredentialsEnabled) {
  1808 + restTemplate.postForEntity(
  1809 + baseURL + "/user/{userId}/userCredentialsEnabled?serCredentialsEnabled={serCredentialsEnabled}",
  1810 + null,
  1811 + Object.class,
  1812 + userId,
  1813 + userCredentialsEnabled);
  1814 + }
  1815 +
  1816 + public Optional<WidgetsBundle> getWidgetsBundleById(String widgetsBundleId) {
  1817 + try {
  1818 + ResponseEntity<WidgetsBundle> widgetsBundle =
  1819 + restTemplate.getForEntity(baseURL + "/widgetsBundle/{widgetsBundleId}", WidgetsBundle.class, widgetsBundleId);
  1820 + return Optional.ofNullable(widgetsBundle.getBody());
  1821 + } catch (HttpClientErrorException exception) {
  1822 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1823 + return Optional.empty();
  1824 + } else {
  1825 + throw exception;
  1826 + }
  1827 + }
  1828 + }
  1829 +
  1830 + public WidgetsBundle saveWidgetsBundle(WidgetsBundle widgetsBundle) {
  1831 + return restTemplate.postForEntity(baseURL + "/widgetsBundle", widgetsBundle, WidgetsBundle.class).getBody();
  1832 + }
  1833 +
  1834 + public void deleteWidgetsBundle(String widgetsBundleId) {
  1835 + restTemplate.delete(baseURL + "/widgetsBundle/{widgetsBundleId}", widgetsBundleId);
  1836 + }
  1837 +
  1838 + public TextPageData<WidgetsBundle> getWidgetsBundles(TextPageLink pageLink) {
  1839 + Map<String, String> params = new HashMap<>();
  1840 + addPageLinkToParam(params, pageLink);
  1841 + return restTemplate.exchange(
  1842 + baseURL + "/widgetsBundles?" + TEXT_PAGE_LINK_URL_PARAMS,
  1843 + HttpMethod.GET,
  1844 + HttpEntity.EMPTY,
  1845 + new ParameterizedTypeReference<TextPageData<WidgetsBundle>>() {
  1846 + }).getBody();
  1847 + }
  1848 +
  1849 + public List<WidgetsBundle> getWidgetsBundles() {
  1850 + return restTemplate.exchange(
  1851 + baseURL + "/widgetsBundles",
  1852 + HttpMethod.GET,
  1853 + HttpEntity.EMPTY,
  1854 + new ParameterizedTypeReference<List<WidgetsBundle>>() {
  1855 + }).getBody();
  1856 + }
  1857 +
  1858 + public Optional<WidgetType> getWidgetTypeById(String widgetTypeId) {
  1859 + try {
  1860 + ResponseEntity<WidgetType> widgetType =
  1861 + restTemplate.getForEntity(baseURL + "/widgetType/{widgetTypeId}", WidgetType.class, widgetTypeId);
  1862 + return Optional.ofNullable(widgetType.getBody());
  1863 + } catch (HttpClientErrorException exception) {
  1864 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1865 + return Optional.empty();
  1866 + } else {
  1867 + throw exception;
  1868 + }
  1869 + }
  1870 + }
  1871 +
  1872 + public WidgetType saveWidgetType(WidgetType widgetType) {
  1873 + return restTemplate.postForEntity(baseURL + "/widgetType", widgetType, WidgetType.class).getBody();
  1874 + }
  1875 +
  1876 + public void deleteWidgetType(String widgetTypeId) {
  1877 + restTemplate.delete(baseURL + "/widgetType/{widgetTypeId}", widgetTypeId);
  1878 + }
  1879 +
  1880 + public List<WidgetType> getBundleWidgetTypes(boolean isSystem, String bundleAlias) {
  1881 + return restTemplate.exchange(
  1882 + baseURL + "/widgetTypes?isSystem={isSystem}&bundleAlias={bundleAlias}",
  1883 + HttpMethod.GET,
  1884 + HttpEntity.EMPTY,
  1885 + new ParameterizedTypeReference<List<WidgetType>>() {
  1886 + },
  1887 + isSystem,
  1888 + bundleAlias).getBody();
  1889 + }
  1890 +
  1891 + public Optional<WidgetType> getWidgetType(boolean isSystem, String bundleAlias, String alias) {
  1892 + try {
  1893 + ResponseEntity<WidgetType> widgetType =
  1894 + restTemplate.getForEntity(
  1895 + baseURL + "/widgetType?isSystem={isSystem}&bundleAlias={bundleAlias}&alias={alias}",
  1896 + WidgetType.class,
  1897 + isSystem,
  1898 + bundleAlias,
  1899 + alias);
  1900 + return Optional.ofNullable(widgetType.getBody());
  1901 + } catch (HttpClientErrorException exception) {
  1902 + if (exception.getStatusCode() == HttpStatus.NOT_FOUND) {
  1903 + return Optional.empty();
  1904 + } else {
  1905 + throw exception;
  1906 + }
  1907 + }
  1908 + }
  1909 +
  1910 + private void addPageLinkToParam(Map<String, String> params, TimePageLink pageLink) {
  1911 + params.put("limit", String.valueOf(pageLink.getLimit()));
  1912 + params.put("startTime", String.valueOf(pageLink.getStartTime()));
  1913 + params.put("endTime", String.valueOf(pageLink.getEndTime()));
  1914 + params.put("ascOrder", String.valueOf(pageLink.isAscOrder()));
  1915 + params.put("offset", pageLink.getIdOffset().toString());
  1916 + }
  1917 +
  1918 + private void addPageLinkToParam(Map<String, String> params, TextPageLink pageLink) {
  1919 + params.put("limit", String.valueOf(pageLink.getLimit()));
  1920 + params.put("textSearch", pageLink.getTextSearch());
  1921 + params.put("idOffset", pageLink.getIdOffset().toString());
  1922 + params.put("textOffset", pageLink.getTextOffset());
252 1923 }
253   -}
\ No newline at end of file
  1924 +}
... ...