未验证 提交 d094a0f7 编写于 作者: wu-sheng's avatar wu-sheng 提交者: GitHub

Support UI template management. (#4843)

上级 705f97f2
......@@ -50,7 +50,8 @@
<include>component-libraries.yml</include>
<include>gateways.yml</include>
<include>service-apdex-threshold.yml</include>
<include>endpoint_name_grouping.yml</include>
<include>endpoint-name-grouping.yml</include>
<include>ui-initialized-templates.yml</include>
<include>oal/core.oal</include>
<include>oal/java-agent.oal</include>
<include>oal/dotnet-agent.oal</include>
......
......@@ -50,7 +50,8 @@
<include>component-libraries.yml</include>
<include>gateways.yml</include>
<include>service-apdex-threshold.yml</include>
<include>endpoint_name_grouping.yml</include>
<include>ui-initialized-templates.yml</include>
<include>endpoint-name-grouping.yml</include>
<include>oal/core.oal</include>
<include>oal/java-agent.oal</include>
<include>oal/dotnet-agent.oal</include>
......
......@@ -10,7 +10,7 @@ Right now, SkyWalking supports following dynamic configurations.
|receiver-trace.default.uninstrumentedGateways| The uninstrumented gateways, override `gateways.yml`. | same as [`gateways.yml`](uninstrumented-gateways.md#configuration-format) |
|alarm.default.alarm-settings| The alarm settings, will override `alarm-settings.yml`. | same as [`alarm-settings.yml`](backend-alarm.md) |
|core.default.apdexThreshold| The apdex threshold settings, will override `service-apdex-threshold.yml`. | same as [`service-apdex-threshold.yml`](apdex-threshold.md) |
|core.default.endpoint-name-grouping| The endpoint name grouping setting, will override `endpoint_name_grouping.yml`. | same as [`endpoint_name_grouping.yml`](endpoint-grouping-rules.md) |
|core.default.endpoint-name-grouping| The endpoint name grouping setting, will override `endpoint-name-grouping.yml`. | same as [`endpoint-name-grouping.yml`](endpoint-grouping-rules.md) |
This feature depends on upstream service, so it is **DISABLED** by default.
......
......@@ -6,7 +6,7 @@ There are some special cases, especially when people use REST style URI, the app
such as putting order id in the URI, like `/prod/ORDER123` and `/prod/ORDER123`. But logically, people expect they could
have an endpoint name like `prod/{order-id}`. This is the feature of parameterized endpoint grouping designed for.
Current, user could set up grouping rules through the static YAML file, named `endpoint_name_grouping.yml`,
Current, user could set up grouping rules through the static YAML file, named `endpoint-name-grouping.yml`,
or use [Dynamic Configuration](dynamic-config.md) to initial and update the endpoint grouping rule.
## Configuration Format
......
......@@ -242,7 +242,8 @@
<exclude>component-libraries.yml</exclude>
<exclude>gateways.yml</exclude>
<exclude>service-apdex-threshold.yml</exclude>
<exclude>endpoint_name_grouping.yml</exclude>
<exclude>endpoint-name-grouping.yml</exclude>
<exclude>ui-initialized-templates.yml</exclude>
<exclude>oal/core.oal</exclude>
<exclude>oal/java-agent.oal</exclude>
<exclude>oal/dotnet-agent.oal</exclude>
......
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
# UI templates initialized file includes the default template when the SkyWalking OAP starts up at the first time.
#
# Also, SkyWalking would detect the existing templates in the database, once they are missing, all templates in this file
# could be added automatically.
#templates:
# - name: "APM (Agent based)"
# # The type includes DASHBOARD, TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT.
# # DASHBOARD type templates could have multiple definitions, by using different names.
# # TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT type templates should be defined once, as they are used in the topology page only.
# type: "DASHBOARD"
# # Configuration could be defined through UI, and use `export` to format in the standard JSON.
# configuration: |-
# JSON format exported from UI.
# # Activated as the DASHBOARD type, makes this templates added into the UI page automatically.
# # False means providing a basic template, user needs to add it manually.
# activated: true
# # True means wouldn't show up on the dashboard. Only keeps the definition in the storage.
# disabled: false
......@@ -28,6 +28,7 @@ import org.apache.skywalking.oap.server.core.config.ConfigService;
import org.apache.skywalking.oap.server.core.config.DownSamplingConfigService;
import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
import org.apache.skywalking.oap.server.core.config.NamingControl;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService;
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoaderService;
import org.apache.skywalking.oap.server.core.profile.ProfileTaskMutationService;
import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
......@@ -46,8 +47,8 @@ import org.apache.skywalking.oap.server.core.server.GRPCHandlerRegister;
import org.apache.skywalking.oap.server.core.server.JettyHandlerRegister;
import org.apache.skywalking.oap.server.core.source.SourceReceiver;
import org.apache.skywalking.oap.server.core.storage.model.IModelManager;
import org.apache.skywalking.oap.server.core.storage.model.ModelManipulator;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.core.storage.model.ModelManipulator;
import org.apache.skywalking.oap.server.core.worker.IWorkerInstanceGetter;
import org.apache.skywalking.oap.server.core.worker.IWorkerInstanceSetter;
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
......@@ -82,10 +83,15 @@ public class CoreModule extends ModuleDefine {
addQueryService(classes);
addProfileService(classes);
addOALService(classes);
addManagementService(classes);
classes.add(CommandService.class);
return classes.toArray(new Class[] {});
return classes.toArray(new Class[]{});
}
private void addManagementService(List<Class> classes) {
classes.add(UITemplateManagementService.class);
}
private void addProfileService(List<Class> classes) {
......
......@@ -28,6 +28,7 @@ import org.apache.skywalking.oap.server.core.analysis.DisableRegister;
import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener;
import org.apache.skywalking.oap.server.core.analysis.meter.MeterSystem;
import org.apache.skywalking.oap.server.core.analysis.metrics.ApdexMetrics;
import org.apache.skywalking.oap.server.core.analysis.worker.ManagementStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.TopNStreamProcessor;
import org.apache.skywalking.oap.server.core.annotation.AnnotationScan;
......@@ -45,6 +46,8 @@ import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogServ
import org.apache.skywalking.oap.server.core.config.NamingControl;
import org.apache.skywalking.oap.server.core.config.group.EndpointNameGrouping;
import org.apache.skywalking.oap.server.core.config.group.EndpointNameGroupingRuleWatcher;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateInitializer;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService;
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoaderService;
import org.apache.skywalking.oap.server.core.profile.ProfileTaskMutationService;
import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
......@@ -87,6 +90,7 @@ import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedExcepti
import org.apache.skywalking.oap.server.library.server.ServerException;
import org.apache.skywalking.oap.server.library.server.grpc.GRPCServer;
import org.apache.skywalking.oap.server.library.server.jetty.JettyServer;
import org.apache.skywalking.oap.server.library.util.ResourceUtils;
import org.apache.skywalking.oap.server.telemetry.TelemetryModule;
/**
......@@ -139,14 +143,14 @@ public class CoreModuleProvider extends ModuleProvider {
}
EndpointNameGrouping endpointNameGrouping = new EndpointNameGrouping();
this.registerServiceImplementation(NamingControl.class, new NamingControl(
moduleConfig.getServiceNameMaxLength(),
moduleConfig.getInstanceNameMaxLength(),
moduleConfig.getEndpointNameMaxLength(),
endpointNameGrouping
moduleConfig.getServiceNameMaxLength(),
moduleConfig.getInstanceNameMaxLength(),
moduleConfig.getEndpointNameMaxLength(),
endpointNameGrouping
));
try {
endpointNameGroupingRuleWatcher = new EndpointNameGroupingRuleWatcher(
this, endpointNameGrouping);
this, endpointNameGrouping);
} catch (FileNotFoundException e) {
throw new ModuleStartException(e.getMessage(), e);
}
......@@ -174,8 +178,8 @@ public class CoreModuleProvider extends ModuleProvider {
if (moduleConfig.isGRPCSslEnabled()) {
grpcServer = new GRPCServer(moduleConfig.getGRPCHost(), moduleConfig.getGRPCPort(),
Paths.get(moduleConfig.getGRPCSslCertChainPath()).toFile(),
Paths.get(moduleConfig.getGRPCSslKeyPath()).toFile()
Paths.get(moduleConfig.getGRPCSslCertChainPath()).toFile(),
Paths.get(moduleConfig.getGRPCSslKeyPath()).toFile()
);
} else {
grpcServer = new GRPCServer(moduleConfig.getGRPCHost(), moduleConfig.getGRPCPort());
......@@ -195,13 +199,13 @@ public class CoreModuleProvider extends ModuleProvider {
grpcServer.initialize();
jettyServer = new JettyServer(
moduleConfig.getRestHost(), moduleConfig.getRestPort(), moduleConfig.getRestContextPath(), moduleConfig
.getJettySelectors());
moduleConfig.getRestHost(), moduleConfig.getRestPort(), moduleConfig.getRestContextPath(), moduleConfig
.getJettySelectors());
jettyServer.initialize();
this.registerServiceImplementation(ConfigService.class, new ConfigService(moduleConfig));
this.registerServiceImplementation(
DownSamplingConfigService.class, new DownSamplingConfigService(moduleConfig.getDownsampling()));
DownSamplingConfigService.class, new DownSamplingConfigService(moduleConfig.getDownsampling()));
this.registerServiceImplementation(GRPCHandlerRegister.class, new GRPCHandlerRegisterImpl(grpcServer));
this.registerServiceImplementation(JettyHandlerRegister.class, new JettyHandlerRegisterImpl(jettyServer));
......@@ -220,7 +224,7 @@ public class CoreModuleProvider extends ModuleProvider {
this.registerServiceImplementation(ModelManipulator.class, storageModels);
this.registerServiceImplementation(
NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
this.registerServiceImplementation(TopologyQueryService.class, new TopologyQueryService(getManager()));
this.registerServiceImplementation(MetricsMetadataQueryService.class, new MetricsMetadataQueryService());
......@@ -234,9 +238,9 @@ public class CoreModuleProvider extends ModuleProvider {
// add profile service implementations
this.registerServiceImplementation(
ProfileTaskMutationService.class, new ProfileTaskMutationService(getManager()));
ProfileTaskMutationService.class, new ProfileTaskMutationService(getManager()));
this.registerServiceImplementation(
ProfileTaskQueryService.class, new ProfileTaskQueryService(getManager(), moduleConfig));
ProfileTaskQueryService.class, new ProfileTaskQueryService(getManager(), moduleConfig));
this.registerServiceImplementation(ProfileTaskCache.class, new ProfileTaskCache(getManager(), moduleConfig));
this.registerServiceImplementation(CommandService.class, new CommandService(getManager()));
......@@ -248,14 +252,17 @@ public class CoreModuleProvider extends ModuleProvider {
if (moduleConfig.isGRPCSslEnabled()) {
this.remoteClientManager = new RemoteClientManager(getManager(), moduleConfig.getRemoteTimeout(),
Paths.get(moduleConfig.getGRPCSslTrustedCAPath())
.toFile()
Paths.get(moduleConfig.getGRPCSslTrustedCAPath())
.toFile()
);
} else {
this.remoteClientManager = new RemoteClientManager(getManager(), moduleConfig.getRemoteTimeout());
}
this.registerServiceImplementation(RemoteClientManager.class, remoteClientManager);
// Management
this.registerServiceImplementation(UITemplateManagementService.class, new UITemplateManagementService(getManager()));
MetricsStreamProcessor.getInstance().setEnableDatabaseSession(moduleConfig.isEnableDatabaseSession());
TopNStreamProcessor.getInstance().setTopNWorkerReportCycle(moduleConfig.getTopNReportPeriod());
apdexThresholdConfig = new ApdexThresholdConfig(this);
......@@ -276,24 +283,24 @@ public class CoreModuleProvider extends ModuleProvider {
}
if (CoreModuleConfig.Role.Mixed.name()
.equalsIgnoreCase(
moduleConfig.getRole())
|| CoreModuleConfig.Role.Aggregator.name()
.equalsIgnoreCase(
moduleConfig.getRole())) {
.equalsIgnoreCase(
moduleConfig.getRole())
|| CoreModuleConfig.Role.Aggregator.name()
.equalsIgnoreCase(
moduleConfig.getRole())) {
RemoteInstance gRPCServerInstance = new RemoteInstance(
new Address(moduleConfig.getGRPCHost(), moduleConfig.getGRPCPort(), true));
new Address(moduleConfig.getGRPCHost(), moduleConfig.getGRPCPort(), true));
this.getManager()
.find(ClusterModule.NAME)
.provider()
.getService(ClusterRegister.class)
.registerRemote(gRPCServerInstance);
.find(ClusterModule.NAME)
.provider()
.getService(ClusterRegister.class)
.registerRemote(gRPCServerInstance);
}
DynamicConfigurationService dynamicConfigurationService = getManager().find(ConfigurationModule.NAME)
.provider()
.getService(
DynamicConfigurationService.class);
.provider()
.getService(
DynamicConfigurationService.class);
dynamicConfigurationService.registerConfigChangeWatcher(apdexThresholdConfig);
dynamicConfigurationService.registerConfigChangeWatcher(endpointNameGroupingRuleWatcher);
}
......@@ -314,13 +321,23 @@ public class CoreModuleProvider extends ModuleProvider {
}
CacheUpdateTimer.INSTANCE.start(getManager(), moduleConfig.getMetricsDataTTL());
try {
new UITemplateInitializer(ResourceUtils.read("ui-initialized-templates.yml"))
.read()
.forEach(uiTemplate -> {
ManagementStreamProcessor.getInstance().in(uiTemplate);
});
} catch (FileNotFoundException e) {
throw new ModuleStartException(e.getMessage(), e);
}
}
@Override
public String[] requiredModules() {
return new String[] {
TelemetryModule.NAME,
ConfigurationModule.NAME
return new String[]{
TelemetryModule.NAME,
ConfigurationModule.NAME
};
}
}
......@@ -19,7 +19,7 @@ package org.apache.skywalking.oap.server.core.analysis;
public enum DownSampling {
/**
* None downsampling is for inventory
* None downsampling is for un-time-series data.
*/
None(0, ""),
/**
......
......@@ -24,7 +24,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamingProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.TopNStreamProcessor;
import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
......@@ -33,7 +33,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
/**
* Stream annotation represents a metadata definition. Include the key values of the distributed streaming calculation.
* See {@link MetricsStreamProcessor}, {@link RecordStreamProcessor}, {@link TopNStreamProcessor} and {@link
* NoneStreamingProcessor} for more details.
* NoneStreamProcessor} for more details.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
......@@ -55,7 +55,7 @@ public @interface Stream {
/**
* @return the stream processor type, see {@link MetricsStreamProcessor}, {@link RecordStreamProcessor}, {@link
* TopNStreamProcessor} and {@link NoneStreamingProcessor} for more details.
* TopNStreamProcessor} and {@link NoneStreamProcessor} for more details.
*/
Class<? extends StreamProcessor> processor();
}
......@@ -20,8 +20,9 @@ package org.apache.skywalking.oap.server.core.analysis;
import java.lang.annotation.Annotation;
import org.apache.skywalking.oap.server.core.UnexpectedException;
import org.apache.skywalking.oap.server.core.analysis.worker.ManagementStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamingProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.TopNStreamProcessor;
import org.apache.skywalking.oap.server.core.annotation.AnnotationListener;
......@@ -56,14 +57,16 @@ public class StreamAnnotationListener implements AnnotationListener {
MetricsStreamProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else if (stream.processor().equals(TopNStreamProcessor.class)) {
TopNStreamProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else if (stream.processor().equals(NoneStreamingProcessor.class)) {
NoneStreamingProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else if (stream.processor().equals(NoneStreamProcessor.class)) {
NoneStreamProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else if (stream.processor().equals(ManagementStreamProcessor.class)) {
ManagementStreamProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else {
throw new UnexpectedException("Unknown stream processor.");
}
} else {
throw new UnexpectedException(
"Stream annotation listener could only parse the class present stream annotation.");
"Stream annotation listener could only parse the class present stream annotation.");
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.analysis.management;
import org.apache.skywalking.oap.server.core.storage.StorageData;
/**
* ManagementData provides the basic CRUD operations.
*/
public abstract class ManagementData implements StorageData {
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.analysis.worker;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.model.Model;
import org.apache.skywalking.oap.server.core.worker.AbstractWorker;
import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder;
@Slf4j
public class ManagementPersistentWorker extends AbstractWorker<ManagementData> {
private final Model model;
private final IManagementDAO configDAO;
public ManagementPersistentWorker(ModuleDefineHolder moduleDefineHolder, Model model, IManagementDAO configDAO) {
super(moduleDefineHolder);
this.model = model;
this.configDAO = configDAO;
}
@Override
public void in(ManagementData managementData) {
try {
configDAO.insert(model, managementData);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.analysis.worker;
import java.util.HashMap;
import java.util.Map;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.UnexpectedException;
import org.apache.skywalking.oap.server.core.analysis.DisableRegister;
import org.apache.skywalking.oap.server.core.analysis.DownSampling;
import org.apache.skywalking.oap.server.core.analysis.Stream;
import org.apache.skywalking.oap.server.core.analysis.StreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.annotation.Storage;
import org.apache.skywalking.oap.server.core.storage.model.Model;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder;
/**
* ManagementProcessor represents the UI/CLI interactive process. They are management data, which size is not huge and
* time serious.
*
* @since 8.0.0
*/
public class ManagementStreamProcessor implements StreamProcessor<ManagementData> {
private static final ManagementStreamProcessor PROCESSOR = new ManagementStreamProcessor();
private Map<Class<? extends ManagementData>, ManagementPersistentWorker> workers = new HashMap<>();
public static ManagementStreamProcessor getInstance() {
return PROCESSOR;
}
@Override
public void in(final ManagementData managementData) {
final ManagementPersistentWorker worker = workers.get(managementData.getClass());
if (worker != null) {
worker.in(managementData);
}
}
@Override
public void create(final ModuleDefineHolder moduleDefineHolder, final Stream stream, final Class<? extends ManagementData> streamClass) throws StorageException {
if (DisableRegister.INSTANCE.include(stream.name())) {
return;
}
StorageDAO storageDAO = moduleDefineHolder.find(StorageModule.NAME).provider().getService(StorageDAO.class);
IManagementDAO managementDAO;
try {
managementDAO = storageDAO.newManagementDao(stream.builder().newInstance());
} catch (InstantiationException | IllegalAccessException e) {
throw new UnexpectedException("Create " + stream.builder()
.getSimpleName() + " none stream record DAO failure.", e);
}
ModelCreator modelSetter = moduleDefineHolder.find(CoreModule.NAME).provider().getService(ModelCreator.class);
Model model = modelSetter.add(streamClass, stream.scopeId(), new Storage(stream.name(), DownSampling.None), false);
final ManagementPersistentWorker persistentWorker = new ManagementPersistentWorker(moduleDefineHolder, model, managementDAO);
workers.put(streamClass, persistentWorker);
}
}
......@@ -19,21 +19,18 @@
package org.apache.skywalking.oap.server.core.analysis.worker;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.storage.INoneStreamDAO;
import org.apache.skywalking.oap.server.core.storage.model.Model;
import org.apache.skywalking.oap.server.core.worker.AbstractWorker;
import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* None persistent use {@link INoneStreamDAO#insert(Model, NoneStream)} on get new data
* None persistent use {@link INoneStreamDAO#insert(Model, NoneStream)} on saving new data
*/
@Slf4j
public class NoneStreamPersistentWorker extends AbstractWorker<NoneStream> {
private static final Logger logger = LoggerFactory.getLogger(NoneStreamPersistentWorker.class);
private final Model model;
private final INoneStreamDAO configDAO;
......@@ -48,7 +45,7 @@ public class NoneStreamPersistentWorker extends AbstractWorker<NoneStream> {
try {
configDAO.insert(model, noneStream);
} catch (IOException e) {
logger.error(e.getMessage(), e);
log.error(e.getMessage(), e);
}
}
}
......@@ -40,13 +40,13 @@ import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder;
* none streaming is designed for user operation configuration in UI interface. It uses storage (synchronization)
* similar to Inventory and supports TTL deletion mode similar to the record.
*/
public class NoneStreamingProcessor implements StreamProcessor<NoneStream> {
public class NoneStreamProcessor implements StreamProcessor<NoneStream> {
private static final NoneStreamingProcessor PROCESSOR = new NoneStreamingProcessor();
private static final NoneStreamProcessor PROCESSOR = new NoneStreamProcessor();
private Map<Class<? extends NoneStream>, NoneStreamPersistentWorker> workers = new HashMap<>();
public static NoneStreamingProcessor getInstance() {
public static NoneStreamProcessor getInstance() {
return PROCESSOR;
}
......
......@@ -40,7 +40,7 @@ public class EndpointNameGroupingRuleWatcher extends ConfigChangeWatcher {
// This is just a place holder text representing the original text.
ruleSetting = "SkyWalking endpoint rule";
grouping.setEndpointGroupingRule(new EndpointGroupingRuleReader(
ResourceUtils.read("endpoint_name_grouping.yml")).read());
ResourceUtils.read("endpoint-name-grouping.yml")).read());
}
@Override
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.management.ui.template;
import java.util.HashMap;
import java.util.Map;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.skywalking.oap.server.core.analysis.Stream;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.worker.ManagementStreamProcessor;
import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.UI_TEMPLATE;
@Setter
@Getter
@ScopeDeclaration(id = UI_TEMPLATE, name = "UITemplate")
@Stream(name = UITemplate.INDEX_NAME, scopeId = UI_TEMPLATE, builder = UITemplate.Builder.class, processor = ManagementStreamProcessor.class)
@EqualsAndHashCode(of = {
"name"
}, 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 CONFIGURATION = "configuration";
public static final String ACTIVATED = "activated";
public static final String DISABLED = "disabled";
@Column(columnName = NAME)
private String name;
@Column(columnName = TYPE, storageOnly = true)
private String type;
/**
* 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 = DISABLED)
private int disabled;
@Override
public String id() {
return name;
}
public static class Builder implements StorageBuilder<UITemplate> {
@Override
public UITemplate map2Data(final Map<String, Object> dbMap) {
UITemplate uiTemplate = new UITemplate();
uiTemplate.setName((String) dbMap.get(NAME));
uiTemplate.setType((String) dbMap.get(TYPE));
uiTemplate.setConfiguration((String) dbMap.get(CONFIGURATION));
uiTemplate.setActivated(((Number) dbMap.get(ACTIVATED)).intValue());
uiTemplate.setDisabled(((Number) dbMap.get(DISABLED)).intValue());
return uiTemplate;
}
@Override
public Map<String, Object> data2Map(final UITemplate storageData) {
final HashMap<String, Object> map = new HashMap<>();
map.put(NAME, storageData.getName());
map.put(TYPE, storageData.getType());
map.put(CONFIGURATION, storageData.getConfiguration());
map.put(ACTIVATED, storageData.getActivated());
map.put(DISABLED, storageData.getDisabled());
return map;
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.management.ui.template;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.skywalking.apm.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;
/**
* UITemplateInitializer load the template from the config file in YAML format. The template definition is by JSON format in default,
* but it depends on the UI implementation only.
*/
public class UITemplateInitializer {
private Map yamlData;
public UITemplateInitializer(InputStream inputStream) {
Yaml yaml = new Yaml();
yamlData = yaml.loadAs(inputStream, Map.class);
}
public UITemplateInitializer(Reader io) {
Yaml yaml = new Yaml();
yamlData = yaml.loadAs(io, Map.class);
}
public List<UITemplate> read() {
List<UITemplate> 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);
});
}
}
return uiTemplates;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.management.ui.template;
import java.io.IOException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.skywalking.oap.server.core.query.input.DashboardSetting;
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.StorageModule;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.module.Service;
@RequiredArgsConstructor
public class UITemplateManagementService implements Service {
private final ModuleManager moduleManager;
private UITemplateManagementDAO uiTemplateManagementDAO;
private UITemplateManagementDAO getUITemplateManagementDAO() {
if (uiTemplateManagementDAO == null) {
this.uiTemplateManagementDAO = moduleManager.find(StorageModule.NAME)
.provider()
.getService(UITemplateManagementDAO.class);
}
return uiTemplateManagementDAO;
}
public List<DashboardConfiguration> getAllTemplates(Boolean includingDisabled) throws IOException {
return getUITemplateManagementDAO().getAllTemplates(includingDisabled);
}
public TemplateChangeStatus addTemplate(DashboardSetting setting) throws IOException {
return getUITemplateManagementDAO().addTemplate(setting);
}
public TemplateChangeStatus changeTemplate(DashboardSetting setting) throws IOException {
return getUITemplateManagementDAO().changeTemplate(setting);
}
public TemplateChangeStatus disableTemplate(String name) throws IOException {
return getUITemplateManagementDAO().disableTemplate(name);
}
}
......@@ -21,11 +21,12 @@ package org.apache.skywalking.oap.server.core.profile;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import org.apache.skywalking.apm.network.constants.ProfileConstants;
import org.apache.skywalking.apm.util.StringUtil;
import org.apache.skywalking.oap.server.core.analysis.DownSampling;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamingProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamProcessor;
import org.apache.skywalking.oap.server.core.query.type.ProfileTaskCreationResult;
import org.apache.skywalking.oap.server.core.query.type.ProfileTask;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
......@@ -34,15 +35,11 @@ import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.module.Service;
import org.apache.skywalking.oap.server.library.util.CollectionUtils;
@RequiredArgsConstructor
public class ProfileTaskMutationService implements Service {
private final ModuleManager moduleManager;
private IProfileTaskQueryDAO profileTaskQueryDAO;
public ProfileTaskMutationService(ModuleManager moduleManager) {
this.moduleManager = moduleManager;
}
private IProfileTaskQueryDAO getProfileTaskDAO() {
if (profileTaskQueryDAO == null) {
this.profileTaskQueryDAO = moduleManager.find(StorageModule.NAME)
......@@ -97,7 +94,7 @@ public class ProfileTaskMutationService implements Service {
task.setCreateTime(createTime);
task.setMaxSamplingCount(maxSamplingCount);
task.setTimeBucket(TimeBucket.getRecordTimeBucket(taskEndTime));
NoneStreamingProcessor.getInstance().in(task);
NoneStreamProcessor.getInstance().in(task);
return ProfileTaskCreationResult.builder().id(task.id()).build();
}
......
......@@ -25,7 +25,7 @@ import lombok.Setter;
import org.apache.skywalking.oap.server.core.Const;
import org.apache.skywalking.oap.server.core.analysis.Stream;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamingProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamProcessor;
import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
......@@ -38,7 +38,7 @@ import static org.apache.skywalking.oap.server.core.source.DefaultScopeDefine.PR
@Getter
@Setter
@ScopeDeclaration(id = PROFILE_TASK, name = "ProfileTask")
@Stream(name = ProfileTaskRecord.INDEX_NAME, scopeId = PROFILE_TASK, builder = ProfileTaskRecord.Builder.class, processor = NoneStreamingProcessor.class)
@Stream(name = ProfileTaskRecord.INDEX_NAME, scopeId = PROFILE_TASK, builder = ProfileTaskRecord.Builder.class, processor = NoneStreamProcessor.class)
public class ProfileTaskRecord extends NoneStream {
public static final String INDEX_NAME = "profile_task";
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.query.enumeration;
public enum TemplateType {
DASHBOARD,
TOPOLOGY_SERVICE,
TOPOLOGY_INSTANCE,
TOPOLOGY_ENDPOINT,
TOPOLOGY_SERVICE_RELATION,
TOPOLOGY_SERVICE_INSTANCE_RELATION;
public static TemplateType forName(String name) {
return Enum.valueOf(TemplateType.class, name.toUpperCase());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.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 configuration;
private boolean active;
public UITemplate toEntity() {
UITemplate uiTemplate = new UITemplate();
uiTemplate.setName(this.getName());
uiTemplate.setConfiguration(this.getConfiguration());
uiTemplate.setType(this.getType().name());
uiTemplate.setActivated(BooleanUtils.booleanToValue(this.isActive()));
uiTemplate.setDisabled(BooleanUtils.FALSE);
return uiTemplate;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.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;
/**
* 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.setConfiguration(templateEntity.getConfiguration());
this.setActivated(BooleanUtils.valueToBoolean(templateEntity.getActivated()));
this.setDisabled(BooleanUtils.valueToBoolean(templateEntity.getDisabled()));
return this;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.query.type;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Builder
public class TemplateChangeStatus {
private boolean status;
private String message;
}
......@@ -66,6 +66,7 @@ public class DefaultScopeDefine {
public static final int SERVICE_META = 29;
public static final int SERVICE_INSTANCE_UPDATE = 30;
public static final int NETWORK_ADDRESS_ALIAS = 31;
public static final int UI_TEMPLATE = 32;
/**
* Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt.
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.storage;
import java.io.IOException;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.storage.model.Model;
/**
* Use synchronize storage to insert storage data
*/
public interface IManagementDAO extends DAO {
void insert(Model model, ManagementData storageData) throws IOException;
}
......@@ -26,7 +26,5 @@ import org.apache.skywalking.oap.server.core.storage.model.Model;
* Use synchronize storage to insert none stream data
*/
public interface INoneStreamDAO extends DAO {
void insert(Model model, NoneStream noneStream) throws IOException;
}
......@@ -19,6 +19,7 @@
package org.apache.skywalking.oap.server.core.storage;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
import org.apache.skywalking.oap.server.core.analysis.record.Record;
import org.apache.skywalking.oap.server.library.module.Service;
......@@ -33,4 +34,6 @@ public interface StorageDAO extends Service {
IRecordDAO newRecordDao(StorageBuilder<Record> storageBuilder);
INoneStreamDAO newNoneStreamDao(StorageBuilder<NoneStream> storageBuilder);
IManagementDAO newManagementDao(StorageBuilder<ManagementData> storageBuilder);
}
......@@ -19,6 +19,7 @@
package org.apache.skywalking.oap.server.core.storage;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileThreadSnapshotQueryDAO;
......@@ -46,22 +47,23 @@ public class StorageModule extends ModuleDefine {
@Override
public Class[] services() {
return new Class[] {
IBatchDAO.class,
StorageDAO.class,
IHistoryDeleteDAO.class,
INetworkAddressAliasDAO.class,
ITopologyQueryDAO.class,
IMetricsQueryDAO.class,
ITraceQueryDAO.class,
IMetadataQueryDAO.class,
IAggregationQueryDAO.class,
IAlarmQueryDAO.class,
ITopNRecordsQueryDAO.class,
ILogQueryDAO.class,
IProfileTaskQueryDAO.class,
IProfileTaskLogQueryDAO.class,
IProfileThreadSnapshotQueryDAO.class
return new Class[]{
IBatchDAO.class,
StorageDAO.class,
IHistoryDeleteDAO.class,
INetworkAddressAliasDAO.class,
ITopologyQueryDAO.class,
IMetricsQueryDAO.class,
ITraceQueryDAO.class,
IMetadataQueryDAO.class,
IAggregationQueryDAO.class,
IAlarmQueryDAO.class,
ITopNRecordsQueryDAO.class,
ILogQueryDAO.class,
IProfileTaskQueryDAO.class,
IProfileTaskLogQueryDAO.class,
IProfileThreadSnapshotQueryDAO.class,
UITemplateManagementDAO.class
};
}
}
......@@ -61,6 +61,10 @@ public @interface Column {
/**
* @return the length of this column, this is only for {@link String} column. The usage of this depends on the
* storage implementation.
*
* Notice, different lengths may cause different types.
* Such as, over 16383 would make the type in MySQL to be MEDIUMTEXT, due to database varchar max=16383
*
* @since 7.1.0
*/
int length() default 200;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.storage.management;
import java.io.IOException;
import java.util.List;
import org.apache.skywalking.oap.server.core.query.input.DashboardSetting;
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.DAO;
/**
* UI Template management, including CRUD.
*/
public interface UITemplateManagementDAO extends DAO {
List<DashboardConfiguration> getAllTemplates(Boolean includingDisabled) throws IOException;
TemplateChangeStatus addTemplate(DashboardSetting setting) throws IOException;
TemplateChangeStatus changeTemplate(DashboardSetting setting) throws IOException;
TemplateChangeStatus disableTemplate(String name) throws IOException;
}
......@@ -26,6 +26,6 @@ public class CoreModuleTest {
public void testOpenServiceList() {
CoreModule coreModule = new CoreModule();
Assert.assertEquals(30, coreModule.services().length);
Assert.assertEquals(31, coreModule.services().length);
}
}
......@@ -28,7 +28,7 @@ public class EndpointGroupingRuleReaderTest {
EndpointGroupingRuleReader reader = new EndpointGroupingRuleReader(this.getClass()
.getClassLoader()
.getResourceAsStream(
"endpoint_name_grouping.yml"));
"endpoint-name-grouping.yml"));
final EndpointGroupingRule rule = reader.read();
StringFormatGroup.FormatResult formatResult = rule.format("serviceA", "/prod/123");
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.core.management.ui.template;
import java.util.List;
import org.apache.skywalking.oap.server.library.util.BooleanUtils;
import org.junit.Assert;
import org.junit.Test;
public class UITemplateInitializerTest {
@Test
public void testReadFile() {
UITemplateInitializer initializer = new UITemplateInitializer(this.getClass()
.getClassLoader()
.getResourceAsStream(
"ui-initialized-templates.yml"));
final List<UITemplate> uiTemplates = 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());
}
@Test(expected = IllegalArgumentException.class)
public void testTemplateConflict() {
UITemplateInitializer initializer = new UITemplateInitializer(this.getClass()
.getClassLoader()
.getResourceAsStream(
"ui-initialized-templates-conflict.yml"));
final List<UITemplate> uiTemplates = initializer.read();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.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;
public class UITemplateTest {
@Test
public void testSerialization() {
UITemplate uiTemplate = new UITemplate();
uiTemplate.setName("name");
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.map2Data(builder.data2Map(uiTemplate));
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.
Assert.assertEquals(uiTemplate, uiTemplate2);
}
}
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
# UI templates initialized file includes the default template when the SkyWalking OAP starts up at the first time.
#
# Also, SkyWalking would detect the existing templates in the database, once they are missing, all templates in this file
# could be added automatically.
templates:
- name: "APM"
# The type includes DASHBOARD, TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT.
# DASHBOARD type templates could have multiple definitions, by using different names.
# TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT type templates should be defined once, as they are used in the topology page only.
type: "DASHBOARD"
# Configuration could be defined through UI, and use `export` to format in the standard JSON.
configuration: |-
ui exported definition in JSONsdfsd
sdjfkasld
sdfui
skdfj:dafjisa
adifaosi
# Activated as the DASHBOARD type, makes this templates added into the UI page automatically.
# False means providing a basic template, user needs to add it manually.
activated: true
# True means wouldn't show up on the dashboard. Only keeps the definition in the storage.
# disabled: false
- name: "APM"
# The type includes DASHBOARD, TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT.
# DASHBOARD type templates could have multiple definitions, by using different names.
# TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT type templates should be defined once, as they are used in the topology page only.
type: "DASHBOARD"
# Configuration could be defined through UI, and use `export` to format in the standard JSON.
configuration: |-
Mesh metrics configuration.
# Activated as the DASHBOARD type, makes this templates added into the UI page automatically.
# False means providing a basic template, user needs to add it manually.
# activated: true
# True means wouldn't show up on the dashboard. Only keeps the definition in the storage.
disabled: true
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
# UI templates initialized file includes the default template when the SkyWalking OAP starts up at the first time.
#
# Also, SkyWalking would detect the existing templates in the database, once they are missing, all templates in this file
# could be added automatically.
templates:
- name: "APM (Agent based)"
# The type includes DASHBOARD, TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT.
# DASHBOARD type templates could have multiple definitions, by using different names.
# TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT type templates should be defined once, as they are used in the topology page only.
type: "DASHBOARD"
# Configuration could be defined through UI, and use `export` to format in the standard JSON.
configuration: |-
ui exported definition in JSONsdfsd
sdjfkasld
sdfui
skdfj:dafjisa
adifaosi
# Activated as the DASHBOARD type, makes this templates added into the UI page automatically.
# False means providing a basic template, user needs to add it manually.
activated: true
# True means wouldn't show up on the dashboard. Only keeps the definition in the storage.
# disable: false
- name: "APM (Service Mesh)"
# The type includes DASHBOARD, TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT.
# DASHBOARD type templates could have multiple definitions, by using different names.
# TOPOLOGY_INSTANCE, TOPOLOGY_ENDPOINT type templates should be defined once, as they are used in the topology page only.
type: "DASHBOARD"
# Configuration could be defined through UI, and use `export` to format in the standard JSON.
configuration: |-
Mesh metrics configuration.
# Activated as the DASHBOARD type, makes this templates added into the UI page automatically.
# False means providing a basic template, user needs to add it manually.
# activated: true
# True means wouldn't show up on the dashboard. Only keeps the definition in the storage.
disabled: true
......@@ -34,6 +34,7 @@ import org.apache.skywalking.oap.query.graphql.resolver.Query;
import org.apache.skywalking.oap.query.graphql.resolver.TopNRecordsQuery;
import org.apache.skywalking.oap.query.graphql.resolver.TopologyQuery;
import org.apache.skywalking.oap.query.graphql.resolver.TraceQuery;
import org.apache.skywalking.oap.query.graphql.resolver.UIConfigurationManagement;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.query.QueryModule;
import org.apache.skywalking.oap.server.core.server.JettyHandlerRegister;
......@@ -70,46 +71,48 @@ public class GraphQLQueryProvider extends ModuleProvider {
@Override
public void prepare() throws ServiceNotProvidedException, ModuleStartException {
GraphQLSchema schema = SchemaParser.newParser()
.file("query-protocol/common.graphqls")
.resolvers(new Query(), new Mutation())
.file("query-protocol/metadata.graphqls")
.resolvers(new MetadataQuery(getManager()))
.file("query-protocol/topology.graphqls")
.resolvers(new TopologyQuery(getManager()))
/**
* Metrics v2 query protocol is an alternative metrics query(s) of original v1,
* defined in the metric.graphql, top-n-records.graphqls, and aggregation.graphqls.
*/
.file("query-protocol/metrics-v2.graphqls")
.resolvers(new MetricsQuery(getManager()))
////////
//Deprecated Queries
////////
.file("query-protocol/metric.graphqls")
.resolvers(new MetricQuery(getManager()))
.file("query-protocol/aggregation.graphqls")
.resolvers(new AggregationQuery(getManager()))
.file("query-protocol/top-n-records.graphqls")
.resolvers(new TopNRecordsQuery(getManager()))
////////
.file("query-protocol/trace.graphqls")
.resolvers(new TraceQuery(getManager()))
.file("query-protocol/alarm.graphqls")
.resolvers(new AlarmQuery(getManager()))
.file("query-protocol/log.graphqls")
.resolvers(new LogQuery(getManager()))
.file("query-protocol/profile.graphqls")
.resolvers(new ProfileQuery(getManager()), new ProfileMutation(getManager()))
.build()
.makeExecutableSchema();
.file("query-protocol/common.graphqls")
.resolvers(new Query(), new Mutation())
.file("query-protocol/metadata.graphqls")
.resolvers(new MetadataQuery(getManager()))
.file("query-protocol/topology.graphqls")
.resolvers(new TopologyQuery(getManager()))
/**
* Metrics v2 query protocol is an alternative metrics query(s) of original v1,
* defined in the metric.graphql, top-n-records.graphqls, and aggregation.graphqls.
*/
.file("query-protocol/metrics-v2.graphqls")
.resolvers(new MetricsQuery(getManager()))
////////
//Deprecated Queries
////////
.file("query-protocol/metric.graphqls")
.resolvers(new MetricQuery(getManager()))
.file("query-protocol/aggregation.graphqls")
.resolvers(new AggregationQuery(getManager()))
.file("query-protocol/top-n-records.graphqls")
.resolvers(new TopNRecordsQuery(getManager()))
////////
.file("query-protocol/trace.graphqls")
.resolvers(new TraceQuery(getManager()))
.file("query-protocol/alarm.graphqls")
.resolvers(new AlarmQuery(getManager()))
.file("query-protocol/log.graphqls")
.resolvers(new LogQuery(getManager()))
.file("query-protocol/profile.graphqls")
.resolvers(new ProfileQuery(getManager()), new ProfileMutation(getManager()))
.file("query-protocol/ui-configuration.graphqls")
.resolvers(new UIConfigurationManagement(getManager()))
.build()
.makeExecutableSchema();
this.graphQL = GraphQL.newGraphQL(schema).build();
}
@Override
public void start() throws ServiceNotProvidedException, ModuleStartException {
JettyHandlerRegister service = getManager().find(CoreModule.NAME)
.provider()
.getService(JettyHandlerRegister.class);
.provider()
.getService(JettyHandlerRegister.class);
service.addHandler(new GraphQLQueryHandler(config.getPath(), graphQL));
}
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.query.graphql.resolver;
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import java.io.IOException;
import java.util.List;
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.type.DashboardConfiguration;
import org.apache.skywalking.oap.server.core.query.type.TemplateChangeStatus;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
/**
* UI Configuration including dashboard, topology pop up page, is based on the available templates or manual configuration.
* UIConfigurationManagement provides the query and operations of templates.
*
* @since 8.0.0
*/
@RequiredArgsConstructor
public class UIConfigurationManagement implements GraphQLQueryResolver, GraphQLMutationResolver {
private final ModuleManager manager;
private UITemplateManagementService uiTemplateManagementService;
private UITemplateManagementService getUITemplateManagementService() {
if (uiTemplateManagementService == null) {
this.uiTemplateManagementService = manager.find(CoreModule.NAME)
.provider()
.getService(UITemplateManagementService.class);
}
return uiTemplateManagementService;
}
public List<DashboardConfiguration> getAllTemplates(Boolean includingDisabled) throws IOException {
if (includingDisabled == null) {
includingDisabled = false;
}
return getUITemplateManagementService().getAllTemplates(includingDisabled);
}
public TemplateChangeStatus addTemplate(DashboardSetting setting) throws IOException {
return getUITemplateManagementService().addTemplate(setting);
}
public TemplateChangeStatus changeTemplate(DashboardSetting setting) throws IOException {
return getUITemplateManagementService().changeTemplate(setting);
}
public TemplateChangeStatus disableTemplate(String name) throws IOException {
return getUITemplateManagementService().disableTemplate(name);
}
}
Subproject commit 3f44392c3b3502b4f3066e7ec89c794bc9ffb54d
Subproject commit 0b38f4e1620ef66e6d9121845b2a55b090d2020f
......@@ -35,6 +35,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO;
......@@ -72,6 +73,7 @@ import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.Profi
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TopNRecordsQueryEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TopologyQueryEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TraceQueryEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.UITemplateManagementEsDAO;
/**
* The storage provider for ElasticSearch 6.
......@@ -112,7 +114,7 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
if (!StringUtil.isEmpty(config.getSecretsManagementFile())) {
MultipleFilesChangeMonitor monitor = new MultipleFilesChangeMonitor(
10, readableContents -> {
10, readableContents -> {
final byte[] secretsFileContent = readableContents.get(0);
if (secretsFileContent == null) {
return;
......@@ -140,39 +142,41 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
}
elasticSearchClient = new ElasticSearchClient(
config.getClusterNodes(), config.getProtocol(), config.getTrustStorePath(), config
.getTrustStorePass(), config.getUser(), config.getPassword(),
indexNameConverters(config.getNameSpace())
config.getClusterNodes(), config.getProtocol(), config.getTrustStorePath(), config
.getTrustStorePass(), config.getUser(), config.getPassword(),
indexNameConverters(config.getNameSpace())
);
this.registerServiceImplementation(
IBatchDAO.class, new BatchProcessEsDAO(elasticSearchClient, config.getBulkActions(), config
.getFlushInterval(), config.getConcurrentRequests()));
IBatchDAO.class, new BatchProcessEsDAO(elasticSearchClient, config.getBulkActions(), config
.getFlushInterval(), config.getConcurrentRequests()));
this.registerServiceImplementation(StorageDAO.class, new StorageEsDAO(elasticSearchClient));
this.registerServiceImplementation(
IHistoryDeleteDAO.class, new HistoryDeleteEsDAO(elasticSearchClient));
IHistoryDeleteDAO.class, new HistoryDeleteEsDAO(elasticSearchClient));
this.registerServiceImplementation(
INetworkAddressAliasDAO.class, new NetworkAddressAliasEsDAO(elasticSearchClient, config
.getResultWindowMaxSize()));
INetworkAddressAliasDAO.class, new NetworkAddressAliasEsDAO(elasticSearchClient, config
.getResultWindowMaxSize()));
this.registerServiceImplementation(ITopologyQueryDAO.class, new TopologyQueryEsDAO(elasticSearchClient));
this.registerServiceImplementation(IMetricsQueryDAO.class, new MetricsQueryEsDAO(elasticSearchClient));
this.registerServiceImplementation(
ITraceQueryDAO.class, new TraceQueryEsDAO(elasticSearchClient, config.getSegmentQueryMaxSize()));
ITraceQueryDAO.class, new TraceQueryEsDAO(elasticSearchClient, config.getSegmentQueryMaxSize()));
this.registerServiceImplementation(
IMetadataQueryDAO.class, new MetadataQueryEsDAO(elasticSearchClient, config.getMetadataQueryMaxSize()));
IMetadataQueryDAO.class, new MetadataQueryEsDAO(elasticSearchClient, config.getMetadataQueryMaxSize()));
this.registerServiceImplementation(IAggregationQueryDAO.class, new AggregationQueryEsDAO(elasticSearchClient));
this.registerServiceImplementation(IAlarmQueryDAO.class, new AlarmQueryEsDAO(elasticSearchClient));
this.registerServiceImplementation(ITopNRecordsQueryDAO.class, new TopNRecordsQueryEsDAO(elasticSearchClient));
this.registerServiceImplementation(ILogQueryDAO.class, new LogQueryEsDAO(elasticSearchClient));
this.registerServiceImplementation(
IProfileTaskQueryDAO.class, new ProfileTaskQueryEsDAO(elasticSearchClient, config
.getProfileTaskQueryMaxSize()));
IProfileTaskQueryDAO.class, new ProfileTaskQueryEsDAO(elasticSearchClient, config
.getProfileTaskQueryMaxSize()));
this.registerServiceImplementation(
IProfileTaskLogQueryDAO.class, new ProfileTaskLogEsDAO(elasticSearchClient, config
.getProfileTaskQueryMaxSize()));
IProfileTaskLogQueryDAO.class, new ProfileTaskLogEsDAO(elasticSearchClient, config
.getProfileTaskQueryMaxSize()));
this.registerServiceImplementation(
IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQueryEsDAO(elasticSearchClient, config
.getProfileTaskQueryMaxSize()));
IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQueryEsDAO(elasticSearchClient, config
.getProfileTaskQueryMaxSize()));
this.registerServiceImplementation(
UITemplateManagementDAO.class, new UITemplateManagementEsDAO(elasticSearchClient));
}
@Override
......@@ -193,7 +197,7 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
@Override
public String[] requiredModules() {
return new String[] {CoreModule.NAME};
return new String[]{CoreModule.NAME};
}
public static List<IndexNameConverter> indexNameConverters(String namespace) {
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.storage.plugin.elasticsearch.base;
import java.io.IOException;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
import org.apache.skywalking.oap.server.core.storage.model.Model;
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.common.xcontent.XContentBuilder;
public class ManagementEsDAO extends EsDAO implements IManagementDAO {
private final StorageBuilder<ManagementData> storageBuilder;
public ManagementEsDAO(ElasticSearchClient client, StorageBuilder<ManagementData> storageBuilder) {
super(client);
this.storageBuilder = storageBuilder;
}
@Override
public void insert(Model model, ManagementData managementData) throws IOException {
String modelName = model.getName();
final String id = managementData.id();
final GetResponse response = getClient().get(modelName, id);
if (response.isExists()) {
return;
}
XContentBuilder builder = map2builder(storageBuilder.data2Map(managementData));
getClient().forceInsert(modelName, id, builder);
}
}
\ No newline at end of file
......@@ -19,8 +19,10 @@
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
import org.apache.skywalking.oap.server.core.analysis.record.Record;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.IMetricsDAO;
import org.apache.skywalking.oap.server.core.storage.INoneStreamDAO;
import org.apache.skywalking.oap.server.core.storage.IRecordDAO;
......@@ -48,4 +50,9 @@ public class StorageEsDAO extends EsDAO implements StorageDAO {
public INoneStreamDAO newNoneStreamDao(StorageBuilder<NoneStream> storageBuilder) {
return new NoneStreamEsDAO(getClient(), storageBuilder);
}
@Override
public IManagementDAO newManagementDao(final StorageBuilder<ManagementData> storageBuilder) {
return new ManagementEsDAO(getClient(), storageBuilder);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.storage.plugin.elasticsearch.query;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate;
import org.apache.skywalking.oap.server.core.query.input.DashboardSetting;
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.client.elasticsearch.ElasticSearchClient;
import org.apache.skywalking.oap.server.library.util.BooleanUtils;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
@Slf4j
public class UITemplateManagementEsDAO extends EsDAO implements UITemplateManagementDAO {
public UITemplateManagementEsDAO(ElasticSearchClient client) {
super(client);
}
@Override
public List<DashboardConfiguration> getAllTemplates(final Boolean includingDisabled) throws IOException {
SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
if (!includingDisabled) {
boolQueryBuilder.must().add(QueryBuilders.termQuery(UITemplate.DISABLED, BooleanUtils.booleanToValue(includingDisabled)));
}
sourceBuilder.query(boolQueryBuilder);
//It is impossible we have 10000+ templates.
sourceBuilder.size(10000);
SearchResponse response = getClient().search(UITemplate.INDEX_NAME, sourceBuilder);
List<DashboardConfiguration> configs = new ArrayList<>();
final UITemplate.Builder builder = new UITemplate.Builder();
for (SearchHit searchHit : response.getHits()) {
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
final UITemplate uiTemplate = builder.map2Data(sourceAsMap);
configs.add(new DashboardConfiguration().fromEntity(uiTemplate));
}
return configs;
}
@Override
public TemplateChangeStatus addTemplate(final DashboardSetting setting) throws IOException {
try {
final UITemplate.Builder builder = new UITemplate.Builder();
final UITemplate uiTemplate = setting.toEntity();
final GetResponse response = getClient().get(UITemplate.INDEX_NAME, uiTemplate.id());
if (response.isExists()) {
return TemplateChangeStatus.builder().status(false).message("Template exists").build();
}
XContentBuilder xContentBuilder = map2builder(builder.data2Map(uiTemplate));
getClient().forceInsert(UITemplate.INDEX_NAME, uiTemplate.id(), xContentBuilder);
return TemplateChangeStatus.builder().status(true).build();
} catch (IOException e) {
log.error(e.getMessage(), e);
return TemplateChangeStatus.builder().status(false).message("Can't add a new template").build();
}
}
@Override
public TemplateChangeStatus changeTemplate(final DashboardSetting setting) throws IOException {
try {
final UITemplate.Builder builder = new UITemplate.Builder();
final UITemplate uiTemplate = setting.toEntity();
final GetResponse response = getClient().get(UITemplate.INDEX_NAME, uiTemplate.id());
if (!response.isExists()) {
return TemplateChangeStatus.builder().status(false).message("Can't find the template").build();
}
XContentBuilder xContentBuilder = map2builder(builder.data2Map(uiTemplate));
getClient().forceUpdate(UITemplate.INDEX_NAME, uiTemplate.id(), xContentBuilder);
return TemplateChangeStatus.builder().status(true).build();
} catch (IOException e) {
log.error(e.getMessage(), e);
return TemplateChangeStatus.builder().status(false).message("Can't find the template").build();
}
}
@Override
public TemplateChangeStatus disableTemplate(final String name) throws IOException {
final GetResponse response = getClient().get(UITemplate.INDEX_NAME, name);
if (response.isExists()) {
final UITemplate.Builder builder = new UITemplate.Builder();
final UITemplate uiTemplate = builder.map2Data(response.getSourceAsMap());
uiTemplate.setDisabled(BooleanUtils.TRUE);
XContentBuilder xContentBuilder = map2builder(builder.data2Map(uiTemplate));
getClient().forceUpdate(UITemplate.INDEX_NAME, uiTemplate.id(), xContentBuilder);
return TemplateChangeStatus.builder().status(true).build();
} else {
return TemplateChangeStatus.builder().status(false).message("Can't find the template").build();
}
}
}
......@@ -33,6 +33,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO;
......@@ -58,6 +59,7 @@ import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.Profi
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.ProfileTaskQueryEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TopNRecordsQueryEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.TopologyQueryEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.UITemplateManagementEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.base.StorageEs7Installer;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.client.ElasticSearch7Client;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.dao.StorageEs7DAO;
......@@ -106,7 +108,7 @@ public class StorageModuleElasticsearch7Provider extends ModuleProvider {
}
if (!StringUtil.isEmpty(config.getSecretsManagementFile())) {
MultipleFilesChangeMonitor monitor = new MultipleFilesChangeMonitor(
10, readableContents -> {
10, readableContents -> {
final byte[] secretsFileContent = readableContents.get(0);
if (secretsFileContent == null) {
return;
......@@ -134,50 +136,52 @@ public class StorageModuleElasticsearch7Provider extends ModuleProvider {
}
elasticSearch7Client = new ElasticSearch7Client(
config.getClusterNodes(), config.getProtocol(), config.getTrustStorePath(), config
.getTrustStorePass(), config.getUser(), config.getPassword(),
indexNameConverters(config.getNameSpace())
config.getClusterNodes(), config.getProtocol(), config.getTrustStorePath(), config
.getTrustStorePass(), config.getUser(), config.getPassword(),
indexNameConverters(config.getNameSpace())
);
this.registerServiceImplementation(
IBatchDAO.class, new BatchProcessEsDAO(elasticSearch7Client, config.getBulkActions(),
config.getFlushInterval(), config.getConcurrentRequests()
));
IBatchDAO.class, new BatchProcessEsDAO(elasticSearch7Client, config.getBulkActions(),
config.getFlushInterval(), config.getConcurrentRequests()
));
this.registerServiceImplementation(StorageDAO.class, new StorageEs7DAO(elasticSearch7Client));
this.registerServiceImplementation(
IHistoryDeleteDAO.class, new HistoryDeleteEsDAO(elasticSearch7Client));
IHistoryDeleteDAO.class, new HistoryDeleteEsDAO(elasticSearch7Client));
this.registerServiceImplementation(
INetworkAddressAliasDAO.class, new NetworkAddressAliasEsDAO(
elasticSearch7Client,
config.getResultWindowMaxSize()
));
INetworkAddressAliasDAO.class, new NetworkAddressAliasEsDAO(
elasticSearch7Client,
config.getResultWindowMaxSize()
));
this.registerServiceImplementation(ITopologyQueryDAO.class, new TopologyQueryEsDAO(elasticSearch7Client));
this.registerServiceImplementation(IMetricsQueryDAO.class, new MetricsQueryEs7DAO(elasticSearch7Client));
this.registerServiceImplementation(
ITraceQueryDAO.class, new TraceQueryEs7DAO(elasticSearch7Client, config.getSegmentQueryMaxSize()));
ITraceQueryDAO.class, new TraceQueryEs7DAO(elasticSearch7Client, config.getSegmentQueryMaxSize()));
this.registerServiceImplementation(
IMetadataQueryDAO.class, new MetadataQueryEs7DAO(elasticSearch7Client, config.getMetadataQueryMaxSize()));
IMetadataQueryDAO.class, new MetadataQueryEs7DAO(elasticSearch7Client, config.getMetadataQueryMaxSize()));
this.registerServiceImplementation(
IAggregationQueryDAO.class, new AggregationQueryEs7DAO(elasticSearch7Client));
IAggregationQueryDAO.class, new AggregationQueryEs7DAO(elasticSearch7Client));
this.registerServiceImplementation(IAlarmQueryDAO.class, new AlarmQueryEs7DAO(elasticSearch7Client));
this.registerServiceImplementation(ITopNRecordsQueryDAO.class, new TopNRecordsQueryEsDAO(elasticSearch7Client));
this.registerServiceImplementation(ILogQueryDAO.class, new LogQueryEs7DAO(elasticSearch7Client));
this.registerServiceImplementation(
IProfileTaskQueryDAO.class, new ProfileTaskQueryEsDAO(
elasticSearch7Client,
config.getProfileTaskQueryMaxSize()
));
IProfileTaskQueryDAO.class, new ProfileTaskQueryEsDAO(
elasticSearch7Client,
config.getProfileTaskQueryMaxSize()
));
this.registerServiceImplementation(
IProfileTaskLogQueryDAO.class, new ProfileTaskLogEsDAO(
elasticSearch7Client,
config.getProfileTaskQueryMaxSize()
));
IProfileTaskLogQueryDAO.class, new ProfileTaskLogEsDAO(
elasticSearch7Client,
config.getProfileTaskQueryMaxSize()
));
this.registerServiceImplementation(
IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQueryEs7DAO(
elasticSearch7Client,
config.getProfileTaskQueryMaxSize()
));
IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQueryEs7DAO(
elasticSearch7Client,
config.getProfileTaskQueryMaxSize()
));
this.registerServiceImplementation(
UITemplateManagementDAO.class, new UITemplateManagementEsDAO(elasticSearch7Client));
}
@Override
......@@ -198,6 +202,6 @@ public class StorageModuleElasticsearch7Provider extends ModuleProvider {
@Override
public String[] requiredModules() {
return new String[] {CoreModule.NAME};
return new String[]{CoreModule.NAME};
}
}
......@@ -19,8 +19,10 @@
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.dao;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
import org.apache.skywalking.oap.server.core.analysis.record.Record;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.IMetricsDAO;
import org.apache.skywalking.oap.server.core.storage.INoneStreamDAO;
import org.apache.skywalking.oap.server.core.storage.IRecordDAO;
......@@ -28,6 +30,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.ManagementEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.NoneStreamEsDAO;
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.RecordEsDAO;
......@@ -51,4 +54,9 @@ public class StorageEs7DAO extends EsDAO implements StorageDAO {
public INoneStreamDAO newNoneStreamDao(StorageBuilder<NoneStream> storageBuilder) {
return new NoneStreamEsDAO(getClient(), storageBuilder);
}
@Override
public IManagementDAO newManagementDao(final StorageBuilder<ManagementData> storageBuilder) {
return new ManagementEsDAO(getClient(), storageBuilder);
}
}
......@@ -26,6 +26,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO;
......@@ -58,6 +59,7 @@ import org.apache.skywalking.oap.server.storage.plugin.influxdb.query.ProfileThr
import org.apache.skywalking.oap.server.storage.plugin.influxdb.query.TopNRecordsQuery;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.query.TopologyQuery;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.query.TraceQuery;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.query.UITemplateManagementDAOImpl;
@Slf4j
public class InfluxStorageProvider extends ModuleProvider {
......@@ -103,12 +105,13 @@ public class InfluxStorageProvider extends ModuleProvider {
this.registerServiceImplementation(IProfileTaskQueryDAO.class, new ProfileTaskQuery(client));
this.registerServiceImplementation(
IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQuery(client));
IProfileThreadSnapshotQueryDAO.class, new ProfileThreadSnapshotQuery(client));
this.registerServiceImplementation(
IProfileTaskLogQueryDAO.class, new ProfileTaskLogQuery(client, config.getFetchTaskLogMaxSize()));
IProfileTaskLogQueryDAO.class, new ProfileTaskLogQuery(client, config.getFetchTaskLogMaxSize()));
this.registerServiceImplementation(
IHistoryDeleteDAO.class, new HistoryDeleteDAO(client));
IHistoryDeleteDAO.class, new HistoryDeleteDAO(client));
this.registerServiceImplementation(UITemplateManagementDAO.class, new UITemplateManagementDAOImpl(client));
}
@Override
......@@ -130,6 +133,6 @@ public class InfluxStorageProvider extends ModuleProvider {
@Override
public String[] requiredModules() {
return new String[] {CoreModule.NAME};
return new String[]{CoreModule.NAME};
}
}
......@@ -19,8 +19,10 @@
package org.apache.skywalking.oap.server.storage.plugin.influxdb.base;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
import org.apache.skywalking.oap.server.core.analysis.record.Record;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.IMetricsDAO;
import org.apache.skywalking.oap.server.core.storage.INoneStreamDAO;
import org.apache.skywalking.oap.server.core.storage.IRecordDAO;
......@@ -49,4 +51,9 @@ public class InfluxStorageDAO implements StorageDAO {
public INoneStreamDAO newNoneStreamDao(StorageBuilder<NoneStream> storageBuilder) {
return new NoneStreamDAO(influxClient, storageBuilder);
}
@Override
public IManagementDAO newManagementDao(final StorageBuilder<ManagementData> storageBuilder) {
return new ManagementDAO(influxClient, storageBuilder);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.storage.plugin.influxdb.base;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.manual.service.ServiceTraffic;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
import org.apache.skywalking.oap.server.core.storage.model.Model;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxClient;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.TableMetaInfo;
import org.influxdb.dto.QueryResult;
import org.influxdb.querybuilder.SelectQueryImpl;
import org.influxdb.querybuilder.WhereQueryImpl;
import static org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxConstants.ID_COLUMN;
import static org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxConstants.NAME;
import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.eq;
import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.select;
@Slf4j
public class ManagementDAO implements IManagementDAO {
private static final long STATIC_TIMESTAMP = 1_000_000;
private InfluxClient client;
private StorageBuilder<ManagementData> storageBuilder;
public ManagementDAO(InfluxClient client, StorageBuilder<ManagementData> storageBuilder) {
this.client = client;
this.storageBuilder = storageBuilder;
}
@Override
public void insert(final Model model, final ManagementData managementData) throws IOException {
final WhereQueryImpl<SelectQueryImpl> query = select()
.column(ID_COLUMN).column(NAME)
.from(ServiceTraffic.INDEX_NAME)
.where(eq(ID_COLUMN, managementData.id()));
QueryResult.Series series = client.queryForSingleSeries(query);
if (log.isDebugEnabled()) {
log.debug("SQL: {} result: {}", query.getCommand(), series);
}
if (series != null && series.getValues().size() > 0) {
return;
}
final InfluxInsertRequest request = new InfluxInsertRequest(model, managementData, storageBuilder)
.time(STATIC_TIMESTAMP, TimeUnit.NANOSECONDS);
TableMetaInfo.get(model.getName()).getStorageAndTagMap().forEach((field, tag) -> {
request.addFieldAsTag(field, tag);
});
client.write(request.getPoint());
}
}
......@@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.NodeType;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
......@@ -59,15 +60,12 @@ import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.eq;
import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.gte;
import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.select;
@RequiredArgsConstructor
@Slf4j
public class MetadataQuery implements IMetadataQueryDAO {
private static final Gson GSON = new Gson();
private final InfluxClient client;
public MetadataQuery(final InfluxClient client) {
this.client = client;
}
@Override
public List<Service> getAllServices(final long startTimestamp, final long endTimestamp) throws IOException {
SelectSubQueryImpl<SelectQueryImpl> subQuery = select()
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.storage.plugin.influxdb.query;
import com.google.common.collect.Maps;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate;
import org.apache.skywalking.oap.server.core.query.input.DashboardSetting;
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.storage.plugin.influxdb.InfluxClient;
import org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxConstants;
import org.influxdb.dto.Point;
import org.influxdb.dto.QueryResult;
import org.influxdb.querybuilder.SelectQueryImpl;
import org.influxdb.querybuilder.WhereQueryImpl;
import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.eq;
import static org.influxdb.querybuilder.BuiltQuery.QueryBuilder.select;
@RequiredArgsConstructor
@Slf4j
public class UITemplateManagementDAOImpl implements UITemplateManagementDAO {
private final InfluxClient client;
@Override
public List<DashboardConfiguration> getAllTemplates(final Boolean includingDisabled) throws IOException {
WhereQueryImpl<SelectQueryImpl> where = select().raw("*::field")
.from(client.getDatabase(), UITemplate.INDEX_NAME)
.where();
if (!includingDisabled) {
where.and(eq(UITemplate.DISABLED, BooleanUtils.FALSE));
}
final QueryResult.Series series = client.queryForSingleSeries(where);
final List<DashboardConfiguration> configs = new ArrayList<>();
final UITemplate.Builder builder = new UITemplate.Builder();
if (Objects.nonNull(series)) {
List<String> columnNames = series.getColumns();
final int size = series.getValues().size();
for (int offset = 0; offset < size; offset++) {
List<Object> columnValues = series.getValues().get(offset);
Map<String, Object> data = Maps.newHashMap();
for (int i = 1; i < columnNames.size(); i++) {
data.put(columnNames.get(i), columnValues.get(i));
}
UITemplate uiTemplate = builder.map2Data(data);
configs.add(new DashboardConfiguration().fromEntity(uiTemplate));
}
}
return configs;
}
@Override
public TemplateChangeStatus addTemplate(final DashboardSetting setting) {
final UITemplate.Builder builder = new UITemplate.Builder();
final UITemplate uiTemplate = setting.toEntity();
Point point = Point.measurement(UITemplate.INDEX_NAME)
.tag(InfluxConstants.TagName.ID_COLUMN, uiTemplate.id())
.fields(builder.data2Map(uiTemplate))
.time(0L, TimeUnit.MILLISECONDS)
.build();
client.write(point);
return TemplateChangeStatus.builder().status(true).build();
}
@Override
public TemplateChangeStatus changeTemplate(final DashboardSetting setting) throws IOException {
final UITemplate.Builder builder = new UITemplate.Builder();
final UITemplate uiTemplate = setting.toEntity();
WhereQueryImpl<SelectQueryImpl> query = select().all()
.from(client.getDatabase(), UITemplate.INDEX_NAME)
.where(eq(InfluxConstants.TagName.ID_COLUMN, uiTemplate.id()));
QueryResult.Series series = client.queryForSingleSeries(query);
if (Objects.nonNull(series)) {
Point point = Point.measurement(UITemplate.INDEX_NAME)
.fields(builder.data2Map(uiTemplate))
.tag(series.getTags())
.time(0L, TimeUnit.MILLISECONDS)
.build();
client.write(point);
return TemplateChangeStatus.builder().status(true).build();
} else {
return TemplateChangeStatus.builder().status(false).message("Can't find the template").build();
}
}
@Override
public TemplateChangeStatus disableTemplate(final String name) throws IOException {
WhereQueryImpl<SelectQueryImpl> query = select().all()
.from(client.getDatabase(), UITemplate.INDEX_NAME)
.where(eq(InfluxConstants.NAME, name));
QueryResult.Series series = client.queryForSingleSeries(query);
if (Objects.nonNull(series)) {
List<String> columnNames = series.getColumns();
List<Object> columnValues = series.getValues().get(0);
Map<String, Object> storageData = Maps.newHashMap();
for (int i = 1; i < columnNames.size(); i++) {
storageData.put(columnNames.get(i), columnValues.get(i));
}
storageData.put(UITemplate.DISABLED, BooleanUtils.TRUE);
Point point = Point.measurement(UITemplate.INDEX_NAME)
.tag(series.getTags())
.fields(storageData)
.time(0L, TimeUnit.MILLISECONDS)
.build();
client.write(point);
return TemplateChangeStatus.builder().status(true).build();
} else {
return TemplateChangeStatus.builder().status(false).message("Can't find the template").build();
}
}
}
......@@ -27,6 +27,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO;
......@@ -61,6 +62,7 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TableInstal
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopNRecordsQueryDAO;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopologyQueryDAO;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TraceQueryDAO;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2UITemplateManagementDAO;
/**
* H2 Storage provider is for demonstration and preview only. I will find that haven't implemented several interfaces,
......@@ -106,24 +108,25 @@ public class H2StorageProvider extends ModuleProvider {
this.registerServiceImplementation(StorageDAO.class, new H2StorageDAO(h2Client));
this.registerServiceImplementation(
INetworkAddressAliasDAO.class, new H2NetworkAddressAliasDAO(h2Client));
INetworkAddressAliasDAO.class, new H2NetworkAddressAliasDAO(h2Client));
this.registerServiceImplementation(ITopologyQueryDAO.class, new H2TopologyQueryDAO(h2Client));
this.registerServiceImplementation(IMetricsQueryDAO.class, new H2MetricsQueryDAO(h2Client));
this.registerServiceImplementation(ITraceQueryDAO.class, new H2TraceQueryDAO(h2Client));
this.registerServiceImplementation(
IMetadataQueryDAO.class, new H2MetadataQueryDAO(h2Client, config.getMetadataQueryMaxSize()));
IMetadataQueryDAO.class, new H2MetadataQueryDAO(h2Client, config.getMetadataQueryMaxSize()));
this.registerServiceImplementation(IAggregationQueryDAO.class, new H2AggregationQueryDAO(h2Client));
this.registerServiceImplementation(IAlarmQueryDAO.class, new H2AlarmQueryDAO(h2Client));
this.registerServiceImplementation(
IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(h2Client));
IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(h2Client));
this.registerServiceImplementation(ITopNRecordsQueryDAO.class, new H2TopNRecordsQueryDAO(h2Client));
this.registerServiceImplementation(ILogQueryDAO.class, new H2LogQueryDAO(h2Client));
this.registerServiceImplementation(IProfileTaskQueryDAO.class, new H2ProfileTaskQueryDAO(h2Client));
this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new H2ProfileTaskLogQueryDAO(h2Client));
this.registerServiceImplementation(
IProfileThreadSnapshotQueryDAO.class, new H2ProfileThreadSnapshotQueryDAO(h2Client));
IProfileThreadSnapshotQueryDAO.class, new H2ProfileThreadSnapshotQueryDAO(h2Client));
this.registerServiceImplementation(UITemplateManagementDAO.class, new H2UITemplateManagementDAO(h2Client));
}
@Override
......@@ -145,6 +148,6 @@ public class H2StorageProvider extends ModuleProvider {
@Override
public String[] requiredModules() {
return new String[] {CoreModule.NAME};
return new String[]{CoreModule.NAME};
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
import org.apache.skywalking.oap.server.core.storage.StorageData;
import org.apache.skywalking.oap.server.core.storage.model.Model;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLExecutor;
/**
* Synchronize storage H2 implements
*/
public class H2ManagementDAO extends H2SQLExecutor implements IManagementDAO {
private JDBCHikariCPClient h2Client;
private StorageBuilder<ManagementData> storageBuilder;
public H2ManagementDAO(JDBCHikariCPClient h2Client, StorageBuilder<ManagementData> storageBuilder) {
this.h2Client = h2Client;
this.storageBuilder = storageBuilder;
}
@Override
public void insert(Model model, ManagementData storageData) throws IOException {
try (Connection connection = h2Client.getConnection()) {
final StorageData data = getByID(h2Client, model.getName(), storageData.id(), storageBuilder);
if (data != null) {
return;
}
SQLExecutor insertExecutor = getInsertExecutor(model.getName(), storageData, storageBuilder);
insertExecutor.invoke(connection);
} catch (IOException | SQLException e) {
throw new IOException(e.getMessage(), e);
}
}
}
......@@ -19,8 +19,10 @@
package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
import org.apache.skywalking.oap.server.core.analysis.config.NoneStream;
import org.apache.skywalking.oap.server.core.analysis.management.ManagementData;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
import org.apache.skywalking.oap.server.core.analysis.record.Record;
import org.apache.skywalking.oap.server.core.storage.IManagementDAO;
import org.apache.skywalking.oap.server.core.storage.IMetricsDAO;
import org.apache.skywalking.oap.server.core.storage.INoneStreamDAO;
import org.apache.skywalking.oap.server.core.storage.IRecordDAO;
......@@ -50,4 +52,9 @@ public class H2StorageDAO implements StorageDAO {
public INoneStreamDAO newNoneStreamDao(StorageBuilder<NoneStream> storageBuilder) {
return new H2NoneStreamDAO(h2Client, storageBuilder);
}
@Override
public IManagementDAO newManagementDao(final StorageBuilder<ManagementData> storageBuilder) {
return new H2ManagementDAO(h2Client, storageBuilder);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplate;
import org.apache.skywalking.oap.server.core.query.input.DashboardSetting;
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.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.storage.plugin.jdbc.SQLExecutor;
@Slf4j
@RequiredArgsConstructor
public class H2UITemplateManagementDAO extends H2SQLExecutor implements UITemplateManagementDAO {
private final JDBCHikariCPClient h2Client;
@Override
public List<DashboardConfiguration> getAllTemplates(final Boolean includingDisabled) throws IOException {
final StringBuilder sql = new StringBuilder();
final ArrayList<Object> condition = new ArrayList<>(1);
sql.append("select * from ").append(UITemplate.INDEX_NAME).append(" where 1=1 ");
if (!includingDisabled) {
sql.append(" and ").append(UITemplate.DISABLED).append("=?");
condition.add(BooleanUtils.booleanToValue(includingDisabled));
}
try (Connection connection = h2Client.getConnection()) {
try (ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]))) {
final List<DashboardConfiguration> configs = new ArrayList<>();
final UITemplate.Builder builder = new UITemplate.Builder();
UITemplate uiTemplate = null;
do {
uiTemplate = (UITemplate) toStorageData(resultSet, UITemplate.INDEX_NAME, builder);
if (uiTemplate != null) {
configs.add(new DashboardConfiguration().fromEntity(uiTemplate));
}
} while (uiTemplate != null);
return configs;
}
} catch (SQLException | JDBCClientException e) {
throw new IOException(e);
}
}
@Override
public TemplateChangeStatus addTemplate(final DashboardSetting setting) throws IOException {
final UITemplate uiTemplate = setting.toEntity();
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();
} catch (SQLException | JDBCClientException e) {
log.error(e.getMessage(), e);
return TemplateChangeStatus.builder().status(false).message("Can't add a new template").build();
}
}
@Override
public TemplateChangeStatus changeTemplate(final DashboardSetting setting) throws IOException {
final UITemplate uiTemplate = setting.toEntity();
return executeUpdate(uiTemplate);
}
@Override
public TemplateChangeStatus disableTemplate(final String name) throws IOException {
final UITemplate uiTemplate = (UITemplate) getByID(h2Client, UITemplate.INDEX_NAME, name, new UITemplate.Builder());
if (uiTemplate == null) {
return TemplateChangeStatus.builder().status(false).message("Can't find the template").build();
}
uiTemplate.setDisabled(BooleanUtils.TRUE);
return executeUpdate(uiTemplate);
}
private TemplateChangeStatus executeUpdate(final UITemplate uiTemplate) throws IOException {
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();
} catch (SQLException | JDBCClientException e) {
log.error(e.getMessage(), e);
return TemplateChangeStatus.builder().status(false).message("Can't add/update the template").build();
}
}
}
......@@ -26,6 +26,7 @@ import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
import org.apache.skywalking.oap.server.core.storage.management.UITemplateManagementDAO;
import org.apache.skywalking.oap.server.core.storage.model.ModelCreator;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskLogQueryDAO;
import org.apache.skywalking.oap.server.core.storage.profile.IProfileTaskQueryDAO;
......@@ -55,6 +56,7 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ProfileThre
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2StorageDAO;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopNRecordsQueryDAO;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopologyQueryDAO;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2UITemplateManagementDAO;
/**
* MySQL storage provider should be secondary choice for production usage as SkyWalking storage solution. It enhanced
......@@ -96,24 +98,25 @@ public class MySQLStorageProvider extends ModuleProvider {
this.registerServiceImplementation(IBatchDAO.class, new H2BatchDAO(mysqlClient));
this.registerServiceImplementation(StorageDAO.class, new H2StorageDAO(mysqlClient));
this.registerServiceImplementation(
INetworkAddressAliasDAO.class, new H2NetworkAddressAliasDAO(mysqlClient));
INetworkAddressAliasDAO.class, new H2NetworkAddressAliasDAO(mysqlClient));
this.registerServiceImplementation(ITopologyQueryDAO.class, new H2TopologyQueryDAO(mysqlClient));
this.registerServiceImplementation(IMetricsQueryDAO.class, new H2MetricsQueryDAO(mysqlClient));
this.registerServiceImplementation(ITraceQueryDAO.class, new MySQLTraceQueryDAO(mysqlClient));
this.registerServiceImplementation(
IMetadataQueryDAO.class, new H2MetadataQueryDAO(mysqlClient, config.getMetadataQueryMaxSize()));
IMetadataQueryDAO.class, new H2MetadataQueryDAO(mysqlClient, config.getMetadataQueryMaxSize()));
this.registerServiceImplementation(IAggregationQueryDAO.class, new MySQLAggregationQueryDAO(mysqlClient));
this.registerServiceImplementation(IAlarmQueryDAO.class, new MySQLAlarmQueryDAO(mysqlClient));
this.registerServiceImplementation(
IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(mysqlClient));
IHistoryDeleteDAO.class, new H2HistoryDeleteDAO(mysqlClient));
this.registerServiceImplementation(ITopNRecordsQueryDAO.class, new H2TopNRecordsQueryDAO(mysqlClient));
this.registerServiceImplementation(ILogQueryDAO.class, new MySQLLogQueryDAO(mysqlClient));
this.registerServiceImplementation(IProfileTaskQueryDAO.class, new H2ProfileTaskQueryDAO(mysqlClient));
this.registerServiceImplementation(IProfileTaskLogQueryDAO.class, new H2ProfileTaskLogQueryDAO(mysqlClient));
this.registerServiceImplementation(
IProfileThreadSnapshotQueryDAO.class, new H2ProfileThreadSnapshotQueryDAO(mysqlClient));
IProfileThreadSnapshotQueryDAO.class, new H2ProfileThreadSnapshotQueryDAO(mysqlClient));
this.registerServiceImplementation(UITemplateManagementDAO.class, new H2UITemplateManagementDAO(mysqlClient));
}
@Override
......@@ -135,6 +138,6 @@ public class MySQLStorageProvider extends ModuleProvider {
@Override
public String[] requiredModules() {
return new String[] {CoreModule.NAME};
return new String[]{CoreModule.NAME};
}
}
......@@ -74,12 +74,12 @@ public class MySQLTableInstaller extends H2TableInstaller {
if (!modelColumn.isStorageOnly()) {
SQLBuilder tableIndexSQL = new SQLBuilder("CREATE INDEX ");
tableIndexSQL.append(model.getName().toUpperCase())
.append("_")
.append(String.valueOf(indexSeq++))
.append("_IDX ");
.append("_")
.append(String.valueOf(indexSeq++))
.append("_IDX ");
tableIndexSQL.append("ON ").append(model.getName()).append("(")
.append(modelColumn.getColumnName().getStorageName())
.append(")");
.append(modelColumn.getColumnName().getStorageName())
.append(")");
createIndex(client, connection, model, tableIndexSQL);
}
}
......@@ -87,9 +87,9 @@ public class MySQLTableInstaller extends H2TableInstaller {
for (final ExtraQueryIndex extraQueryIndex : model.getExtraQueryIndices()) {
SQLBuilder tableIndexSQL = new SQLBuilder("CREATE INDEX ");
tableIndexSQL.append(model.getName().toUpperCase())
.append("_")
.append(String.valueOf(indexSeq++))
.append("_IDX ");
.append("_")
.append(String.valueOf(indexSeq++))
.append("_IDX ");
tableIndexSQL.append(" ON ").append(model.getName()).append("(");
final String[] columns = extraQueryIndex.getColumns();
for (int i = 0; i < columns.length; i++) {
......@@ -105,8 +105,15 @@ public class MySQLTableInstaller extends H2TableInstaller {
@Override
protected String getColumnType(final ModelColumn column) {
if (StorageDataComplexObject.class.isAssignableFrom(column.getType())) {
final Class<?> type = column.getType();
if (StorageDataComplexObject.class.isAssignableFrom(type)) {
return "MEDIUMTEXT";
} else if (String.class.equals(type)) {
if (column.getLength() > 16383) {
return "MEDIUMTEXT";
} else {
return "VARCHAR(" + column.getLength() + ")";
}
}
return super.getColumnType(column);
}
......
......@@ -30,7 +30,7 @@ public class ModuleProviderTesting implements ModuleServiceHolder {
@Override
public void registerServiceImplementation(Class<? extends Service> serviceType,
Service service) throws ServiceNotProvidedException {
Service service) throws ServiceNotProvidedException {
if (serviceType.isInstance(service)) {
this.services.put(serviceType, service);
} else {
......
......@@ -33,6 +33,7 @@ import org.apache.skywalking.oap.server.core.config.DownSamplingConfigService;
import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
import org.apache.skywalking.oap.server.core.config.NamingControl;
import org.apache.skywalking.oap.server.core.config.group.EndpointNameGrouping;
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService;
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoaderService;
import org.apache.skywalking.oap.server.core.profile.ProfileTaskMutationService;
import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
......@@ -99,8 +100,8 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
@Override
public void prepare() throws ServiceNotProvidedException, ModuleStartException {
this.registerServiceImplementation(
NamingControl.class,
new NamingControl(50, 50, 150, new EndpointNameGrouping())
NamingControl.class,
new NamingControl(50, 50, 150, new EndpointNameGrouping())
);
MockStreamAnnotationListener streamAnnotationListener = new MockStreamAnnotationListener(getManager());
......@@ -119,13 +120,13 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
CoreModuleConfig moduleConfig = new CoreModuleConfig();
this.registerServiceImplementation(ConfigService.class, new ConfigService(moduleConfig));
this.registerServiceImplementation(
DownSamplingConfigService.class, new DownSamplingConfigService(Collections.emptyList()));
DownSamplingConfigService.class, new DownSamplingConfigService(Collections.emptyList()));
this.registerServiceImplementation(GRPCHandlerRegister.class, new MockGRPCHandlerRegister());
this.registerServiceImplementation(JettyHandlerRegister.class, new MockJettyHandlerRegister());
this.registerServiceImplementation(
IComponentLibraryCatalogService.class, new MockComponentLibraryCatalogService());
IComponentLibraryCatalogService.class, new MockComponentLibraryCatalogService());
this.registerServiceImplementation(SourceReceiver.class, new MockSourceReceiver());
......@@ -139,7 +140,7 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
this.registerServiceImplementation(ModelManipulator.class, storageModels);
this.registerServiceImplementation(
NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
this.registerServiceImplementation(TopologyQueryService.class, new TopologyQueryService(getManager()));
this.registerServiceImplementation(MetricsMetadataQueryService.class, new MetricsMetadataQueryService());
......@@ -153,9 +154,9 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
// add profile service implementations
this.registerServiceImplementation(
ProfileTaskMutationService.class, new ProfileTaskMutationService(getManager()));
ProfileTaskMutationService.class, new ProfileTaskMutationService(getManager()));
this.registerServiceImplementation(
ProfileTaskQueryService.class, new ProfileTaskQueryService(getManager(), moduleConfig));
ProfileTaskQueryService.class, new ProfileTaskQueryService(getManager(), moduleConfig));
this.registerServiceImplementation(ProfileTaskCache.class, new ProfileTaskCache(getManager(), moduleConfig));
this.registerServiceImplementation(CommandService.class, new CommandService(getManager()));
......@@ -164,6 +165,9 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
// add oal engine loader service implementations
this.registerServiceImplementation(OALEngineLoaderService.class, new OALEngineLoaderService(getManager()));
// Management
this.registerServiceImplementation(UITemplateManagementService.class, new UITemplateManagementService(getManager()));
}
@Override
......@@ -181,8 +185,8 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
@Override
public String[] requiredModules() {
return new String[] {
TelemetryModule.NAME
return new String[]{
TelemetryModule.NAME
};
}
}
......@@ -22,7 +22,7 @@ import java.lang.annotation.Annotation;
import org.apache.skywalking.oap.server.core.UnexpectedException;
import org.apache.skywalking.oap.server.core.analysis.Stream;
import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamingProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.NoneStreamProcessor;
import org.apache.skywalking.oap.server.core.analysis.worker.RecordStreamProcessor;
import org.apache.skywalking.oap.server.core.annotation.AnnotationListener;
import org.apache.skywalking.oap.server.core.storage.StorageException;
......@@ -51,8 +51,8 @@ public class MockStreamAnnotationListener implements AnnotationListener {
if (stream.processor().equals(RecordStreamProcessor.class)) {
RecordStreamProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else if (stream.processor().equals(NoneStreamingProcessor.class)) {
NoneStreamingProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
} else if (stream.processor().equals(NoneStreamProcessor.class)) {
NoneStreamProcessor.getInstance().create(moduleDefineHolder, stream, aClass);
}
} else {
throw new UnexpectedException(
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e;
import com.google.common.io.Resources;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.skywalking.e2e.dashboard.DashboardConfiguration;
import org.apache.skywalking.e2e.dashboard.DashboardConfigurationListWrapper;
import org.apache.skywalking.e2e.dashboard.DashboardSetting;
import org.apache.skywalking.e2e.dashboard.TemplateChangeStatus;
import org.apache.skywalking.e2e.dashboard.TemplateChangeStatusWrapper;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
public class UIConfigurationManagementClient extends SimpleQueryClient {
public UIConfigurationManagementClient(final String endpointUrl) {
super(endpointUrl);
}
public UIConfigurationManagementClient(final String host, final int port) {
super(host, port);
}
public TemplateChangeStatus addTemplate(DashboardSetting setting) throws IOException {
final URL queryFileUrl = Resources.getResource("ui-addTemplate.gql");
final String queryString = Resources.readLines(queryFileUrl, StandardCharsets.UTF_8)
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{name}", setting.name())
.replace("{type}", String.valueOf(setting.type()))
.replace("{configuration}", setting.configuration())
.replace("{active}", String.valueOf(setting.active()));
final ResponseEntity<GQLResponse<TemplateChangeStatusWrapper>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<TemplateChangeStatusWrapper>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getChangeStatusResult();
}
public List<DashboardConfiguration> getAllTemplates(Boolean includingDisabled) throws IOException {
final URL queryFileUrl = Resources.getResource("ui-getTemplates.gql");
final String queryString =
Resources.readLines(queryFileUrl, StandardCharsets.UTF_8)
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{includingDisabled}", String.valueOf(includingDisabled));
final ResponseEntity<GQLResponse<DashboardConfigurationListWrapper>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<DashboardConfigurationListWrapper>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getConfigurations();
}
public TemplateChangeStatus changeTemplate(DashboardSetting setting) throws IOException {
final URL queryFileUrl = Resources.getResource("ui-changeTemplate.gql");
final String queryString = Resources.readLines(queryFileUrl, StandardCharsets.UTF_8)
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{name}", setting.name())
.replace("{type}", String.valueOf(setting.type()))
.replace("{configuration}", setting.configuration())
.replace("{active}", String.valueOf(setting.active()));
final ResponseEntity<GQLResponse<TemplateChangeStatusWrapper>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<TemplateChangeStatusWrapper>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getChangeStatusResult();
}
public TemplateChangeStatus disableTemplate(String name) throws IOException {
final URL queryFileUrl = Resources.getResource("ui-disableTemplate.gql");
final String queryString =
Resources.readLines(queryFileUrl, StandardCharsets.UTF_8)
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{name}", name);
final ResponseEntity<GQLResponse<TemplateChangeStatusWrapper>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<TemplateChangeStatusWrapper>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getChangeStatusResult();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import lombok.Data;
@Data
public class DashboardConfiguration {
private String name;
private TemplateType type;
private String configuration;
private boolean activated;
private boolean disabled;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import java.util.List;
import lombok.Data;
@Data
public class DashboardConfigurationListWrapper {
private List<DashboardConfiguration> configurations;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import lombok.Data;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
@Data
public class DashboardConfigurationMatcher extends AbstractMatcher<DashboardConfiguration> {
private String name;
private String type;
private String configuration;
private String activated;
private String disabled;
@Override
public void verify(final DashboardConfiguration configuration) {
doVerify(this.name, configuration.getName());
doVerify(this.type, String.valueOf(configuration.getType()));
doVerify(this.configuration, configuration.getConfiguration());
doVerify(this.activated, String.valueOf(configuration.isActivated()));
doVerify(this.disabled, String.valueOf(configuration.isDisabled()));
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import java.util.List;
import lombok.Data;
@Data
public class DashboardConfigurations {
private List<DashboardConfiguration> configurations;
public int size() {
return configurations.size();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DashboardConfigurationsMatcher extends AbstractMatcher<DashboardConfigurations> {
private List<DashboardConfigurationMatcher> configurations;
@Override
public void verify(final DashboardConfigurations configurations) {
DashboardConfigurationMatcher matcher = this.configurations.get(0);
for (int i = 0; i < configurations.size(); i++) {
DashboardConfiguration configuration = configurations.getConfigurations().get(i);
if (matcher.getName().equals(configuration.getName())) {
matcher.verify(configuration);
return;
}
}
throw new RuntimeException("Assertion failed!");
}
}
\ No newline at end of file
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(fluent = true)
public class DashboardSetting {
private String name;
private TemplateType type;
private String configuration;
private boolean active;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import lombok.Data;
@Data
public class TemplateChangeStatus {
private boolean status;
private String message;
}
\ No newline at end of file
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
import lombok.Data;
@Data
public class TemplateChangeStatusWrapper {
private TemplateChangeStatus changeStatusResult;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.skywalking.e2e.dashboard;
public enum TemplateType {
DASHBOARD,
TOPOLOGY_SERVICE,
TOPOLOGY_INSTANCE,
TOPOLOGY_ENDPOINT,
TOPOLOGY_SERVICE_RELATION,
TOPOLOGY_SERVICE_INSTANCE_RELATION;
public static TemplateType forName(String name) {
return Enum.valueOf(TemplateType.class, name.toUpperCase());
}
}
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
{
"query":"mutation addTemplate($settingRequest: DashboardSetting!) {
changeStatusResult: addTemplate(setting: $settingRequest) {
status: status
message: message
}
}",
"variables": {
"settingRequest": {
"name": "{name}",
"type": "{type}",
"configuration": {configuration},
"active": {active}
}
}
}
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
{
"query":"mutation changeTemplate($settingRequest: DashboardSetting!) {
changeStatusResult: changeTemplate(setting: $settingRequest) {
status: status
message: message
}
}",
"variables": {
"settingRequest": {
"name": "{name}",
"type": "{type}",
"configuration": {configuration},
"active": {active}
}
}
}
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
{
"query":"mutation disableTemplate($name: String!) {
changeStatusResult: disableTemplate(name: $name) {
status: status
message: message
}
}",
"variables": {
"name": "{name}"
}
}
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
{
"query":"query getAllTemplates($includingDisabled: Boolean!) {
configurations: getAllTemplates(includingDisabled: $includingDisabled) {
name: name
type: type
configuration: configuration
activated: activated
disabled: disabled
}
}",
"variables": {
"includingDisabled": "{includingDisabled}"
}
}
......@@ -18,13 +18,21 @@
package org.apache.skywalking.e2e.storage;
import java.io.IOException;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.e2e.UIConfigurationManagementClient;
import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
import org.apache.skywalking.e2e.annotation.DockerCompose;
import org.apache.skywalking.e2e.base.SkyWalkingE2E;
import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
import org.apache.skywalking.e2e.common.HostAndPort;
import org.apache.skywalking.e2e.dashboard.DashboardConfiguration;
import org.apache.skywalking.e2e.dashboard.DashboardConfigurations;
import org.apache.skywalking.e2e.dashboard.DashboardConfigurationsMatcher;
import org.apache.skywalking.e2e.dashboard.DashboardSetting;
import org.apache.skywalking.e2e.dashboard.TemplateChangeStatus;
import org.apache.skywalking.e2e.dashboard.TemplateType;
import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
import org.apache.skywalking.e2e.metrics.Metrics;
import org.apache.skywalking.e2e.metrics.MetricsQuery;
......@@ -45,14 +53,15 @@ import org.apache.skywalking.e2e.topo.Call;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopology;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyMatcher;
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyQuery;
import org.apache.skywalking.e2e.topo.Topology;
import org.apache.skywalking.e2e.topo.TopoMatcher;
import org.apache.skywalking.e2e.topo.TopoQuery;
import org.apache.skywalking.e2e.topo.Topology;
import org.apache.skywalking.e2e.trace.Trace;
import org.apache.skywalking.e2e.trace.TracesMatcher;
import org.apache.skywalking.e2e.trace.TracesQuery;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.DockerComposeContainer;
import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
......@@ -65,6 +74,7 @@ import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATIO
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
import static org.apache.skywalking.e2e.utils.Times.now;
import static org.apache.skywalking.e2e.utils.Yamls.load;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Slf4j
@SkyWalkingE2E
......@@ -85,9 +95,11 @@ public class StorageE2E extends SkyWalkingTestAdapter {
@ContainerHostAndPort(name = "provider", port = 9090)
private HostAndPort serviceHostPort;
private UIConfigurationManagementClient graphql;
@BeforeAll
void setUp() throws Exception {
queryClient(swWebappHostPort);
graphql = new UIConfigurationManagementClient(swWebappHostPort.host(), swWebappHostPort.port());
trafficController(serviceHostPort, "/users");
}
......@@ -156,6 +168,60 @@ public class StorageE2E extends SkyWalkingTestAdapter {
verifyServiceInstanceRelationMetrics(topology.getCalls());
}
@Test
void addUITemplate() throws Exception {
try {
TemplateChangeStatus templateChangeStatus = graphql.addTemplate(
emptySetting("test-ui-config-1").type(TemplateType.DASHBOARD)
);
LOGGER.info("add template = {}", templateChangeStatus);
} catch (Exception e) {
LOGGER.error("add ui template error.", e);
}
verifyTemplates("expected/storage/dashboardConfiguration.yml");
}
@Test
void changeTemplate() throws Exception {
try {
final String name = "test-ui-config-2";
assertTrue(
graphql.addTemplate(
emptySetting(name).type(TemplateType.TOPOLOGY_SERVICE)
).isStatus()
);
TemplateChangeStatus templateChangeStatus = graphql.changeTemplate(
emptySetting(name).configuration("{\"key\":\"value\"}")
);
LOGGER.info("change UITemplate = {}", templateChangeStatus);
assertTrue(templateChangeStatus.isStatus());
} catch (Exception e) {
LOGGER.error("add ui template error.", e);
}
verifyTemplates("expected/storage/dashboardConfiguration-change.yml");
}
@Test
void disableTemplate() throws IOException {
try {
final String name = "test-ui-config-3";
assertTrue(
graphql.addTemplate(
emptySetting(name).type(TemplateType.DASHBOARD)
).isStatus()
);
TemplateChangeStatus templateChangeStatus = graphql.disableTemplate(name);
LOGGER.info("disable template = {}", templateChangeStatus);
assertTrue(templateChangeStatus.isStatus());
} catch (Exception e) {
LOGGER.error("add ui template error.", e);
}
verifyTemplates("expected/storage/dashboardConfiguration-disable.yml");
}
private Instances verifyServiceInstances(final Service service) throws Exception {
final Instances instances = graphql.instances(
new InstancesQuery().serviceId(service.getKey()).start(startTime).end(now())
......@@ -272,4 +338,20 @@ public class StorageE2E extends SkyWalkingTestAdapter {
}
}
}
private void verifyTemplates(String file) throws IOException {
List<DashboardConfiguration> configurations = graphql.getAllTemplates(Boolean.TRUE);
LOGGER.info("get all templates = {}", configurations);
DashboardConfigurations dashboardConfigurations = new DashboardConfigurations();
dashboardConfigurations.setConfigurations(configurations);
load(file).as(DashboardConfigurationsMatcher.class).verify(dashboardConfigurations);
}
private DashboardSetting emptySetting(final String name) {
return new DashboardSetting()
.name(name)
.active(true)
.configuration("{}");
}
}
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
configurations:
- name: test-ui-config-2
type: TOPOLOGY_SERVICE
configuration: "{}"
activated: true
disabled: false
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
configurations:
- name: test-ui-config-3
type: not null
configuration: not null
activated: true
disabled: true
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
configurations:
- name: test-ui-config-1
type: not null
configuration: not null
activated: true
disabled: false
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册