created tenant profile configuration
This commit is contained in:
parent
1f6c0c54cd
commit
41212e11c0
@ -5,7 +5,7 @@
|
|||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import lombok.Setter;
|
|||||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||||
import org.thingsboard.server.common.data.ApiUsageState;
|
import org.thingsboard.server.common.data.ApiUsageState;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantProfileId;
|
import org.thingsboard.server.common.data.id.TenantProfileId;
|
||||||
import org.thingsboard.server.common.msg.tools.SchedulerUtils;
|
import org.thingsboard.server.common.msg.tools.SchedulerUtils;
|
||||||
|
|||||||
@ -30,7 +30,8 @@ import org.thingsboard.server.common.data.Device;
|
|||||||
import org.thingsboard.server.common.data.DeviceProfile;
|
import org.thingsboard.server.common.data.DeviceProfile;
|
||||||
import org.thingsboard.server.common.data.Tenant;
|
import org.thingsboard.server.common.data.Tenant;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.common.data.User;
|
import org.thingsboard.server.common.data.User;
|
||||||
import org.thingsboard.server.common.data.asset.Asset;
|
import org.thingsboard.server.common.data.asset.Asset;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
@ -127,6 +128,10 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
|
|||||||
public void createDefaultTenantProfiles() throws Exception {
|
public void createDefaultTenantProfiles() throws Exception {
|
||||||
tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID);
|
tenantProfileService.findOrCreateDefaultTenantProfile(TenantId.SYS_TENANT_ID);
|
||||||
|
|
||||||
|
TenantProfileData tenantProfileData = new TenantProfileData();
|
||||||
|
DefaultTenantProfileConfiguration configuration = new DefaultTenantProfileConfiguration();
|
||||||
|
tenantProfileData.setConfiguration(configuration);
|
||||||
|
|
||||||
TenantProfile isolatedTbCoreProfile = new TenantProfile();
|
TenantProfile isolatedTbCoreProfile = new TenantProfile();
|
||||||
isolatedTbCoreProfile.setDefault(false);
|
isolatedTbCoreProfile.setDefault(false);
|
||||||
isolatedTbCoreProfile.setName("Isolated TB Core");
|
isolatedTbCoreProfile.setName("Isolated TB Core");
|
||||||
@ -134,6 +139,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
|
|||||||
isolatedTbCoreProfile.setDescription("Isolated TB Core tenant profile");
|
isolatedTbCoreProfile.setDescription("Isolated TB Core tenant profile");
|
||||||
isolatedTbCoreProfile.setIsolatedTbCore(true);
|
isolatedTbCoreProfile.setIsolatedTbCore(true);
|
||||||
isolatedTbCoreProfile.setIsolatedTbRuleEngine(false);
|
isolatedTbCoreProfile.setIsolatedTbRuleEngine(false);
|
||||||
|
isolatedTbCoreProfile.setProfileData(tenantProfileData);
|
||||||
try {
|
try {
|
||||||
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreProfile);
|
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreProfile);
|
||||||
} catch (DataValidationException e) {
|
} catch (DataValidationException e) {
|
||||||
@ -147,6 +153,8 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
|
|||||||
isolatedTbRuleEngineProfile.setDescription("Isolated TB Rule Engine tenant profile");
|
isolatedTbRuleEngineProfile.setDescription("Isolated TB Rule Engine tenant profile");
|
||||||
isolatedTbRuleEngineProfile.setIsolatedTbCore(false);
|
isolatedTbRuleEngineProfile.setIsolatedTbCore(false);
|
||||||
isolatedTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
|
isolatedTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
|
||||||
|
isolatedTbRuleEngineProfile.setProfileData(tenantProfileData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbRuleEngineProfile);
|
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbRuleEngineProfile);
|
||||||
} catch (DataValidationException e) {
|
} catch (DataValidationException e) {
|
||||||
@ -160,6 +168,8 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
|
|||||||
isolatedTbCoreAndTbRuleEngineProfile.setDescription("Isolated TB Core and TB Rule Engine tenant profile");
|
isolatedTbCoreAndTbRuleEngineProfile.setDescription("Isolated TB Core and TB Rule Engine tenant profile");
|
||||||
isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbCore(true);
|
isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbCore(true);
|
||||||
isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
|
isolatedTbCoreAndTbRuleEngineProfile.setIsolatedTbRuleEngine(true);
|
||||||
|
isolatedTbCoreAndTbRuleEngineProfile.setProfileData(tenantProfileData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreAndTbRuleEngineProfile);
|
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, isolatedTbCoreAndTbRuleEngineProfile);
|
||||||
} catch (DataValidationException e) {
|
} catch (DataValidationException e) {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.thingsboard.server.common.data.EntityInfo;
|
import org.thingsboard.server.common.data.EntityInfo;
|
||||||
import org.thingsboard.server.common.data.Tenant;
|
import org.thingsboard.server.common.data.Tenant;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.thingsboard.server.common.data.id.TenantProfileId;
|
import org.thingsboard.server.common.data.id.TenantProfileId;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data;
|
||||||
|
|
||||||
|
public enum TenantProfileType {
|
||||||
|
DEFAULT
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.tenant.profile;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.thingsboard.server.common.data.TenantProfileType;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DefaultTenantProfileConfiguration implements TenantProfileConfiguration {
|
||||||
|
|
||||||
|
private long maxDevices;
|
||||||
|
private long maxAssets;
|
||||||
|
|
||||||
|
private String transportTenantMsgRateLimit;
|
||||||
|
private String transportTenantTelemetryMsgRateLimit;
|
||||||
|
private String transportTenantTelemetryDataPointsRateLimit;
|
||||||
|
private String transportDeviceMsgRateLimit;
|
||||||
|
private String transportDeviceTelemetryMsgRateLimit;
|
||||||
|
private String transportDeviceTelemetryDataPointsRateLimit;
|
||||||
|
|
||||||
|
private long maxTransportMessages;
|
||||||
|
private long maxTransportDataPoints;
|
||||||
|
private long maxREExecutions;
|
||||||
|
private long maxJSExecutions;
|
||||||
|
private long maxDPStorageDays;
|
||||||
|
private int maxRuleNodeExecutionsPerMessage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TenantProfileType getType() {
|
||||||
|
return TenantProfileType.DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.tenant.profile;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import org.thingsboard.server.common.data.TenantProfileType;
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
include = JsonTypeInfo.As.PROPERTY,
|
||||||
|
property = "type")
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = DefaultTenantProfileConfiguration.class, name = "DEFAULT")})
|
||||||
|
public interface TenantProfileConfiguration {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
TenantProfileType getType();
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.thingsboard.server.common.data;
|
package org.thingsboard.server.common.data.tenant.profile;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||||
@ -26,6 +26,8 @@ import java.util.Map;
|
|||||||
@Data
|
@Data
|
||||||
public class TenantProfileData {
|
public class TenantProfileData {
|
||||||
|
|
||||||
|
private TenantProfileConfiguration configuration;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private Map<String, Object> properties = new HashMap<>();
|
private Map<String, Object> properties = new HashMap<>();
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ package org.thingsboard.server.common.transport.limits;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
|
||||||
import org.thingsboard.server.common.data.id.DeviceId;
|
import org.thingsboard.server.common.data.id.DeviceId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.common.transport.TransportTenantProfileCache;
|
import org.thingsboard.server.common.transport.TransportTenantProfileCache;
|
||||||
import org.thingsboard.server.common.transport.profile.TenantProfileUpdateResult;
|
import org.thingsboard.server.common.transport.profile.TenantProfileUpdateResult;
|
||||||
import org.thingsboard.server.queue.util.TbTransportComponent;
|
import org.thingsboard.server.queue.util.TbTransportComponent;
|
||||||
|
|||||||
@ -22,14 +22,13 @@ import lombok.EqualsAndHashCode;
|
|||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
import org.hibernate.annotations.TypeDef;
|
import org.hibernate.annotations.TypeDef;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
|
||||||
import org.thingsboard.server.common.data.id.TenantProfileId;
|
import org.thingsboard.server.common.data.id.TenantProfileId;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.dao.model.BaseSqlEntity;
|
import org.thingsboard.server.dao.model.BaseSqlEntity;
|
||||||
import org.thingsboard.server.dao.model.ModelConstants;
|
import org.thingsboard.server.dao.model.ModelConstants;
|
||||||
import org.thingsboard.server.dao.model.SearchTextEntity;
|
import org.thingsboard.server.dao.model.SearchTextEntity;
|
||||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
||||||
import org.thingsboard.server.dao.util.mapping.JsonBinaryType;
|
import org.thingsboard.server.dao.util.mapping.JsonBinaryType;
|
||||||
import org.thingsboard.server.dao.util.mapping.JsonStringType;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|||||||
@ -23,20 +23,18 @@ import org.springframework.cache.Cache;
|
|||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.DeviceProfile;
|
|
||||||
import org.thingsboard.server.common.data.EntityInfo;
|
import org.thingsboard.server.common.data.EntityInfo;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
|
||||||
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.id.TenantProfileId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
import org.thingsboard.server.dao.service.DataValidator;
|
import org.thingsboard.server.dao.service.DataValidator;
|
||||||
import org.thingsboard.server.dao.service.PaginatedRemover;
|
import org.thingsboard.server.dao.service.PaginatedRemover;
|
||||||
import org.thingsboard.server.dao.service.Validator;
|
import org.thingsboard.server.dao.service.Validator;
|
||||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|||||||
@ -21,13 +21,12 @@ import org.junit.Test;
|
|||||||
import org.thingsboard.server.common.data.EntityInfo;
|
import org.thingsboard.server.common.data.EntityInfo;
|
||||||
import org.thingsboard.server.common.data.Tenant;
|
import org.thingsboard.server.common.data.Tenant;
|
||||||
import org.thingsboard.server.common.data.TenantProfile;
|
import org.thingsboard.server.common.data.TenantProfile;
|
||||||
import org.thingsboard.server.common.data.TenantProfileData;
|
|
||||||
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.id.TenantProfileId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -188,8 +187,8 @@ public class BaseTenantProfileServiceTest extends AbstractServiceTest {
|
|||||||
Assert.assertTrue(pageData.getData().isEmpty());
|
Assert.assertTrue(pageData.getData().isEmpty());
|
||||||
tenantProfiles.addAll(pageData.getData());
|
tenantProfiles.addAll(pageData.getData());
|
||||||
|
|
||||||
for (int i=0;i<28;i++) {
|
for (int i = 0; i < 28; i++) {
|
||||||
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"+i);
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile" + i);
|
||||||
tenantProfiles.add(tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile));
|
tenantProfiles.add(tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +223,8 @@ public class BaseTenantProfileServiceTest extends AbstractServiceTest {
|
|||||||
|
|
||||||
List<TenantProfile> tenantProfiles = new ArrayList<>();
|
List<TenantProfile> tenantProfiles = new ArrayList<>();
|
||||||
|
|
||||||
for (int i=0;i<28;i++) {
|
for (int i = 0; i < 28; i++) {
|
||||||
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile"+i);
|
TenantProfile tenantProfile = this.createTenantProfile("Tenant Profile" + i);
|
||||||
tenantProfiles.add(tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile));
|
tenantProfiles.add(tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -113,6 +113,8 @@ import { AlarmScheduleInfoComponent } from './profile/alarm/alarm-schedule-info.
|
|||||||
import { AlarmScheduleDialogComponent } from '@home/components/profile/alarm/alarm-schedule-dialog.component';
|
import { AlarmScheduleDialogComponent } from '@home/components/profile/alarm/alarm-schedule-dialog.component';
|
||||||
import { EditAlarmDetailsDialogComponent } from './profile/alarm/edit-alarm-details-dialog.component';
|
import { EditAlarmDetailsDialogComponent } from './profile/alarm/edit-alarm-details-dialog.component';
|
||||||
import { AlarmRuleConditionDialogComponent } from '@home/components/profile/alarm/alarm-rule-condition-dialog.component';
|
import { AlarmRuleConditionDialogComponent } from '@home/components/profile/alarm/alarm-rule-condition-dialog.component';
|
||||||
|
import { DefaultTenantProfileConfigurationComponent } from './profile/tenant/default-tenant-profile-configuration.component';
|
||||||
|
import { TenantProfileConfigurationComponent } from './profile/tenant/tenant-profile-configuration.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations:
|
declarations:
|
||||||
@ -182,6 +184,8 @@ import { AlarmRuleConditionDialogComponent } from '@home/components/profile/alar
|
|||||||
FilterUserInfoDialogComponent,
|
FilterUserInfoDialogComponent,
|
||||||
FilterPredicateValueComponent,
|
FilterPredicateValueComponent,
|
||||||
TenantProfileAutocompleteComponent,
|
TenantProfileAutocompleteComponent,
|
||||||
|
DefaultTenantProfileConfigurationComponent,
|
||||||
|
TenantProfileConfigurationComponent,
|
||||||
TenantProfileDataComponent,
|
TenantProfileDataComponent,
|
||||||
TenantProfileComponent,
|
TenantProfileComponent,
|
||||||
TenantProfileDialogComponent,
|
TenantProfileDialogComponent,
|
||||||
|
|||||||
@ -204,7 +204,6 @@ export class TenantProfileAutocompleteComponent implements ControlValueAccessor,
|
|||||||
createTenantProfile($event: Event, profileName: string) {
|
createTenantProfile($event: Event, profileName: string) {
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
const tenantProfile: TenantProfile = {
|
const tenantProfile: TenantProfile = {
|
||||||
id: null,
|
|
||||||
name: profileName
|
name: profileName
|
||||||
};
|
};
|
||||||
this.openTenantProfileDialog(tenantProfile, true);
|
this.openTenantProfileDialog(tenantProfile, true);
|
||||||
|
|||||||
@ -16,9 +16,15 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<form [formGroup]="tenantProfileDataFormGroup" style="padding-bottom: 16px;">
|
<form [formGroup]="tenantProfileDataFormGroup" style="padding-bottom: 16px;">
|
||||||
<tb-json-object-edit
|
<mat-expansion-panel [expanded]="true">
|
||||||
[required]="required"
|
<mat-expansion-panel-header>
|
||||||
label="{{ 'tenant-profile.data' | translate }}"
|
<mat-panel-title>
|
||||||
formControlName="tenantProfileData">
|
<div translate>tenant-profile.profile-configuration</div>
|
||||||
</tb-json-object-edit>
|
</mat-panel-title>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
<tb-tenant-profile-configuration
|
||||||
|
formControlName="configuration"
|
||||||
|
required>
|
||||||
|
</tb-tenant-profile-configuration>
|
||||||
|
</mat-expansion-panel>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export class TenantProfileDataComponent implements ControlValueAccessor, OnInit
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.tenantProfileDataFormGroup = this.fb.group({
|
this.tenantProfileDataFormGroup = this.fb.group({
|
||||||
tenantProfileData: [null, Validators.required]
|
configuration: [null, Validators.required]
|
||||||
});
|
});
|
||||||
this.tenantProfileDataFormGroup.valueChanges.subscribe(() => {
|
this.tenantProfileDataFormGroup.valueChanges.subscribe(() => {
|
||||||
this.updateModel();
|
this.updateModel();
|
||||||
@ -79,13 +79,13 @@ export class TenantProfileDataComponent implements ControlValueAccessor, OnInit
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeValue(value: TenantProfileData | null): void {
|
writeValue(value: TenantProfileData | null): void {
|
||||||
this.tenantProfileDataFormGroup.get('tenantProfileData').patchValue(value, {emitEvent: false});
|
this.tenantProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateModel() {
|
private updateModel() {
|
||||||
let tenantProfileData: TenantProfileData = null;
|
let tenantProfileData: TenantProfileData = null;
|
||||||
if (this.tenantProfileDataFormGroup.valid) {
|
if (this.tenantProfileDataFormGroup.valid) {
|
||||||
tenantProfileData = this.tenantProfileDataFormGroup.getRawValue().tenantProfileData;
|
tenantProfileData = this.tenantProfileDataFormGroup.getRawValue();
|
||||||
}
|
}
|
||||||
this.propagateChange(tenantProfileData);
|
this.propagateChange(tenantProfileData);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,12 @@ import { Component, Inject, Input, Optional } from '@angular/core';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { TenantProfile } from '@app/shared/models/tenant.model';
|
import {
|
||||||
|
createTenantProfileConfiguration,
|
||||||
|
TenantProfile,
|
||||||
|
TenantProfileData,
|
||||||
|
TenantProfileType
|
||||||
|
} from '@app/shared/models/tenant.model';
|
||||||
import { ActionNotificationShow } from '@app/core/notification/notification.actions';
|
import { ActionNotificationShow } from '@app/core/notification/notification.actions';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
|
import { EntityTableConfig } from '@home/models/entity/entities-table-config.models';
|
||||||
@ -56,7 +61,9 @@ export class TenantProfileComponent extends EntityComponent<TenantProfile> {
|
|||||||
name: [entity ? entity.name : '', [Validators.required]],
|
name: [entity ? entity.name : '', [Validators.required]],
|
||||||
isolatedTbCore: [entity ? entity.isolatedTbCore : false, []],
|
isolatedTbCore: [entity ? entity.isolatedTbCore : false, []],
|
||||||
isolatedTbRuleEngine: [entity ? entity.isolatedTbRuleEngine : false, []],
|
isolatedTbRuleEngine: [entity ? entity.isolatedTbRuleEngine : false, []],
|
||||||
profileData: [entity && !this.isAdd ? entity.profileData : {}, []],
|
profileData: [entity && !this.isAdd ? entity.profileData : {
|
||||||
|
configuration: createTenantProfileConfiguration(TenantProfileType.DEFAULT)
|
||||||
|
} as TenantProfileData, []],
|
||||||
description: [entity ? entity.description : '', []],
|
description: [entity ? entity.description : '', []],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -66,7 +73,9 @@ export class TenantProfileComponent extends EntityComponent<TenantProfile> {
|
|||||||
this.entityForm.patchValue({name: entity.name});
|
this.entityForm.patchValue({name: entity.name});
|
||||||
this.entityForm.patchValue({isolatedTbCore: entity.isolatedTbCore});
|
this.entityForm.patchValue({isolatedTbCore: entity.isolatedTbCore});
|
||||||
this.entityForm.patchValue({isolatedTbRuleEngine: entity.isolatedTbRuleEngine});
|
this.entityForm.patchValue({isolatedTbRuleEngine: entity.isolatedTbRuleEngine});
|
||||||
this.entityForm.patchValue({profileData: entity.profileData});
|
this.entityForm.patchValue({profileData: !this.isAdd ? entity.profileData: {
|
||||||
|
configuration: createTenantProfileConfiguration(TenantProfileType.DEFAULT)
|
||||||
|
} as TenantProfileData});
|
||||||
this.entityForm.patchValue({description: entity.description});
|
this.entityForm.patchValue({description: entity.description});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,141 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<section [formGroup]="defaultTenantProfileConfigurationFormGroup">
|
||||||
|
<section formGroupName="configuration" fxLayout="column">
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.maximum-devices</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxDevices"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxDevices').hasError('required')">
|
||||||
|
{{ 'tenant-profile.maximum-devices-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxDevices').hasError('min')">
|
||||||
|
{{ 'tenant-profile.maximum-devices-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.maximum-assets</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxAssets"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxAssets').hasError('required')">
|
||||||
|
{{ 'tenant-profile.maximum-assets-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxAssets').hasError('min')">
|
||||||
|
{{ 'tenant-profile.maximum-assets-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.max-transport-messages</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxTransportMessages"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxTransportMessages').hasError('required')">
|
||||||
|
{{ 'tenant-profile.max-transport-messages-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxTransportMessages').hasError('min')">
|
||||||
|
{{ 'tenant-profile.max-transport-messages-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.max-transport-data-points</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxTransportDataPoints"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxTransportDataPoints').hasError('required')">
|
||||||
|
{{ 'tenant-profile.max-transport-data-points-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxTransportDataPoints').hasError('min')">
|
||||||
|
{{ 'tenant-profile.max-transport-data-points-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.max-r-e-executions</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxREExecutions"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxREExecutions').hasError('required')">
|
||||||
|
{{ 'tenant-profile.max-r-e-executions-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxREExecutions').hasError('min')">
|
||||||
|
{{ 'tenant-profile.max-r-e-executions-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.max-j-s-executions</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxJSExecutions"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxJSExecutions').hasError('required')">
|
||||||
|
{{ 'tenant-profile.max-j-s-executions-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxJSExecutions').hasError('min')">
|
||||||
|
{{ 'tenant-profile.max-j-s-executions-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.max-d-p-storage-days</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxDPStorageDays"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxDPStorageDays').hasError('required')">
|
||||||
|
{{ 'tenant-profile.max-d-p-storage-days-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxDPStorageDays').hasError('min')">
|
||||||
|
{{ 'tenant-profile.max-d-p-storage-days-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.max-rule-node-executions-per-message</mat-label>
|
||||||
|
<input matInput required min="0" step="1"
|
||||||
|
formControlName="maxRuleNodeExecutionsPerMessage"
|
||||||
|
type="number">
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxRuleNodeExecutionsPerMessage').hasError('required')">
|
||||||
|
{{ 'tenant-profile.max-rule-node-executions-per-message-required' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('configuration.maxRuleNodeExecutionsPerMessage').hasError('min')">
|
||||||
|
{{ 'tenant-profile.max-rule-node-executions-per-message-range' | translate}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.transport-tenant-msg-rate-limit</mat-label>
|
||||||
|
<input matInput formControlName="transportTenantMsgRateLimit">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.transport-tenant-telemetry-msg-rate-limit</mat-label>
|
||||||
|
<input matInput formControlName="transportTenantTelemetryMsgRateLimit">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.transport-tenant-telemetry-data-points-rate-limit</mat-label>
|
||||||
|
<input matInput formControlName="transportTenantTelemetryDataPointsRateLimit">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.transport-device-msg-rate-limit</mat-label>
|
||||||
|
<input matInput formControlName="transportDeviceMsgRateLimit">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.transport-device-telemetry-msg-rate-limit</mat-label>
|
||||||
|
<input matInput formControlName="transportDeviceTelemetryMsgRateLimit">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="mat-block">
|
||||||
|
<mat-label translate>tenant-profile.transport-device-telemetry-data-points-rate-limit</mat-label>
|
||||||
|
<input matInput formControlName="transportDeviceTelemetryDataPointsRateLimit">
|
||||||
|
</mat-form-field>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
///
|
||||||
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
|
||||||
|
import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
||||||
|
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { AppState } from '@app/core/core.state';
|
||||||
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||||
|
import {
|
||||||
|
DefaultTenantProfileConfiguration,
|
||||||
|
TenantProfileConfiguration,
|
||||||
|
TenantProfileType
|
||||||
|
} from '@shared/models/tenant.model';
|
||||||
|
import { isDefinedAndNotNull } from '@core/utils';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'tb-default-tenant-profile-configuration',
|
||||||
|
templateUrl: './default-tenant-profile-configuration.component.html',
|
||||||
|
styleUrls: [],
|
||||||
|
providers: [{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => DefaultTenantProfileConfigurationComponent),
|
||||||
|
multi: true
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
export class DefaultTenantProfileConfigurationComponent implements ControlValueAccessor, OnInit {
|
||||||
|
|
||||||
|
defaultTenantProfileConfigurationFormGroup: FormGroup;
|
||||||
|
|
||||||
|
private requiredValue: boolean;
|
||||||
|
get required(): boolean {
|
||||||
|
return this.requiredValue;
|
||||||
|
}
|
||||||
|
@Input()
|
||||||
|
set required(value: boolean) {
|
||||||
|
this.requiredValue = coerceBooleanProperty(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
disabled: boolean;
|
||||||
|
|
||||||
|
private propagateChange = (v: any) => { };
|
||||||
|
|
||||||
|
constructor(private store: Store<AppState>,
|
||||||
|
private fb: FormBuilder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.propagateChange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.defaultTenantProfileConfigurationFormGroup = this.fb.group({
|
||||||
|
configuration: this.fb.group({
|
||||||
|
maxDevices: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxAssets: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
transportTenantMsgRateLimit: [null, []],
|
||||||
|
transportTenantTelemetryMsgRateLimit: [null, []],
|
||||||
|
transportTenantTelemetryDataPointsRateLimit: [null, []],
|
||||||
|
transportDeviceMsgRateLimit: [null, []],
|
||||||
|
transportDeviceTelemetryMsgRateLimit: [null, []],
|
||||||
|
transportDeviceTelemetryDataPointsRateLimit: [null, []],
|
||||||
|
maxTransportMessages: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxTransportDataPoints: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxREExecutions: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxJSExecutions: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxDPStorageDays: [null, [Validators.required, Validators.min(0)]],
|
||||||
|
maxRuleNodeExecutionsPerMessage: [null, [Validators.required, Validators.min(0)]]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
this.defaultTenantProfileConfigurationFormGroup.valueChanges.subscribe(() => {
|
||||||
|
this.updateModel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisabledState(isDisabled: boolean): void {
|
||||||
|
this.disabled = isDisabled;
|
||||||
|
if (this.disabled) {
|
||||||
|
this.defaultTenantProfileConfigurationFormGroup.disable({emitEvent: false});
|
||||||
|
} else {
|
||||||
|
this.defaultTenantProfileConfigurationFormGroup.enable({emitEvent: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(value: DefaultTenantProfileConfiguration | null): void {
|
||||||
|
if (isDefinedAndNotNull(value)) {
|
||||||
|
this.defaultTenantProfileConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateModel() {
|
||||||
|
let configuration: TenantProfileConfiguration = null;
|
||||||
|
if (this.defaultTenantProfileConfigurationFormGroup.valid) {
|
||||||
|
configuration = this.defaultTenantProfileConfigurationFormGroup.getRawValue().configuration;
|
||||||
|
configuration.type = TenantProfileType.DEFAULT;
|
||||||
|
}
|
||||||
|
this.propagateChange(configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<div [formGroup]="tenantProfileConfigurationFormGroup">
|
||||||
|
<div [ngSwitch]="type">
|
||||||
|
<ng-template [ngSwitchCase]="tenantProfileType.DEFAULT">
|
||||||
|
<tb-default-tenant-profile-configuration
|
||||||
|
[required]="required"
|
||||||
|
formControlName="configuration">
|
||||||
|
</tb-default-tenant-profile-configuration>
|
||||||
|
</ng-template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
///
|
||||||
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
|
||||||
|
import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
||||||
|
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { AppState } from '@app/core/core.state';
|
||||||
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
||||||
|
import { deepClone } from '@core/utils';
|
||||||
|
import { TenantProfileConfiguration, TenantProfileType } from '@shared/models/tenant.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'tb-tenant-profile-configuration',
|
||||||
|
templateUrl: './tenant-profile-configuration.component.html',
|
||||||
|
styleUrls: [],
|
||||||
|
providers: [{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => TenantProfileConfigurationComponent),
|
||||||
|
multi: true
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
export class TenantProfileConfigurationComponent implements ControlValueAccessor, OnInit {
|
||||||
|
|
||||||
|
tenantProfileType = TenantProfileType;
|
||||||
|
|
||||||
|
tenantProfileConfigurationFormGroup: FormGroup;
|
||||||
|
|
||||||
|
private requiredValue: boolean;
|
||||||
|
get required(): boolean {
|
||||||
|
return this.requiredValue;
|
||||||
|
}
|
||||||
|
@Input()
|
||||||
|
set required(value: boolean) {
|
||||||
|
this.requiredValue = coerceBooleanProperty(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
disabled: boolean;
|
||||||
|
|
||||||
|
type: TenantProfileType;
|
||||||
|
|
||||||
|
private propagateChange = (v: any) => { };
|
||||||
|
|
||||||
|
constructor(private store: Store<AppState>,
|
||||||
|
private fb: FormBuilder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.propagateChange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.tenantProfileConfigurationFormGroup = this.fb.group({
|
||||||
|
configuration: [null, Validators.required]
|
||||||
|
});
|
||||||
|
this.tenantProfileConfigurationFormGroup.valueChanges.subscribe(() => {
|
||||||
|
this.updateModel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisabledState(isDisabled: boolean): void {
|
||||||
|
this.disabled = isDisabled;
|
||||||
|
if (this.disabled) {
|
||||||
|
this.tenantProfileConfigurationFormGroup.disable({emitEvent: false});
|
||||||
|
} else {
|
||||||
|
this.tenantProfileConfigurationFormGroup.enable({emitEvent: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(value: TenantProfileConfiguration | null): void {
|
||||||
|
this.type = value?.type;
|
||||||
|
const configuration = deepClone(value);
|
||||||
|
if (configuration) {
|
||||||
|
delete configuration.type;
|
||||||
|
}
|
||||||
|
this.tenantProfileConfigurationFormGroup.patchValue({configuration}, {emitEvent: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateModel() {
|
||||||
|
let configuration: TenantProfileConfiguration = null;
|
||||||
|
if (this.tenantProfileConfigurationFormGroup.valid) {
|
||||||
|
configuration = this.tenantProfileConfigurationFormGroup.getRawValue().configuration;
|
||||||
|
configuration.type = this.type;
|
||||||
|
}
|
||||||
|
this.propagateChange(configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,8 +19,59 @@ import { TenantId } from './id/tenant-id';
|
|||||||
import { TenantProfileId } from '@shared/models/id/tenant-profile-id';
|
import { TenantProfileId } from '@shared/models/id/tenant-profile-id';
|
||||||
import { BaseData } from '@shared/models/base-data';
|
import { BaseData } from '@shared/models/base-data';
|
||||||
|
|
||||||
|
export enum TenantProfileType {
|
||||||
|
DEFAULT = 'DEFAULT'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DefaultTenantProfileConfiguration {
|
||||||
|
maxDevices: number;
|
||||||
|
maxAssets: number;
|
||||||
|
|
||||||
|
transportTenantMsgRateLimit?: string;
|
||||||
|
transportTenantTelemetryMsgRateLimit?: string;
|
||||||
|
transportTenantTelemetryDataPointsRateLimit?: string;
|
||||||
|
transportDeviceMsgRateLimit?: string;
|
||||||
|
transportDeviceTelemetryMsgRateLimit?: string;
|
||||||
|
transportDeviceTelemetryDataPointsRateLimit?: string;
|
||||||
|
|
||||||
|
maxTransportMessages: number;
|
||||||
|
maxTransportDataPoints: number;
|
||||||
|
maxREExecutions: number;
|
||||||
|
maxJSExecutions: number;
|
||||||
|
maxDPStorageDays: number;
|
||||||
|
maxRuleNodeExecutionsPerMessage: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TenantProfileConfigurations = DefaultTenantProfileConfiguration;
|
||||||
|
|
||||||
|
export interface TenantProfileConfiguration extends TenantProfileConfigurations {
|
||||||
|
type: TenantProfileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createTenantProfileConfiguration(type: TenantProfileType): TenantProfileConfiguration {
|
||||||
|
let configuration: TenantProfileConfiguration = null;
|
||||||
|
if (type) {
|
||||||
|
switch (type) {
|
||||||
|
case TenantProfileType.DEFAULT:
|
||||||
|
const defaultConfiguration: DefaultTenantProfileConfiguration = {
|
||||||
|
maxDevices: 0,
|
||||||
|
maxAssets: 0,
|
||||||
|
maxTransportMessages: 0,
|
||||||
|
maxTransportDataPoints: 0,
|
||||||
|
maxREExecutions: 0,
|
||||||
|
maxJSExecutions: 0,
|
||||||
|
maxDPStorageDays: 0,
|
||||||
|
maxRuleNodeExecutionsPerMessage: 0
|
||||||
|
};
|
||||||
|
configuration = {...defaultConfiguration, type: TenantProfileType.DEFAULT};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TenantProfileData {
|
export interface TenantProfileData {
|
||||||
[key: string]: string;
|
configuration: TenantProfileConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TenantProfile extends BaseData<TenantProfileId> {
|
export interface TenantProfile extends BaseData<TenantProfileId> {
|
||||||
|
|||||||
@ -1923,6 +1923,7 @@
|
|||||||
"name": "Name",
|
"name": "Name",
|
||||||
"name-required": "Name is required.",
|
"name-required": "Name is required.",
|
||||||
"data": "Profile data",
|
"data": "Profile data",
|
||||||
|
"profile-configuration": "Profile configuration",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"default": "Default",
|
"default": "Default",
|
||||||
"delete-tenant-profile-title": "Are you sure you want to delete the tenant profile '{{tenantProfileName}}'?",
|
"delete-tenant-profile-title": "Are you sure you want to delete the tenant profile '{{tenantProfileName}}'?",
|
||||||
@ -1932,7 +1933,37 @@
|
|||||||
"set-default-tenant-profile-title": "Are you sure you want to make the tenant profile '{{tenantProfileName}}' default?",
|
"set-default-tenant-profile-title": "Are you sure you want to make the tenant profile '{{tenantProfileName}}' default?",
|
||||||
"set-default-tenant-profile-text": "After the confirmation the tenant profile will be marked as default and will be used for new tenants with no profile specified.",
|
"set-default-tenant-profile-text": "After the confirmation the tenant profile will be marked as default and will be used for new tenants with no profile specified.",
|
||||||
"no-tenant-profiles-found": "No tenant profiles found.",
|
"no-tenant-profiles-found": "No tenant profiles found.",
|
||||||
"create-new-tenant-profile": "Create a new one!"
|
"create-new-tenant-profile": "Create a new one!",
|
||||||
|
"maximum-devices": "Maximum number of devices (0 - unlimited)",
|
||||||
|
"maximum-devices-required": "Maximum number of devices is required.",
|
||||||
|
"maximum-devices-range": "Minimum number of devices can't be negative",
|
||||||
|
"maximum-assets": "Maximum number of assets (0 - unlimited)",
|
||||||
|
"maximum-assets-required": "Maximum number of assets is required.",
|
||||||
|
"maximum-assets-range": "Maximum number of assets can't be negative",
|
||||||
|
"transport-tenant-msg-rate-limit": "Transport tenant messages rate limit.",
|
||||||
|
"transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages rate limit.",
|
||||||
|
"transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points rate limit.",
|
||||||
|
"transport-device-msg-rate-limit": "Transport device messages rate limit.",
|
||||||
|
"transport-device-telemetry-msg-rate-limit": "Transport device telemetry messages rate limit.",
|
||||||
|
"transport-device-telemetry-data-points-rate-limit": "Transport device telemetry data points rate limit.",
|
||||||
|
"max-transport-messages": "Maximum number of transport messages (0 - unlimited)",
|
||||||
|
"max-transport-messages-required": "Maximum number of transport messages is required.",
|
||||||
|
"max-transport-messages-range": "Maximum number of transport messages can't be negative",
|
||||||
|
"max-transport-data-points": "Maximum number of transport data points (0 - unlimited)",
|
||||||
|
"max-transport-data-points-required": "Maximum number of transport data points is required.",
|
||||||
|
"max-transport-data-points-range": "Minimum number of transport data points can't be negative",
|
||||||
|
"max-r-e-executions": "Maximum number of Rule Engine executions (0 - unlimited)",
|
||||||
|
"max-r-e-executions-required": "Maximum number of Rule Engine executions is required.",
|
||||||
|
"max-r-e-executions-range": "Minimum number of Rule Engine executions can't be negative",
|
||||||
|
"max-j-s-executions": "Maximum number of JavaScript executions (0 - unlimited)",
|
||||||
|
"max-j-s-executions-required": "Maximum number of JavaScript executions is required.",
|
||||||
|
"max-j-s-executions-range": "Minimum number of JavaScript executions can't be negative",
|
||||||
|
"max-d-p-storage-days": "Maximum number of data points storage days (0 - unlimited)",
|
||||||
|
"max-d-p-storage-days-required": "Maximum number of data points storage days is required.",
|
||||||
|
"max-d-p-storage-days-range": "Minimum number of data points storage days can't be negative",
|
||||||
|
"max-rule-node-executions-per-message": "Maximum number of rule node executions per message (0 - unlimited)",
|
||||||
|
"max-rule-node-executions-per-message-required": "Maximum number of rule node executions per message is required.",
|
||||||
|
"max-rule-node-executions-per-message-range": "Minimum number of rule node executions per message can't be negative"
|
||||||
},
|
},
|
||||||
"timeinterval": {
|
"timeinterval": {
|
||||||
"seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }",
|
"seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user