You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/05/21 16:32:41 UTC
[skywalking] 01/01: Support composite ID to replace entity ID in BanyanDB case.
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch composite-id
in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit 59fb2aba24e80b4c6a2abe2456a2a5e7658e1434
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sun May 21 20:32:22 2023 +0400
Support composite ID to replace entity ID in BanyanDB case.
---
docs/en/changes/changes.md | 3 ++
.../org/apache/skywalking/oal/rt/OALRuntime.java | 43 +++++++++++++++-------
.../skywalking/oal/rt/parser/SourceColumn.java | 3 ++
.../oal/rt/parser/SourceColumnsFactory.java | 6 ++-
.../oap/server/core/oal/rt/OALEngine.java | 3 ++
.../server/core/oal/rt/OALEngineLoaderService.java | 4 ++
.../oap/server/core/source/DefaultScopeDefine.java | 13 +++++--
.../oap/server/core/source/Endpoint.java | 4 +-
.../oap/server/core/source/ScopeDefaultColumn.java | 33 ++++++++++-------
.../oap/server/core/source/ServiceInstance.java | 4 +-
.../oap/server/core/storage/StorageCharacter.java | 27 ++++++++++++++
.../oap/server/core/storage/StorageModule.java | 1 +
.../plugin/banyandb/BanyanDBStorageProvider.java | 10 +++++
.../StorageModuleElasticsearchProvider.java | 6 +++
.../plugin/jdbc/common/JDBCStorageProvider.java | 6 +++
15 files changed, 129 insertions(+), 37 deletions(-)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 3b95fca657..86e5bb94d1 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -71,6 +71,9 @@
* Add OpenTelemetry log protocol support.
* [Breaking Change] Configuration key `enabledOtelRules` is renamed to `enabledOtelMetricsRules` and
the corresponding environment variable is renamed to `SW_OTEL_RECEIVER_ENABLED_OTEL_METRICS_RULES`.
+* Support composite ID declared from existing columns, rather a new virtual column, in the BanyanDB.
+* In the BanyanDB implementation, metrics built from ServiceInstance and Endpoint sources are not using `entity_id` as ID,
+ instead, they use composite ID built by `service_id` and `name` to reduce redundant indices in the database.
#### Documentation
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java
index 53937f7b29..5dc6cf7c62 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java
@@ -20,6 +20,17 @@ package org.apache.skywalking.oal.rt;
import freemarker.template.Configuration;
import freemarker.template.Version;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
@@ -59,6 +70,7 @@ import org.apache.skywalking.oap.server.core.source.oal.rt.dispatcher.Dispatcher
import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.MetricClassPackageHolder;
import org.apache.skywalking.oap.server.core.source.oal.rt.metrics.builder.MetricBuilderClassPackageHolder;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
+import org.apache.skywalking.oap.server.core.storage.StorageCharacter;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB;
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
@@ -66,18 +78,6 @@ import org.apache.skywalking.oap.server.library.module.ModuleStartException;
import org.apache.skywalking.oap.server.library.util.ResourceUtils;
import org.apache.skywalking.oap.server.library.util.StringUtil;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
/**
* OAL Runtime is the class generation engine, which load the generated classes from OAL scrip definitions. This runtime
* is loaded dynamically.
@@ -115,6 +115,7 @@ public class OALRuntime implements OALEngine {
private StreamAnnotationListener streamAnnotationListener;
private DispatcherDetectorListener dispatcherDetectorListener;
private StorageBuilderFactory storageBuilderFactory;
+ private StorageCharacter character;
private final List<Class> metricsClasses;
private final List<Class> dispatcherClasses;
private final boolean openEngineDebug;
@@ -191,6 +192,11 @@ public class OALRuntime implements OALEngine {
}
}
+ @Override
+ public void setStorageCharacter(final StorageCharacter character) {
+ this.character = character;
+ }
+
private void generateClassAtRuntime(OALScripts oalScripts) throws OALCompileException {
List<AnalysisResult> metricsStmts = oalScripts.getMetricsStmts();
metricsStmts.forEach(this::buildDispatcherContext);
@@ -248,8 +254,15 @@ public class OALRuntime implements OALEngine {
*
* private ${sourceField.typeName} ${sourceField.fieldName};
*/
+ List<SourceColumn> excludedFields = new ArrayList<>(1);
for (SourceColumn field : metricsStmt.getFieldsFromSource()) {
try {
+ if (field.isID() && field.getIdxOfCompositeID() < 0 && character.supportCompositeID()) {
+ // Skip virtual column when storage supports composite ID.
+ excludedFields.add(field);
+ continue;
+ }
+
CtField newField = CtField.make(
"private " + field.getType()
.getName() + " " + field.getFieldName() + ";", metricsClass);
@@ -271,9 +284,10 @@ public class OALRuntime implements OALEngine {
}
annotationsAttribute.addAnnotation(columnAnnotation);
if (field.isID()) {
- // Add SeriesID = 0 annotation to ID field.
+ // Add SeriesID = 0 annotation to ID field if no index declared, such as virtual columen as ID.
+ int seriesIDIdx = field.getIdxOfCompositeID() < 0 ? 0 : field.getIdxOfCompositeID();
Annotation banyanShardingKeyAnnotation = new Annotation(BanyanDB.SeriesID.class.getName(), constPool);
- banyanShardingKeyAnnotation.addMemberValue("index", new IntegerMemberValue(constPool, 0));
+ banyanShardingKeyAnnotation.addMemberValue("index", new IntegerMemberValue(constPool, seriesIDIdx));
annotationsAttribute.addAnnotation(banyanShardingKeyAnnotation);
}
@@ -289,6 +303,7 @@ public class OALRuntime implements OALEngine {
throw new OALCompileException(e.getMessage(), e);
}
}
+ metricsStmt.getFieldsFromSource().removeAll(excludedFields);
/**
* Generate methods
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumn.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumn.java
index f8cea14003..b5a192b7af 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumn.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumn.java
@@ -34,9 +34,11 @@ public class SourceColumn {
private int length;
private String fieldSetter;
private String fieldGetter;
+ private final int idxOfCompositeID;
private final boolean groupByCondInTopN;
public SourceColumn(String fieldName, String columnName, Class<?> type, boolean isID, int length,
+ final int idxOfCompositeID,
boolean groupByCondInTopN) {
this.fieldName = fieldName;
this.columnName = columnName;
@@ -47,6 +49,7 @@ public class SourceColumn {
this.fieldGetter = ClassMethodUtil.toGetMethod(fieldName);
this.fieldSetter = ClassMethodUtil.toSetMethod(fieldName);
+ this.idxOfCompositeID = idxOfCompositeID;
this.groupByCondInTopN = groupByCondInTopN;
}
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumnsFactory.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumnsFactory.java
index fdd3c0d6d7..2e1a877592 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumnsFactory.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/SourceColumnsFactory.java
@@ -30,8 +30,10 @@ public class SourceColumnsFactory {
List<ScopeDefaultColumn> columns = DefaultScopeDefine.getDefaultColumns(source);
for (ScopeDefaultColumn defaultColumn : columns) {
sourceColumns.add(
- new SourceColumn(defaultColumn.getFieldName(), defaultColumn.getColumnName(), defaultColumn
- .getType(), defaultColumn.isID(), defaultColumn.getLength(), defaultColumn.isGroupByCondInTopN()));
+ new SourceColumn(defaultColumn.getFieldName(), defaultColumn.getColumnName(),
+ defaultColumn.getType(), defaultColumn.isID(), defaultColumn.getLength(),
+ defaultColumn.getIdxOfCompositeID(), defaultColumn.isGroupByCondInTopN()
+ ));
}
return sourceColumns;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java
index fefde9684b..ad8563f96c 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngine.java
@@ -21,6 +21,7 @@ package org.apache.skywalking.oap.server.core.oal.rt;
import org.apache.skywalking.oap.server.core.analysis.DispatcherDetectorListener;
import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
+import org.apache.skywalking.oap.server.core.storage.StorageCharacter;
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
/**
@@ -36,4 +37,6 @@ public interface OALEngine {
void start(ClassLoader currentClassLoader) throws ModuleStartException, OALCompileException;
void notifyAllListeners() throws ModuleStartException;
+
+ void setStorageCharacter(StorageCharacter character);
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngineLoaderService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngineLoaderService.java
index d1f4c63c5c..3fda0137ea 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngineLoaderService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/oal/rt/OALEngineLoaderService.java
@@ -26,6 +26,7 @@ import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.analysis.StreamAnnotationListener;
import org.apache.skywalking.oap.server.core.source.SourceReceiver;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
+import org.apache.skywalking.oap.server.core.storage.StorageCharacter;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
@@ -61,6 +62,9 @@ public class OALEngineLoaderService implements Service {
engine.setStorageBuilderFactory(moduleManager.find(StorageModule.NAME)
.provider()
.getService(StorageBuilderFactory.class));
+ engine.setStorageCharacter(moduleManager.find(StorageModule.NAME)
+ .provider()
+ .getService(StorageCharacter.class));
engine.start(OALEngineLoaderService.class.getClassLoader());
engine.notifyAllListeners();
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
index 838d7af936..67ecd1cf0a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/DefaultScopeDefine.java
@@ -203,9 +203,10 @@ public class DefaultScopeDefine {
ScopeDefaultColumn.VirtualColumnDefinition virtualColumn = (ScopeDefaultColumn.VirtualColumnDefinition) originalClass
.getAnnotation(ScopeDefaultColumn.VirtualColumnDefinition.class);
if (virtualColumn != null) {
+ // Virtual column doesn't use composite ID mechanism.
scopeDefaultColumns.add(
new ScopeDefaultColumn(virtualColumn.fieldName(), virtualColumn.columnName(), virtualColumn
- .type(), virtualColumn.isID(), virtualColumn.length(), false));
+ .type(), virtualColumn.isID(), virtualColumn.length(), -1, false));
}
Field[] scopeClassField = originalClass.getDeclaredFields();
if (scopeClassField != null) {
@@ -216,8 +217,14 @@ public class DefaultScopeDefine {
if (!definedByField.requireDynamicActive() || ACTIVE_EXTRA_MODEL_COLUMNS) {
scopeDefaultColumns.add(
new ScopeDefaultColumn(
- field.getName(), definedByField.columnName(), field.getType(), false,
- definedByField.length(), definedByField.groupByCondInTopN()
+ field.getName(),
+ definedByField.columnName(),
+ field.getType(),
+ // If the index for the composite ID, this column is an ID.
+ definedByField.idxOfCompositeID() > -1,
+ definedByField.length(),
+ definedByField.idxOfCompositeID(),
+ definedByField.groupByCondInTopN()
));
}
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Endpoint.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Endpoint.java
index 9e7933e0ab..bdd399c154 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Endpoint.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Endpoint.java
@@ -51,10 +51,10 @@ public class Endpoint extends Source {
@Getter
@Setter
- @ScopeDefaultColumn.DefinedByField(columnName = "name", requireDynamicActive = true)
+ @ScopeDefaultColumn.DefinedByField(columnName = "name", requireDynamicActive = true, idxOfCompositeID = 1)
private String name;
@Getter
- @ScopeDefaultColumn.DefinedByField(columnName = "service_id", groupByCondInTopN = true)
+ @ScopeDefaultColumn.DefinedByField(columnName = "service_id", groupByCondInTopN = true, idxOfCompositeID = 0)
private String serviceId;
@Getter
@Setter
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ScopeDefaultColumn.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ScopeDefaultColumn.java
index 5d2986e102..4661c6b776 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ScopeDefaultColumn.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ScopeDefaultColumn.java
@@ -24,29 +24,23 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import lombok.RequiredArgsConstructor;
/**
* Define the default columns of source scope. These columns pass down into the persistent entity(OAL metrics entity)
* automatically.
*/
@Getter
+@RequiredArgsConstructor
public class ScopeDefaultColumn {
- private String fieldName;
- private String columnName;
- private Class<?> type;
- private boolean isID;
- private int length;
+ private final String fieldName;
+ private final String columnName;
+ private final Class<?> type;
+ private final boolean isID;
+ private final int length;
+ private final int idxOfCompositeID;
private final boolean groupByCondInTopN;
- public ScopeDefaultColumn(String fieldName, String columnName, Class<?> type, boolean isID, int length, boolean groupByCondInTopN) {
- this.fieldName = fieldName;
- this.columnName = columnName;
- this.type = type;
- this.isID = isID;
- this.length = length;
- this.groupByCondInTopN = groupByCondInTopN;
- }
-
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DefinedByField {
@@ -71,6 +65,17 @@ public class ScopeDefaultColumn {
* @since 9.5.0
*/
boolean groupByCondInTopN() default false;
+
+ /**
+ * Each metric should include all fields composing the raw ID.
+ * In the previous implementation, we build an entity_id by {@link VirtualColumnDefinition#isID()} == true,
+ * but in now, some storage like BanyanDB, it supports a composite ID by multiple existing fields natively,
+ * so, this new composite ID is created, logically as same as the virtual ID.
+ *
+ * @return the index of this field when it is a part of ID. Or return -1 if not a part of ID.
+ * @since 9.5.0
+ */
+ int idxOfCompositeID() default -1;
}
@Target({ElementType.TYPE})
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstance.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstance.java
index 6382c80ba5..2ec85d10cd 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstance.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstance.java
@@ -47,11 +47,11 @@ public class ServiceInstance extends Source {
}
@Getter
- @ScopeDefaultColumn.DefinedByField(columnName = "service_id")
+ @ScopeDefaultColumn.DefinedByField(columnName = "service_id", idxOfCompositeID = 0)
private String serviceId;
@Getter
@Setter
- @ScopeDefaultColumn.DefinedByField(columnName = "name", requireDynamicActive = true)
+ @ScopeDefaultColumn.DefinedByField(columnName = "name", requireDynamicActive = true, idxOfCompositeID = 1)
private String name;
@Getter
@Setter
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageCharacter.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageCharacter.java
new file mode 100644
index 0000000000..0f1118645c
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageCharacter.java
@@ -0,0 +1,27 @@
+package org.apache.skywalking.oap.server.core.storage;
+
+import org.apache.skywalking.oap.server.core.source.ScopeDefaultColumn;
+import org.apache.skywalking.oap.server.library.module.Service;
+
+/**
+ * StorageCharacter provides core aware characters which make the core could run optimized codes accordingly.
+ *
+ * @since 9.5.0
+ */
+public interface StorageCharacter extends Service {
+ /**
+ * See {@link ScopeDefaultColumn.DefinedByField#idxOfCompositeID()}
+ *
+ * @return true if ID is declared through existing column, but not a virtual column. Typically, there was an entity_id
+ * column to represent a subject(service, endpoint, et.c)
+ */
+ boolean supportCompositeID();
+
+ class Default implements StorageCharacter {
+
+ @Override
+ public boolean supportCompositeID() {
+ return false;
+ }
+ }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java
index c25ebdc61d..a7de44fdd1 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/StorageModule.java
@@ -59,6 +59,7 @@ public class StorageModule extends ModuleDefine {
public Class[] services() {
return new Class[] {
StorageBuilderFactory.class,
+ StorageCharacter.class,
IBatchDAO.class,
StorageDAO.class,
IHistoryDeleteDAO.class,
diff --git a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java
index ee01d0f94b..6f2c91bbd2 100644
--- a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java
+++ b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/BanyanDBStorageProvider.java
@@ -24,6 +24,7 @@ import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.storage.IBatchDAO;
import org.apache.skywalking.oap.server.core.storage.IHistoryDeleteDAO;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
+import org.apache.skywalking.oap.server.core.storage.StorageCharacter;
import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
@@ -116,6 +117,15 @@ public class BanyanDBStorageProvider extends ModuleProvider {
@Override
public void prepare() throws ServiceNotProvidedException, ModuleStartException {
this.registerServiceImplementation(StorageBuilderFactory.class, new StorageBuilderFactory.Default());
+ this.registerServiceImplementation(
+ StorageCharacter.class,
+ new StorageCharacter() {
+ @Override
+ public boolean supportCompositeID() {
+ return true;
+ }
+ }
+ );
this.client = new BanyanDBStorageClient(config.getHost(), config.getPort());
this.modelInstaller = new BanyanDBIndexInstaller(client, getManager(), this.config);
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
index c8e74d13cd..95bbc1d868 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/StorageModuleElasticsearchProvider.java
@@ -27,6 +27,7 @@ import org.apache.skywalking.oap.server.core.config.ConfigService;
import org.apache.skywalking.oap.server.core.storage.IBatchDAO;
import org.apache.skywalking.oap.server.core.storage.IHistoryDeleteDAO;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
+import org.apache.skywalking.oap.server.core.storage.StorageCharacter;
import org.apache.skywalking.oap.server.core.storage.StorageDAO;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressAliasDAO;
@@ -133,6 +134,11 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
public void prepare() throws ServiceNotProvidedException {
this.registerServiceImplementation(StorageBuilderFactory.class, new StorageBuilderFactory.Default());
+ this.registerServiceImplementation(
+ StorageCharacter.class,
+ new StorageCharacter.Default()
+ );
+
if (StringUtil.isEmpty(config.getNamespace())) {
config.setNamespace("sw");
} else {
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java
index 6c000d8707..4b30c5cae4 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/common/JDBCStorageProvider.java
@@ -22,6 +22,7 @@ import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.storage.IBatchDAO;
import org.apache.skywalking.oap.server.core.storage.IHistoryDeleteDAO;
import org.apache.skywalking.oap.server.core.storage.StorageBuilderFactory;
+import org.apache.skywalking.oap.server.core.storage.StorageCharacter;
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;
@@ -130,6 +131,11 @@ public abstract class JDBCStorageProvider extends ModuleProvider {
StorageBuilderFactory.class,
new StorageBuilderFactory.Default());
+ this.registerServiceImplementation(
+ StorageCharacter.class,
+ new StorageCharacter.Default()
+ );
+
this.registerServiceImplementation(
IBatchDAO.class,
new JDBCBatchDAO(