Added tests on api usage

This commit is contained in:
Artem Barysh 2025-02-19 18:26:34 +02:00
parent 5ced8457f1
commit a118c44cf5
2 changed files with 220 additions and 324 deletions

View File

@ -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);
}
}

View File

@ -15,359 +15,111 @@
*/
package org.thingsboard.server.service.apiusage;
import com.google.common.util.concurrent.Futures;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.*;
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.TenantProfileData;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.controller.AbstractControllerTest;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
import org.thingsboard.server.gen.transport.TransportProtos;
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 static org.hamcrest.CoreMatchers.is;
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;
import static org.junit.Assert.assertEquals;
@ExtendWith(MockitoExtension.class)
public class DefaultTbApiUsageStateServiceTest {
@DaoSqlTest
public class DefaultTbApiUsageStateServiceTest extends AbstractControllerTest {
@Mock
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
@Autowired
DefaultTbApiUsageStateService service;
private TenantApiUsageState tenantApiUsageState;
private Tenant dummyTenant;
@Autowired
private ApiUsageStateService apiUsageStateService;
private TenantId tenantId;
private Tenant savedTenant;
private static final int MAX_ENABLE_VALUE = 5000;
private static final long VALUE_WARNING = 4500L;
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;
@BeforeEach
public void setUp() {
var tenantId = TenantId.fromUUID(UUID.randomUUID());
dummyTenant = new Tenant();
dummyTenant.setId(tenantId);
dummyTenant.setEmail("test@tenant.com");
@Before
public void init() throws Exception {
loginSysAdmin();
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()
.maxJSExecutions(MAX_ENABLE_VALUE)
.maxTransportMessages(MAX_ENABLE_VALUE)
.maxRuleChains(MAX_ENABLE_VALUE)
.maxTbelExecutions(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)
.build();
TenantProfileData profileData = new TenantProfileData();
profileData.setConfiguration(config);
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;
tenantProfileData.setConfiguration(config);
tenantProfile.setProfileData(tenantProfileData);
return tenantProfile;
}
}