Added tests on api usage
This commit is contained in:
		
							parent
							
								
									5ced8457f1
								
							
						
					
					
						commit
						a118c44cf5
					
				@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2024 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.service.apiusage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Before;
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			||||||
 | 
					import org.springframework.test.context.TestPropertySource;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.ApiUsageStateValue;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.Device;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.Tenant;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.TenantProfile;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.User;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.security.Authority;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.security.DeviceCredentials;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.security.DeviceCredentialsType;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
 | 
				
			||||||
 | 
					import org.thingsboard.server.controller.AbstractControllerTest;
 | 
				
			||||||
 | 
					import org.thingsboard.server.controller.TbUrlConstants;
 | 
				
			||||||
 | 
					import org.thingsboard.server.dao.service.DaoSqlTest;
 | 
				
			||||||
 | 
					import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.concurrent.TimeUnit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.awaitility.Awaitility.await;
 | 
				
			||||||
 | 
					import static org.junit.Assert.assertEquals;
 | 
				
			||||||
 | 
					import static org.junit.Assert.assertNotNull;
 | 
				
			||||||
 | 
					import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@DaoSqlTest
 | 
				
			||||||
 | 
					@TestPropertySource(properties = {
 | 
				
			||||||
 | 
					        "usage.stats.report.enabled=true",
 | 
				
			||||||
 | 
					        "usage.stats.report.interval=2",
 | 
				
			||||||
 | 
					        "usage.stats.gauge_report_interval=1",
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					public class ApiUsageTest extends AbstractControllerTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Tenant savedTenant;
 | 
				
			||||||
 | 
					    private User tenantAdmin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final int MAX_DP_ENABLE_VALUE = 12;
 | 
				
			||||||
 | 
					    private static final double WARN_THRESHOLD_VALUE = 0.5;
 | 
				
			||||||
 | 
					    @Autowired
 | 
				
			||||||
 | 
					    private ApiUsageStateService apiUsageStateService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Before
 | 
				
			||||||
 | 
					    public void beforeTest() throws Exception {
 | 
				
			||||||
 | 
					        loginSysAdmin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TenantProfile tenantProfile = createTenantProfile();
 | 
				
			||||||
 | 
					        TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class);
 | 
				
			||||||
 | 
					        assertNotNull(savedTenantProfile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Tenant tenant = new Tenant();
 | 
				
			||||||
 | 
					        tenant.setTitle("My tenant");
 | 
				
			||||||
 | 
					        tenant.setTenantProfileId(savedTenantProfile.getId());
 | 
				
			||||||
 | 
					        savedTenant = saveTenant(tenant);
 | 
				
			||||||
 | 
					        tenantId = savedTenant.getId();
 | 
				
			||||||
 | 
					        assertNotNull(savedTenant);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tenantAdmin = new User();
 | 
				
			||||||
 | 
					        tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
 | 
				
			||||||
 | 
					        tenantAdmin.setTenantId(savedTenant.getId());
 | 
				
			||||||
 | 
					        tenantAdmin.setEmail("tenant2@thingsboard.org");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testTelemetryApiCall() throws Exception {
 | 
				
			||||||
 | 
					        Device device = createDevice();
 | 
				
			||||||
 | 
					        assertNotNull(device);
 | 
				
			||||||
 | 
					        String telemetryPayload = "{\"temperature\":25, \"humidity\":60}";
 | 
				
			||||||
 | 
					        String url = TbUrlConstants.TELEMETRY_URL_PREFIX + "/DEVICE/" + device.getId() + "/timeseries/ANY";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        long VALUE_WARNING = (long) (MAX_DP_ENABLE_VALUE * WARN_THRESHOLD_VALUE) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = 0; i < VALUE_WARNING; i++) {
 | 
				
			||||||
 | 
					            doPostAsync(url, telemetryPayload, String.class, status().isOk());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> assertEquals(ApiUsageStateValue.WARNING, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        long VALUE_DISABLE = (long) (MAX_DP_ENABLE_VALUE - (MAX_DP_ENABLE_VALUE * WARN_THRESHOLD_VALUE)) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = 0; i < VALUE_DISABLE; i++) {
 | 
				
			||||||
 | 
					            doPostAsync(url, telemetryPayload, String.class, status().isOk());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await().atMost(5, TimeUnit.SECONDS)
 | 
				
			||||||
 | 
					                .untilAsserted(() -> {
 | 
				
			||||||
 | 
					                    assertEquals(ApiUsageStateValue.DISABLED, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState());
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private TenantProfile createTenantProfile() {
 | 
				
			||||||
 | 
					        TenantProfile tenantProfile = new TenantProfile();
 | 
				
			||||||
 | 
					        tenantProfile.setName("Tenant Profile");
 | 
				
			||||||
 | 
					        tenantProfile.setDescription("Tenant Profile" + " Test");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TenantProfileData tenantProfileData = new TenantProfileData();
 | 
				
			||||||
 | 
					        DefaultTenantProfileConfiguration config = DefaultTenantProfileConfiguration.builder()
 | 
				
			||||||
 | 
					                .maxDPStorageDays(MAX_DP_ENABLE_VALUE)
 | 
				
			||||||
 | 
					                .warnThreshold(WARN_THRESHOLD_VALUE)
 | 
				
			||||||
 | 
					                .build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tenantProfileData.setConfiguration(config);
 | 
				
			||||||
 | 
					        tenantProfile.setProfileData(tenantProfileData);
 | 
				
			||||||
 | 
					        return tenantProfile;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Device createDevice() throws Exception {
 | 
				
			||||||
 | 
					        String testToken = "TEST_TOKEN";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Device device = new Device();
 | 
				
			||||||
 | 
					        device.setName("My device");
 | 
				
			||||||
 | 
					        device.setType("default");
 | 
				
			||||||
 | 
					        device.setTenantId(tenantId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DeviceCredentials deviceCredentials = new DeviceCredentials();
 | 
				
			||||||
 | 
					        deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
 | 
				
			||||||
 | 
					        deviceCredentials.setCredentialsId(testToken);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SaveDeviceWithCredentialsRequest saveRequest = new SaveDeviceWithCredentialsRequest(device, deviceCredentials);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return readResponse(doPost("/api/device-with-credentials", saveRequest).andExpect(status().isOk()), Device.class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -15,359 +15,111 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
package org.thingsboard.server.service.apiusage;
 | 
					package org.thingsboard.server.service.apiusage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.common.util.concurrent.Futures;
 | 
					import org.junit.Assert;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.junit.Before;
 | 
				
			||||||
import org.junit.jupiter.api.BeforeEach;
 | 
					import org.junit.Test;
 | 
				
			||||||
import org.junit.jupiter.api.Test;
 | 
					import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			||||||
import org.junit.jupiter.api.extension.ExtendWith;
 | 
					 | 
				
			||||||
import org.mockito.InjectMocks;
 | 
					 | 
				
			||||||
import org.mockito.Mock;
 | 
					 | 
				
			||||||
import org.mockito.Spy;
 | 
					 | 
				
			||||||
import org.mockito.junit.jupiter.MockitoExtension;
 | 
					 | 
				
			||||||
import org.springframework.test.util.ReflectionTestUtils;
 | 
					 | 
				
			||||||
import org.thingsboard.server.common.data.*;
 | 
					import org.thingsboard.server.common.data.*;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
					import org.thingsboard.server.common.data.id.TenantId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.TenantProfileId;
 | 
					 | 
				
			||||||
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
 | 
					import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
 | 
				
			||||||
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
 | 
					import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
 | 
				
			||||||
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
 | 
					 | 
				
			||||||
import org.thingsboard.server.common.msg.queue.TbCallback;
 | 
					import org.thingsboard.server.common.msg.queue.TbCallback;
 | 
				
			||||||
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
 | 
					import org.thingsboard.server.controller.AbstractControllerTest;
 | 
				
			||||||
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
 | 
					import org.thingsboard.server.dao.service.DaoSqlTest;
 | 
				
			||||||
import org.thingsboard.server.dao.tenant.TenantService;
 | 
					 | 
				
			||||||
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
 | 
					import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
 | 
				
			||||||
import org.thingsboard.server.gen.transport.TransportProtos;
 | 
					import org.thingsboard.server.gen.transport.TransportProtos;
 | 
				
			||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
					import org.thingsboard.server.queue.common.TbProtoQueueMsg;
 | 
				
			||||||
import org.thingsboard.server.queue.discovery.PartitionService;
 | 
					 | 
				
			||||||
import org.thingsboard.server.service.mail.MailExecutorService;
 | 
					 | 
				
			||||||
import org.thingsboard.server.service.telemetry.InternalTelemetryService;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.UUID;
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.hamcrest.CoreMatchers.is;
 | 
					import static org.junit.Assert.assertEquals;
 | 
				
			||||||
import static org.hamcrest.MatcherAssert.assertThat;
 | 
					 | 
				
			||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
 | 
					 | 
				
			||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
 | 
					 | 
				
			||||||
import static org.mockito.ArgumentMatchers.any;
 | 
					 | 
				
			||||||
import static org.mockito.ArgumentMatchers.eq;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.atLeastOnce;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.doReturn;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.lenient;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.mock;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.never;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.times;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.verify;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.when;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ExtendWith(MockitoExtension.class)
 | 
					@DaoSqlTest
 | 
				
			||||||
public class DefaultTbApiUsageStateServiceTest {
 | 
					public class DefaultTbApiUsageStateServiceTest extends AbstractControllerTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Mock
 | 
					    @Autowired
 | 
				
			||||||
    private NotificationRuleProcessor notificationRuleProcessor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Mock
 | 
					 | 
				
			||||||
    private ApiUsageStateService apiUsageStateService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Mock
 | 
					 | 
				
			||||||
    private TenantService tenantService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Mock
 | 
					 | 
				
			||||||
    private InternalTelemetryService tsWsService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Mock
 | 
					 | 
				
			||||||
    private MailExecutorService mailExecutor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Mock
 | 
					 | 
				
			||||||
    private PartitionService partitionService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Mock
 | 
					 | 
				
			||||||
    private TbTenantProfileCache tbTenantProfileCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Spy
 | 
					 | 
				
			||||||
    @InjectMocks
 | 
					 | 
				
			||||||
    DefaultTbApiUsageStateService service;
 | 
					    DefaultTbApiUsageStateService service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private TenantApiUsageState tenantApiUsageState;
 | 
					    @Autowired
 | 
				
			||||||
    private Tenant dummyTenant;
 | 
					    private ApiUsageStateService apiUsageStateService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private TenantId tenantId;
 | 
				
			||||||
 | 
					    private Tenant savedTenant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static final int MAX_ENABLE_VALUE = 5000;
 | 
					    private static final int MAX_ENABLE_VALUE = 5000;
 | 
				
			||||||
    private static final long VALUE_WARNING = 4500L;
 | 
					    private static final long VALUE_WARNING = 4500L;
 | 
				
			||||||
    private static final long VALUE_DISABLE = 5500L;
 | 
					    private static final long VALUE_DISABLE = 5500L;
 | 
				
			||||||
    private static final int NEW_MAX_ENABLE_VALUE = 4000;
 | 
					 | 
				
			||||||
    private static final double NEW_WARN_THRESHOLD_VALUE = 0.9;
 | 
					 | 
				
			||||||
    private static final double WARN_THRESHOLD_VALUE = 0.8;
 | 
					    private static final double WARN_THRESHOLD_VALUE = 0.8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @BeforeEach
 | 
					    @Before
 | 
				
			||||||
    public void setUp() {
 | 
					    public void init() throws Exception {
 | 
				
			||||||
        var tenantId = TenantId.fromUUID(UUID.randomUUID());
 | 
					        loginSysAdmin();
 | 
				
			||||||
        dummyTenant = new Tenant();
 | 
					 | 
				
			||||||
        dummyTenant.setId(tenantId);
 | 
					 | 
				
			||||||
        dummyTenant.setEmail("test@tenant.com");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        lenient().when(tsWsService.saveTimeseriesInternal(any())).thenReturn(Futures.immediateFuture(0));
 | 
					        TenantProfile tenantProfile = createTenantProfile();
 | 
				
			||||||
 | 
					        TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class);
 | 
				
			||||||
 | 
					        Assert.assertNotNull(savedTenantProfile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ReflectionTestUtils.setField(service, "tsWsService", tsWsService);
 | 
					        Tenant tenant = new Tenant();
 | 
				
			||||||
 | 
					        tenant.setTitle("My tenant");
 | 
				
			||||||
 | 
					        tenant.setTenantProfileId(savedTenantProfile.getId());
 | 
				
			||||||
 | 
					        savedTenant = saveTenant(tenant);
 | 
				
			||||||
 | 
					        tenantId = savedTenant.getId();
 | 
				
			||||||
 | 
					        Assert.assertNotNull(savedTenant);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testProcess_transitionFromWarningToDisabled() {
 | 
				
			||||||
 | 
					        TransportProtos.ToUsageStatsServiceMsg.Builder warningMsgBuilder = TransportProtos.ToUsageStatsServiceMsg.newBuilder()
 | 
				
			||||||
 | 
					                .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
 | 
				
			||||||
 | 
					                .setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
 | 
				
			||||||
 | 
					                .setCustomerIdMSB(0)
 | 
				
			||||||
 | 
					                .setCustomerIdLSB(0)
 | 
				
			||||||
 | 
					                .setServiceId("testService");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                warningMsgBuilder.addValues(TransportProtos.UsageStatsKVProto.newBuilder()
 | 
				
			||||||
 | 
					                        .setKey(ApiUsageRecordKey.STORAGE_DP_COUNT.name())
 | 
				
			||||||
 | 
					                        .setValue(VALUE_WARNING)
 | 
				
			||||||
 | 
					                        .build());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TransportProtos.ToUsageStatsServiceMsg warningStatsMsg = warningMsgBuilder.build();
 | 
				
			||||||
 | 
					        TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg> warningMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), warningStatsMsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        service.process(warningMsg, TbCallback.EMPTY);
 | 
				
			||||||
 | 
					        assertEquals(ApiUsageStateValue.WARNING, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TransportProtos.ToUsageStatsServiceMsg.Builder disableMsgBuilder = TransportProtos.ToUsageStatsServiceMsg.newBuilder()
 | 
				
			||||||
 | 
					                .setTenantIdMSB(tenantId.getId().getMostSignificantBits())
 | 
				
			||||||
 | 
					                .setTenantIdLSB(tenantId.getId().getLeastSignificantBits())
 | 
				
			||||||
 | 
					                .setCustomerIdMSB(0)
 | 
				
			||||||
 | 
					                .setCustomerIdLSB(0)
 | 
				
			||||||
 | 
					                .setServiceId("testService");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                disableMsgBuilder.addValues(TransportProtos.UsageStatsKVProto.newBuilder()
 | 
				
			||||||
 | 
					                        .setKey(ApiUsageRecordKey.STORAGE_DP_COUNT.name())
 | 
				
			||||||
 | 
					                        .setValue(VALUE_DISABLE)
 | 
				
			||||||
 | 
					                        .build());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TransportProtos.ToUsageStatsServiceMsg disableStatsMsg = disableMsgBuilder.build();
 | 
				
			||||||
 | 
					        TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg> disableMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), disableStatsMsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        service.process(disableMsg, TbCallback.EMPTY);
 | 
				
			||||||
 | 
					        assertEquals(ApiUsageStateValue.DISABLED, apiUsageStateService.findTenantApiUsageState(tenantId).getDbStorageState());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private TenantProfile createTenantProfile() {
 | 
				
			||||||
 | 
					        TenantProfile tenantProfile = new TenantProfile();
 | 
				
			||||||
 | 
					        tenantProfile.setName("Tenant Profile");
 | 
				
			||||||
 | 
					        tenantProfile.setDescription("Tenant Profile" + " Test");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TenantProfileData tenantProfileData = new TenantProfileData();
 | 
				
			||||||
        DefaultTenantProfileConfiguration config = DefaultTenantProfileConfiguration.builder()
 | 
					        DefaultTenantProfileConfiguration config = DefaultTenantProfileConfiguration.builder()
 | 
				
			||||||
                .maxJSExecutions(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxTransportMessages(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxRuleChains(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxTbelExecutions(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxDPStorageDays(MAX_ENABLE_VALUE)
 | 
					                .maxDPStorageDays(MAX_ENABLE_VALUE)
 | 
				
			||||||
                .maxREExecutions(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxEmails(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxSms(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxCreatedAlarms(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .warnThreshold(WARN_THRESHOLD_VALUE)
 | 
					                .warnThreshold(WARN_THRESHOLD_VALUE)
 | 
				
			||||||
                .build();
 | 
					                .build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TenantProfileData profileData = new TenantProfileData();
 | 
					        tenantProfileData.setConfiguration(config);
 | 
				
			||||||
        profileData.setConfiguration(config);
 | 
					        tenantProfile.setProfileData(tenantProfileData);
 | 
				
			||||||
 | 
					        return tenantProfile;
 | 
				
			||||||
        TenantProfile dummyTenantProfile = new TenantProfile();
 | 
					 | 
				
			||||||
        dummyTenantProfile.setId(new TenantProfileId(UUID.randomUUID()));
 | 
					 | 
				
			||||||
        dummyTenantProfile.setProfileData(profileData);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ApiUsageState dummyUsageState = getApiUsageState(tenantId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        tenantApiUsageState = new TenantApiUsageState(dummyTenantProfile, dummyUsageState);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        service.myUsageStates.put(tenantId, tenantApiUsageState);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @NotNull
 | 
					 | 
				
			||||||
    private static ApiUsageState getApiUsageState(TenantId tenantId) {
 | 
					 | 
				
			||||||
        ApiUsageState dummyUsageState = new ApiUsageState();
 | 
					 | 
				
			||||||
        dummyUsageState.setTransportState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setDbStorageState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setReExecState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setJsExecState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setTbelExecState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setEmailExecState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setSmsExecState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setAlarmExecState(ApiUsageStateValue.ENABLED);
 | 
					 | 
				
			||||||
        dummyUsageState.setTenantId(tenantId);
 | 
					 | 
				
			||||||
        dummyUsageState.setEntityId(tenantId);
 | 
					 | 
				
			||||||
        dummyUsageState.setVersion(1L);
 | 
					 | 
				
			||||||
        return dummyUsageState;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void givenTenantIdFromEntityStatesMap_whenGetApiUsageState() {
 | 
					 | 
				
			||||||
        ApiUsageState tenantUsageState = service.getApiUsageState(dummyTenant.getTenantId());
 | 
					 | 
				
			||||||
        assertThat(tenantUsageState, is(tenantApiUsageState.getApiUsageState()));
 | 
					 | 
				
			||||||
        verify(service, never()).getOrFetchState(dummyTenant.getTenantId(), dummyTenant.getTenantId());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testGetApiUsageState_fromOtherUsageStates() {
 | 
					 | 
				
			||||||
        TenantId tenantId = dummyTenant.getTenantId();
 | 
					 | 
				
			||||||
        service.myUsageStates.remove(tenantId);
 | 
					 | 
				
			||||||
        ApiUsageState otherState = new ApiUsageState();
 | 
					 | 
				
			||||||
        otherState.setTenantId(tenantId);
 | 
					 | 
				
			||||||
        service.otherUsageStates.put(tenantId, otherState);
 | 
					 | 
				
			||||||
        ApiUsageState result = service.getApiUsageState(tenantId);
 | 
					 | 
				
			||||||
        assertThat(result, is(otherState));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testGetApiUsageState_whenMyPartition() {
 | 
					 | 
				
			||||||
        TenantId tenantId = dummyTenant.getTenantId();
 | 
					 | 
				
			||||||
        service.myUsageStates.remove(tenantId);
 | 
					 | 
				
			||||||
        service.otherUsageStates.remove(tenantId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TopicPartitionInfo tpi = mock(TopicPartitionInfo.class);
 | 
					 | 
				
			||||||
        when(tpi.isMyPartition()).thenReturn(true);
 | 
					 | 
				
			||||||
        when(partitionService.resolve(any(), eq(dummyTenant.getId()), eq(dummyTenant.getId()))).thenReturn(tpi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TenantApiUsageState fetchedState = tenantApiUsageState;
 | 
					 | 
				
			||||||
        doReturn(fetchedState).when(service).getOrFetchState(tenantId, tenantId);
 | 
					 | 
				
			||||||
        ApiUsageState result = service.getApiUsageState(tenantId);
 | 
					 | 
				
			||||||
        assertThat(result, is(fetchedState.getApiUsageState()));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testGetApiUsageState_whenNotMyPartition() {
 | 
					 | 
				
			||||||
        TenantId tenantId = dummyTenant.getTenantId();
 | 
					 | 
				
			||||||
        service.myUsageStates.remove(tenantId);
 | 
					 | 
				
			||||||
        service.otherUsageStates.remove(tenantId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TopicPartitionInfo tpi = mock(TopicPartitionInfo.class);
 | 
					 | 
				
			||||||
        when(tpi.isMyPartition()).thenReturn(false);
 | 
					 | 
				
			||||||
        when(partitionService.resolve(any(), eq(tenantId), eq(tenantId))).thenReturn(tpi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ApiUsageState foundState = new ApiUsageState();
 | 
					 | 
				
			||||||
        foundState.setTenantId(tenantId);
 | 
					 | 
				
			||||||
        when(apiUsageStateService.findTenantApiUsageState(tenantId)).thenReturn(foundState);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ApiUsageState result = service.getApiUsageState(tenantId);
 | 
					 | 
				
			||||||
        assertThat(result, is(foundState));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assertThat(service.otherUsageStates.get(tenantId), is(foundState));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testProcess_AllFeaturesTransitionToWarning() {
 | 
					 | 
				
			||||||
        TransportProtos.ToUsageStatsServiceMsg.Builder msgBuilder = TransportProtos.ToUsageStatsServiceMsg.newBuilder()
 | 
					 | 
				
			||||||
                .setTenantIdMSB(dummyTenant.getId().getId().getMostSignificantBits())
 | 
					 | 
				
			||||||
                .setTenantIdLSB(dummyTenant.getId().getId().getLeastSignificantBits())
 | 
					 | 
				
			||||||
                .setCustomerIdMSB(0)
 | 
					 | 
				
			||||||
                .setCustomerIdLSB(0)
 | 
					 | 
				
			||||||
                .setServiceId("testService");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {
 | 
					 | 
				
			||||||
            if (key.getApiFeature() != null) {
 | 
					 | 
				
			||||||
                msgBuilder.addValues(TransportProtos.UsageStatsKVProto.newBuilder()
 | 
					 | 
				
			||||||
                        .setKey(key.name())
 | 
					 | 
				
			||||||
                        .setValue(VALUE_WARNING)
 | 
					 | 
				
			||||||
                        .build());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TransportProtos.ToUsageStatsServiceMsg statsMsg = msgBuilder.build();
 | 
					 | 
				
			||||||
        TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg> msg = new TbProtoQueueMsg<>(UUID.randomUUID(), statsMsg);
 | 
					 | 
				
			||||||
        TbCallback callback = mock(TbCallback.class);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        when(apiUsageStateService.update(any(ApiUsageState.class))).thenAnswer(invocation -> {
 | 
					 | 
				
			||||||
            ApiUsageState state = invocation.getArgument(0);
 | 
					 | 
				
			||||||
            state.setVersion(2L);
 | 
					 | 
				
			||||||
            return state;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        when(tenantService.findTenantById(dummyTenant.getTenantId())).thenReturn(dummyTenant);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        service.process(msg, callback);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        verify(callback, times(1)).onSuccess();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (ApiFeature feature : ApiFeature.values()) {
 | 
					 | 
				
			||||||
            if (containsFeature(feature)) {
 | 
					 | 
				
			||||||
                assertEquals(ApiUsageStateValue.WARNING, tenantApiUsageState.getFeatureValue(feature),
 | 
					 | 
				
			||||||
                        "For feature " + feature + " expected state WARNING");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assertEquals(ApiUsageStateValue.WARNING, tenantApiUsageState.getFeatureValue(ApiFeature.JS));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        verify(notificationRuleProcessor, atLeastOnce()).process(any());
 | 
					 | 
				
			||||||
        verify(mailExecutor, atLeastOnce()).submit((Runnable) any());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testProcess_AllFeaturesTransitionToDisabled() {
 | 
					 | 
				
			||||||
        TransportProtos.ToUsageStatsServiceMsg.Builder msgBuilder = TransportProtos.ToUsageStatsServiceMsg.newBuilder()
 | 
					 | 
				
			||||||
                .setTenantIdMSB(dummyTenant.getId().getId().getMostSignificantBits())
 | 
					 | 
				
			||||||
                .setTenantIdLSB(dummyTenant.getId().getId().getLeastSignificantBits())
 | 
					 | 
				
			||||||
                .setCustomerIdMSB(0)
 | 
					 | 
				
			||||||
                .setCustomerIdLSB(0)
 | 
					 | 
				
			||||||
                .setServiceId("testService");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {
 | 
					 | 
				
			||||||
            if (key.getApiFeature() != null) {
 | 
					 | 
				
			||||||
                msgBuilder.addValues(TransportProtos.UsageStatsKVProto.newBuilder()
 | 
					 | 
				
			||||||
                        .setKey(key.name())
 | 
					 | 
				
			||||||
                        .setValue(VALUE_DISABLE)
 | 
					 | 
				
			||||||
                        .build());
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        TransportProtos.ToUsageStatsServiceMsg statsMsg = msgBuilder.build();
 | 
					 | 
				
			||||||
        TbProtoQueueMsg<TransportProtos.ToUsageStatsServiceMsg> msg = new TbProtoQueueMsg<>(UUID.randomUUID(), statsMsg);
 | 
					 | 
				
			||||||
        TbCallback callback = mock(TbCallback.class);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        when(apiUsageStateService.update(any(ApiUsageState.class))).thenAnswer(invocation -> {
 | 
					 | 
				
			||||||
            ApiUsageState state = invocation.getArgument(0);
 | 
					 | 
				
			||||||
            state.setVersion(2L);
 | 
					 | 
				
			||||||
            return state;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        when(tenantService.findTenantById(dummyTenant.getTenantId())).thenReturn(dummyTenant);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        service.process(msg, callback);
 | 
					 | 
				
			||||||
        verify(callback, times(1)).onSuccess();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (ApiFeature feature : ApiFeature.values()) {
 | 
					 | 
				
			||||||
            if (containsFeature(feature)) {
 | 
					 | 
				
			||||||
                assertEquals(ApiUsageStateValue.DISABLED, tenantApiUsageState.getFeatureValue(feature),
 | 
					 | 
				
			||||||
                        "For feature " + feature + " expected state DISABLED");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        verify(notificationRuleProcessor, atLeastOnce()).process(any());
 | 
					 | 
				
			||||||
        verify(mailExecutor, atLeastOnce()).submit((Runnable) any());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testOnTenantProfileUpdate_updatesStateForMatchingTenant() {
 | 
					 | 
				
			||||||
        TenantProfileId currentProfileId = tenantApiUsageState.getTenantProfileId();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TenantProfileData newProfileData = new TenantProfileData();
 | 
					 | 
				
			||||||
        DefaultTenantProfileConfiguration newConfig = DefaultTenantProfileConfiguration.builder()
 | 
					 | 
				
			||||||
                .maxJSExecutions(NEW_MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxTransportMessages(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxRuleChains(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxTbelExecutions(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxDPStorageDays(NEW_MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxREExecutions(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxEmails(NEW_MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxSms(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxCreatedAlarms(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .warnThreshold(NEW_WARN_THRESHOLD_VALUE)
 | 
					 | 
				
			||||||
                .build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        newProfileData.setConfiguration(newConfig);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TenantProfile newProfile = new TenantProfile();
 | 
					 | 
				
			||||||
        newProfile.setId(currentProfileId);
 | 
					 | 
				
			||||||
        newProfile.setProfileData(newProfileData);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        when(tbTenantProfileCache.get(currentProfileId)).thenReturn(newProfile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        service.onTenantProfileUpdate(currentProfileId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assertEquals(currentProfileId, tenantApiUsageState.getTenantProfileId());
 | 
					 | 
				
			||||||
        assertEquals(newProfileData, tenantApiUsageState.getTenantProfileData());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Test
 | 
					 | 
				
			||||||
    public void testOnTenantUpdate_updatesStateWhenProfileChanged() {
 | 
					 | 
				
			||||||
        TenantProfileId oldProfileId = tenantApiUsageState.getTenantProfileId();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TenantProfileId newProfileId = new TenantProfileId(UUID.randomUUID());
 | 
					 | 
				
			||||||
        TenantProfileData newProfileData = new TenantProfileData();
 | 
					 | 
				
			||||||
        DefaultTenantProfileConfiguration newConfig = DefaultTenantProfileConfiguration.builder()
 | 
					 | 
				
			||||||
                .maxJSExecutions(NEW_MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxTransportMessages(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxRuleChains(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxTbelExecutions(NEW_MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxDPStorageDays(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxREExecutions(NEW_MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxEmails(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxSms(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .maxCreatedAlarms(MAX_ENABLE_VALUE)
 | 
					 | 
				
			||||||
                .warnThreshold(NEW_WARN_THRESHOLD_VALUE)
 | 
					 | 
				
			||||||
                .build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        newProfileData.setConfiguration(newConfig);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TenantProfile newProfile = new TenantProfile();
 | 
					 | 
				
			||||||
        newProfile.setId(newProfileId);
 | 
					 | 
				
			||||||
        newProfile.setProfileData(newProfileData);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        when(tbTenantProfileCache.get(dummyTenant.getTenantId())).thenReturn(newProfile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assertNotEquals(oldProfileId, newProfileId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        service.onTenantUpdate(dummyTenant.getTenantId());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assertEquals(newProfileId, tenantApiUsageState.getTenantProfileId());
 | 
					 | 
				
			||||||
        assertEquals(newProfileData, tenantApiUsageState.getTenantProfileData());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private boolean containsFeature(ApiFeature feature) {
 | 
					 | 
				
			||||||
        for (ApiUsageRecordKey key : ApiUsageRecordKey.values()) {
 | 
					 | 
				
			||||||
            if (key.getApiFeature() != null && key.getApiFeature().equals(feature)) {
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user