From f3743ee017cca7d165a25c0319ffe870ea9d1791 Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 9 Mar 2022 08:15:55 +0800 Subject: [PATCH] Introduce booster-ui and implement v9 template management protocol (#8637) --- .gitmodules | 6 +-- CHANGES.md | 2 + apm-webapp/pom.xml | 2 +- .../management/ui/template/UITemplate.java | 28 ++++------ .../ui/template/UITemplateInitializer.java | 43 +-------------- .../template/UITemplateManagementService.java | 16 +++--- .../core/query/input/DashboardSetting.java | 11 ++-- .../NewDashboardSetting.java} | 25 ++++----- .../query/type/DashboardConfiguration.java | 10 +--- .../core/query/type/TemplateChangeStatus.java | 1 + .../management/UITemplateManagementDAO.java | 4 +- .../template/UITemplateInitializerTest.java | 28 +--------- .../ui/template/UITemplateTest.java | 12 +---- .../resolver/UIConfigurationManagement.java | 27 ++++++---- .../src/main/resources/query-protocol | 2 +- .../query/UITemplateManagementEsDAO.java | 41 ++++++++++---- .../query/UITemplateManagementDAOImpl.java | 53 +++++++++++++++---- .../IoTDBUITemplateManagementDAO.java | 38 ++++++++++--- .../h2/dao/H2UITemplateManagementDAO.java | 42 ++++++++++++--- skywalking-ui | 2 +- 20 files changed, 213 insertions(+), 180 deletions(-) rename oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/{enumeration/TemplateType.java => input/NewDashboardSetting.java} (64%) diff --git a/.gitmodules b/.gitmodules index f78cd69d01..8011ff2bf1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,9 @@ [submodule "oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol"] path = oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol url = https://github.com/apache/skywalking-query-protocol.git -[submodule "skywalking-ui"] - path = skywalking-ui - url = https://github.com/apache/skywalking-rocketbot-ui.git [submodule "test/e2e-v2/java-test-service/e2e-protocol/src/main/proto"] path = test/e2e-v2/java-test-service/e2e-protocol/src/main/proto url = https://github.com/apache/skywalking-data-collect-protocol.git +[submodule "skywalking-ui"] + path = skywalking-ui + url = https://github.com/apache/skywalking-booster-ui.git diff --git a/CHANGES.md b/CHANGES.md index dc49f34c8c..802a140ac0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -85,12 +85,14 @@ Release Notes. * Support large service/instance/networkAddressAlias list query by using ElasticSearch scrolling API, add `metadataQueryBatchSize` to configure scrolling page size. * Change default value of `metadataQueryMaxSize` from `5000` to `10000` * Replace deprecated Armeria API `BasicToken.of` with `AuthToken.ofBasic`. +* Implement v9 UI template management protocol. #### UI * Remove unused jars (log4j-api.jar) in classpath. * Bump up netty version to fix CVE. * Add Database Connection pool metric. +* Introduce skywalking-booster-ui, remove skywalking-rocketbot-ui. #### Documentation diff --git a/apm-webapp/pom.xml b/apm-webapp/pom.xml index 2e5d797f33..91e43c3cb5 100644 --- a/apm-webapp/pom.xml +++ b/apm-webapp/pom.xml @@ -147,7 +147,7 @@ ${frontend-maven-plugin.version} ${ui.path} - v8.17.0 + v14.19.0 diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplate.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplate.java index f4544fd746..cc96e43c96 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplate.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplate.java @@ -37,43 +37,38 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.UI @ScopeDeclaration(id = UI_TEMPLATE, name = "UITemplate") @Stream(name = UITemplate.INDEX_NAME, scopeId = UI_TEMPLATE, builder = UITemplate.Builder.class, processor = ManagementStreamProcessor.class) @EqualsAndHashCode(of = { - "name" + "templateId" }, callSuper = false) public class UITemplate extends ManagementData { public static final String INDEX_NAME = "ui_template"; - public static final String NAME = "name"; - public static final String TYPE = "type"; + public static final String TEMPLATE_ID = "template_id"; public static final String CONFIGURATION = "configuration"; - public static final String ACTIVATED = "activated"; + public static final String UPDATE_TIME = "update_time"; public static final String DISABLED = "disabled"; - @Column(columnName = NAME) - private String name; - @Column(columnName = TYPE, storageOnly = true) - private String type; + @Column(columnName = TEMPLATE_ID) + private String templateId; /** * Configuration in JSON format. */ @Column(columnName = CONFIGURATION, storageOnly = true, length = 1_000_000) private String configuration; - @Column(columnName = ACTIVATED, storageOnly = true) - private int activated; + @Column(columnName = UPDATE_TIME) + private long updateTime; @Column(columnName = DISABLED) private int disabled; @Override public String id() { - return name; + return templateId; } public static class Builder implements StorageHashMapBuilder { @Override public UITemplate storage2Entity(final Map dbMap) { UITemplate uiTemplate = new UITemplate(); - uiTemplate.setName((String) dbMap.get(NAME)); - uiTemplate.setType((String) dbMap.get(TYPE)); + uiTemplate.setTemplateId((String) dbMap.get(TEMPLATE_ID)); uiTemplate.setConfiguration((String) dbMap.get(CONFIGURATION)); - uiTemplate.setActivated(((Number) dbMap.get(ACTIVATED)).intValue()); uiTemplate.setDisabled(((Number) dbMap.get(DISABLED)).intValue()); return uiTemplate; } @@ -81,10 +76,9 @@ public class UITemplate extends ManagementData { @Override public Map entity2Storage(final UITemplate storageData) { final HashMap map = new HashMap<>(); - map.put(NAME, storageData.getName()); - map.put(TYPE, storageData.getType()); + map.put(TEMPLATE_ID, storageData.getTemplateId()); map.put(CONFIGURATION, storageData.getConfiguration()); - map.put(ACTIVATED, storageData.getActivated()); + map.put(UPDATE_TIME, storageData.getUpdateTime()); map.put(DISABLED, storageData.getDisabled()); return map; } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java index 93a5b428cf..d1bdb87005 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializer.java @@ -23,11 +23,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import lombok.extern.slf4j.Slf4j; -import org.apache.skywalking.oap.server.library.util.StringUtil; -import org.apache.skywalking.oap.server.core.query.enumeration.TemplateType; -import org.apache.skywalking.oap.server.library.util.BooleanUtils; import org.yaml.snakeyaml.Yaml; /** @@ -53,44 +49,7 @@ public class UITemplateInitializer { public List read() { List uiTemplates = new ArrayList<>(); - if (Objects.nonNull(yamlData)) { - List templates = (List) yamlData.get("templates"); - if (templates != null) { - templates.forEach(templateObj -> { - final Map template = (Map) templateObj; - UITemplate newTemplate = new UITemplate(); - final String name = (String) template.get("name"); - if (StringUtil.isEmpty(name)) { - throw new IllegalArgumentException("template name shouldn't be null"); - } - newTemplate.setName(name); - final String type = (String) template.getOrDefault("type", TemplateType.DASHBOARD.name()); - TemplateType.forName(type); // for checking. - newTemplate.setType(type); - final String configuration = (String) template.get("configuration"); - if (StringUtil.isEmpty(configuration)) { - throw new IllegalArgumentException("template configuration shouldn't be null"); - } - newTemplate.setConfiguration(configuration); - newTemplate.setActivated( - BooleanUtils.booleanToValue( - // The template should be activated in default, it is just an option. - (Boolean) template.getOrDefault("activated", false) - ) - ); - newTemplate.setDisabled( - BooleanUtils.booleanToValue( - // The template should be available in default. - (Boolean) template.getOrDefault("disabled", false) - ) - ); - if (uiTemplates.contains(newTemplate)) { - throw new IllegalArgumentException("Template " + newTemplate.getName() + " name conflicts"); - } - uiTemplates.add(newTemplate); - }); - } - } + //Todo: implement later when new template file ready return uiTemplates; } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateManagementService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateManagementService.java index 27d6d478b6..c64374f116 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateManagementService.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateManagementService.java @@ -19,8 +19,6 @@ package org.apache.skywalking.oap.server.core.management.ui.template; import java.io.IOException; -import java.util.Collections; -import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; import org.apache.skywalking.oap.server.core.query.input.DashboardSetting; @@ -45,11 +43,17 @@ public class UITemplateManagementService implements Service { return uiTemplateManagementDAO; } + public DashboardConfiguration getTemplate(String id) throws IOException { + DashboardConfiguration configuration = getUITemplateManagementDAO().getTemplate(id); + if (configuration.isDisabled()) { + return null; + } + return configuration; + } + public List getAllTemplates(Boolean includingDisabled) throws IOException { final List allTemplates = getUITemplateManagementDAO().getAllTemplates(includingDisabled); - // Make sure the template in A-Za-z - Collections.sort(allTemplates, Comparator.comparing(DashboardConfiguration::getName)); return allTemplates; } @@ -61,7 +65,7 @@ public class UITemplateManagementService implements Service { return getUITemplateManagementDAO().changeTemplate(setting); } - public TemplateChangeStatus disableTemplate(String name) throws IOException { - return getUITemplateManagementDAO().disableTemplate(name); + public TemplateChangeStatus disableTemplate(String id) throws IOException { + return getUITemplateManagementDAO().disableTemplate(id); } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/DashboardSetting.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/DashboardSetting.java index f9464d8569..354e2390b7 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/DashboardSetting.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/DashboardSetting.java @@ -21,23 +21,20 @@ package org.apache.skywalking.oap.server.core.query.input; import lombok.Getter; import lombok.Setter; import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate; -import org.apache.skywalking.oap.server.core.query.enumeration.TemplateType; import org.apache.skywalking.oap.server.library.util.BooleanUtils; @Setter @Getter public class DashboardSetting { - private String name; - private TemplateType type; + private String id; private String configuration; - private boolean active; + private long updateTime; public UITemplate toEntity() { UITemplate uiTemplate = new UITemplate(); - uiTemplate.setName(this.getName()); + uiTemplate.setTemplateId(this.id); uiTemplate.setConfiguration(this.getConfiguration()); - uiTemplate.setType(this.getType().name()); - uiTemplate.setActivated(BooleanUtils.booleanToValue(this.isActive())); + uiTemplate.setUpdateTime(this.updateTime); uiTemplate.setDisabled(BooleanUtils.FALSE); return uiTemplate; } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/enumeration/TemplateType.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/NewDashboardSetting.java similarity index 64% rename from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/enumeration/TemplateType.java rename to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/NewDashboardSetting.java index cbc06bb924..d6284651b7 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/enumeration/TemplateType.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/NewDashboardSetting.java @@ -16,19 +16,20 @@ * */ -package org.apache.skywalking.oap.server.core.query.enumeration; +package org.apache.skywalking.oap.server.core.query.input; -public enum TemplateType { - DASHBOARD, - TOPOLOGY_SERVICE, - TOPOLOGY_INSTANCE, - TOPOLOGY_ENDPOINT, - TOPOLOGY_SERVICE_RELATION, - TOPOLOGY_SERVICE_INSTANCE_RELATION, - TOPOLOGY_ENDPOINT_RELATION, - ; +import lombok.Getter; +import lombok.Setter; +import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate; - public static TemplateType forName(String name) { - return Enum.valueOf(TemplateType.class, name.toUpperCase()); +@Setter +@Getter +public class NewDashboardSetting { + private String configuration; + + public UITemplate toEntity() { + UITemplate uiTemplate = new UITemplate(); + uiTemplate.setConfiguration(this.getConfiguration()); + return uiTemplate; } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/DashboardConfiguration.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/DashboardConfiguration.java index e4e2788b8d..1e1c69b532 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/DashboardConfiguration.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/DashboardConfiguration.java @@ -21,28 +21,22 @@ package org.apache.skywalking.oap.server.core.query.type; import lombok.Getter; import lombok.Setter; import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate; -import org.apache.skywalking.oap.server.core.query.enumeration.TemplateType; import org.apache.skywalking.oap.server.library.util.BooleanUtils; @Setter @Getter public class DashboardConfiguration { - private String name; - private TemplateType type; + private String id; /** * Configuration in JSON format. */ private String configuration; - private boolean activated; private boolean disabled; public DashboardConfiguration fromEntity(UITemplate templateEntity) { - this.setName(templateEntity.getName()); - this.setType(TemplateType.forName(templateEntity.getType())); + this.setId(templateEntity.getTemplateId()); this.setConfiguration(templateEntity.getConfiguration()); - this.setActivated(BooleanUtils.valueToBoolean(templateEntity.getActivated())); this.setDisabled(BooleanUtils.valueToBoolean(templateEntity.getDisabled())); - return this; } } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/TemplateChangeStatus.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/TemplateChangeStatus.java index 8282672da5..00cbfce8f6 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/TemplateChangeStatus.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/TemplateChangeStatus.java @@ -26,6 +26,7 @@ import lombok.Setter; @Getter @Builder public class TemplateChangeStatus { + private String id; private boolean status; private String message; } diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/management/UITemplateManagementDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/management/UITemplateManagementDAO.java index aee1bbbdf9..4208af4f19 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/management/UITemplateManagementDAO.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/management/UITemplateManagementDAO.java @@ -29,11 +29,13 @@ import org.apache.skywalking.oap.server.core.storage.DAO; * UI Template management, including CRUD. */ public interface UITemplateManagementDAO extends DAO { + DashboardConfiguration getTemplate(String id) throws IOException; + List getAllTemplates(Boolean includingDisabled) throws IOException; TemplateChangeStatus addTemplate(DashboardSetting setting) throws IOException; TemplateChangeStatus changeTemplate(DashboardSetting setting) throws IOException; - TemplateChangeStatus disableTemplate(String name) throws IOException; + TemplateChangeStatus disableTemplate(String id) throws IOException; } diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializerTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializerTest.java index 82e9d3a56e..4e6d4a6810 100644 --- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializerTest.java +++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateInitializerTest.java @@ -18,38 +18,12 @@ package org.apache.skywalking.oap.server.core.management.ui.template; -import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.List; -import org.apache.skywalking.oap.server.library.util.BooleanUtils; -import org.apache.skywalking.oap.server.library.util.ResourceUtils; -import org.junit.Assert; import org.junit.Test; public class UITemplateInitializerTest { @Test public void testReadFile() throws FileNotFoundException { - final File[] templateFiles = ResourceUtils.getPathFiles("test-ui-templates"); - final List uiTemplates = new ArrayList<>(); - for (final File templateFile : templateFiles) { - UITemplateInitializer initializer = new UITemplateInitializer( - new FileInputStream(templateFile)); - uiTemplates.addAll(initializer.read()); - } - - Assert.assertEquals(2, uiTemplates.size()); - UITemplate uiTemplate = uiTemplates.get(0); - Assert.assertEquals("APM (Agent based)", uiTemplate.getName()); - Assert.assertTrue(uiTemplate.getConfiguration().length() > 0); - Assert.assertEquals(BooleanUtils.TRUE, uiTemplate.getActivated()); - Assert.assertEquals(BooleanUtils.FALSE, uiTemplate.getDisabled()); - - uiTemplate = uiTemplates.get(1); - Assert.assertEquals("APM (Service Mesh)", uiTemplate.getName()); - Assert.assertTrue(uiTemplate.getConfiguration().length() > 0); - Assert.assertEquals(BooleanUtils.FALSE, uiTemplate.getActivated()); - Assert.assertEquals(BooleanUtils.TRUE, uiTemplate.getDisabled()); + //Todo: implement later when new template file ready } } diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateTest.java index 5510b4dbc4..fc1ef80224 100644 --- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateTest.java +++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/management/ui/template/UITemplateTest.java @@ -18,8 +18,6 @@ package org.apache.skywalking.oap.server.core.management.ui.template; -import org.apache.skywalking.oap.server.core.query.enumeration.TemplateType; -import org.apache.skywalking.oap.server.library.util.BooleanUtils; import org.junit.Assert; import org.junit.Test; @@ -27,11 +25,8 @@ public class UITemplateTest { @Test public void testSerialization() { UITemplate uiTemplate = new UITemplate(); - uiTemplate.setName("name"); + uiTemplate.setTemplateId("id"); uiTemplate.setConfiguration("configuration"); - uiTemplate.setType(TemplateType.DASHBOARD.name()); - uiTemplate.setActivated(BooleanUtils.TRUE); - uiTemplate.setDisabled(BooleanUtils.FALSE); final UITemplate.Builder builder = new UITemplate.Builder(); final UITemplate uiTemplate2 = builder.storage2Entity(builder.entity2Storage(uiTemplate)); @@ -39,10 +34,7 @@ public class UITemplateTest { Assert.assertEquals(uiTemplate, uiTemplate2); uiTemplate2.setConfiguration("configuration2"); - uiTemplate.setType(TemplateType.TOPOLOGY_ENDPOINT.name()); - uiTemplate.setActivated(BooleanUtils.FALSE); - uiTemplate.setDisabled(BooleanUtils.TRUE); - // Equals method is only for `name` field. + // Equals method is only for `templateId` field. Assert.assertEquals(uiTemplate, uiTemplate2); } } diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/UIConfigurationManagement.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/UIConfigurationManagement.java index 00f0eee766..cf68f6574e 100644 --- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/UIConfigurationManagement.java +++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/UIConfigurationManagement.java @@ -22,10 +22,12 @@ import graphql.kickstart.tools.GraphQLMutationResolver; import graphql.kickstart.tools.GraphQLQueryResolver; import java.io.IOException; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService; import org.apache.skywalking.oap.server.core.query.input.DashboardSetting; +import org.apache.skywalking.oap.server.core.query.input.NewDashboardSetting; import org.apache.skywalking.oap.server.core.query.type.DashboardConfiguration; import org.apache.skywalking.oap.server.core.query.type.TemplateChangeStatus; import org.apache.skywalking.oap.server.library.module.ModuleManager; @@ -50,22 +52,29 @@ public class UIConfigurationManagement implements GraphQLQueryResolver, GraphQLM return uiTemplateManagementService; } - public List getAllTemplates(Boolean includingDisabled) throws IOException { - if (includingDisabled == null) { - includingDisabled = false; - } - return getUITemplateManagementService().getAllTemplates(includingDisabled); + public DashboardConfiguration getTemplate(String id) throws IOException { + return getUITemplateManagementService().getTemplate(id); } - public TemplateChangeStatus addTemplate(DashboardSetting setting) throws IOException { - return getUITemplateManagementService().addTemplate(setting); + public List getAllTemplates() throws IOException { + return getUITemplateManagementService().getAllTemplates(false); + } + + public TemplateChangeStatus addTemplate(NewDashboardSetting setting) throws IOException { + DashboardSetting dashboardSetting = new DashboardSetting(); + //Backend generate the Id for new template + dashboardSetting.setId(UUID.randomUUID().toString()); + dashboardSetting.setUpdateTime(System.currentTimeMillis()); + dashboardSetting.setConfiguration(setting.getConfiguration()); + return getUITemplateManagementService().addTemplate(dashboardSetting); } public TemplateChangeStatus changeTemplate(DashboardSetting setting) throws IOException { + setting.setUpdateTime(System.currentTimeMillis()); return getUITemplateManagementService().changeTemplate(setting); } - public TemplateChangeStatus disableTemplate(String name) throws IOException { - return getUITemplateManagementService().disableTemplate(name); + public TemplateChangeStatus disableTemplate(String id) throws IOException { + return getUITemplateManagementService().disableTemplate(id); } } diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol index d6e294735a..74f9bc7ee6 160000 --- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol +++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol @@ -1 +1 @@ -Subproject commit d6e294735ab43b2fa9e70b11c91d85268591dec0 +Subproject commit 74f9bc7ee6af33fc341331cf381c98847dcccfff diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/UITemplateManagementEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/UITemplateManagementEsDAO.java index ac48a263be..5f1e906d5c 100644 --- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/UITemplateManagementEsDAO.java +++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/UITemplateManagementEsDAO.java @@ -37,6 +37,7 @@ import org.apache.skywalking.oap.server.core.query.type.TemplateChangeStatus; import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO; import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient; import org.apache.skywalking.oap.server.library.util.BooleanUtils; +import org.apache.skywalking.oap.server.library.util.StringUtil; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO; import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.IndexController; @@ -46,6 +47,26 @@ public class UITemplateManagementEsDAO extends EsDAO implements UITemplateManage super(client); } + @Override + public DashboardConfiguration getTemplate(final String id) { + if (StringUtil.isEmpty(id)) { + return null; + } + final String index = + IndexController.LogicIndicesRegister.getPhysicalTableName(UITemplate.INDEX_NAME); + final SearchBuilder search = + Search.builder().query(Query.ids(id)) + .size(1); + final SearchResponse response = getClient().search(index, search.build()); + + if (response.getHits().getHits().size() > 0) { + UITemplate.Builder builder = new UITemplate.Builder(); + SearchHit data = response.getHits().getHits().get(0); + return new DashboardConfiguration().fromEntity(builder.storage2Entity(data.getSource())); + } + return null; + } + @Override public List getAllTemplates(final Boolean includingDisabled) { final BoolQueryBuilder boolQuery = Query.bool(); @@ -84,16 +105,16 @@ public class UITemplateManagementEsDAO extends EsDAO implements UITemplateManage final boolean exist = getClient().existDoc(UITemplate.INDEX_NAME, uiTemplate.id()); if (exist) { - return TemplateChangeStatus.builder().status(false).message("Template exists") + return TemplateChangeStatus.builder().status(false).id(setting.getId()).message("Template exists") .build(); } final Map xContentBuilder = builder.entity2Storage(uiTemplate); getClient().forceInsert(UITemplate.INDEX_NAME, uiTemplate.id(), xContentBuilder); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(uiTemplate.getTemplateId()).build(); } catch (Exception e) { log.error(e.getMessage(), e); - return TemplateChangeStatus.builder().status(false).message("Can't add a new template") + return TemplateChangeStatus.builder().status(false).id(setting.getId()).message("Can't add a new template") .build(); } } @@ -106,23 +127,23 @@ public class UITemplateManagementEsDAO extends EsDAO implements UITemplateManage final boolean exist = getClient().existDoc(UITemplate.INDEX_NAME, uiTemplate.id()); if (!exist) { - return TemplateChangeStatus.builder().status(false) + return TemplateChangeStatus.builder().status(false).id(setting.getId()) .message("Can't find the template").build(); } final Map xContentBuilder = builder.entity2Storage(uiTemplate); getClient().forceUpdate(UITemplate.INDEX_NAME, uiTemplate.id(), xContentBuilder); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(setting.getId()).build(); } catch (Exception e) { log.error(e.getMessage(), e); - return TemplateChangeStatus.builder().status(false).message("Can't find the template") + return TemplateChangeStatus.builder().status(false).id(setting.getId()).message("Can't find the template") .build(); } } @Override - public TemplateChangeStatus disableTemplate(final String name) { - final Optional response = getClient().get(UITemplate.INDEX_NAME, name); + public TemplateChangeStatus disableTemplate(final String id) { + final Optional response = getClient().get(UITemplate.INDEX_NAME, id); if (response.isPresent()) { final UITemplate.Builder builder = new UITemplate.Builder(); final UITemplate uiTemplate = builder.storage2Entity(response.get().getSource()); @@ -130,9 +151,9 @@ public class UITemplateManagementEsDAO extends EsDAO implements UITemplateManage final Map xContentBuilder = builder.entity2Storage(uiTemplate); getClient().forceUpdate(UITemplate.INDEX_NAME, uiTemplate.id(), xContentBuilder); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(id).build(); } else { - return TemplateChangeStatus.builder().status(false).message("Can't find the template") + return TemplateChangeStatus.builder().status(false).id(id).message("Can't find the template") .build(); } } diff --git a/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/UITemplateManagementDAOImpl.java b/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/UITemplateManagementDAOImpl.java index c23f07fc59..7528fa0be0 100644 --- a/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/UITemplateManagementDAOImpl.java +++ b/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/UITemplateManagementDAOImpl.java @@ -33,6 +33,7 @@ import org.apache.skywalking.oap.server.core.query.type.DashboardConfiguration; import org.apache.skywalking.oap.server.core.query.type.TemplateChangeStatus; import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO; import org.apache.skywalking.oap.server.library.util.BooleanUtils; +import org.apache.skywalking.oap.server.library.util.StringUtil; import org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxClient; import org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxConstants; import org.influxdb.dto.Point; @@ -49,12 +50,44 @@ public class UITemplateManagementDAOImpl implements UITemplateManagementDAO { private final InfluxClient client; @Override - public List getAllTemplates(final Boolean includingDisabled) throws IOException { + public DashboardConfiguration getTemplate(final String id) throws IOException { + if (StringUtil.isEmpty(id)) { + return null; + } + + final SelectQueryImpl query = select().all() + .from(client.getDatabase(), UITemplate.INDEX_NAME) + .where(eq(InfluxConstants.TagName.ID_COLUMN, id)) + .limit(1); + + final QueryResult.Series series = client.queryForSingleSeries(query); + if (log.isDebugEnabled()) { + log.debug("SQL: {} result: {}", query.getCommand(), series); + } + final UITemplate.Builder builder = new UITemplate.Builder(); + + if (Objects.nonNull(series)) { + List columnNames = series.getColumns(); + List columnValues = series.getValues().get(0); + + Map data = Maps.newHashMap(); + for (int i = 1; i < columnNames.size(); i++) { + data.put(columnNames.get(i), columnValues.get(i)); + } + UITemplate uiTemplate = builder.storage2Entity(data); + return new DashboardConfiguration().fromEntity(uiTemplate); + + } + return null; + } + + @Override + public List getAllTemplates(Boolean includingDisabled) throws IOException { final WhereQueryImpl where = select().raw("*::field") .from(client.getDatabase(), UITemplate.INDEX_NAME) .where(); if (!includingDisabled) { - where.and(eq(UITemplate.DISABLED, BooleanUtils.FALSE)); + where.and(eq(UITemplate.DISABLED, BooleanUtils.booleanToValue(includingDisabled))); } final QueryResult.Series series = client.queryForSingleSeries(where); final List configs = new ArrayList<>(); @@ -88,7 +121,7 @@ public class UITemplateManagementDAOImpl implements UITemplateManagementDAO { .time(1L, TimeUnit.NANOSECONDS) .build(); client.write(point); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(setting.getId()).build(); } @Override @@ -108,28 +141,28 @@ public class UITemplateManagementDAOImpl implements UITemplateManagementDAO { .time(1L, TimeUnit.NANOSECONDS) .build(); client.write(point); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(setting.getId()).build(); } else { - return TemplateChangeStatus.builder().status(false).message("Can't find the template").build(); + return TemplateChangeStatus.builder().status(false).id(setting.getId()).message("Can't find the template").build(); } } @Override - public TemplateChangeStatus disableTemplate(final String name) throws IOException { + public TemplateChangeStatus disableTemplate(final String id) throws IOException { WhereQueryImpl query = select().all() .from(client.getDatabase(), UITemplate.INDEX_NAME) - .where(eq(InfluxConstants.TagName.ID_COLUMN, name)); + .where(eq(InfluxConstants.TagName.ID_COLUMN, id)); QueryResult.Series series = client.queryForSingleSeries(query); if (Objects.nonNull(series)) { final Point point = Point.measurement(UITemplate.INDEX_NAME) - .tag(InfluxConstants.TagName.ID_COLUMN, name) + .tag(InfluxConstants.TagName.ID_COLUMN, id) .addField(UITemplate.DISABLED, BooleanUtils.TRUE) .time(1L, TimeUnit.NANOSECONDS) .build(); client.write(point); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(id).build(); } else { - return TemplateChangeStatus.builder().status(false).message("Can't find the template").build(); + return TemplateChangeStatus.builder().status(false).id(id).message("Can't find the template").build(); } } } diff --git a/oap-server/server-storage-plugin/storage-iotdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/iotdb/management/IoTDBUITemplateManagementDAO.java b/oap-server/server-storage-plugin/storage-iotdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/iotdb/management/IoTDBUITemplateManagementDAO.java index 0bf9c2034d..12c3f0b398 100644 --- a/oap-server/server-storage-plugin/storage-iotdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/iotdb/management/IoTDBUITemplateManagementDAO.java +++ b/oap-server/server-storage-plugin/storage-iotdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/iotdb/management/IoTDBUITemplateManagementDAO.java @@ -20,7 +20,9 @@ package org.apache.skywalking.oap.server.storage.plugin.iotdb.management; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate; @@ -31,7 +33,9 @@ import org.apache.skywalking.oap.server.core.storage.StorageData; import org.apache.skywalking.oap.server.core.storage.StorageHashMapBuilder; import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO; import org.apache.skywalking.oap.server.library.util.BooleanUtils; +import org.apache.skywalking.oap.server.library.util.StringUtil; import org.apache.skywalking.oap.server.storage.plugin.iotdb.IoTDBClient; +import org.apache.skywalking.oap.server.storage.plugin.iotdb.IoTDBIndexes; import org.apache.skywalking.oap.server.storage.plugin.iotdb.base.IoTDBInsertRequest; @Slf4j @@ -41,6 +45,26 @@ public class IoTDBUITemplateManagementDAO implements UITemplateManagementDAO { private final StorageHashMapBuilder storageBuilder = new UITemplate.Builder(); private static final long UI_TEMPLATE_TIMESTAMP = 1L; + @Override + public DashboardConfiguration getTemplate(final String id) throws IOException { + if (StringUtil.isEmpty(id)) { + return null; + } + StringBuilder query = new StringBuilder(); + query.append("select * from "); + query = client.addModelPath(query, UITemplate.INDEX_NAME); + Map indexAndValueMap = new HashMap<>(); + indexAndValueMap.put(IoTDBIndexes.ID_IDX, id); + query = client.addQueryIndexValue(UITemplate.INDEX_NAME, query, indexAndValueMap); + query.append(" limit 1").append(IoTDBClient.ALIGN_BY_DEVICE); + + List storageDataList = client.filterQuery(UITemplate.INDEX_NAME, query.toString(), storageBuilder); + if (storageDataList.size() > 0) { + return new DashboardConfiguration().fromEntity((UITemplate) storageDataList.get(0)); + } + return null; + } + @Override public List getAllTemplates(Boolean includingDisabled) throws IOException { StringBuilder query = new StringBuilder(); @@ -67,7 +91,7 @@ public class IoTDBUITemplateManagementDAO implements UITemplateManagementDAO { IoTDBInsertRequest request = new IoTDBInsertRequest(UITemplate.INDEX_NAME, UI_TEMPLATE_TIMESTAMP, uiTemplate, storageBuilder); client.write(request); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(setting.getId()).build(); } @Override @@ -81,33 +105,33 @@ public class IoTDBUITemplateManagementDAO implements UITemplateManagementDAO { .append(IoTDBClient.ALIGN_BY_DEVICE); List queryResult = client.filterQuery(UITemplate.INDEX_NAME, query.toString(), storageBuilder); if (queryResult.size() == 0) { - return TemplateChangeStatus.builder().status(false).message("Can't find the template").build(); + return TemplateChangeStatus.builder().status(false).id(setting.getId()).message("Can't find the template").build(); } else { IoTDBInsertRequest request = new IoTDBInsertRequest(UITemplate.INDEX_NAME, UI_TEMPLATE_TIMESTAMP, uiTemplate, storageBuilder); client.write(request); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(setting.getId()).build(); } } @Override - public TemplateChangeStatus disableTemplate(String name) throws IOException { + public TemplateChangeStatus disableTemplate(String id) throws IOException { StringBuilder query = new StringBuilder(); query.append("select * from "); query = client.addModelPath(query, UITemplate.INDEX_NAME); - query.append(IoTDBClient.DOT).append(client.indexValue2LayerName(name)) + query.append(IoTDBClient.DOT).append(client.indexValue2LayerName(id)) .append(IoTDBClient.ALIGN_BY_DEVICE); List queryResult = client.filterQuery(UITemplate.INDEX_NAME, query.toString(), storageBuilder); if (queryResult.size() == 0) { - return TemplateChangeStatus.builder().status(false).message("Can't find the template").build(); + return TemplateChangeStatus.builder().status(false).id(id).message("Can't find the template").build(); } else { final UITemplate uiTemplate = (UITemplate) queryResult.get(0); uiTemplate.setDisabled(BooleanUtils.TRUE); IoTDBInsertRequest request = new IoTDBInsertRequest(UITemplate.INDEX_NAME, UI_TEMPLATE_TIMESTAMP, uiTemplate, storageBuilder); client.write(request); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(id).build(); } } } diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2UITemplateManagementDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2UITemplateManagementDAO.java index 8802b28c24..7f1c227329 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2UITemplateManagementDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2UITemplateManagementDAO.java @@ -34,6 +34,7 @@ import org.apache.skywalking.oap.server.core.storage.management.UITemplateManage import org.apache.skywalking.oap.server.library.client.jdbc.JDBCClientException; import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; import org.apache.skywalking.oap.server.library.util.BooleanUtils; +import org.apache.skywalking.oap.server.library.util.StringUtil; import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLExecutor; @Slf4j @@ -42,7 +43,32 @@ public class H2UITemplateManagementDAO extends H2SQLExecutor implements UITempla private final JDBCHikariCPClient h2Client; @Override - public List getAllTemplates(final Boolean includingDisabled) throws IOException { + public DashboardConfiguration getTemplate(final String id) throws IOException { + if (StringUtil.isEmpty(id)) { + return null; + } + final StringBuilder sql = new StringBuilder(); + final ArrayList condition = new ArrayList<>(1); + sql.append("select * from ").append(UITemplate.INDEX_NAME).append(" where id=? LIMIT 1 "); + condition.add(id); + + try (Connection connection = h2Client.getConnection()) { + try (ResultSet rs = h2Client.executeQuery( + connection, sql.toString(), condition.toArray(new Object[0]))) { + final UITemplate.Builder builder = new UITemplate.Builder(); + UITemplate uiTemplate = (UITemplate) toStorageData(rs, UITemplate.INDEX_NAME, builder); + if (uiTemplate != null) { + return new DashboardConfiguration().fromEntity(uiTemplate); + } + } + } catch (SQLException | JDBCClientException e) { + throw new IOException(e); + } + return null; + } + + @Override + public List getAllTemplates(Boolean includingDisabled) throws IOException { final StringBuilder sql = new StringBuilder(); final ArrayList condition = new ArrayList<>(1); sql.append("select * from ").append(UITemplate.INDEX_NAME).append(" where 1=1 "); @@ -75,10 +101,10 @@ public class H2UITemplateManagementDAO extends H2SQLExecutor implements UITempla final SQLExecutor insertExecutor = getInsertExecutor(UITemplate.INDEX_NAME, uiTemplate, new UITemplate.Builder()); try (Connection connection = h2Client.getConnection()) { insertExecutor.invoke(connection); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(setting.getId()).build(); } catch (SQLException | JDBCClientException e) { log.error(e.getMessage(), e); - return TemplateChangeStatus.builder().status(false).message("Can't add a new template").build(); + return TemplateChangeStatus.builder().status(false).id(setting.getId()).message("Can't add a new template").build(); } } @@ -89,10 +115,10 @@ public class H2UITemplateManagementDAO extends H2SQLExecutor implements UITempla } @Override - public TemplateChangeStatus disableTemplate(final String name) throws IOException { - final UITemplate uiTemplate = (UITemplate) getByID(h2Client, UITemplate.INDEX_NAME, name, new UITemplate.Builder()); + public TemplateChangeStatus disableTemplate(final String id) throws IOException { + final UITemplate uiTemplate = (UITemplate) getByID(h2Client, UITemplate.INDEX_NAME, id, new UITemplate.Builder()); if (uiTemplate == null) { - return TemplateChangeStatus.builder().status(false).message("Can't find the template").build(); + return TemplateChangeStatus.builder().status(false).id(id).message("Can't find the template").build(); } uiTemplate.setDisabled(BooleanUtils.TRUE); return executeUpdate(uiTemplate); @@ -102,10 +128,10 @@ public class H2UITemplateManagementDAO extends H2SQLExecutor implements UITempla final SQLExecutor updateExecutor = getUpdateExecutor(UITemplate.INDEX_NAME, uiTemplate, new UITemplate.Builder()); try (Connection connection = h2Client.getConnection()) { updateExecutor.invoke(connection); - return TemplateChangeStatus.builder().status(true).build(); + return TemplateChangeStatus.builder().status(true).id(uiTemplate.getTemplateId()).build(); } catch (SQLException | JDBCClientException e) { log.error(e.getMessage(), e); - return TemplateChangeStatus.builder().status(false).message("Can't add/update the template").build(); + return TemplateChangeStatus.builder().status(false).id(uiTemplate.getTemplateId()).message("Can't add/update the template").build(); } } } diff --git a/skywalking-ui b/skywalking-ui index 0e2541e3f1..8ad1c91082 160000 --- a/skywalking-ui +++ b/skywalking-ui @@ -1 +1 @@ -Subproject commit 0e2541e3f1c0c5bacd7da4d13a32bd2b99402b8f +Subproject commit 8ad1c91082b5c58a7be39cd78ecef783e60d50c2