Browse Source

Merge pull request #14470 from dashevchenko/restClientFix

Fixed java rest client
pull/14542/head
Viacheslav Klimov 6 months ago
committed by GitHub
parent
commit
396787ed6b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 289
      msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/JavaRestClientTest.java
  2. 42
      rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java

289
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/JavaRestClientTest.java

@ -15,10 +15,11 @@
*/
package org.thingsboard.server.msa.connectivity;
import com.google.gson.JsonObject;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
import org.apache.hc.client5.http.ssl.HostnameVerificationPolicy;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
@ -30,26 +31,83 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rest.client.RestClient;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.domain.Domain;
import org.thingsboard.server.common.data.domain.DomainInfo;
import org.thingsboard.server.common.data.id.NotificationTargetId;
import org.thingsboard.server.common.data.id.NotificationTemplateId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.mobile.app.MobileApp;
import org.thingsboard.server.common.data.mobile.app.MobileAppStatus;
import org.thingsboard.server.common.data.mobile.bundle.MobileAppBundle;
import org.thingsboard.server.common.data.mobile.bundle.MobileAppBundleInfo;
import org.thingsboard.server.common.data.notification.Notification;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.notification.NotificationRequestConfig;
import org.thingsboard.server.common.data.notification.NotificationRequestInfo;
import org.thingsboard.server.common.data.notification.NotificationRequestPreview;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
import org.thingsboard.server.common.data.notification.settings.SlackNotificationDeliveryMethodConfig;
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter;
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.HasSubject;
import org.thingsboard.server.common.data.notification.template.MobileAppDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.oauth2.PlatformType;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.query.AvailableEntityKeys;
import org.thingsboard.server.common.data.query.EntityDataPageLink;
import org.thingsboard.server.common.data.query.EntityDataQuery;
import org.thingsboard.server.common.data.query.EntityDataSortOrder;
import org.thingsboard.server.common.data.query.EntityKey;
import org.thingsboard.server.common.data.query.EntityKeyType;
import org.thingsboard.server.common.data.query.EntityTypeFilter;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.TestProperties;
import javax.net.ssl.SSLContext;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.common.data.notification.NotificationDeliveryMethod.EMAIL;
import static org.thingsboard.server.common.data.notification.NotificationDeliveryMethod.MICROSOFT_TEAMS;
import static org.thingsboard.server.common.data.notification.NotificationDeliveryMethod.WEB;
import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype;
import static org.thingsboard.server.msa.ui.utils.EntityPrototypes.defaultTenantAdmin;
public class JavaRestClientTest extends AbstractContainerTest {
public static final String DEFAULT_NOTIFICATION_SUBJECT = "Just a test";
public static final NotificationType DEFAULT_NOTIFICATION_TYPE = NotificationType.GENERAL;
private RestClient restClient;
private Tenant tenant;
private User user;
@BeforeClass
public void beforeClass() throws Exception {
@ -77,11 +135,25 @@ public class JavaRestClientTest extends AbstractContainerTest {
@BeforeMethod
public void setUp() throws Exception {
restClient.login("tenant@thingsboard.org", "tenant");
restClient.login("sysadmin@thingsboard.org", "sysadmin");
// create tenant and tenant admin
tenant = new Tenant();
tenant.setTitle("Java Rest Client Test Tenant " + RandomStringUtils.randomAlphabetic(5));
tenant = restClient.saveTenant(tenant);
String email = RandomStringUtils.randomAlphabetic(5) + "@gmail.com";
user = restClient.saveUser(defaultTenantAdmin(tenant.getId(), email), false);
restClient.activateUser(user.getId(), "password123", false);
restClient.login(email, "password123");
}
@AfterMethod
public void tearDown() {
restClient.login("sysadmin@thingsboard.org", "sysadmin");
if (tenant != null) {
restClient.deleteTenant(tenant.getId());
}
}
@Test
@ -123,6 +195,219 @@ public class JavaRestClientTest extends AbstractContainerTest {
PageData<AlarmInfo> allClearedAlarms = restClient.getAllAlarms(AlarmSearchStatus.CLEARED, null, new TimePageLink(10, 0), null);
assertThat(allClearedAlarms.getData()).hasSize(0);
}
@Test
public void testTimeSeriesByReadTsKvQueries() {
Device device = restClient.saveDevice(defaultDevicePrototype(RandomStringUtils.randomAlphabetic(5)));
assertThat(device).isNotNull();
DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(device.getId()).get();
for (int i = 0; i < 3; i++) {
JsonObject values = new JsonObject();
values.addProperty("temperature", i + 25);
testRestClient.postTelemetry(deviceCredentials.getCredentialsId(), JacksonUtil.toJsonNode(createPayload().toString()));
}
restClient.saveEntityTelemetry(device.getId(), "ts", JacksonUtil.toJsonNode("{\"temperature\": 25, \"humidity\": 60}"));
restClient.saveEntityTelemetry(device.getId(), "ts", JacksonUtil.toJsonNode("{\"temperature\": 27, \"humidity\": 59}"));
restClient.saveEntityTelemetry(device.getId(), "ts", JacksonUtil.toJsonNode("{\"temperature\": 33, \"humidity\": 62}"));
EntityTypeFilter filter = new EntityTypeFilter();
filter.setEntityType(EntityType.DEVICE);
var pageLink = new EntityDataPageLink(20, 0, null, new EntityDataSortOrder(new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"), EntityDataSortOrder.Direction.DESC), false);
var entityFields = Arrays.asList(new EntityKey(EntityKeyType.ENTITY_FIELD, "name"), new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"));
EntityDataQuery entityDataQuery = new EntityDataQuery(filter, pageLink, entityFields, null, null);
AvailableEntityKeys availableEntityKeys = restClient.findAvailableEntityKeysByQuery(entityDataQuery, true, true, null);
assertThat(availableEntityKeys).isNotNull();
assertThat(availableEntityKeys.timeseries()).contains("temperature", "humidity");
}
@Test
public void testFindNotifications() {
NotificationTarget notificationTarget = createNotificationTarget(user.getId());
String notificationText1 = "Notification 1";
NotificationTemplate notificationTemplate = createNotificationTemplate(DEFAULT_NOTIFICATION_TYPE, DEFAULT_NOTIFICATION_SUBJECT, notificationText1, new NotificationDeliveryMethod[]{WEB});
NotificationRequest notificationRequest = submitNotificationRequest(notificationTarget.getId(), notificationTemplate.getId());
String notificationText2 = "Notification 2";
NotificationTemplate notificationTemplate2 = createNotificationTemplate(DEFAULT_NOTIFICATION_TYPE, DEFAULT_NOTIFICATION_SUBJECT, notificationText2, new NotificationDeliveryMethod[]{WEB});
NotificationRequest notificationRequest2 = submitNotificationRequest(notificationTarget.getId(), notificationTemplate2.getId());
PageData<NotificationRequestInfo> initialRequests = restClient.getNotificationRequests(new PageLink(30));
assertThat(initialRequests.getTotalElements()).isGreaterThanOrEqualTo(2);
NotificationRequestInfo notificationRequestInfo = restClient.getNotificationRequestById(notificationRequest.getId()).get();
assertThat(notificationRequestInfo.getName()).isEqualTo(notificationRequest.getName());
assertThat(notificationRequestInfo.getTemplateName()).isEqualTo(notificationTemplate.getName());
NotificationRequestPreview requestPreview = restClient.getNotificationRequestPreview(notificationRequest, 10);
assertThat(requestPreview.getTotalRecipientsCount()).isEqualTo(1);
assertThat(requestPreview.getRecipientsPreview()).isEqualTo(List.of(user.getEmail()));
PageData<Notification> notifications = restClient.getNotifications(false, WEB, new PageLink(30));
assertThat(notifications.getTotalElements()).isEqualTo(2);
Integer unreadCount = restClient.getUnreadNotificationsCount(WEB);
assertThat(unreadCount).isEqualTo(2);
restClient.markNotificationAsRead(notifications.getData().get(0).getId());
Integer unreadCountAfterRead = restClient.getUnreadNotificationsCount(WEB);
assertThat(unreadCountAfterRead).isEqualTo(1);
restClient.markAllNotificationsAsRead(WEB);
Integer unreadCountAfterAllRead = restClient.getUnreadNotificationsCount(WEB);
assertThat(unreadCountAfterAllRead).isEqualTo(0);
restClient.deleteNotification(notifications.getData().get(0).getId());
notifications = restClient.getNotifications(false, WEB, new PageLink(30));
assertThat(notifications.getTotalElements()).isEqualTo(1);
restClient.deleteNotificationRequest(notificationRequest.getId());
PageData<NotificationRequestInfo> requestsAfterUpdate = restClient.getNotificationRequests(new PageLink(30));
assertThat(requestsAfterUpdate.getTotalElements()).isEqualTo(initialRequests.getTotalElements() - 1);
List<NotificationDeliveryMethod> availableDeliveryMethods = restClient.getAvailableDeliveryMethods();
assertThat(availableDeliveryMethods).contains(WEB, EMAIL, MICROSOFT_TEAMS);
}
@Test
public void testSaveNotificationSettings() {
NotificationSettings settings = new NotificationSettings();
SlackNotificationDeliveryMethodConfig slackConfig = new SlackNotificationDeliveryMethodConfig();
String slackToken = "xoxb-123123123";
slackConfig.setBotToken(slackToken);
settings.setDeliveryMethodsConfigs(Map.of(
NotificationDeliveryMethod.SLACK, slackConfig
));
restClient.saveNotificationSettings(settings);
NotificationSettings savedSettings = restClient.getNotificationSettings().get();
assertThat(savedSettings.getDeliveryMethodsConfigs()).hasSize(1);
assertThat(savedSettings.getDeliveryMethodsConfigs().get(slackConfig.getMethod())).isEqualTo(slackConfig);
// save user notification settings
var entityActionNotificationPref = new UserNotificationSettings.NotificationPref();
entityActionNotificationPref.setEnabled(true);
entityActionNotificationPref.setEnabledDeliveryMethods(Map.of(
NotificationDeliveryMethod.WEB, true,
NotificationDeliveryMethod.SMS, false,
NotificationDeliveryMethod.EMAIL, false
));
UserNotificationSettings userNotificationSettings = new UserNotificationSettings(Map.of(
NotificationType.ENTITY_ACTION, entityActionNotificationPref
));
UserNotificationSettings saved = restClient.saveUserNotificationSettings(userNotificationSettings);
UserNotificationSettings retrieved = restClient.getUserNotificationSettings().get();
assertThat(retrieved).isEqualTo(saved);
}
@Test
public void testSaveDomain() {
restClient.login("sysadmin@thingsboard.org", "sysadmin");
Domain domain = new Domain();
String prefix = RandomStringUtils.randomAlphabetic(5).toLowerCase();
domain.setName(prefix + ".test.com");
Domain savedDomain = restClient.saveDomain(domain);
assertThat(savedDomain.getName()).isEqualTo(domain.getName());
PageData<DomainInfo> domainInfos = restClient.getTenantDomainInfos(new PageLink(10, 0 , prefix));
assertThat(domainInfos.getData()).hasSize(1);
}
@Test
public void testSaveMobileApp() {
restClient.login("sysadmin@thingsboard.org", "sysadmin");
MobileApp mobileApp = new MobileApp();
String prefix = RandomStringUtils.randomAlphabetic(5).toLowerCase();
mobileApp.setPkgName(prefix + "test.app.apple");
mobileApp.setPlatformType(PlatformType.ANDROID);
mobileApp.setAppSecret(RandomStringUtils.randomAlphabetic(20));
mobileApp.setStatus(MobileAppStatus.DRAFT);
MobileApp savedMobileApp = restClient.saveMobileApp(mobileApp);
assertThat(savedMobileApp.getName()).isEqualTo(mobileApp.getName());
PageData<MobileApp> retrieved = restClient.getTenantMobileApps(new PageLink(10, 0, prefix));
assertThat(retrieved.getData()).hasSize(1);
MobileAppBundle mobileAppBundle = new MobileAppBundle();
String bundlePrefix = RandomStringUtils.randomAlphabetic(5).toLowerCase();
mobileAppBundle.setTitle(bundlePrefix + "Test Bundle");
mobileAppBundle.setAndroidAppId(savedMobileApp.getId());
MobileAppBundle savedMobileAppBundle = restClient.saveMobileBundle(mobileAppBundle);
PageData<MobileAppBundleInfo> bundleInfos = restClient.getTenantMobileBundleInfos(new PageLink(10, 0, bundlePrefix));
assertThat(bundleInfos.getData()).hasSize(1);
}
private NotificationTarget createNotificationTarget(UserId... usersIds) {
UserListFilter filter = new UserListFilter();
filter.setUsersIds(Arrays.stream(usersIds).map(UUIDBased::getId).toList());
NotificationTarget notificationTarget = new NotificationTarget();
notificationTarget.setName(filter.toString() + org.apache.commons.lang3.RandomStringUtils.randomNumeric(5));
PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig();
targetConfig.setUsersFilter(filter);
notificationTarget.setConfiguration(targetConfig);
return restClient.saveNotificationTarget(notificationTarget);
}
private NotificationTemplate createNotificationTemplate(NotificationType notificationType, String subject,
String text, NotificationDeliveryMethod... deliveryMethods) {
NotificationTemplate notificationTemplate = new NotificationTemplate();
notificationTemplate.setName("Notification template: " + RandomStringUtils.randomAlphabetic(5));
notificationTemplate.setNotificationType(notificationType);
NotificationTemplateConfig config = new NotificationTemplateConfig();
config.setDeliveryMethodsTemplates(new HashMap<>());
for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) {
DeliveryMethodNotificationTemplate deliveryMethodNotificationTemplate;
switch (deliveryMethod) {
case WEB: {
deliveryMethodNotificationTemplate = new WebDeliveryMethodNotificationTemplate();
break;
}
case EMAIL: {
deliveryMethodNotificationTemplate = new EmailDeliveryMethodNotificationTemplate();
break;
}
case SMS: {
deliveryMethodNotificationTemplate = new SmsDeliveryMethodNotificationTemplate();
break;
}
case MOBILE_APP:
deliveryMethodNotificationTemplate = new MobileAppDeliveryMethodNotificationTemplate();
break;
default:
throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod);
}
deliveryMethodNotificationTemplate.setEnabled(true);
deliveryMethodNotificationTemplate.setBody(text);
if (deliveryMethodNotificationTemplate instanceof HasSubject) {
((HasSubject) deliveryMethodNotificationTemplate).setSubject(subject);
}
config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate);
}
notificationTemplate.setConfiguration(config);
return restClient.saveNotificationTemplate(notificationTemplate);
}
private NotificationRequest submitNotificationRequest(NotificationTargetId targetId, NotificationTemplateId notificationTemplateId) {
NotificationRequestConfig config = new NotificationRequestConfig();
config.setSendingDelayInSec(0);
NotificationRequest notificationRequest = NotificationRequest.builder()
.targets(List.of(targetId).stream().map(UUIDBased::getId).collect(Collectors.toList()))
.templateId(notificationTemplateId)
.additionalConfig(config)
.build();
return restClient.saveNotificationRequest(notificationRequest);
}
}

42
rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java

@ -146,6 +146,8 @@ import org.thingsboard.server.common.data.notification.NotificationRequestInfo;
import org.thingsboard.server.common.data.notification.NotificationRequestPreview;
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo;
import org.thingsboard.server.common.data.oauth2.OAuth2ClientLoginInfo;
@ -2294,7 +2296,8 @@ public class RestClient implements Closeable {
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<PageData<DomainInfo>>() {
}).getBody();
},
params).getBody();
}
public Optional<DomainInfo> getDomainInfoById(DomainId domainId) {
@ -2330,7 +2333,8 @@ public class RestClient implements Closeable {
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<PageData<MobileApp>>() {
}).getBody();
},
params).getBody();
}
public Optional<MobileApp> getMobileAppById(MobileAppId mobileAppId) {
@ -2362,7 +2366,8 @@ public class RestClient implements Closeable {
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<PageData<MobileAppBundleInfo>>() {
}).getBody();
},
params).getBody();
}
public Optional<MobileAppBundle> getMobileBundleById(MobileAppBundleId mobileAppBundleId) {
@ -4289,11 +4294,23 @@ public class RestClient implements Closeable {
}
}
public PageData<Notification> getNotifications(PageLink pageLink) {
public PageData<Notification> getNotifications(Boolean unreadOnly, NotificationDeliveryMethod deliveryMethod, PageLink pageLink) {
Map<String, String> params = new HashMap<>();
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(baseURL).append("/api/notifications?").append(getUrlParams(pageLink));
addPageLinkToParam(params, pageLink);
return restTemplate.exchange(
baseURL + "/api/notifications?" + getUrlParams(pageLink),
if (unreadOnly != null) {
urlBuilder.append("&unreadOnly={unreadOnly}");
params.put("unreadOnly", unreadOnly.toString());
}
if (deliveryMethod != null) {
urlBuilder.append("&deliveryMethod={deliveryMethod}");
params.put("deliveryMethod", deliveryMethod.name());
}
return restTemplate.exchange(urlBuilder.toString(),
HttpMethod.GET,
HttpEntity.EMPTY,
new ParameterizedTypeReference<PageData<Notification>>() {
@ -4334,7 +4351,8 @@ public class RestClient implements Closeable {
baseURL + uri,
HttpMethod.PUT,
HttpEntity.EMPTY,
Void.class);
Void.class,
params);
}
@ -4342,7 +4360,7 @@ public class RestClient implements Closeable {
restTemplate.delete(baseURL + "/api/notification/{id}", notificationId.getId());
}
public NotificationRequest createNotificationRequest(NotificationRequest notificationRequest) {
public NotificationRequest saveNotificationRequest(NotificationRequest notificationRequest) {
return restTemplate.postForEntity(baseURL + "/api/notification/request", notificationRequest, NotificationRequest.class).getBody();
}
@ -4421,6 +4439,14 @@ public class RestClient implements Closeable {
}
}
public NotificationTarget saveNotificationTarget(NotificationTarget notificationTarget) {
return restTemplate.postForEntity(baseURL + "/api/notification/target", notificationTarget, NotificationTarget.class).getBody();
}
public NotificationTemplate saveNotificationTemplate(NotificationTemplate notificationTemplate) {
return restTemplate.postForEntity(baseURL + "/api/notification/template", notificationTemplate, NotificationTemplate.class).getBody();
}
public AiModel saveAiModel(AiModel aiModel) {
return restTemplate.postForEntity(baseURL + "/api/ai/model", aiModel, AiModel.class).getBody();
}

Loading…
Cancel
Save