|
|
|
@ -29,9 +29,13 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; |
|
|
|
import org.thingsboard.server.common.data.id.CustomerId; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; |
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
|
import org.thingsboard.server.common.data.rule.RuleChain; |
|
|
|
import org.thingsboard.server.common.data.rule.RuleChainMetaData; |
|
|
|
import org.thingsboard.server.common.data.widget.DeprecatedFilter; |
|
|
|
import org.thingsboard.server.common.data.widget.WidgetTypeDetails; |
|
|
|
import org.thingsboard.server.common.data.widget.WidgetTypeInfo; |
|
|
|
import org.thingsboard.server.common.data.widget.WidgetsBundle; |
|
|
|
import org.thingsboard.server.dao.dashboard.DashboardService; |
|
|
|
import org.thingsboard.server.dao.exception.DataValidationException; |
|
|
|
@ -48,7 +52,9 @@ import java.nio.file.Path; |
|
|
|
import java.nio.file.Paths; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Base64; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Optional; |
|
|
|
import java.util.function.Function; |
|
|
|
|
|
|
|
@ -189,6 +195,38 @@ public class InstallScripts { |
|
|
|
} |
|
|
|
|
|
|
|
public void loadSystemWidgets() throws Exception { |
|
|
|
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))) { |
|
|
|
dirStream.forEach( |
|
|
|
path -> { |
|
|
|
JsonNode widgetsBundleDescriptorJson; |
|
|
|
try { |
|
|
|
widgetsBundleDescriptorJson = JacksonUtil.toJsonNode(path.toFile()); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Unable to parse widgets bundle from json: [{}]", path); |
|
|
|
throw new RuntimeException("Unable to parse widgets bundle from json", e); |
|
|
|
} |
|
|
|
if (widgetsBundleDescriptorJson == null || !widgetsBundleDescriptorJson.has("widgetsBundle")) { |
|
|
|
log.error("Invalid widgets bundle json: [{}]", path); |
|
|
|
throw new RuntimeException("Invalid widgets bundle json: [" + path + "]"); |
|
|
|
} |
|
|
|
widgetsBundlesMap.put(path, widgetsBundleDescriptorJson); |
|
|
|
JsonNode bundleAliasNode = widgetsBundleDescriptorJson.get("widgetsBundle").get("alias"); |
|
|
|
if (bundleAliasNode == null || !bundleAliasNode.isTextual()) { |
|
|
|
log.error("Invalid widgets bundle json: [{}]", path); |
|
|
|
throw new RuntimeException("Invalid widgets bundle json: [" + path + "]"); |
|
|
|
} |
|
|
|
String bundleAlias = bundleAliasNode.asText(); |
|
|
|
try { |
|
|
|
this.deleteSystemWidgetBundle(bundleAlias); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Failed to delete system widgets bundle: [{}]", bundleAlias); |
|
|
|
throw new RuntimeException("Failed to delete system widgets bundle: [" + bundleAlias + "]", e); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
} |
|
|
|
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))) { |
|
|
|
@ -206,44 +244,56 @@ public class InstallScripts { |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
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))) { |
|
|
|
dirStream.forEach( |
|
|
|
path -> { |
|
|
|
try { |
|
|
|
JsonNode widgetsBundleDescriptorJson = JacksonUtil.toJsonNode(path.toFile()); |
|
|
|
JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); |
|
|
|
WidgetsBundle widgetsBundle = JacksonUtil.treeToValue(widgetsBundleJson, WidgetsBundle.class); |
|
|
|
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); |
|
|
|
List<String> widgetTypeFqns = new ArrayList<>(); |
|
|
|
if (widgetsBundleDescriptorJson.has("widgetTypes")) { |
|
|
|
JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); |
|
|
|
widgetTypesArrayJson.forEach( |
|
|
|
widgetTypeJson -> { |
|
|
|
try { |
|
|
|
WidgetTypeDetails widgetTypeDetails = JacksonUtil.treeToValue(widgetTypeJson, WidgetTypeDetails.class); |
|
|
|
var savedWidgetType = widgetTypeService.saveWidgetType(widgetTypeDetails); |
|
|
|
widgetTypeFqns.add(savedWidgetType.getFqn()); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Unable to load widget type from json: [{}]", path.toString()); |
|
|
|
throw new RuntimeException("Unable to load widget type from json", e); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
} |
|
|
|
if (widgetsBundleDescriptorJson.has("widgetTypeFqns")) { |
|
|
|
JsonNode widgetFqnsArrayJson = widgetsBundleDescriptorJson.get("widgetTypeFqns"); |
|
|
|
widgetFqnsArrayJson.forEach(fqnJson -> { |
|
|
|
widgetTypeFqns.add(fqnJson.asText()); |
|
|
|
}); |
|
|
|
for (var widgetsBundleDescriptorEntry : widgetsBundlesMap.entrySet()) { |
|
|
|
Path path = widgetsBundleDescriptorEntry.getKey(); |
|
|
|
try { |
|
|
|
JsonNode widgetsBundleDescriptorJson = widgetsBundleDescriptorEntry.getValue(); |
|
|
|
JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); |
|
|
|
WidgetsBundle widgetsBundle = JacksonUtil.treeToValue(widgetsBundleJson, WidgetsBundle.class); |
|
|
|
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); |
|
|
|
List<String> widgetTypeFqns = new ArrayList<>(); |
|
|
|
if (widgetsBundleDescriptorJson.has("widgetTypes")) { |
|
|
|
JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); |
|
|
|
widgetTypesArrayJson.forEach( |
|
|
|
widgetTypeJson -> { |
|
|
|
try { |
|
|
|
WidgetTypeDetails widgetTypeDetails = JacksonUtil.treeToValue(widgetTypeJson, WidgetTypeDetails.class); |
|
|
|
var savedWidgetType = widgetTypeService.saveWidgetType(widgetTypeDetails); |
|
|
|
widgetTypeFqns.add(savedWidgetType.getFqn()); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Unable to load widget type from json: [{}]", path.toString()); |
|
|
|
throw new RuntimeException("Unable to load widget type from json", e); |
|
|
|
} |
|
|
|
} |
|
|
|
widgetTypeService.updateWidgetsBundleWidgetFqns(TenantId.SYS_TENANT_ID, savedWidgetsBundle.getId(), widgetTypeFqns); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Unable to load widgets bundle from json: [{}]", path.toString()); |
|
|
|
throw new RuntimeException("Unable to load widgets bundle from json", e); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
if (widgetsBundleDescriptorJson.has("widgetTypeFqns")) { |
|
|
|
JsonNode widgetFqnsArrayJson = widgetsBundleDescriptorJson.get("widgetTypeFqns"); |
|
|
|
widgetFqnsArrayJson.forEach(fqnJson -> { |
|
|
|
widgetTypeFqns.add(fqnJson.asText()); |
|
|
|
}); |
|
|
|
} |
|
|
|
widgetTypeService.updateWidgetsBundleWidgetFqns(TenantId.SYS_TENANT_ID, savedWidgetsBundle.getId(), widgetTypeFqns); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("Unable to load widgets bundle from json: [{}]", path.toString()); |
|
|
|
throw new RuntimeException("Unable to load widgets bundle from json", e); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void deleteSystemWidgetBundle(String bundleAlias) { |
|
|
|
WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(TenantId.SYS_TENANT_ID, bundleAlias); |
|
|
|
if (widgetsBundle != null) { |
|
|
|
PageData<WidgetTypeInfo> widgetTypes; |
|
|
|
var pageLink = new PageLink(1024); |
|
|
|
do { |
|
|
|
widgetTypes = widgetTypeService.findWidgetTypesInfosByWidgetsBundleId(TenantId.SYS_TENANT_ID, widgetsBundle.getId(), false, DeprecatedFilter.ALL, null, pageLink); |
|
|
|
for (var widgetType : widgetTypes.getData()) { |
|
|
|
widgetTypeService.deleteWidgetType(TenantId.SYS_TENANT_ID, widgetType.getId()); |
|
|
|
} |
|
|
|
pageLink.nextPageLink(); |
|
|
|
} while (widgetTypes.hasNext()); |
|
|
|
widgetsBundleService.deleteWidgetsBundle(TenantId.SYS_TENANT_ID, widgetsBundle.getId()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|