Merge pull request #11949 from thingsboard/fix/gateways-dashboard
Don't create gateways dashboard for new tenants; process images for system dashboard resource
This commit is contained in:
commit
8f5305b6f2
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,7 @@ package org.thingsboard.server.service.entitiy.dashboard;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.ResourceType;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
@ -39,6 +40,7 @@ import java.util.stream.Stream;
|
||||
@TbCoreComponent
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@ConditionalOnProperty(value = "transport.gateway.dashboard.sync.enabled", havingValue = "true")
|
||||
public class DashboardSyncService {
|
||||
|
||||
private final GitSyncService gitSyncService;
|
||||
@ -46,8 +48,6 @@ public class DashboardSyncService {
|
||||
private final WidgetsBundleService widgetsBundleService;
|
||||
private final PartitionService partitionService;
|
||||
|
||||
@Value("${transport.gateway.dashboard.sync.enabled:true}")
|
||||
private boolean enabled;
|
||||
@Value("${transport.gateway.dashboard.sync.repository_url:}")
|
||||
private String repoUrl;
|
||||
@Value("${transport.gateway.dashboard.sync.branch:main}")
|
||||
@ -60,9 +60,6 @@ public class DashboardSyncService {
|
||||
|
||||
@AfterStartUp(order = AfterStartUp.REGULAR_SERVICE)
|
||||
public void init() throws Exception {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
gitSyncService.registerSync(REPO_KEY, repoUrl, branch, TimeUnit.HOURS.toMillis(fetchFrequencyHours), this::update);
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -54,8 +53,8 @@ import org.thingsboard.server.service.install.update.ImagesUpdater;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
@ -170,7 +169,6 @@ public class InstallScripts {
|
||||
loadRuleChainsFromPath(tenantId, edgeChainsDir);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void loadRuleChainsFromPath(TenantId tenantId, Path ruleChainsPath) {
|
||||
findRuleChainsFromPath(ruleChainsPath).forEach(path -> {
|
||||
try {
|
||||
@ -182,12 +180,10 @@ public class InstallScripts {
|
||||
});
|
||||
}
|
||||
|
||||
List<Path> findRuleChainsFromPath(Path ruleChainsPath) throws IOException {
|
||||
List<Path> paths = new ArrayList<>();
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(ruleChainsPath, path -> path.toString().endsWith(InstallScripts.JSON_EXT))) {
|
||||
dirStream.forEach(paths::add);
|
||||
List<Path> findRuleChainsFromPath(Path ruleChainsPath) {
|
||||
try (Stream<Path> files = listDir(ruleChainsPath).filter(path -> path.toString().endsWith(InstallScripts.JSON_EXT))) {
|
||||
return files.toList();
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
public RuleChain createDefaultRuleChain(TenantId tenantId, String ruleChainName) {
|
||||
@ -211,11 +207,11 @@ public class InstallScripts {
|
||||
return ruleChain;
|
||||
}
|
||||
|
||||
public void loadSystemWidgets() throws Exception {
|
||||
public void loadSystemWidgets() {
|
||||
log.info("Loading system widgets");
|
||||
Map<Path, JsonNode> widgetsBundlesMap = new HashMap<>();
|
||||
Path widgetBundlesDir = Paths.get(getDataDir(), JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR);
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(JSON_EXT))) {
|
||||
try (Stream<Path> dirStream = listDir(widgetBundlesDir).filter(path -> path.toString().endsWith(JSON_EXT))) {
|
||||
dirStream.forEach(
|
||||
path -> {
|
||||
JsonNode widgetsBundleDescriptorJson;
|
||||
@ -247,12 +243,14 @@ public class InstallScripts {
|
||||
}
|
||||
Path widgetTypesDir = Paths.get(getDataDir(), JSON_DIR, SYSTEM_DIR, WIDGET_TYPES_DIR);
|
||||
if (Files.exists(widgetTypesDir)) {
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(widgetTypesDir, path -> path.toString().endsWith(JSON_EXT))) {
|
||||
try (Stream<Path> dirStream = listDir(widgetTypesDir).filter(path -> path.toString().endsWith(JSON_EXT))) {
|
||||
dirStream.forEach(
|
||||
path -> {
|
||||
try {
|
||||
JsonNode widgetTypeJson = JacksonUtil.toJsonNode(path.toFile());
|
||||
WidgetTypeDetails widgetTypeDetails = JacksonUtil.treeToValue(widgetTypeJson, WidgetTypeDetails.class);
|
||||
String widgetTypeJson = Files.readString(path);
|
||||
widgetTypeJson = resourceService.checkSystemResourcesUsage(widgetTypeJson, ResourceType.JS_MODULE);
|
||||
|
||||
WidgetTypeDetails widgetTypeDetails = JacksonUtil.fromString(widgetTypeJson, WidgetTypeDetails.class);
|
||||
widgetTypeService.saveWidgetType(widgetTypeDetails);
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to load widget type from json: [{}]", path.toString());
|
||||
@ -300,12 +298,12 @@ public class InstallScripts {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSystemScadaSymbols() throws Exception {
|
||||
private void loadSystemScadaSymbols() {
|
||||
log.info("Loading system SCADA symbols");
|
||||
Path scadaSymbolsDir = Paths.get(getDataDir(), JSON_DIR, SYSTEM_DIR, SCADA_SYMBOLS_DIR);
|
||||
if (Files.exists(scadaSymbolsDir)) {
|
||||
WidgetTypeDetails scadaSymbolWidgetTemplate = widgetTypeService.findWidgetTypeDetailsByTenantIdAndFqn(TenantId.SYS_TENANT_ID, "scada_symbol");
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(scadaSymbolsDir, path -> path.toString().endsWith(SVG_EXT))) {
|
||||
try (Stream<Path> dirStream = listDir(scadaSymbolsDir).filter(path -> path.toString().endsWith(SVG_EXT))) {
|
||||
dirStream.forEach(
|
||||
path -> {
|
||||
try {
|
||||
@ -404,11 +402,10 @@ public class InstallScripts {
|
||||
imagesUpdater.updateAssetProfilesImages();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void loadSystemImages() {
|
||||
log.info("Loading system images...");
|
||||
Stream<Path> dashboardsFiles = Stream.concat(Files.list(Paths.get(getDataDir(), JSON_DIR, DEMO_DIR, DASHBOARDS_DIR)),
|
||||
Files.list(Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, DASHBOARDS_DIR)));
|
||||
Stream<Path> dashboardsFiles = Stream.concat(listDir(Paths.get(getDataDir(), JSON_DIR, DEMO_DIR, DASHBOARDS_DIR)),
|
||||
listDir(Paths.get(getDataDir(), JSON_DIR, TENANT_DIR, DASHBOARDS_DIR)));
|
||||
try (dashboardsFiles) {
|
||||
dashboardsFiles.forEach(file -> {
|
||||
try {
|
||||
@ -431,25 +428,22 @@ public class InstallScripts {
|
||||
loadDashboardsFromDir(tenantId, customerId, dashboardsDir);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void loadDashboardsFromDir(TenantId tenantId, CustomerId customerId, Path dashboardsDir) {
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(JSON_EXT))) {
|
||||
dirStream.forEach(
|
||||
path -> {
|
||||
try {
|
||||
JsonNode dashboardJson = JacksonUtil.toJsonNode(path.toFile());
|
||||
Dashboard dashboard = JacksonUtil.treeToValue(dashboardJson, Dashboard.class);
|
||||
dashboard.setTenantId(tenantId);
|
||||
Dashboard savedDashboard = dashboardService.saveDashboard(dashboard);
|
||||
if (customerId != null && !customerId.isNullUid()) {
|
||||
dashboardService.assignDashboardToCustomer(TenantId.SYS_TENANT_ID, savedDashboard.getId(), customerId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to load dashboard from json: [{}]", path.toString());
|
||||
throw new RuntimeException("Unable to load dashboard from json", e);
|
||||
}
|
||||
try (Stream<Path> dashboards = listDir(dashboardsDir).filter(path -> path.toString().endsWith(JSON_EXT))) {
|
||||
dashboards.forEach(path -> {
|
||||
try {
|
||||
JsonNode dashboardJson = JacksonUtil.toJsonNode(path.toFile());
|
||||
Dashboard dashboard = JacksonUtil.treeToValue(dashboardJson, Dashboard.class);
|
||||
dashboard.setTenantId(tenantId);
|
||||
Dashboard savedDashboard = dashboardService.saveDashboard(dashboard);
|
||||
if (customerId != null && !customerId.isNullUid()) {
|
||||
dashboardService.assignDashboardToCustomer(TenantId.SYS_TENANT_ID, savedDashboard.getId(), customerId);
|
||||
}
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("Unable to load dashboard from json: [{}]", path.toString());
|
||||
throw new RuntimeException("Unable to load dashboard from json", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -464,9 +458,9 @@ public class InstallScripts {
|
||||
}
|
||||
}
|
||||
|
||||
public void createOAuth2Templates() throws Exception {
|
||||
public void createOAuth2Templates() {
|
||||
Path oauth2ConfigTemplatesDir = Paths.get(getDataDir(), JSON_DIR, SYSTEM_DIR, OAUTH2_CONFIG_TEMPLATES_DIR);
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(oauth2ConfigTemplatesDir, path -> path.toString().endsWith(JSON_EXT))) {
|
||||
try (Stream<Path> dirStream = listDir(oauth2ConfigTemplatesDir).filter(path -> path.toString().endsWith(JSON_EXT))) {
|
||||
dirStream.forEach(
|
||||
path -> {
|
||||
try {
|
||||
@ -489,7 +483,7 @@ public class InstallScripts {
|
||||
|
||||
public void loadSystemLwm2mResources() {
|
||||
Path resourceLwm2mPath = Paths.get(getDataDir(), MODELS_LWM2M_DIR);
|
||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(resourceLwm2mPath, path -> path.toString().endsWith(InstallScripts.XML_EXT))) {
|
||||
try (Stream<Path> dirStream = listDir(resourceLwm2mPath).filter(path -> path.toString().endsWith(InstallScripts.XML_EXT))) {
|
||||
dirStream.forEach(
|
||||
path -> {
|
||||
try {
|
||||
@ -539,9 +533,11 @@ public class InstallScripts {
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<Path> listDir(Path resourcesDir) {
|
||||
private Stream<Path> listDir(Path dir) {
|
||||
try {
|
||||
return Files.list(resourcesDir);
|
||||
return Files.list(dir);
|
||||
} catch (NoSuchFileException e) {
|
||||
return Stream.empty();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
||||
@ -39,7 +39,6 @@ import org.thingsboard.server.dao.widget.WidgetTypeService;
|
||||
import org.thingsboard.server.dao.widget.WidgetsBundleService;
|
||||
import org.thingsboard.server.service.install.update.ImagesUpdater;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -87,14 +86,14 @@ class InstallScriptsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultRuleChainsTemplates() throws IOException {
|
||||
void testDefaultRuleChainsTemplates() {
|
||||
Path dir = installScripts.getTenantRuleChainsDir();
|
||||
installScripts.findRuleChainsFromPath(dir)
|
||||
.forEach(this::validateRuleChainTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultEdgeRuleChainsTemplates() throws IOException {
|
||||
void testDefaultEdgeRuleChainsTemplates() {
|
||||
Path dir = installScripts.getEdgeRuleChainsDir();
|
||||
installScripts.findRuleChainsFromPath(dir)
|
||||
.forEach(this::validateRuleChainTemplate);
|
||||
|
||||
@ -17,15 +17,19 @@ package org.thingsboard.server.dao.resource;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.common.util.RegexUtils;
|
||||
import org.thingsboard.server.cache.resourceInfo.ResourceInfoCacheKey;
|
||||
import org.thingsboard.server.cache.resourceInfo.ResourceInfoEvictEvent;
|
||||
import org.thingsboard.server.common.data.Dashboard;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ResourceType;
|
||||
import org.thingsboard.server.common.data.TbResource;
|
||||
@ -54,7 +58,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId;
|
||||
|
||||
@Service("TbResourceDaoService")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
@Primary
|
||||
public class BaseResourceService extends AbstractCachedEntityService<ResourceInfoCacheKey, TbResourceInfo, ResourceInfoEvictEvent> implements ResourceService {
|
||||
|
||||
@ -62,6 +66,8 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
||||
protected final TbResourceDao resourceDao;
|
||||
protected final TbResourceInfoDao resourceInfoDao;
|
||||
protected final ResourceDataValidator resourceValidator;
|
||||
@Autowired @Lazy
|
||||
private ImageService imageService;
|
||||
|
||||
@Override
|
||||
public TbResource saveResource(TbResource resource, boolean doValidate) {
|
||||
@ -243,6 +249,11 @@ public class BaseResourceService extends AbstractCachedEntityService<ResourceInf
|
||||
public TbResource createOrUpdateSystemResource(ResourceType resourceType, String resourceKey, String data) {
|
||||
if (resourceType == ResourceType.DASHBOARD) {
|
||||
data = checkSystemResourcesUsage(data, ResourceType.JS_MODULE);
|
||||
|
||||
Dashboard dashboard = JacksonUtil.fromString(data, Dashboard.class);
|
||||
dashboard.setTenantId(TenantId.SYS_TENANT_ID);
|
||||
imageService.replaceBase64WithImageUrl(dashboard);
|
||||
data = JacksonUtil.toString(dashboard);
|
||||
}
|
||||
|
||||
TbResource resource = findResourceByTenantIdAndKey(TenantId.SYS_TENANT_ID, resourceType, resourceKey);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user