diff --git a/README.md b/README.md
index 7abfb85..7bc5757 100644
--- a/README.md
+++ b/README.md
@@ -120,7 +120,7 @@ For a Maven project, add the following to your pom.xml file:
group.rxcloudcapa-sdk
- 1.0.6.RELEASE
+ 1.0.7.RELEASE
...
@@ -140,7 +140,7 @@ Sample implementation library:
group.rxcloudcapa-sdk-spi-demo
- 1.0.6.RELEASE
+ 1.0.7.RELEASE
...
diff --git a/README_ZH.md b/README_ZH.md
index 15e2d00..a13a2ae 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -118,7 +118,7 @@ For a Maven project, add the following to your pom.xml file:
group.rxcloudcapa-sdk
- 1.0.6.RELEASE
+ 1.0.7.RELEASE
...
@@ -138,7 +138,7 @@ Sample implementation library:
group.rxcloudcapa-sdk-spi-demo
- 1.0.6.RELEASE
+ 1.0.7.RELEASE
...
diff --git a/examples/pom.xml b/examples/pom.xml
index 8af886a..739a0b7 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -23,7 +23,7 @@
capa-parentgroup.rxcloud
- 1.0.6.RELEASE
+ 1.0.7.RELEASEcapa-examples
@@ -31,7 +31,9 @@
capa-sdk-examples
- 2.14.1
+ 2.8.2
+ 1.1.7
+ 1.7.32
@@ -58,21 +60,23 @@
-
+
org.apache.logging.log4jlog4j-slf4j-impl${log4j.version}
-
-
- log4j-core
- org.apache.logging.log4j
-
-
- log4j-api
- org.apache.logging.log4j
-
-
+
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.2
diff --git a/examples/src/main/java/group/rxcloud/capa/examples/log/DemoLog.java b/examples/src/main/java/group/rxcloud/capa/examples/log/DemoLog.java
new file mode 100644
index 0000000..20ac7e2
--- /dev/null
+++ b/examples/src/main/java/group/rxcloud/capa/examples/log/DemoLog.java
@@ -0,0 +1,35 @@
+/*
+ * 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 group.rxcloud.capa.examples.log;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * An application cannot use log4j and logback configuration to print logs at the same time.
+ * So if you want to test the log4j2 configuration to print logs, then you need to copy the resources/xml/log4j2.xml file to the resources directory, and then add log4j-slf4j-impl dependency to the pom file.
+ * Else if you want to use logback configuration to print logs, then the resources/xml/logback.xml file needs to be copied to the resources path, and the logback-classic dependency needs to be added to the pom file.
+ * Notice:
+ * 1. Resources cannot contain log4j2.xml and logback.xml files at the same time,
+ * 2. log4j-slf4j-impl and logback-classic cannot exist at the same time.
+ */
+@Slf4j
+public class DemoLog {
+
+ public static void main(String[] args) {
+ log.info("test");
+ }
+}
diff --git a/examples/src/main/java/group/rxcloud/capa/examples/telemetry/DemoTelemetryClient.java b/examples/src/main/java/group/rxcloud/capa/examples/telemetry/DemoTelemetryClient.java
new file mode 100644
index 0000000..8ef4efd
--- /dev/null
+++ b/examples/src/main/java/group/rxcloud/capa/examples/telemetry/DemoTelemetryClient.java
@@ -0,0 +1,61 @@
+/*
+ * 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 group.rxcloud.capa.examples.telemetry;
+
+import group.rxcloud.capa.component.telemetry.metrics.MetricsReaderConfig;
+import group.rxcloud.capa.telemetry.CapaTelemetryClient;
+import group.rxcloud.capa.telemetry.CapaTelemetryClientBuilder;
+import io.opentelemetry.api.metrics.LongCounter;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.Tracer;
+
+import java.util.concurrent.TimeUnit;
+
+public class DemoTelemetryClient {
+
+ public static void main(String[] args) throws InterruptedException {
+ MetricsReaderConfig readerConfig = new MetricsReaderConfig();
+ readerConfig.setExporterType(MetricTestExporter.class.getName());
+ readerConfig.setName("metric-reader");
+ readerConfig.setExportInterval(1, TimeUnit.SECONDS);
+ CapaTelemetryClient capaTelemetryClient = new CapaTelemetryClientBuilder()
+ .addProcessor(new TraceProcessor())
+ .addMetricReaderConfig(readerConfig)
+ .build();
+
+ // tracer
+ Tracer tracer = capaTelemetryClient.buildTracer("tracer-test")
+ .block();
+
+ LongCounter counter = capaTelemetryClient.buildMeter("meter-test")
+ .block()
+ .counterBuilder("counter-test")
+ .build();
+
+ Span span = tracer.spanBuilder("span-test")
+ .setAttribute("key1", 1)
+ .setAttribute("key2", 2)
+ .startSpan();
+ // working
+ for (int i = 0; i < 50; i++) {
+ Thread.sleep(200);
+ counter.add(i);
+ }
+
+ span.end();
+ }
+}
diff --git a/examples/src/main/java/group/rxcloud/capa/examples/telemetry/MetricTestExporter.java b/examples/src/main/java/group/rxcloud/capa/examples/telemetry/MetricTestExporter.java
new file mode 100644
index 0000000..2615920
--- /dev/null
+++ b/examples/src/main/java/group/rxcloud/capa/examples/telemetry/MetricTestExporter.java
@@ -0,0 +1,42 @@
+/*
+ * 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 group.rxcloud.capa.examples.telemetry;
+
+import io.opentelemetry.sdk.common.CompletableResultCode;
+import io.opentelemetry.sdk.metrics.data.MetricData;
+import io.opentelemetry.sdk.metrics.export.MetricExporter;
+
+import java.util.Collection;
+
+public class MetricTestExporter implements MetricExporter {
+
+ @Override
+ public CompletableResultCode export(Collection metrics) {
+ metrics.forEach(System.out::println);
+ return CompletableResultCode.ofSuccess();
+ }
+
+ @Override
+ public CompletableResultCode flush() {
+ return CompletableResultCode.ofSuccess();
+ }
+
+ @Override
+ public CompletableResultCode shutdown() {
+ return CompletableResultCode.ofSuccess();
+ }
+}
diff --git a/examples/src/main/java/group/rxcloud/capa/examples/telemetry/TraceProcessor.java b/examples/src/main/java/group/rxcloud/capa/examples/telemetry/TraceProcessor.java
new file mode 100644
index 0000000..63f5589
--- /dev/null
+++ b/examples/src/main/java/group/rxcloud/capa/examples/telemetry/TraceProcessor.java
@@ -0,0 +1,45 @@
+/*
+ * 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 group.rxcloud.capa.examples.telemetry;
+
+import io.opentelemetry.context.Context;
+import io.opentelemetry.sdk.trace.ReadWriteSpan;
+import io.opentelemetry.sdk.trace.ReadableSpan;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+
+public class TraceProcessor implements SpanProcessor {
+
+ @Override
+ public void onStart(Context context, ReadWriteSpan span) {
+
+ }
+
+ @Override
+ public boolean isStartRequired() {
+ return false;
+ }
+
+ @Override
+ public void onEnd(ReadableSpan span) {
+ System.out.println(span.toSpanData());
+ }
+
+ @Override
+ public boolean isEndRequired() {
+ return true;
+ }
+}
diff --git a/examples/src/main/resources/log4j2.xml b/examples/src/main/resources/log4j2.xml
index f923cdb..3587353 100644
--- a/examples/src/main/resources/log4j2.xml
+++ b/examples/src/main/resources/log4j2.xml
@@ -20,10 +20,12 @@
+
-
+
+
\ No newline at end of file
diff --git a/examples/src/main/resources/xml/log4j2.xml b/examples/src/main/resources/xml/log4j2.xml
new file mode 100644
index 0000000..3587353
--- /dev/null
+++ b/examples/src/main/resources/xml/log4j2.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/src/main/resources/xml/logback.xml b/examples/src/main/resources/xml/logback.xml
new file mode 100644
index 0000000..268d16c
--- /dev/null
+++ b/examples/src/main/resources/xml/logback.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 352e1ab..8928e20 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
group.rxcloudcapa-parentpom
- 1.0.6.RELEASE
+ 1.0.7.RELEASEcapa-sdk-parentSDK for Capa.https://github.com/reactivegroup
@@ -73,8 +73,12 @@
8UTF-83.8.1
- 1.0.7.RELEASE
+ 1.0.9.RELEASE3.3.22.RELEASE
+ 1.7.21
+ 1.9.0
+ 1.9.0-alpha
+
5.3.13.6.03.1.2
@@ -132,6 +136,25 @@
true
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+
+ io.opentelemetry
+ opentelemetry-api
+ ${open.telemetry.version}
+
+
+ io.opentelemetry
+ opentelemetry-api-metrics
+ ${open.telemetry.version.alpha}
+
+
org.junit.jupiter
@@ -308,6 +331,7 @@
docs/**spec/****/generated/**
+ **/*.json
diff --git a/sdk-component/pom.xml b/sdk-component/pom.xml
index 5cea9fb..22941a3 100644
--- a/sdk-component/pom.xml
+++ b/sdk-component/pom.xml
@@ -23,7 +23,7 @@
group.rxcloudcapa-parent
- 1.0.6.RELEASE
+ 1.0.7.RELEASEcapa-sdk-component
@@ -33,6 +33,8 @@
4.9.11.4.10
+ 2.8.2
+ 1.1.7
@@ -42,6 +44,17 @@
capa-sdk-infrastructure
+
+ io.opentelemetry
+ opentelemetry-sdk
+ 1.9.0
+
+
+ io.opentelemetry
+ opentelemetry-sdk-metrics
+ 1.9.0-alpha
+
+
com.squareup.okhttp3
@@ -71,6 +84,21 @@
${kotlin-stdlib.version}
+
+
+ org.apache.logging.log4j
+ log4j-core
+ true
+ ${log4j.version}
+
+
+
+ ch.qos.logback
+ logback-core
+ true
+ ${logback.version}
+
+
org.junit.jupiterjunit-jupiter-engine
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStore.java b/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStore.java
index b6513bb..c4dd186 100644
--- a/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStore.java
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStore.java
@@ -55,6 +55,8 @@ public CapaConfigStore(CapaObjectSerializer objectSerializer) {
/**
* Init the configuration store.
+ *
+ * @param storeConfig storeConfig
*/
public void init(StoreConfig storeConfig) {
this.storeName = storeConfig.getStoreName();
@@ -68,6 +70,8 @@ public void init(StoreConfig storeConfig) {
/**
* Gets store name.
+ *
+ * @return storeName
*/
public String getStoreName() {
return this.storeName;
@@ -75,26 +79,42 @@ public String getStoreName() {
/**
* GetSpecificKeysValue get specific key value.
+ *
+ * @param getRequest request
+ * @param type response type
+ * @param type
+ * @return mono of response
*/
public abstract Mono>> get(GetRequest getRequest, TypeRef type);
/**
* Subscribe the configurations updates.
+ *
+ * @param subscribeReq request
+ * @param type response type
+ * @param type
+ * @return flux of subscribe
*/
public abstract Flux> subscribe(SubscribeReq subscribeReq, TypeRef type);
/**
* StopSubscribe stop subs
+ *
+ * @return result
*/
public abstract String stopSubscribe();
/**
* GetDefaultGroup returns default group.This method will be invoked if a request doesn't specify the group field
+ *
+ * @return default
*/
public abstract String getDefaultGroup();
/**
* GetDefaultLabel returns default label
+ *
+ * @return default
*/
public abstract String getDefaultLabel();
}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStoreBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStoreBuilder.java
index fe5baef..c12e3c8 100644
--- a/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStoreBuilder.java
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/configstore/CapaConfigStoreBuilder.java
@@ -81,6 +81,7 @@ public CapaConfigStore build() {
* @return Instance of {@link CapaConfigStore} implementor
*/
private CapaConfigStore buildCapaConfigStore() {
+ // TODO: 2021/11/30 build multi component
// load spi capa config store impl
return CapaClassLoader.loadComponentClassObj(
"configuration",
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/http/CapaHttpBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/http/CapaHttpBuilder.java
index 2d3d9c5..087ceba 100644
--- a/sdk-component/src/main/java/group/rxcloud/capa/component/http/CapaHttpBuilder.java
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/http/CapaHttpBuilder.java
@@ -108,7 +108,9 @@ private CapaHttp buildCapaHttp() {
return CapaClassLoader.loadComponentClassObj(
"rpc",
CapaHttp.class,
- new Class[]{OkHttpClient.class, CapaObjectSerializer.class},
- new Object[]{OK_HTTP_CLIENT.get(), this.objectSerializer});
+ new Class[]{OkHttpClient.class,
+ CapaObjectSerializer.class},
+ new Object[]{OK_HTTP_CLIENT.get(),
+ this.objectSerializer});
}
}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/http/HttpResponse.java b/sdk-component/src/main/java/group/rxcloud/capa/component/http/HttpResponse.java
index 82537e1..e0fc625 100644
--- a/sdk-component/src/main/java/group/rxcloud/capa/component/http/HttpResponse.java
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/http/HttpResponse.java
@@ -45,6 +45,8 @@ public HttpResponse(T body, Map headers, int statusCode) {
/**
* Gets actual response data.
+ *
+ * @return
*/
public T getBody() {
return body;
@@ -52,6 +54,8 @@ public T getBody() {
/**
* Gets http headers.
+ *
+ * @return
*/
public Map getHeaders() {
return headers;
@@ -59,6 +63,8 @@ public Map getHeaders() {
/**
* Gets http invocation status code.
+ *
+ * @return
*/
public int getStatusCode() {
return statusCode;
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/log/agent/CapaLog4jAppenderAgent.java b/sdk-component/src/main/java/group/rxcloud/capa/component/log/agent/CapaLog4jAppenderAgent.java
new file mode 100644
index 0000000..e05cd68
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/log/agent/CapaLog4jAppenderAgent.java
@@ -0,0 +1,115 @@
+/*
+ * 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 group.rxcloud.capa.component.log.agent;
+
+import group.rxcloud.capa.infrastructure.CapaClassLoader;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+
+import java.io.Serializable;
+
+/**
+ * The abstract log4j appender. Extend this and provide your specific impl.
+ */
+@Plugin(name = "CapaLog4jAppender", elementType = Appender.ELEMENT_TYPE, category = "Core")
+public class CapaLog4jAppenderAgent extends AbstractAppender {
+
+ /**
+ * The log component type.
+ */
+ private static final String LOG_COMPONENT_TYPE = "log";
+ /**
+ * Capa log4j appender instance.
+ */
+ private static final CapaLog4jAppender logAppender;
+
+ /**
+ * Init the logbackAppender impl.
+ */
+ static {
+ logAppender = buildCapaLog4jAppender();
+ }
+
+ /**
+ * Instantiates a new Capa log4j appender.
+ *
+ * @param name The name of the appender.
+ * @param filter The filter of the appender.
+ * @param layout The layout of the appender.
+ * @param ignoreExceptions Whether to ignore exceptions.
+ */
+ public CapaLog4jAppenderAgent(String name,
+ Filter filter,
+ Layout extends Serializable> layout,
+ boolean ignoreExceptions) {
+ super(name, filter, layout, ignoreExceptions);
+ }
+
+ /**
+ * Create a appender instance.
+ *
+ * @param name The name of the appender.
+ * @param filter The filter of the appender.
+ * @param layout The layout of the appender.
+ * @param ignoreExceptions Whether to ignore exceptions.
+ * @return CapaLog4jAppender instance.
+ */
+ @PluginFactory
+ public static CapaLog4jAppenderAgent createAppender(@PluginAttribute("name") String name,
+ @PluginElement("Filter") final Filter filter,
+ @PluginElement("Layout") Layout extends Serializable> layout,
+ @PluginAttribute("ignoreExceptions") boolean ignoreExceptions) {
+ return new CapaLog4jAppenderAgent(name, filter, layout, ignoreExceptions);
+ }
+
+ /**
+ * Build a appender instance.
+ *
+ * @return CapaLog4jAppender instance.
+ */
+ public static CapaLog4jAppender buildCapaLog4jAppender() {
+ // load spi capa Log4j appender impl
+ return CapaClassLoader.loadComponentClassObj(
+ LOG_COMPONENT_TYPE,
+ CapaLog4jAppender.class);
+ }
+
+ @Override
+ public void append(LogEvent event) {
+ logAppender.appendLog(event);
+ }
+
+ /**
+ * The abstract api of the log4j appender impl.Implement this and provide your specific impl.
+ */
+ public interface CapaLog4jAppender {
+
+ /**
+ * Deal with the log.
+ *
+ * @param event The log event.
+ */
+ void appendLog(LogEvent event);
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/log/agent/CapaLogbackAppenderAgent.java b/sdk-component/src/main/java/group/rxcloud/capa/component/log/agent/CapaLogbackAppenderAgent.java
new file mode 100644
index 0000000..c4c0d54
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/log/agent/CapaLogbackAppenderAgent.java
@@ -0,0 +1,77 @@
+/*
+ * 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 group.rxcloud.capa.component.log.agent;
+
+import ch.qos.logback.core.UnsynchronizedAppenderBase;
+import group.rxcloud.capa.infrastructure.CapaClassLoader;
+
+/**
+ * The agent of the logback impl.
+ */
+public class CapaLogbackAppenderAgent extends UnsynchronizedAppenderBase {
+
+ /**
+ * The log component type.
+ */
+ private static final String LOG_COMPONENT_TYPE = "log";
+ /**
+ * Capa logback appender instance.
+ */
+ private static final CapaLogbackAppender logbackAppender;
+
+ /**
+ * Init the logbackAppender impl.
+ */
+ static {
+ logbackAppender = buildCapaLogbackAppender();
+ }
+
+ /**
+ * Build the logback appender impl.
+ *
+ * @return CapaLogbackAppender instance.
+ */
+ public static CapaLogbackAppender buildCapaLogbackAppender() {
+ // load spi capa logback appender impl
+ return CapaClassLoader.loadComponentClassObj(
+ LOG_COMPONENT_TYPE,
+ CapaLogbackAppender.class);
+ }
+
+ /**
+ * Deal with the log.
+ *
+ * @param event The log event.
+ */
+ @Override
+ protected void append(EVENT event) {
+ logbackAppender.appendLog(event);
+ }
+
+ /**
+ * The abstract api of the logback appender impl.Implement this and provide your specific impl.
+ */
+ public interface CapaLogbackAppender {
+
+ /**
+ * Deal with the log.
+ *
+ * @param event The log event.
+ */
+ void appendLog(EVENT event);
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSub.java b/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSub.java
index fb86728..4ed01fd 100644
--- a/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSub.java
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSub.java
@@ -38,6 +38,8 @@ public abstract class CapaPubSub implements AutoCloseable {
/**
* Gets pubsub name.
+ *
+ * @return pubsubName
*/
public String getPubSubName() {
return this.pubsubName;
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSubBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSubBuilder.java
index 4f4e8cf..3ed6f04 100644
--- a/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSubBuilder.java
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/pubsub/CapaPubSubBuilder.java
@@ -52,6 +52,7 @@ public CapaPubSub build() {
* @return Instance of {@link CapaPubSub} implementor
*/
private CapaPubSub buildCapaPubSub() {
+ // TODO: 2021/11/30 build multi component
return CapaClassLoader.loadComponentClassObj("pubsub", CapaPubSub.class);
}
}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/SamplerConfig.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/SamplerConfig.java
new file mode 100644
index 0000000..702962e
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/SamplerConfig.java
@@ -0,0 +1,81 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry;
+
+import group.rxcloud.capa.infrastructure.utils.SpiUtils;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+/**
+ * Sampler config.
+ */
+public class SamplerConfig implements Serializable {
+
+ public static final String FILE_PATH = "/capa-sample.properties";
+
+ /**
+ * Sample all data as default.
+ */
+ public static final transient SamplerConfig DEFAULT_CONFIG = new SamplerConfig();
+
+ private static final long serialVersionUID = -2113523925814197551L;
+
+ private boolean metricsSample = true;
+
+ private boolean traceSample = true;
+
+ private boolean logSample = true;
+
+ public boolean isMetricsSample() {
+ return metricsSample;
+ }
+
+ public void setMetricsSample(boolean metricsSample) {
+ this.metricsSample = metricsSample;
+ }
+
+ public boolean isTraceSample() {
+ return traceSample;
+ }
+
+ public void setTraceSample(boolean traceSample) {
+ this.traceSample = traceSample;
+ }
+
+ public boolean isLogSample() {
+ return logSample;
+ }
+
+ public void setLogSample(boolean logSample) {
+ this.logSample = logSample;
+ }
+
+ public static SamplerConfig loadOrDefault() {
+ Properties properties = SpiUtils.loadPropertiesNullable(FILE_PATH);
+ if (properties == null) {
+ return DEFAULT_CONFIG;
+ }
+
+ SamplerConfig result = new SamplerConfig();
+ result.setMetricsSample(Boolean.valueOf(properties.getProperty("metricsSample", Boolean.TRUE.toString())));
+ result.setTraceSample(Boolean.valueOf(properties.getProperty("traceSample", Boolean.TRUE.toString())));
+ result.setLogSample(Boolean.valueOf(properties.getProperty("logSample", Boolean.TRUE.toString())));
+
+ return result;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContext.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContext.java
new file mode 100644
index 0000000..a00c310
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContext.java
@@ -0,0 +1,67 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import group.rxcloud.capa.infrastructure.utils.SpiUtils;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Method for async context.
+ */
+public final class CapaContext {
+
+ private static final CapaContextAsyncWrapper WRAPPER = getAsyncWrapper();
+
+ private CapaContext() {
+ }
+
+ public static Runnable taskWrapping(Runnable runnable) {
+ return WRAPPER.wrap(runnable);
+ }
+
+ public static Callable taskWrapping(Callable callable) {
+ return WRAPPER.wrap(callable);
+ }
+
+ public static Executor taskWrapping(Executor executor) {
+ return WRAPPER.wrap(executor);
+ }
+
+ public static ExecutorService taskWrapping(ExecutorService executor) {
+ return WRAPPER.wrap(executor);
+ }
+
+ public static ScheduledExecutorService taskWrapping(ScheduledExecutorService executor) {
+ return WRAPPER.wrap(executor);
+ }
+
+ public static String getTraceId() {
+ return WRAPPER.getTraceId();
+ }
+
+ private static CapaContextAsyncWrapper getAsyncWrapper() {
+ CapaContextAsyncWrapper WRAPPER = SpiUtils.loadFromSpiComponentFileNullable(CapaContextAsyncWrapper.class, "telemetry");
+ if (WRAPPER == null) {
+ return new CapaContextAsyncWrapper() {};
+ }
+ return WRAPPER;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextAsyncWrapper.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextAsyncWrapper.java
new file mode 100644
index 0000000..94fc790
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextAsyncWrapper.java
@@ -0,0 +1,54 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Context;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ */
+public interface CapaContextAsyncWrapper {
+
+ default Runnable wrap(Runnable runnable) {
+ return Context.current().wrap(runnable);
+ }
+
+ default Callable wrap(Callable callable) {
+ return Context.current().wrap(callable);
+ }
+
+ default Executor wrap(Executor executor) {
+ return Context.current().wrap(executor);
+ }
+
+ default ExecutorService wrap(ExecutorService executor) {
+ return Context.current().wrap(executor);
+ }
+
+ default ScheduledExecutorService wrap(ScheduledExecutorService executor) {
+ return Context.current().wrap(executor);
+ }
+
+ default String getTraceId() {
+ return Span.fromContext(Context.current()).getSpanContext().getTraceId();
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorBuilder.java
new file mode 100644
index 0000000..0f19fc0
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorBuilder.java
@@ -0,0 +1,93 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import group.rxcloud.capa.infrastructure.utils.SpiUtils;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import io.opentelemetry.context.propagation.TextMapPropagator;
+
+import javax.annotation.concurrent.NotThreadSafe;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builder for capa context propagator.
+ */
+@NotThreadSafe
+public class CapaContextPropagatorBuilder implements CapaContextPropagatorSettings {
+
+ /**
+ * Context config.
+ */
+ private ContextConfig contextConfig;
+
+ /**
+ * Context propagator instances.
+ */
+ private List contextPropagatorsInstance;
+
+ @Override
+ public CapaContextPropagatorBuilder setContextConfig(ContextConfig config) {
+ contextConfig = config;
+ return this;
+ }
+
+ @Override
+ public CapaContextPropagatorBuilder addContextPropagators(TextMapPropagator processor) {
+ if (contextPropagatorsInstance == null) {
+ contextPropagatorsInstance = new ArrayList<>();
+ }
+ contextPropagatorsInstance.add(processor);
+ return this;
+ }
+
+ /**
+ * Build context propagators.
+ *
+ * @return context propagators.
+ */
+ public ContextPropagators buildContextPropagators() {
+ if (contextPropagatorsInstance != null && !contextPropagatorsInstance.isEmpty()) {
+ return ContextPropagators
+ .create(TextMapPropagator.composite(contextPropagatorsInstance.toArray(new TextMapPropagator[0])));
+ }
+
+ initContextConfig();
+ if (contextConfig != null) {
+ List types = contextConfig.getContextPropagators();
+ if (types != null && !types.isEmpty()) {
+ return ContextPropagators
+ .create(TextMapPropagator.composite(types.stream()
+ .map(path -> SpiUtils
+ .newInstanceWithConstructorCache(path, TextMapPropagator.class))
+ .toArray(TextMapPropagator[]::new)));
+ }
+ }
+
+ ContextPropagatorLoader loader = SpiUtils.loadFromSpiComponentFileNullable(ContextPropagatorLoader.class, "telemetry");
+ if (loader == null) {
+ loader = ContextPropagatorLoader.DEFAULT;
+ }
+ return loader.load();
+ }
+
+ private void initContextConfig() {
+ if (contextConfig == null) {
+ contextConfig = SpiUtils.loadConfigNullable(FILE_PATH, ContextConfig.class);;
+ }
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorSettings.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorSettings.java
new file mode 100644
index 0000000..bba38ab
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorSettings.java
@@ -0,0 +1,44 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import io.opentelemetry.context.propagation.TextMapPropagator;
+
+/**
+ * Settings for capa context propagator.
+ */
+public interface CapaContextPropagatorSettings {
+
+ // FIXME: 2021/11/28 change to capa-component-telemetry-context.json
+ String FILE_PATH = "/capa-context.json";
+
+ /**
+ * Replace the whole context config.
+ *
+ * @param config context config
+ * @return current settings.
+ */
+ CapaContextPropagatorSettings setContextConfig(ContextConfig config);
+
+ /**
+ * Add one more processor to current context config.
+ *
+ * @param processor processor config
+ * @return current settings.
+ */
+ CapaContextPropagatorSettings addContextPropagators(TextMapPropagator processor);
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/ContextConfig.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/ContextConfig.java
new file mode 100644
index 0000000..5b17317
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/ContextConfig.java
@@ -0,0 +1,38 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Config for context propagators.
+ */
+public class ContextConfig implements Serializable {
+
+ private static final long serialVersionUID = 6587103489345563395L;
+
+ private List contextPropagators;
+
+ public List getContextPropagators() {
+ return contextPropagators;
+ }
+
+ public void setContextPropagators(List contextPropagators) {
+ this.contextPropagators = contextPropagators;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/ContextPropagatorLoader.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/ContextPropagatorLoader.java
new file mode 100644
index 0000000..dff7460
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/context/ContextPropagatorLoader.java
@@ -0,0 +1,37 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import io.opentelemetry.context.propagation.ContextPropagators;
+
+/**
+ * Load default context propagator.
+ */
+public interface ContextPropagatorLoader {
+
+ ContextPropagatorLoader DEFAULT = new ContextPropagatorLoader() {
+ };
+
+ /**
+ * Load default context propagator.
+ *
+ * @return default context propagator.
+ */
+ default ContextPropagators load() {
+ return ContextPropagators.noop();
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMeterProviderBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMeterProviderBuilder.java
new file mode 100644
index 0000000..044eb92
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMeterProviderBuilder.java
@@ -0,0 +1,158 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.metrics;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import group.rxcloud.capa.infrastructure.utils.SpiUtils;
+import io.opentelemetry.api.metrics.MeterProvider;
+import io.opentelemetry.sdk.metrics.SdkMeterProvider;
+import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
+import io.opentelemetry.sdk.metrics.export.MetricExporter;
+import io.opentelemetry.sdk.metrics.export.MetricReaderFactory;
+import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
+import org.jetbrains.annotations.NotNull;
+
+import javax.annotation.concurrent.NotThreadSafe;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Builder for capa metric provider.
+ */
+@NotThreadSafe
+public class CapaMeterProviderBuilder implements CapaMeterProviderSettings {
+
+ /**
+ * Config for capa metric provider.
+ */
+ private MeterConfig meterConfigs;
+
+ /**
+ * Sampler config.
+ */
+ private SamplerConfig samplerConfig;
+
+ /**
+ * Readers manually set.
+ */
+ private List metricsReaderConfigs;
+
+ /**
+ * Build the reader factories with reader configs.
+ * Each factory defined the export interval and exporter of the reader it will generate.
+ *
+ * @param readerConfigs metrics reader configs.
+ * @return metrics reader factories.
+ */
+ private static List bulidReaderFactories(List readerConfigs) {
+ List factories = new ArrayList<>();
+ for (MetricsReaderConfig config : readerConfigs) {
+ MetricExporter exporter = SpiUtils
+ .newInstanceWithConstructorCache(config.getExporterType(), MetricExporter.class);
+ if (exporter == null) {
+ throw new IllegalArgumentException(
+ "Metric Exporter is not configured. readerName = " + config.getName() + '.');
+ }
+
+ ScheduledThreadPoolExecutor worker = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
+ @Override
+ public Thread newThread(@NotNull Runnable r) {
+ Thread thread = new Thread(r);
+ thread.setDaemon(true);
+ thread.setName("capa-metric-reader-" + config.getName() + '-' + System
+ .currentTimeMillis());
+ return thread;
+ }
+ });
+
+ factories.add(PeriodicMetricReader.builder(exporter)
+ .setInterval(config.getExportIntervalMillis(), TimeUnit.MILLISECONDS)
+ .setExecutor(worker)
+ .newMetricReaderFactory());
+ }
+ return factories;
+ }
+
+ @Override
+ public CapaMeterProviderBuilder setSamplerConfig(SamplerConfig samplerConfig) {
+ this.samplerConfig = samplerConfig;
+ return this;
+ }
+
+ @Override
+ public CapaMeterProviderBuilder setMeterConfig(MeterConfig config) {
+ meterConfigs = config;
+ return this;
+ }
+
+ @Override
+ public CapaMeterProviderBuilder addMetricReaderConfig(MetricsReaderConfig config) {
+ if (metricsReaderConfigs == null) {
+ metricsReaderConfigs = new ArrayList<>();
+ }
+ metricsReaderConfigs.add(config);
+ return this;
+ }
+
+ /**
+ * Build the meter provider with the config.
+ * In the following cases, a noop implementation will be returned and no new thread will be started.
+ * 1. No metrics reader was defined.
+ *
+ * @return the meter provider.
+ */
+ public MeterProvider buildMeterProvider() {
+ List metricsReaderConfigs = this.metricsReaderConfigs;
+ if (metricsReaderConfigs == null || metricsReaderConfigs.isEmpty()) {
+ // if config was not explicitly set, try loading the config from the config loader.
+ initMeterConfig();
+
+ if (meterConfigs != null) {
+ metricsReaderConfigs = meterConfigs.getReaders();
+ }
+ }
+
+ if (metricsReaderConfigs == null || metricsReaderConfigs.isEmpty()) {
+ return MeterProvider.noop();
+ }
+
+ List factories = bulidReaderFactories(metricsReaderConfigs);
+
+ initSampleConfig();
+
+ SdkMeterProviderBuilder builder = SdkMeterProvider.builder()
+ .setExemplarFilter(CapaMetricsSampler.getInstance()
+ .update(samplerConfig));
+ factories.forEach(f -> builder.registerMetricReader(f));
+ return builder.build();
+ }
+
+ private void initMeterConfig() {
+ if (meterConfigs == null) {
+ meterConfigs = SpiUtils.loadConfigNullable(FILE_PATH, MeterConfig.class);
+ }
+ }
+
+ private void initSampleConfig() {
+ if (samplerConfig == null) {
+ samplerConfig = SamplerConfig.loadOrDefault();
+ }
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMeterProviderSettings.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMeterProviderSettings.java
new file mode 100644
index 0000000..01967a6
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMeterProviderSettings.java
@@ -0,0 +1,52 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.metrics;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+
+/**
+ * Settings for capa meter provider.
+ */
+public interface CapaMeterProviderSettings {
+
+ // FIXME: 2021/11/28 change to capa-component-telemetry-meter.json
+ String FILE_PATH ="/capa-meter.json";
+
+ /**
+ * Replace the whole config for the meter.
+ *
+ * @param config meter config.
+ * @return current settings.
+ */
+ CapaMeterProviderSettings setMeterConfig(MeterConfig config);
+
+ /**
+ * Add one more reader to current meter config.
+ *
+ * @param config metrics reader config.
+ * @return current settings.
+ */
+ CapaMeterProviderSettings addMetricReaderConfig(MetricsReaderConfig config);
+
+ /**
+ * Set sample config.
+ *
+ * @param samplerConfig sample config.
+ * @return current settings.
+ */
+ CapaMeterProviderSettings setSamplerConfig(SamplerConfig samplerConfig);
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMetricsSampler.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMetricsSampler.java
new file mode 100644
index 0000000..049a7a0
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/CapaMetricsSampler.java
@@ -0,0 +1,81 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.metrics;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.sdk.metrics.exemplar.ExemplarFilter;
+
+/**
+ * Sampler for metrics data.
+ * Choose to sample all or none data according to the config file.
+ */
+public class CapaMetricsSampler implements ExemplarFilter {
+
+ /**
+ * Sampler instance, which samples all the data if no config was explicitly set.
+ */
+ private static final CapaMetricsSampler INSTANCE = new CapaMetricsSampler(SamplerConfig.DEFAULT_CONFIG);
+
+ /**
+ * Inner instance.
+ */
+ private ExemplarFilter inner;
+
+ /**
+ * Get the sampler instance.
+ *
+ * @return the sampler instance.
+ */
+ public static CapaMetricsSampler getInstance() {
+ return INSTANCE;
+ }
+
+ private CapaMetricsSampler(SamplerConfig config) {
+ update(config);
+ }
+
+ /**
+ * Update the sample policy.
+ *
+ * @param config new sample config.
+ * @return the updated sampler instance.
+ */
+ public CapaMetricsSampler update(SamplerConfig config) {
+ if (config == null) {
+ return this;
+ }
+
+ if (config.isMetricsSample()) {
+ inner = ExemplarFilter.alwaysSample();
+ } else {
+ inner = ExemplarFilter.neverSample();
+ }
+ return this;
+ }
+
+ @Override
+ public boolean shouldSampleMeasurement(long value, Attributes attributes, Context context) {
+ return inner.shouldSampleMeasurement(value, attributes, context);
+ }
+
+ @Override
+ public boolean shouldSampleMeasurement(double value, Attributes attributes, Context context) {
+ return inner.shouldSampleMeasurement(value, attributes, context);
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/MeterConfig.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/MeterConfig.java
new file mode 100644
index 0000000..aa91b1f
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/MeterConfig.java
@@ -0,0 +1,43 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.metrics;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Config for meters.
+ */
+public class MeterConfig implements Serializable {
+
+ private static final long serialVersionUID = 7090415828392034412L;
+
+ /**
+ * Configs for metrics readers.
+ * Each reader related with a scheduled thread.
+ */
+ private List readers = Collections.emptyList();
+
+ public List getReaders() {
+ return readers;
+ }
+
+ public void setReaders(List readers) {
+ this.readers = readers;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/MetricsReaderConfig.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/MetricsReaderConfig.java
new file mode 100644
index 0000000..aff868b
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/metrics/MetricsReaderConfig.java
@@ -0,0 +1,73 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.metrics;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Config for metrics reader.
+ * Control the export interval and target exporter.
+ */
+public class MetricsReaderConfig implements Serializable {
+
+ private static final long serialVersionUID = 5186270483151262376L;
+
+ /**
+ * Reader name, used to find the related reader thread.
+ */
+ private String name = "_DEFAULT_METRIC_READER";
+
+ /**
+ * Exporter interval.
+ * default 1min.
+ */
+ private long exportIntervalMillis = TimeUnit.MINUTES.toMillis(1L);
+
+ /**
+ * Exporter class name. Must have a no-args constructor.
+ */
+ private String exporterType;
+
+ public String getExporterType() {
+ return exporterType;
+ }
+
+ public void setExporterType(String exporterType) {
+ this.exporterType = exporterType;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getExportIntervalMillis() {
+ return exportIntervalMillis;
+ }
+
+ public void setExportIntervalMillis(long exportIntervalMillis) {
+ this.exportIntervalMillis = exportIntervalMillis;
+ }
+
+ public void setExportInterval(long export, TimeUnit timeUnit) {
+ setExportIntervalMillis(timeUnit.toMillis(export));
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaReadWriteSpan.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaReadWriteSpan.java
new file mode 100644
index 0000000..5a9f137
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaReadWriteSpan.java
@@ -0,0 +1,160 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanContext;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
+import io.opentelemetry.sdk.trace.ReadWriteSpan;
+import io.opentelemetry.sdk.trace.data.SpanData;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Read write span proxy.
+ */
+public class CapaReadWriteSpan implements ReadWriteSpan {
+
+ protected final ReadWriteSpan span;
+
+ protected final String tracerName;
+
+ protected final String version;
+
+ protected final String schemaUrl;
+
+ public CapaReadWriteSpan(String tracerName, String version, String schemaUrl, ReadWriteSpan span) {
+ this.span = span;
+ this.tracerName = tracerName;
+ this.version = version;
+ this.schemaUrl = schemaUrl;
+ }
+
+ public String getTracerName() {
+ return tracerName == null ? getInstrumentationLibraryInfo().getName() : tracerName;
+ }
+
+ public String getVersion() {
+ return version == null ? getInstrumentationLibraryInfo().getVersion() : version;
+ }
+
+ public String getSchemaUrl() {
+ return schemaUrl == null ? getInstrumentationLibraryInfo().getSchemaUrl() : schemaUrl;
+ }
+
+ @Override
+ public Span setAttribute(AttributeKey key, T value) {
+ span.setAttribute(key, value);
+ return this;
+ }
+
+ @Override
+ public Span addEvent(String name, Attributes attributes) {
+ span.addEvent(name, attributes);
+ return this;
+ }
+
+ @Override
+ public Span addEvent(String name, Attributes attributes, long timestamp, TimeUnit unit) {
+ span.addEvent(name, attributes, timestamp, unit);
+ return this;
+ }
+
+ @Override
+ public Span setStatus(StatusCode statusCode, String description) {
+ span.setStatus(statusCode, description);
+ return this;
+ }
+
+ @Override
+ public Span recordException(Throwable exception, Attributes additionalAttributes) {
+ span.recordException(exception, additionalAttributes);
+ return this;
+ }
+
+ @Override
+ public Span updateName(String name) {
+ span.updateName(name);
+ return this;
+ }
+
+ @Override
+ public void end() {
+ span.end();
+ }
+
+ @Override
+ public void end(long timestamp, TimeUnit unit) {
+ span.end(timestamp, unit);
+ }
+
+ @Override
+ public SpanContext getSpanContext() {
+ return span.getSpanContext();
+ }
+
+ @Override
+ public SpanContext getParentSpanContext() {
+ return span.getParentSpanContext();
+ }
+
+ @Override
+ public String getName() {
+ return span.getName();
+ }
+
+ @Override
+ public SpanData toSpanData() {
+ return span.toSpanData();
+ }
+
+ @Override
+ public InstrumentationLibraryInfo getInstrumentationLibraryInfo() {
+ return span.getInstrumentationLibraryInfo();
+ }
+
+ @Override
+ public boolean hasEnded() {
+ return span.hasEnded();
+ }
+
+ @Override
+ public long getLatencyNanos() {
+ return span.getLatencyNanos();
+ }
+
+ @Override
+ public SpanKind getKind() {
+ return span.getKind();
+ }
+
+ @Nullable
+ @Override
+ public T getAttribute(AttributeKey key) {
+ return span.getAttribute(key);
+ }
+
+ @Override
+ public boolean isRecording() {
+ return span.isRecording();
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaSpanBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaSpanBuilder.java
new file mode 100644
index 0000000..2979570
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaSpanBuilder.java
@@ -0,0 +1,136 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanBuilder;
+import io.opentelemetry.api.trace.SpanContext;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.sdk.trace.ReadWriteSpan;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Span builder proxy.
+ */
+public class CapaSpanBuilder implements SpanBuilder {
+
+ protected final String tracerName;
+
+ protected String version;
+
+ protected String schemaUrl;
+
+ protected final String spanName;
+
+ protected final SpanBuilder spanBuilder;
+
+ public CapaSpanBuilder(String tracerName, String version, String schemaUrl, String spanName,
+ SpanBuilder spanBuilder) {
+ this.tracerName = tracerName;
+ this.version = version;
+ this.schemaUrl = schemaUrl;
+ this.spanName = spanName;
+ this.spanBuilder = spanBuilder;
+ }
+
+ public String getSchemaUrl() {
+ return schemaUrl;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ @Override
+ public SpanBuilder setParent(Context context) {
+ spanBuilder.setParent(context);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setNoParent() {
+ spanBuilder.setNoParent();
+ return this;
+ }
+
+ @Override
+ public SpanBuilder addLink(SpanContext spanContext) {
+ spanBuilder.addLink(spanContext);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder addLink(SpanContext spanContext, Attributes attributes) {
+ spanBuilder.addLink(spanContext, attributes);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setAttribute(String key, String value) {
+ spanBuilder.setAttribute(key, value);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setAttribute(String key, long value) {
+ spanBuilder.setAttribute(key, value);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setAttribute(String key, double value) {
+ spanBuilder.setAttribute(key, value);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setAttribute(String key, boolean value) {
+ spanBuilder.setAttribute(key, value);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setAttribute(AttributeKey key, T value) {
+ spanBuilder.setAttribute(key, value);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setSpanKind(SpanKind spanKind) {
+ spanBuilder.setSpanKind(spanKind);
+ return this;
+ }
+
+ @Override
+ public SpanBuilder setStartTimestamp(long startTimestamp, TimeUnit unit) {
+ spanBuilder.setStartTimestamp(startTimestamp, unit);
+ return this;
+ }
+
+ @Override
+ public Span startSpan() {
+ Span span = spanBuilder.startSpan();
+ if (span instanceof ReadWriteSpan) {
+ return CapaWrapper.wrap(tracerName, version, schemaUrl, (ReadWriteSpan) span);
+ }
+ return span;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTraceSampler.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTraceSampler.java
new file mode 100644
index 0000000..4c1873b
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTraceSampler.java
@@ -0,0 +1,70 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.sdk.trace.data.LinkData;
+import io.opentelemetry.sdk.trace.samplers.Sampler;
+import io.opentelemetry.sdk.trace.samplers.SamplingResult;
+
+import java.util.List;
+
+/**
+ * Sampler for trace data.
+ * Choose to sample all or none data according to the config file.
+ */
+public class CapaTraceSampler implements Sampler {
+
+ private static final CapaTraceSampler INSTANCE = new CapaTraceSampler(SamplerConfig.DEFAULT_CONFIG);
+
+ private Sampler inner;
+
+ public static CapaTraceSampler getInstance() {
+ return INSTANCE;
+ }
+
+ private CapaTraceSampler(SamplerConfig config) {
+ update(config);
+ }
+
+ public CapaTraceSampler update(SamplerConfig config) {
+ if (config == null) {
+ return this;
+ }
+
+ if (config.isTraceSample()) {
+ inner = Sampler.alwaysOn();
+ } else {
+ inner = Sampler.alwaysOff();
+ }
+ return this;
+ }
+
+ @Override
+ public SamplingResult shouldSample(Context context, String traceId, String name, SpanKind kind,
+ Attributes attributes, List list) {
+ return inner.shouldSample(context, traceId, name, kind, attributes, list);
+ }
+
+ @Override
+ public String getDescription() {
+ return "Always or never sample the telemetry data.";
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracer.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracer.java
new file mode 100644
index 0000000..15d0a6b
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracer.java
@@ -0,0 +1,52 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.trace.SpanBuilder;
+import io.opentelemetry.api.trace.Tracer;
+
+/**
+ * Tracer proxy.
+ */
+public class CapaTracer implements Tracer {
+
+ protected final String tracerName;
+ protected final String version;
+ protected final String schemaUrl;
+ protected final Tracer tracer;
+
+ public CapaTracer(String tracerName, String version, String schemaUrl, Tracer tracer) {
+ this.tracerName = tracerName;
+ this.version = version;
+ this.schemaUrl = schemaUrl;
+ this.tracer = tracer;
+ }
+
+ @Override
+ public SpanBuilder spanBuilder(String spanName) {
+ SpanBuilder builder = tracer.spanBuilder(spanName);
+ return CapaWrapper.wrap(tracerName, version, schemaUrl, spanName, builder);
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getSchemaUrl() {
+ return schemaUrl;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerBuilder.java
new file mode 100644
index 0000000..06708c6
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerBuilder.java
@@ -0,0 +1,58 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerBuilder;
+
+/**
+ * Tracer builder proxy.
+ */
+public class CapaTracerBuilder implements TracerBuilder {
+
+ protected final TracerBuilder tracerBuilder;
+
+ protected final String tracerName;
+
+ protected String version;
+
+ protected String schemaUrl;
+
+ public CapaTracerBuilder(String tracerName, TracerBuilder tracerBuilder) {
+ this.tracerName = tracerName;
+ this.tracerBuilder = tracerBuilder;
+ }
+
+ @Override
+ public TracerBuilder setSchemaUrl(String schemaUrl) {
+ tracerBuilder.setSchemaUrl(schemaUrl);
+ this.schemaUrl = schemaUrl;
+ return this;
+ }
+
+ @Override
+ public TracerBuilder setInstrumentationVersion(String instrumentationVersion) {
+ tracerBuilder.setInstrumentationVersion(instrumentationVersion);
+ this.version = instrumentationVersion;
+ return this;
+ }
+
+ @Override
+ public Tracer build() {
+ return CapaWrapper.wrap(tracerName, version, schemaUrl, tracerBuilder.build());
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProvider.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProvider.java
new file mode 100644
index 0000000..3b102ae
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerBuilder;
+import io.opentelemetry.api.trace.TracerProvider;
+
+/**
+ * Capa tracer provider proxy.
+ */
+public class CapaTracerProvider implements TracerProvider {
+
+ private final TracerProvider provider;
+
+ public CapaTracerProvider(TracerProvider provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public Tracer get(String instrumentationName) {
+ return tracerBuilder(instrumentationName).build();
+ }
+
+ @Override
+ public Tracer get(String instrumentationName, String instrumentationVersion) {
+ return tracerBuilder(instrumentationName).setInstrumentationVersion(instrumentationVersion).build();
+ }
+
+ @Override
+ public TracerBuilder tracerBuilder(String instrumentationName) {
+ TracerBuilder tracerBuilder = provider.tracerBuilder(instrumentationName);
+ return CapaWrapper.wrap(instrumentationName, tracerBuilder);
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProviderBuilder.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProviderBuilder.java
new file mode 100644
index 0000000..60f1bba
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProviderBuilder.java
@@ -0,0 +1,237 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import group.rxcloud.capa.infrastructure.exceptions.CapaErrorContext;
+import group.rxcloud.capa.infrastructure.exceptions.CapaException;
+import group.rxcloud.capa.infrastructure.utils.SpiUtils;
+import io.opentelemetry.api.trace.TracerProvider;
+import io.opentelemetry.sdk.trace.IdGenerator;
+import io.opentelemetry.sdk.trace.SdkTracerProvider;
+import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
+import io.opentelemetry.sdk.trace.SpanLimits;
+import io.opentelemetry.sdk.trace.SpanLimitsBuilder;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+import io.opentelemetry.sdk.trace.samplers.Sampler;
+
+import javax.annotation.concurrent.NotThreadSafe;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builder for capa tracer provider.
+ */
+@NotThreadSafe
+public class CapaTracerProviderBuilder implements CapaTracerProviderSettings {
+
+ /**
+ * Config for capa tracer provider.
+ */
+ private TracerConfig tracerConfig;
+
+ /**
+ * Id generator instance.
+ */
+ private IdGenerator idGenerator;
+
+ /**
+ * Span processor instances.
+ */
+ private List processors;
+
+ /**
+ * Span limits.
+ */
+ private SpanLimitsConfig spanLimitsConfig;
+
+ /**
+ * Sampler config.
+ */
+ private SamplerConfig samplerConfig;
+
+ private static boolean addSpanLimits(SpanLimitsConfig spanLimits, SpanLimitsBuilder limits) {
+ if (spanLimits == null) {
+ return false;
+ }
+ boolean added = false;
+ if (spanLimits.getMaxAttributeValueLength() != null) {
+ limits.setMaxAttributeValueLength(spanLimits.getMaxAttributeValueLength());
+ added = true;
+ }
+ if (spanLimits.getMaxNumAttributes() != null) {
+ limits.setMaxNumberOfAttributes(spanLimits.getMaxNumAttributes());
+ added = true;
+ }
+ if (spanLimits.getMaxNumEvents() != null) {
+ limits.setMaxNumberOfEvents(spanLimits.getMaxNumEvents());
+ added = true;
+ }
+ if (spanLimits.getMaxNumLinks() != null) {
+ limits.setMaxNumberOfLinks(spanLimits.getMaxNumLinks());
+ added = true;
+ }
+ if (spanLimits.getMaxNumAttributesPerLink() != null) {
+ limits.setMaxNumberOfAttributesPerLink(spanLimits.getMaxNumAttributesPerLink());
+ added = true;
+ }
+ if (spanLimits.getMaxNumAttributesPerEvent() != null) {
+ limits.setMaxNumberOfAttributesPerEvent(spanLimits.getMaxNumAttributesPerEvent());
+ added = true;
+ }
+ return added;
+ }
+
+ private static void skipIdValidate(SdkTracerProvider provider) {
+ try {
+ Field fieldTracerSharedState = SdkTracerProvider.class.getDeclaredField("sharedState");
+ fieldTracerSharedState.setAccessible(true);
+ Object sharedStatus = fieldTracerSharedState.get(provider);
+ Class sharedStatusType = sharedStatus.getClass();
+ Field fieldFlag = sharedStatusType.getDeclaredField("idGeneratorSafeToSkipIdValidation");
+ fieldFlag.setAccessible(true);
+ fieldFlag.set(sharedStatus, true);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new CapaException(CapaErrorContext.SYSTEM_ERROR, "Fail to skip id validation.", e);
+ }
+ }
+
+ @Override
+ public CapaTracerProviderBuilder setSamplerConfig(SamplerConfig samplerConfig) {
+ this.samplerConfig = samplerConfig;
+ return this;
+ }
+
+ @Override
+ public CapaTracerProviderBuilder setTracerConfig(TracerConfig tracerConfig) {
+ this.tracerConfig = tracerConfig;
+ return this;
+ }
+
+ @Override
+ public CapaTracerProviderBuilder setSpanLimits(SpanLimitsConfig spanLimits) {
+ spanLimitsConfig = spanLimits;
+ return this;
+ }
+
+ @Override
+ public CapaTracerProviderBuilder setIdGenerator(IdGenerator idGenerator) {
+ this.idGenerator = idGenerator;
+ return this;
+ }
+
+ @Override
+ public CapaTracerProviderBuilder addProcessor(SpanProcessor processor) {
+ if (processors == null) {
+ processors = new ArrayList<>();
+ }
+ processors.add(processor);
+ return this;
+ }
+
+ private void initTracerConfig() {
+ if (tracerConfig == null) {
+ tracerConfig = SpiUtils.loadConfigNullable(CapaTracerProviderSettings.FILE_PATH, TracerConfig.class);
+ }
+ }
+
+ /**
+ * Build the tracer provider with the config.
+ * In the following cases, a noop implementation will be returned.
+ * 1. No processor config was defined.
+ *
+ * @return the meter provider.
+ */
+ public CapaTracerProvider buildTracerProvider() {
+ // if config was not explicitly set, try loading the config from the config loader.
+ initTracerConfig();
+
+ if ((processors == null || processors.isEmpty()) && (tracerConfig == null
+ || tracerConfig.getProcessors() == null
+ || tracerConfig.getProcessors().isEmpty())) {
+ return new CapaTracerProvider(TracerProvider.noop());
+ }
+
+ SdkTracerProviderBuilder builder = SdkTracerProvider.builder();
+ addSpanLimits(builder);
+ addIdGenerator(builder);
+ addSampler(builder);
+ addProcessors(builder);
+
+ SdkTracerProvider provider = builder.build();
+
+ if (tracerConfig != null && !tracerConfig.isEnableIdValidate()) {
+ skipIdValidate(provider);
+ }
+
+ return new CapaTracerProvider(provider);
+ }
+
+ private void addIdGenerator(SdkTracerProviderBuilder builder) {
+ if (idGenerator != null) {
+ builder.setIdGenerator(idGenerator);
+ } else if (tracerConfig != null) {
+ IdGenerator generator = SpiUtils
+ .newInstanceWithConstructorCache(tracerConfig.getIdGenerator(), IdGenerator.class);
+ if (generator != null) {
+ builder.setIdGenerator(generator);
+ }
+ }
+ }
+
+ private void addSpanLimits(SdkTracerProviderBuilder builder) {
+ SpanLimitsBuilder limits = SpanLimits.builder();
+ boolean added = false;
+ if (tracerConfig != null && tracerConfig.getSpanLimits() != null) {
+ added |= addSpanLimits(tracerConfig.getSpanLimits(), limits);
+ }
+ if (spanLimitsConfig != null) {
+ added |= addSpanLimits(spanLimitsConfig, limits);
+ }
+
+ if (added) {
+ builder.setSpanLimits(limits.build());
+ }
+ }
+
+ private void addSampler(SdkTracerProviderBuilder builder) {
+ initSampleConfig();
+ builder.setSampler(Sampler.parentBased(CapaTraceSampler.getInstance().update(samplerConfig)));
+ }
+
+ private void initSampleConfig() {
+ if (samplerConfig == null) {
+ samplerConfig = SamplerConfig.loadOrDefault();
+ }
+ }
+
+ private void addProcessors(SdkTracerProviderBuilder builder) {
+ List processors = this.processors;
+ if (processors != null && !processors.isEmpty()) {
+ processors.forEach(p -> builder.addSpanProcessor(p));
+ } else if (tracerConfig != null && tracerConfig.getProcessors() != null) {
+ tracerConfig.getProcessors().forEach(p -> {
+ SpanProcessor processor = SpiUtils.newInstanceWithConstructorCache(p, SpanProcessor.class);
+ if (processor != null) {
+ builder.addSpanProcessor(processor);
+ }
+ });
+ }
+ }
+}
+
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProviderSettings.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProviderSettings.java
new file mode 100644
index 0000000..f1ac0da
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaTracerProviderSettings.java
@@ -0,0 +1,71 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import io.opentelemetry.sdk.trace.IdGenerator;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+
+/**
+ * Settings for capa trace provider.
+ */
+public interface CapaTracerProviderSettings {
+
+ // FIXME: 2021/11/28 change to capa-component-telemetry-tracer.json
+ String FILE_PATH = "/capa-tracer.json";
+
+ /**
+ * Replace the whole config for the meter.
+ *
+ * @param tracerConfig tracer config
+ * @return current settings.
+ */
+ CapaTracerProviderSettings setTracerConfig(TracerConfig tracerConfig);
+
+ /**
+ * Set the span limits.
+ *
+ * @param spanLimits span limits config.
+ * @return current settings.
+ */
+ CapaTracerProviderSettings setSpanLimits(SpanLimitsConfig spanLimits);
+
+ /**
+ * Set the trace/span id generator.
+ *
+ * @param idGenerator trace/span id generator.
+ * @return current settings.
+ */
+ CapaTracerProviderSettings setIdGenerator(IdGenerator idGenerator);
+
+ /**
+ * Add one more span processor to current meter config.
+ *
+ * @param processor span processor.
+ * @return current settings.
+ */
+ CapaTracerProviderSettings addProcessor(SpanProcessor processor);
+
+ /**
+ * Set sample config.
+ *
+ * @param samplerConfig sample config.
+ * @return current settings.
+ */
+ CapaTracerProviderSettings setSamplerConfig(SamplerConfig samplerConfig);
+
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaWrapper.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaWrapper.java
new file mode 100644
index 0000000..fec1d7c
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/CapaWrapper.java
@@ -0,0 +1,94 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import group.rxcloud.capa.infrastructure.utils.SpiUtils;
+import io.opentelemetry.api.trace.SpanBuilder;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerBuilder;
+import io.opentelemetry.sdk.trace.ReadWriteSpan;
+
+import javax.annotation.Nullable;
+
+/**
+ * Load capa implementation.
+ */
+final class CapaWrapper {
+
+ static final String FILE_SUFFIX = "telemetry";
+
+ static final boolean CACHE = true;
+
+ private CapaWrapper() {
+ }
+
+ @Nullable
+ static CapaSpanBuilder wrap(String tracerName, String version, String schemaUrl, String spanName, SpanBuilder builder) {
+ if (builder instanceof CapaSpanBuilder) {
+ return (CapaSpanBuilder) builder;
+ }
+ CapaSpanBuilder result = SpiUtils
+ .loadFromSpiComponentFileNullable(CapaSpanBuilder.class, new Class[]{String.class, String.class, String.class, String.class, SpanBuilder.class},
+ new Object[]{tracerName, version, schemaUrl, spanName, builder}, FILE_SUFFIX, CACHE);
+ if (result == null) {
+ result = new CapaSpanBuilder(tracerName, version, schemaUrl, spanName, builder);
+ }
+ return result;
+ }
+
+ @Nullable
+ static CapaReadWriteSpan wrap(String tracerName, String version, String schemaUrl, ReadWriteSpan span) {
+ if (span instanceof CapaReadWriteSpan) {
+ return (CapaReadWriteSpan) span;
+ }
+ CapaReadWriteSpan result = SpiUtils
+ .loadFromSpiComponentFileNullable(CapaReadWriteSpan.class, new Class[]{String.class, String.class, String.class, ReadWriteSpan.class}, new Object[]{tracerName, version, schemaUrl, span},
+ FILE_SUFFIX, CACHE);
+ if (result == null) {
+ result = new CapaReadWriteSpan(tracerName, version, schemaUrl, span);
+ }
+ return result;
+ }
+
+ @Nullable
+ static CapaTracer wrap(String tracerName, String version, String schemaUrl, Tracer tracer) {
+ if (tracer instanceof CapaTracer) {
+ return (CapaTracer) tracer;
+ }
+ CapaTracer result = SpiUtils.loadFromSpiComponentFileNullable(CapaTracer.class, new Class[]{String.class, String.class, String.class, Tracer.class},
+ new Object[]{tracerName, version, schemaUrl, tracer}, FILE_SUFFIX, CACHE);
+ if (result == null) {
+ result = new CapaTracer(tracerName, version, schemaUrl, tracer);
+ }
+ return result;
+ }
+
+ @Nullable
+ static CapaTracerBuilder wrap(String tracerName, TracerBuilder tracerBuilder) {
+ if (tracerBuilder instanceof CapaTracerBuilder) {
+ return (CapaTracerBuilder) tracerBuilder;
+ }
+ CapaTracerBuilder result = SpiUtils
+ .loadFromSpiComponentFileNullable(CapaTracerBuilder.class, new Class[]{String.class, TracerBuilder.class},
+ new Object[]{tracerName, tracerBuilder}, FILE_SUFFIX, CACHE);
+ if (result == null) {
+ result = new CapaTracerBuilder(tracerName, tracerBuilder);
+ }
+ return result;
+ }
+
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/EventAttributeKey.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/EventAttributeKey.java
new file mode 100644
index 0000000..057896a
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/EventAttributeKey.java
@@ -0,0 +1,63 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.AttributeType;
+
+
+/**
+ * Attribute key for event params.
+ */
+public final class EventAttributeKey implements AttributeKey {
+
+ public static EventAttributeKey SIZE = new EventAttributeKey(AttributeKey.longKey("_capa_event_size"));
+
+ public static EventAttributeKey COUNT = new EventAttributeKey(AttributeKey.longKey("_capa_event_count"));
+
+ public static EventAttributeKey FAIL = new EventAttributeKey(AttributeKey.longKey("_capa_event_fail"));
+
+ private final AttributeKey key;
+
+ private EventAttributeKey(AttributeKey key) {
+ this.key = key;
+ }
+
+ public Integer getNum(Object value) {
+ if (!(value instanceof Long)) {
+ return null;
+ }
+
+ Long l = (Long) value;
+ // overflow
+ if (l.compareTo((long)Integer.MAX_VALUE) > 0 || l.compareTo((long)Integer.MIN_VALUE) < 0 ) {
+ return null;
+ }
+
+ return ((Long) value).intValue();
+ }
+
+ @Override
+ public String getKey() {
+ return key.getKey();
+ }
+
+ @Override
+ public AttributeType getType() {
+ return key.getType();
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/SpanLimitsConfig.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/SpanLimitsConfig.java
new file mode 100644
index 0000000..5f3c010
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/SpanLimitsConfig.java
@@ -0,0 +1,87 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import java.io.Serializable;
+
+/**
+ * Span limits.
+ */
+public class SpanLimitsConfig implements Serializable {
+
+ private static final long serialVersionUID = 6918786580143929155L;
+
+ private Integer maxNumAttributes;
+
+ private Integer maxNumEvents;
+
+ private Integer maxNumLinks;
+
+ private Integer maxNumAttributesPerEvent;
+
+ private Integer maxNumAttributesPerLink;
+
+ private Integer maxAttributeValueLength;
+
+ public Integer getMaxNumAttributes() {
+ return maxNumAttributes;
+ }
+
+ public void setMaxNumAttributes(Integer maxNumAttributes) {
+ this.maxNumAttributes = maxNumAttributes;
+ }
+
+ public Integer getMaxNumEvents() {
+ return maxNumEvents;
+ }
+
+ public void setMaxNumEvents(Integer maxNumEvents) {
+ this.maxNumEvents = maxNumEvents;
+ }
+
+ public Integer getMaxNumLinks() {
+ return maxNumLinks;
+ }
+
+ public void setMaxNumLinks(Integer maxNumLinks) {
+ this.maxNumLinks = maxNumLinks;
+ }
+
+ public Integer getMaxNumAttributesPerEvent() {
+ return maxNumAttributesPerEvent;
+ }
+
+ public void setMaxNumAttributesPerEvent(Integer maxNumAttributesPerEvent) {
+ this.maxNumAttributesPerEvent = maxNumAttributesPerEvent;
+ }
+
+ public Integer getMaxNumAttributesPerLink() {
+ return maxNumAttributesPerLink;
+ }
+
+ public void setMaxNumAttributesPerLink(Integer maxNumAttributesPerLink) {
+ this.maxNumAttributesPerLink = maxNumAttributesPerLink;
+ }
+
+ public Integer getMaxAttributeValueLength() {
+ return maxAttributeValueLength;
+ }
+
+ public void setMaxAttributeValueLength(Integer maxAttributeValueLength) {
+ this.maxAttributeValueLength = maxAttributeValueLength;
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/StatusAttributeKey.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/StatusAttributeKey.java
new file mode 100644
index 0000000..2730207
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/StatusAttributeKey.java
@@ -0,0 +1,49 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.AttributeType;
+
+/**
+ * Attribute key for status params.
+ */
+public final class StatusAttributeKey implements AttributeKey {
+
+ public static StatusAttributeKey MESSAGE = new StatusAttributeKey(AttributeKey.stringKey("_capa_error_message"));
+
+ public static StatusAttributeKey STATUS = new StatusAttributeKey(AttributeKey.stringKey("_capa_status"));
+
+ public static StatusAttributeKey LINK = new StatusAttributeKey(AttributeKey.stringKey("_capa_link"));
+
+ private final AttributeKey key;
+
+ private StatusAttributeKey(AttributeKey key) {
+ this.key = key;
+ }
+
+
+ @Override
+ public String getKey() {
+ return key.getKey();
+ }
+
+ @Override
+ public AttributeType getType() {
+ return key.getType();
+ }
+}
diff --git a/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/TracerConfig.java b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/TracerConfig.java
new file mode 100644
index 0000000..5f8edb1
--- /dev/null
+++ b/sdk-component/src/main/java/group/rxcloud/capa/component/telemetry/trace/TracerConfig.java
@@ -0,0 +1,81 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.trace;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Trace config.
+ */
+public class TracerConfig implements Serializable {
+
+ private static final long serialVersionUID = 6587103489345563395L;
+
+ /**
+ * Id generator class.
+ */
+ private String idGenerator;
+
+ /**
+ * Will trace/span id be validated with open telemetry restriction.
+ */
+ private boolean enableIdValidate;
+
+ /**
+ * Span limits.
+ */
+ private SpanLimitsConfig spanLimits;
+
+ /**
+ * Span processor classes.
+ */
+ private List processors;
+
+ public String getIdGenerator() {
+ return idGenerator;
+ }
+
+ public void setIdGenerator(String className) {
+ this.idGenerator = className;
+ }
+
+ public boolean isEnableIdValidate() {
+ return enableIdValidate;
+ }
+
+ public void setEnableIdValidate(boolean enableIdValidate) {
+ this.enableIdValidate = enableIdValidate;
+ }
+
+ public SpanLimitsConfig getSpanLimits() {
+ return spanLimits;
+ }
+
+ public void setSpanLimits(SpanLimitsConfig spanLimits) {
+ this.spanLimits = spanLimits;
+ }
+
+ public List getProcessors() {
+ return processors;
+ }
+
+ public void setProcessors(List processors) {
+ this.processors = processors;
+ }
+
+}
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpBuilderTest.java b/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpBuilderTest.java
index 2f60a08..b1beb44 100644
--- a/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpBuilderTest.java
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpBuilderTest.java
@@ -1,66 +1,66 @@
-/*
- * 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 group.rxcloud.capa.component.http;
-
-import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
-import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
-import group.rxcloud.capa.infrastructure.serializer.ObjectSerializer;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class CapaHttpBuilderTest {
-
- @Test
- public void testWithObjectSerializer_FailWhenCapaObjectSerializerIsNull() {
- Assertions.assertThrows(IllegalArgumentException.class, () -> {
- new CapaHttpBuilder().withObjectSerializer(null);
- });
- }
-
- @Test
- public void testWithObjectSerializer_FailWhenContentTypeIsNull() {
- Assertions.assertThrows(IllegalArgumentException.class, () -> {
- new CapaHttpBuilder().withObjectSerializer(new TestObjectSerializer());
- });
- }
-
- @Test
- public void testWithObjectSerializer_SuccessWhenDefaultObjectSerializerIsUsed() {
- CapaHttpBuilder capaHttpBuilder = new CapaHttpBuilder().withObjectSerializer(new DefaultObjectSerializer());
- Assertions.assertNotNull(capaHttpBuilder);
- }
-
- @Test
- public void testBuild_Success() {
- CapaHttpBuilder capaHttpBuilder = new CapaHttpBuilder();
- capaHttpBuilder.build();
- }
-
- /**
- * serializer/deserializer for request/response objects used in tests only
- */
- private class TestObjectSerializer extends ObjectSerializer implements CapaObjectSerializer {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getContentType() {
- return "";
- }
- }
-}
+/*
+ * 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 group.rxcloud.capa.component.http;
+
+import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
+import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
+import group.rxcloud.capa.infrastructure.serializer.ObjectSerializer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class CapaHttpBuilderTest {
+
+ @Test
+ public void testWithObjectSerializer_FailWhenCapaObjectSerializerIsNull() {
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ new CapaHttpBuilder().withObjectSerializer(null);
+ });
+ }
+
+ @Test
+ public void testWithObjectSerializer_FailWhenContentTypeIsNull() {
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ new CapaHttpBuilder().withObjectSerializer(new TestObjectSerializer());
+ });
+ }
+
+ @Test
+ public void testWithObjectSerializer_SuccessWhenDefaultObjectSerializerIsUsed() {
+ CapaHttpBuilder capaHttpBuilder = new CapaHttpBuilder().withObjectSerializer(new DefaultObjectSerializer());
+ Assertions.assertNotNull(capaHttpBuilder);
+ }
+
+ @Test
+ public void testBuild_Success() {
+ CapaHttpBuilder capaHttpBuilder = new CapaHttpBuilder();
+ capaHttpBuilder.build();
+ }
+
+ /**
+ * serializer/deserializer for request/response objects used in tests only
+ */
+ private class TestObjectSerializer extends ObjectSerializer implements CapaObjectSerializer {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getContentType() {
+ return "";
+ }
+ }
+}
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpTest.java b/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpTest.java
index 443daf5..bcc67ad 100644
--- a/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpTest.java
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/http/CapaHttpTest.java
@@ -1,63 +1,63 @@
-/*
- * 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 group.rxcloud.capa.component.http;
-
-import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
-import group.rxcloud.cloudruntimes.utils.TypeRef;
-import okhttp3.OkHttpClient;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import reactor.core.publisher.Mono;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author huijing xu
- * @date 2021/10/18
- */
-public class CapaHttpTest {
-
- @Test
- public void testInvokeApi_Success() {
- Map headers = new HashMap<>();
- headers.put("Content-Type", "application/json");
-
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
- TestCapaHttp capaHttp = new TestCapaHttp(builder.build(), new DefaultObjectSerializer());
- Mono> responseMono = capaHttp.invokeApi("post",
- null,
- null,
- null,
- headers,
- null,
- TypeRef.STRING);
-
- HttpResponse block = responseMono.block();
- int statusCode = block.getStatusCode();
-
- Assertions.assertEquals(200, statusCode);
- }
-
- @Test
- public void testClose_Success() throws Exception {
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
- TestCapaHttp capaHttp = new TestCapaHttp(builder.build(), new DefaultObjectSerializer());
-
- capaHttp.close();
- }
-}
+/*
+ * 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 group.rxcloud.capa.component.http;
+
+import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
+import group.rxcloud.cloudruntimes.utils.TypeRef;
+import okhttp3.OkHttpClient;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import reactor.core.publisher.Mono;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author huijing xu
+ * @date 2021/10/18
+ */
+public class CapaHttpTest {
+
+ @Test
+ public void testInvokeApi_Success() {
+ Map headers = new HashMap<>();
+ headers.put("Content-Type", "application/json");
+
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ TestCapaHttp capaHttp = new TestCapaHttp(builder.build(), new DefaultObjectSerializer());
+ Mono> responseMono = capaHttp.invokeApi("post",
+ null,
+ null,
+ null,
+ headers,
+ null,
+ TypeRef.STRING);
+
+ HttpResponse block = responseMono.block();
+ int statusCode = block.getStatusCode();
+
+ Assertions.assertEquals(200, statusCode);
+ }
+
+ @Test
+ public void testClose_Success() throws Exception {
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ TestCapaHttp capaHttp = new TestCapaHttp(builder.build(), new DefaultObjectSerializer());
+
+ capaHttp.close();
+ }
+}
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/http/HttpResponseTest.java b/sdk-component/src/test/java/group/rxcloud/capa/component/http/HttpResponseTest.java
index b61aae4..b4aabb5 100644
--- a/sdk-component/src/test/java/group/rxcloud/capa/component/http/HttpResponseTest.java
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/http/HttpResponseTest.java
@@ -1,46 +1,46 @@
-/*
- * 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 group.rxcloud.capa.component.http;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class HttpResponseTest {
-
- @Test
- public void testGet_Success() {
- Map headers = new HashMap<>();
- headers.put("Content-Type", "application/json");
-
- HttpResponse httpResponse = new HttpResponse("body", headers, 200);
-
- Assertions.assertEquals("body", httpResponse.getBody());
-
- Map resultMap = headers;
- if (httpResponse.getHeaders() != null) {
- resultMap = httpResponse.getHeaders();
- }
- Assertions.assertEquals("application/json", resultMap.get("Content-Type"));
-
- Assertions.assertEquals(200, httpResponse.getStatusCode());
- }
-
-
-}
+/*
+ * 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 group.rxcloud.capa.component.http;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class HttpResponseTest {
+
+ @Test
+ public void testGet_Success() {
+ Map headers = new HashMap<>();
+ headers.put("Content-Type", "application/json");
+
+ HttpResponse httpResponse = new HttpResponse("body", headers, 200);
+
+ Assertions.assertEquals("body", httpResponse.getBody());
+
+ Map resultMap = headers;
+ if (httpResponse.getHeaders() != null) {
+ resultMap = httpResponse.getHeaders();
+ }
+ Assertions.assertEquals("application/json", resultMap.get("Content-Type"));
+
+ Assertions.assertEquals(200, httpResponse.getStatusCode());
+ }
+
+
+}
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/http/TestCapaHttp.java b/sdk-component/src/test/java/group/rxcloud/capa/component/http/TestCapaHttp.java
index e5dc9de..fa69654 100644
--- a/sdk-component/src/test/java/group/rxcloud/capa/component/http/TestCapaHttp.java
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/http/TestCapaHttp.java
@@ -1,51 +1,51 @@
-/*
- * 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 group.rxcloud.capa.component.http;
-
-import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
-import group.rxcloud.cloudruntimes.utils.TypeRef;
-import okhttp3.OkHttpClient;
-import reactor.util.context.Context;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * The capa http invoker used in tests only.
- */
-public class TestCapaHttp extends CapaHttp {
-
- public TestCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
- super(httpClient, objectSerializer);
- }
-
- @Override
- protected CompletableFuture> doInvokeApi(String httpMethod,
- String[] pathSegments,
- Map> urlParameters,
- Object requestData,
- Map headers,
- Context context,
- TypeRef type) {
- return CompletableFuture.supplyAsync(
- () -> {
- return new HttpResponse<>(null, null, 200);
- },
- Runnable::run);
- }
-}
+/*
+ * 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 group.rxcloud.capa.component.http;
+
+import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
+import group.rxcloud.cloudruntimes.utils.TypeRef;
+import okhttp3.OkHttpClient;
+import reactor.util.context.Context;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * The capa http invoker used in tests only.
+ */
+public class TestCapaHttp extends CapaHttp {
+
+ public TestCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
+ super(httpClient, objectSerializer);
+ }
+
+ @Override
+ protected CompletableFuture> doInvokeApi(String httpMethod,
+ String[] pathSegments,
+ Map> urlParameters,
+ Object requestData,
+ Map headers,
+ Context context,
+ TypeRef type) {
+ return CompletableFuture.supplyAsync(
+ () -> {
+ return new HttpResponse<>(null, null, 200);
+ },
+ Runnable::run);
+ }
+}
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/CapaLog4jAppenderAgentTest.java b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/CapaLog4jAppenderAgentTest.java
new file mode 100644
index 0000000..2b1ab7d
--- /dev/null
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/CapaLog4jAppenderAgentTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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 group.rxcloud.capa.component.log.agent;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.message.Message;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+class CapaLog4jAppenderAgentTest {
+
+ @Test
+ void testCreateAppender() {
+ Filter filter = Mockito.mock(Filter.class);
+ Layout layout = Mockito.mock(Layout.class);
+ new CapaLog4jAppenderAgent("CapaLog4jAppender", filter, layout, true);
+ }
+
+ @Test
+ void testBuildCapaLog4jAppender() {
+ Filter filter = Mockito.mock(Filter.class);
+ Layout layout = Mockito.mock(Layout.class);
+ CapaLog4jAppenderAgent.createAppender("CapaLog4jAppender", filter, layout, true);
+ }
+
+ @Test
+ void testAppend() {
+ Filter filter = Mockito.mock(Filter.class);
+ Layout layout = Mockito.mock(Layout.class);
+ CapaLog4jAppenderAgent capaLog4jAppender = CapaLog4jAppenderAgent.createAppender("CapaLog4jAppender", filter, layout, true);
+ LogEvent logEvent = Mockito.mock(LogEvent.class);
+ Message message = Mockito.mock(Message.class);
+ Mockito.when(logEvent.getMessage()).thenReturn(Mockito.mock(Message.class));
+ Mockito.when(message.getFormattedMessage()).thenReturn("TEST");
+ capaLog4jAppender.append(logEvent);
+ }
+}
\ No newline at end of file
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/CapaLogbackAppenderAgentTest.java b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/CapaLogbackAppenderAgentTest.java
new file mode 100644
index 0000000..16b61fc
--- /dev/null
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/CapaLogbackAppenderAgentTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 group.rxcloud.capa.component.log.agent;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.message.Message;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+class CapaLogbackAppenderAgentTest {
+
+ @Test
+ void testBuildCapaLogbackAppender() {
+ CapaLogbackAppenderAgent.CapaLogbackAppender capaLogbackAppender = CapaLogbackAppenderAgent.buildCapaLogbackAppender();
+ Assertions.assertNotNull(capaLogbackAppender);
+ }
+
+ @Test
+ void testAppend() {
+ CapaLogbackAppenderAgent.CapaLogbackAppender capaLogbackAppender = CapaLogbackAppenderAgent.buildCapaLogbackAppender();
+ LogEvent logEvent = Mockito.mock(LogEvent.class);
+ Message message = Mockito.mock(Message.class);
+ Mockito.when(logEvent.getMessage()).thenReturn(Mockito.mock(Message.class));
+ Mockito.when(message.getFormattedMessage()).thenReturn("TEST");
+ capaLogbackAppender.appendLog(logEvent);
+ }
+}
\ No newline at end of file
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/TestCapaLog4jAppender.java b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/TestCapaLog4jAppender.java
new file mode 100644
index 0000000..4dbdca6
--- /dev/null
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/TestCapaLog4jAppender.java
@@ -0,0 +1,30 @@
+/*
+ * 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 group.rxcloud.capa.component.log.agent;
+
+import org.apache.logging.log4j.core.LogEvent;
+
+/**
+ * The capa log4j appender used in tests only.
+ */
+public class TestCapaLog4jAppender implements CapaLog4jAppenderAgent.CapaLog4jAppender {
+
+ @Override
+ public void appendLog(LogEvent event) {
+ System.out.println("test log log4j and content is " + event.getMessage().getFormattedMessage());
+ }
+}
\ No newline at end of file
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/TestCapaLogbackAppender.java b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/TestCapaLogbackAppender.java
new file mode 100644
index 0000000..af58bcd
--- /dev/null
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/log/agent/TestCapaLogbackAppender.java
@@ -0,0 +1,34 @@
+/*
+ * 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 group.rxcloud.capa.component.log.agent;
+
+import org.apache.logging.log4j.core.LogEvent;
+
+/**
+ * The capa logback appender used in tests only.
+ */
+public class TestCapaLogbackAppender implements CapaLogbackAppenderAgent.CapaLogbackAppender {
+
+ public TestCapaLogbackAppender() {
+ }
+
+ @Override
+ public void appendLog(LogEvent event) {
+ System.out.println("test logback log and content is " + event.getMessage().getFormattedMessage());
+ }
+}
+
diff --git a/sdk-component/src/test/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorBuilderTest.java b/sdk-component/src/test/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorBuilderTest.java
new file mode 100644
index 0000000..8256824
--- /dev/null
+++ b/sdk-component/src/test/java/group/rxcloud/capa/component/telemetry/context/CapaContextPropagatorBuilderTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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 group.rxcloud.capa.component.telemetry.context;
+
+import com.google.common.collect.Lists;
+import io.opentelemetry.context.Context;
+import io.opentelemetry.context.ContextKey;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import io.opentelemetry.context.propagation.TextMapSetter;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * @author: chenyijiang
+ * @date: 2021/11/25 21:03
+ */
+public class CapaContextPropagatorBuilderTest {
+
+ @Test
+ public void setContextConfig() {
+ TestPropagator.clean();
+ ContextConfig config = new ContextConfig();
+ config.setContextPropagators(
+ Lists.newArrayList("group.rxcloud.capa.component.telemetry.context.TestPropagator"));
+ ContextPropagators propagators = new CapaContextPropagatorBuilder().setContextConfig(config)
+ .buildContextPropagators();
+ propagators.getTextMapPropagator().inject(new Context() {
+ @Nullable
+ @Override
+ public V get(ContextKey key) {
+ return null;
+ }
+
+ @Override
+ public Context with(ContextKey k1, V v1) {
+ return null;
+ }
+ }, null, new TextMapSetter
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+ io.opentelemetry
+ opentelemetry-api
+
+
+ io.opentelemetry
+ opentelemetry-api-metrics
+
+
com.kevinten
@@ -57,13 +72,6 @@
${vrml.version}
-
-
- org.slf4j
- slf4j-api
- ${slf4j-api.version}
-
-
io.grpc
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaConstants.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaConstants.java
index 04fb156..752ea46 100644
--- a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaConstants.java
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaConstants.java
@@ -30,15 +30,18 @@ interface Properties {
* The {@code infrastructure} properties prefix.
*/
String CAPA_INFRASTRUCTURE_PROPERTIES_PREFIX = "/capa-infrastructure-";
-
/**
* The {@code component} properties prefix.
*/
String CAPA_COMPONENT_PROPERTIES_PREFIX = "/capa-component-";
/**
- * The constant SUFFIX.
+ * The properties suffix.
*/
String CAPA_PROPERTIES_SUFFIX = ".properties";
+ /**
+ * The json suffix.
+ */
+ String CAPA_JSON_SUFFIX = ".json";
}
}
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaProperties.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaProperties.java
index ce0ddfd..c47bdc0 100644
--- a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaProperties.java
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/CapaProperties.java
@@ -16,6 +16,12 @@
*/
package group.rxcloud.capa.infrastructure;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -30,6 +36,7 @@
import static group.rxcloud.capa.infrastructure.CapaConstants.Properties.CAPA_COMPONENT_PROPERTIES_PREFIX;
import static group.rxcloud.capa.infrastructure.CapaConstants.Properties.CAPA_INFRASTRUCTURE_PROPERTIES_PREFIX;
import static group.rxcloud.capa.infrastructure.CapaConstants.Properties.CAPA_PROPERTIES_SUFFIX;
+import static group.rxcloud.capa.infrastructure.Module.OBJECT_MAPPER;
/**
* Global properties for Capa's SDK, using Supplier so they are dynamically resolved.
@@ -60,13 +67,13 @@ public abstract class CapaProperties {
/**
* Capa's properties cache map.
*/
- private static final Map PROPERTIES_MAP = new ConcurrentHashMap<>();
+ private static final Map PROPERTIES_MAP = new ConcurrentHashMap<>();
/**
* Capa's infrastructure properties.
*/
public static final Function INFRASTRUCTURE_PROPERTIES_SUPPLIER
- = (infrastructureDomain) -> PROPERTIES_MAP.computeIfAbsent(infrastructureDomain,
+ = (infrastructureDomain) -> (Properties) PROPERTIES_MAP.computeIfAbsent(infrastructureDomain,
s -> {
final String fileName = CAPA_INFRASTRUCTURE_PROPERTIES_PREFIX
+ infrastructureDomain.toLowerCase()
@@ -78,7 +85,7 @@ public abstract class CapaProperties {
* Capa's component properties.
*/
public static final Function COMPONENT_PROPERTIES_SUPPLIER
- = (componentDomain) -> PROPERTIES_MAP.computeIfAbsent(componentDomain,
+ = (componentDomain) -> (Properties) PROPERTIES_MAP.computeIfAbsent(componentDomain,
s -> {
final String fileName = CAPA_COMPONENT_PROPERTIES_PREFIX
+ componentDomain.toLowerCase()
@@ -97,4 +104,23 @@ private static Properties loadCapaProperties(final String fileName) {
throw new IllegalArgumentException(fileName + " file not found.");
}
}
+
+ public static T loadCapaConfig(final String fileName, Class configClazz) {
+ Objects.requireNonNull(fileName, "fileName not found.");
+ try (InputStream in = configClazz.getResourceAsStream(fileName)) {
+ InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
+ return OBJECT_MAPPER.readValue(inputStreamReader, configClazz);
+ } catch (JsonParseException | JsonMappingException e) {
+ throw new IllegalArgumentException(fileName + " file not load.");
+ } catch (IOException e) {
+ throw new IllegalArgumentException(fileName + " file not found.");
+ }
+ }
+}
+
+interface Module {
+
+ ObjectMapper OBJECT_MAPPER = new ObjectMapper()
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/ConfigurationHooks.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/ConfigurationHooks.java
new file mode 100644
index 0000000..8845bba
--- /dev/null
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/ConfigurationHooks.java
@@ -0,0 +1,95 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.hook;
+
+import group.rxcloud.cloudruntimes.domain.core.ConfigurationRuntimes;
+import group.rxcloud.cloudruntimes.domain.core.configuration.ConfigurationItem;
+import group.rxcloud.cloudruntimes.domain.core.configuration.ConfigurationRequestItem;
+import group.rxcloud.cloudruntimes.domain.core.configuration.SaveConfigurationRequest;
+import group.rxcloud.cloudruntimes.domain.core.configuration.SubConfigurationResp;
+import group.rxcloud.cloudruntimes.utils.TypeRef;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The Mixer configuration hooks.
+ */
+public interface ConfigurationHooks extends ConfigurationRuntimes {
+
+ /**
+ * Registry Store Names.
+ */
+ List registryStoreNames();
+
+ /**
+ * Default configuration appI.
+ */
+ String defaultConfigurationAppId();
+
+ @Override
+ default Mono>> getConfiguration(String storeName, String appId, List keys, Map metadata, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono>> getConfiguration(String storeName, String appId, List keys, Map metadata, String group, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono>> getConfiguration(String storeName, String appId, List keys, Map metadata, String group, String label, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono>> getConfiguration(ConfigurationRequestItem configurationRequestItem, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono saveConfiguration(SaveConfigurationRequest saveConfigurationRequest) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono deleteConfiguration(ConfigurationRequestItem configurationRequestItem) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Flux> subscribeConfiguration(String storeName, String appId, List keys, Map metadata, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Flux> subscribeConfiguration(String storeName, String appId, List keys, Map metadata, String group, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Flux> subscribeConfiguration(String storeName, String appId, List keys, Map metadata, String group, String label, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Flux> subscribeConfiguration(ConfigurationRequestItem configurationRequestItem, TypeRef type) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+}
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/Mixer.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/Mixer.java
new file mode 100644
index 0000000..3a28b05
--- /dev/null
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/Mixer.java
@@ -0,0 +1,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 group.rxcloud.capa.infrastructure.hook;
+
+import group.rxcloud.capa.infrastructure.CapaClassLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.util.Optional;
+
+/**
+ * The Inner Runtimes Mixer.
+ */
+public abstract class Mixer {
+
+ private static final Logger logger = LoggerFactory.getLogger(Mixer.class);
+
+ private static ConfigurationHooks configurationHooks;
+ private static TelemetryHooks telemetryHooks;
+
+ static {
+ try {
+ MixerProvider mixerProvider = CapaClassLoader.loadInfrastructureClassObj("mixer", MixerProvider.class);
+ if (mixerProvider != null) {
+ registerConfigurationHooks(mixerProvider.provideConfigurationHooks());
+ registerTelemetryHooks(mixerProvider.provideTelemetryHooks());
+ }
+ } catch (Exception e) {
+ logger.info("[CapaMixer] load empty mixer. expected error: ", e);
+ }
+ }
+
+ /**
+ * The SPI Mixer provider.
+ */
+ public interface MixerProvider {
+
+ /**
+ * Provide global configuration hooks.
+ *
+ * @return the configuration hooks
+ */
+ ConfigurationHooks provideConfigurationHooks();
+
+ /**
+ * Provide global telemetry hooks.
+ *
+ * @return the telemetry hooks
+ */
+ TelemetryHooks provideTelemetryHooks();
+ }
+
+ /**
+ * Register configuration hooks.
+ *
+ * @param configurationHooks the configuration hooks
+ */
+ private static void registerConfigurationHooks(ConfigurationHooks configurationHooks) {
+ Mixer.configurationHooks = configurationHooks;
+ }
+
+ /**
+ * Register telemetry hooks.
+ *
+ * @param telemetryHooks the telemetry hooks
+ */
+ private static void registerTelemetryHooks(TelemetryHooks telemetryHooks) {
+ Mixer.telemetryHooks = telemetryHooks;
+ }
+
+ /**
+ * Gets configuration hooks.
+ *
+ * @return the configuration hooks
+ */
+ @Nullable
+ public static ConfigurationHooks configurationHooks() {
+ return configurationHooks;
+ }
+
+ /**
+ * Gets configuration hooks.
+ *
+ * @return the configuration hooks
+ */
+ public static Optional configurationHooksNullable() {
+ return Optional.ofNullable(configurationHooks);
+ }
+
+ /**
+ * Gets telemetry hooks.
+ *
+ * @return the telemetry hooks
+ */
+ @Nullable
+ public static TelemetryHooks telemetryHooks() {
+ return telemetryHooks;
+ }
+
+ /**
+ * Gets telemetry hooks.
+ *
+ * @return the telemetry hooks
+ */
+ public static Optional telemetryHooksNullable() {
+ return Optional.ofNullable(telemetryHooks);
+ }
+}
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/TelemetryHooks.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/TelemetryHooks.java
new file mode 100644
index 0000000..b48fbf9
--- /dev/null
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/TelemetryHooks.java
@@ -0,0 +1,64 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.hook;
+
+import group.rxcloud.cloudruntimes.domain.enhanced.TelemetryRuntimes;
+import io.opentelemetry.api.metrics.Meter;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import reactor.core.publisher.Mono;
+
+/**
+ * The Mixer telemetry hooks.
+ */
+public interface TelemetryHooks extends TelemetryRuntimes {
+
+ @Override
+ default Mono buildTracer(String tracerName) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono buildTracer(String tracerName, String version) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono buildTracer(String tracerName, String version, String schemaUrl) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono getContextPropagators() {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono buildMeter(String meterName) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono buildMeter(String meterName, String version) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+
+ @Override
+ default Mono buildMeter(String meterName, String version, String schemaUrl) {
+ throw new UnsupportedOperationException("If you want to use this operate, please impl this.");
+ }
+}
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/package-info.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/package-info.java
new file mode 100644
index 0000000..1aba000
--- /dev/null
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/hook/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+/**
+ * Hooks design:
+ * TODO
+ */
+package group.rxcloud.capa.infrastructure.hook;
diff --git a/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/utils/SpiUtils.java b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/utils/SpiUtils.java
new file mode 100644
index 0000000..89b02ac
--- /dev/null
+++ b/sdk-infrastructure/src/main/java/group/rxcloud/capa/infrastructure/utils/SpiUtils.java
@@ -0,0 +1,165 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.utils;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import group.rxcloud.capa.infrastructure.CapaProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Load class and create instance from config file.
+ */
+public final class SpiUtils {
+
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+ private static final Map CACHE = new ConcurrentHashMap<>();
+
+ private static final Logger log = LoggerFactory.getLogger(SpiUtils.class);
+
+ private SpiUtils() {
+ }
+
+ public static T loadConfigNullable(String path, Class configType) {
+ try (InputStream in = configType.getResourceAsStream(path)) {
+ if (in != null) {
+ InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
+ return OBJECT_MAPPER.readValue(inputStreamReader, configType);
+ } else {
+ log.warn(path + " file not found.");
+ }
+ } catch (IOException e) {
+ log.warn(path + " config file not found.", e);
+ }
+ return null;
+ }
+
+ public static Properties loadPropertiesNullable(String path) {
+ try (InputStream in = SpiUtils.class.getResourceAsStream(path)) {
+ if (in != null) {
+ InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
+ Properties properties = new Properties();
+ properties.load(inputStreamReader);
+ return properties;
+ } else {
+ log.warn(path + " file not found.");
+ }
+ } catch (IOException e) {
+ log.warn(path + " file not found.", e);
+ }
+ return null;
+ }
+
+ public static Properties loadProperties(String path) {
+ try (InputStream in = SpiUtils.class.getResourceAsStream(path)) {
+ if (in != null) {
+ InputStreamReader inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8);
+ Properties properties = new Properties();
+ properties.load(inputStreamReader);
+ return properties;
+ } else {
+ throw new IllegalArgumentException(path + " file not found.");
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException(path + " file not found.", e);
+ }
+ }
+
+ @Nullable
+ public static T loadFromSpiComponentFileNullable(Class type, String fileSuffix) {
+ return loadFromSpiComponentFileNullable(type, null, null, fileSuffix, false);
+ }
+
+ @Nullable
+ public static T loadFromSpiComponentFileNullable(Class type, Class[] argTypes, Object[] args,
+ String fileSuffix, boolean cache) {
+ try {
+ Properties properties = CapaProperties.COMPONENT_PROPERTIES_SUPPLIER.apply(fileSuffix);
+ String path = properties.getProperty(type.getName());
+ if (path != null) {
+ return doNewInstance(path, type, argTypes, args, cache);
+ }
+ return null;
+ } catch (Throwable e) {
+ log.warn("Fail to load " + type.getName() + " instance from spi config file.", e);
+ }
+ return null;
+ }
+
+ @Nullable
+ public static T newInstanceWithConstructorCache(String path, Class type) {
+ return newInstance(path, type, null, null, true);
+ }
+
+ @Nullable
+ public static T newInstance(String path, Class type, Class[] argTypes, Object[] args, boolean cache) {
+ if (path == null) {
+ return null;
+ }
+ return doNewInstance(path, type, argTypes, args, cache);
+ }
+
+ private static String keyOf(String path, Class type, Class[] argTypes) {
+ StringBuilder builder = new StringBuilder(type.getName()).append('=').append(path);
+ if (argTypes != null) {
+ for (Class arg : argTypes) {
+ builder.append('_').append(arg.getName());
+ }
+ }
+ return builder.toString();
+ }
+
+ @Nonnull
+ private static T doNewInstance(String path, Class type, Class[] argTypes, Object[] args, boolean cache) {
+ String key = keyOf(path, type, argTypes);
+ Constructor targetCons = cache
+ ? CACHE.computeIfAbsent(key, k -> findConstructor(path, type, argTypes))
+ : findConstructor(path, type, argTypes);
+ try {
+ return targetCons.getParameterCount() == 0 ? targetCons.newInstance() : targetCons.newInstance(args);
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalArgumentException("Fail to create component. targetType = " + type.getName(), e);
+ }
+ }
+
+ private static Constructor findConstructor(String path, Class type, Class[] argTypes) {
+ try {
+ Class aClass = path == null ? type : (Class) Class.forName(path);
+ return aClass.getConstructor(argTypes);
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ throw new IllegalArgumentException("Fail to find the constructor. path = " + path, e);
+ }
+ }
+}
diff --git a/sdk-infrastructure/src/main/resources/sample/capa-infrastructure-mixer.properties b/sdk-infrastructure/src/main/resources/sample/capa-infrastructure-mixer.properties
new file mode 100644
index 0000000..105ef32
--- /dev/null
+++ b/sdk-infrastructure/src/main/resources/sample/capa-infrastructure-mixer.properties
@@ -0,0 +1 @@
+# optional
\ No newline at end of file
diff --git a/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyImpl.java b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyImpl.java
new file mode 100644
index 0000000..1791222
--- /dev/null
+++ b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyImpl.java
@@ -0,0 +1,22 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.utils;
+
+public class MyImpl implements MyInterface{
+
+}
diff --git a/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyImplWithArgs.java b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyImplWithArgs.java
new file mode 100644
index 0000000..5232dca
--- /dev/null
+++ b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyImplWithArgs.java
@@ -0,0 +1,35 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.utils;
+
+public class MyImplWithArgs implements MyInterfaceWithArgs{
+
+ private MyImplWithArgs(Integer a) {
+
+ }
+ public MyImplWithArgs(String a) {
+
+ }
+ public MyImplWithArgs(Integer a, String b) {
+
+ }
+
+ public MyImplWithArgs(boolean a, short b, int c, long d, float e, double f, byte g, char h, String i) {
+
+ }
+}
diff --git a/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyInterface.java b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyInterface.java
new file mode 100644
index 0000000..70fb329
--- /dev/null
+++ b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyInterface.java
@@ -0,0 +1,22 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.utils;
+
+public interface MyInterface {
+
+}
diff --git a/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyInterfaceWithArgs.java b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyInterfaceWithArgs.java
new file mode 100644
index 0000000..fe69c4c
--- /dev/null
+++ b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/MyInterfaceWithArgs.java
@@ -0,0 +1,22 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.utils;
+
+public interface MyInterfaceWithArgs {
+
+}
diff --git a/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/SpiUtilsTest.java b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/SpiUtilsTest.java
new file mode 100644
index 0000000..ddefc30
--- /dev/null
+++ b/sdk-infrastructure/src/test/java/group/rxcloud/capa/infrastructure/utils/SpiUtilsTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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 group.rxcloud.capa.infrastructure.utils;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Properties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class SpiUtilsTest {
+
+ @Test
+ public void loadConfigNullable() {
+ Config config = SpiUtils.loadConfigNullable("/config.json", Config.class);
+ assertEquals("aaa", config.str);
+ assertEquals(2, config.getList().size());
+ assertEquals("zzz", config.getList().get(0));
+
+ assertNull(SpiUtils.loadConfigNullable("aaa", Config.class));
+ assertNull(SpiUtils.loadConfigNullable("/config.json", Integer.class));
+ }
+
+ @Test
+ public void loadPropertiesNullable() {
+ Properties properties = SpiUtils.loadPropertiesNullable("/config.properties");
+ assertEquals("aaa", properties.getProperty("str"));
+
+ assertNull(SpiUtils.loadPropertiesNullable("lalala"));
+ }
+
+ @Test
+ public void loadProperties() {
+ Properties properties = SpiUtils.loadProperties("/config.properties");
+ assertEquals("aaa", properties.getProperty("str"));
+ }
+
+ @Test
+ public void loadPropertiesFail() {
+ Throwable t = null;
+ try {
+ Properties properties = SpiUtils.loadProperties("aaaa");
+ } catch (Throwable throwable) {
+ t = throwable;
+ }
+ assertNotNull(t);
+ }
+ @Test
+ public void loadFromSpiComponentFileNullable() {
+ MyInterface myInterface = SpiUtils.loadFromSpiComponentFileNullable(MyInterface.class, "test");
+ assertTrue(myInterface instanceof MyImpl);
+ }
+
+ @Test
+ public void loadFromSpiComponentFileNullable2() {
+ MyInterfaceWithArgs myInterfaceWithArgs = SpiUtils.loadFromSpiComponentFileNullable(MyInterfaceWithArgs.class, new Class[] {boolean.class, short.class, int.class, long.class, float.class, double.class, byte.class, char.class, String.class}, new Object[] {true, (short)1, 2, 3L, 4.0f, 5.0, (byte)0x1, 'x', "a"}, "test", true);
+
+ assertTrue(myInterfaceWithArgs instanceof MyImplWithArgs);
+
+
+ }
+
+ @Test
+ public void loadFromSpiComponentFileNullable2Fail() {
+ MyInterfaceWithArgs myInterfaceWithArgs = SpiUtils.loadFromSpiComponentFileNullable(MyInterfaceWithArgs.class, "test");
+ assertNull(myInterfaceWithArgs);
+
+
+ assertNull(SpiUtils.loadFromSpiComponentFileNullable(MyImplWithArgs.class, new Class[] {String.class}, new Object[] {"a"}, "test", true));
+
+ assertNull(SpiUtils.loadFromSpiComponentFileNullable(MyInterfaceWithArgs.class, new Class[] {Long.class}, new Object[] {1L}, "test", false));
+
+ assertNull(SpiUtils.loadFromSpiComponentFileNullable(MyInterfaceWithArgs.class, new Class[] {Integer.class}, new Object[] {1}, "test", false));
+
+ assertNull(SpiUtils.loadFromSpiComponentFileNullable(MyInterfaceWithArgs.class, new Class[] {boolean.class, short.class, int.class, long.class, float.class, double.class, byte.class, char.class, String.class}, new Object[] {true, (short)1, 2, 3L, 4.0f, 5.0, null, 'x', "a"}, "test", true));
+
+
+ }
+
+ @Test
+ public void newInstance() {
+ assertNull(SpiUtils.newInstance(null, Config.class, null, null, false));
+
+ MyImpl my = SpiUtils.newInstanceWithConstructorCache(MyImpl.class.getCanonicalName(), MyImpl.class);
+ assertNotNull(my);
+
+ MyImplWithArgs myImplWithArgs = SpiUtils.newInstance(MyImplWithArgs.class.getCanonicalName(),MyImplWithArgs.class, new Class[] {String.class}, new Object[] {"a"}, false);
+ assertNotNull(myImplWithArgs);
+ }
+
+ @Test
+ public void newInstanceFail() {
+ Throwable t = null;
+ try {
+ Config my = SpiUtils.newInstanceWithConstructorCache(Config.class.getCanonicalName(), Config.class);
+ } catch (Throwable throwable) {
+ t = throwable;
+ }
+ assertNotNull(t);
+ }
+
+ static class Config {
+
+ private String str;
+
+ private List list;
+
+ public String getStr() {
+ return str;
+ }
+
+ public Config setStr(String str) {
+ this.str = str;
+ return this;
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public Config setList(List list) {
+ this.list = list;
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdk-infrastructure/src/test/resources/capa-component-test.properties b/sdk-infrastructure/src/test/resources/capa-component-test.properties
new file mode 100644
index 0000000..dafd0e8
--- /dev/null
+++ b/sdk-infrastructure/src/test/resources/capa-component-test.properties
@@ -0,0 +1,2 @@
+group.rxcloud.capa.infrastructure.utils.MyInterface=group.rxcloud.capa.infrastructure.utils.MyImpl
+group.rxcloud.capa.infrastructure.utils.MyInterfaceWithArgs=group.rxcloud.capa.infrastructure.utils.MyImplWithArgs
\ No newline at end of file
diff --git a/sdk-infrastructure/src/test/resources/config.json b/sdk-infrastructure/src/test/resources/config.json
new file mode 100644
index 0000000..0de38f1
--- /dev/null
+++ b/sdk-infrastructure/src/test/resources/config.json
@@ -0,0 +1,4 @@
+{
+ "str": "aaa",
+ "list": ["zzz", "yyy"]
+}
\ No newline at end of file
diff --git a/sdk-infrastructure/src/test/resources/config.properties b/sdk-infrastructure/src/test/resources/config.properties
new file mode 100644
index 0000000..2b9c2c9
--- /dev/null
+++ b/sdk-infrastructure/src/test/resources/config.properties
@@ -0,0 +1 @@
+str=aaa
\ No newline at end of file
diff --git a/sdk-spi-demo/pom.xml b/sdk-spi-demo/pom.xml
index 1081e97..4256367 100644
--- a/sdk-spi-demo/pom.xml
+++ b/sdk-spi-demo/pom.xml
@@ -23,13 +23,18 @@
capa-parentgroup.rxcloud
- 1.0.6.RELEASE
+ 1.0.7.RELEASEcapa-sdk-spi-demojarcapa-sdk-spi-demo
+
+ 2.8.2
+ 1.1.7
+
+
@@ -37,6 +42,37 @@
capa-sdk-spi
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+ true
+
+
+ ch.qos.logback
+ logback-core
+ ${logback.version}
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j.version}
+
+
+ org.apache.logging.log4j
+ log4j-api
+ ${log4j.version}
+
+
org.junit.jupiter
diff --git a/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/http/DemoCapaHttp.java b/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/http/DemoCapaHttp.java
index 921ac11..0f93d72 100644
--- a/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/http/DemoCapaHttp.java
+++ b/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/http/DemoCapaHttp.java
@@ -18,14 +18,15 @@
import group.rxcloud.capa.component.http.HttpResponse;
import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
-import group.rxcloud.capa.spi.http.config.RpcServiceOptions;
import group.rxcloud.capa.spi.demo.http.config.DemoRpcServiceOptions;
import group.rxcloud.capa.spi.http.CapaSerializeHttpSpi;
+import group.rxcloud.capa.spi.http.config.RpcServiceOptions;
import group.rxcloud.cloudruntimes.utils.TypeRef;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -47,12 +48,15 @@ public DemoCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializ
}
@Override
- protected CompletableFuture> invokeSpiApi(String appId,
- String method,
- Object requestData,
- Map headers,
- TypeRef type,
- RpcServiceOptions rpcServiceOptions) {
+ protected CompletableFuture> invokeSpiApi(
+ String appId,
+ String method,
+ Object requestData,
+ String httpMethod,
+ Map headers,
+ Map> urlParameters,
+ TypeRef type,
+ RpcServiceOptions rpcServiceOptions) {
DemoRpcServiceOptions demoRpcServiceOptions = (DemoRpcServiceOptions) rpcServiceOptions;
logger.info("[DemoCapaHttp.invokeSpiApi] rpcServiceOptions[{}]", demoRpcServiceOptions);
diff --git a/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/log/DemoLog4jAppender.java b/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/log/DemoLog4jAppender.java
new file mode 100644
index 0000000..ccf07cc
--- /dev/null
+++ b/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/log/DemoLog4jAppender.java
@@ -0,0 +1,28 @@
+/*
+ * 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 group.rxcloud.capa.spi.demo.log;
+
+import group.rxcloud.capa.component.log.agent.CapaLog4jAppenderAgent;
+import org.apache.logging.log4j.core.LogEvent;
+
+public class DemoLog4jAppender implements CapaLog4jAppenderAgent.CapaLog4jAppender {
+
+ @Override
+ public void appendLog(LogEvent event) {
+ System.out.println("test log log4j and content is " + event.getMessage().getFormattedMessage());
+ }
+}
diff --git a/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/log/DemoLogbackAppender.java b/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/log/DemoLogbackAppender.java
new file mode 100644
index 0000000..c6029cd
--- /dev/null
+++ b/sdk-spi-demo/src/main/java/group/rxcloud/capa/spi/demo/log/DemoLogbackAppender.java
@@ -0,0 +1,31 @@
+/*
+ * 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 group.rxcloud.capa.spi.demo.log;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import group.rxcloud.capa.component.log.agent.CapaLogbackAppenderAgent;
+
+public class DemoLogbackAppender implements CapaLogbackAppenderAgent.CapaLogbackAppender {
+
+ public DemoLogbackAppender() {
+ }
+
+ @Override
+ public void appendLog(ILoggingEvent event) {
+ System.out.println("test logback log and content is " + event.getFormattedMessage());
+ }
+}
diff --git a/sdk-spi-demo/src/main/resources/capa-component-log.properties b/sdk-spi-demo/src/main/resources/capa-component-log.properties
new file mode 100644
index 0000000..2b10f8d
--- /dev/null
+++ b/sdk-spi-demo/src/main/resources/capa-component-log.properties
@@ -0,0 +1,2 @@
+group.rxcloud.capa.component.log.agent.CapaLog4jAppenderAgent$CapaLog4jAppender=group.rxcloud.capa.spi.demo.log.DemoLog4jAppender
+group.rxcloud.capa.component.log.agent.CapaLogbackAppenderAgent$CapaLogbackAppender=group.rxcloud.capa.spi.demo.log.DemoLogbackAppender
\ No newline at end of file
diff --git a/sdk-spi/pom.xml b/sdk-spi/pom.xml
index 78521df..dc3077f 100644
--- a/sdk-spi/pom.xml
+++ b/sdk-spi/pom.xml
@@ -23,7 +23,7 @@
capa-parentgroup.rxcloud
- 1.0.6.RELEASE
+ 1.0.7.RELEASEcapa-sdk-spi
diff --git a/sdk-spi/src/main/java/group/rxcloud/capa/spi/http/CapaHttpSpi.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/http/CapaHttpSpi.java
index f0d07c3..711b514 100644
--- a/sdk-spi/src/main/java/group/rxcloud/capa/spi/http/CapaHttpSpi.java
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/http/CapaHttpSpi.java
@@ -22,7 +22,6 @@
import group.rxcloud.capa.spi.http.config.CapaSpiOptionsLoader;
import group.rxcloud.capa.spi.http.config.CapaSpiProperties;
import group.rxcloud.capa.spi.http.config.RpcServiceOptions;
-import group.rxcloud.cloudruntimes.domain.core.invocation.HttpExtension;
import group.rxcloud.cloudruntimes.utils.TypeRef;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
@@ -41,15 +40,18 @@ public abstract class CapaHttpSpi extends CapaHttp {
private static final Logger logger = LoggerFactory.getLogger(CapaHttpSpi.class);
+ /**
+ * Instantiates a new Capa http spi.
+ *
+ * @param httpClient the http client
+ * @param objectSerializer the object serializer
+ */
public CapaHttpSpi(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
super(httpClient, objectSerializer);
}
/**
* Templates, delegate to specific http invoker.
- *
- * @param httpMethod Ignore, fix to POST. FIXME
- * @param urlParameters Ignore, fix to EMPTY. FIXME
*/
@Override
protected CompletableFuture> doInvokeApi(String httpMethod,
@@ -73,22 +75,6 @@ protected CompletableFuture> doInvokeApi(String httpMethod,
logger.debug("[CapaHttpSpi] invoke rpc context[{}]", context);
}
}
- // FIXME Ignore, fix to POST.
- if (!HttpExtension.POST.getMethod().toString().equalsIgnoreCase(httpMethod)) {
- if (logger.isWarnEnabled()) {
- logger.warn("[CapaHttpSpi] invoke rpc httpMethod[{}] only support POST now.",
- httpMethod);
- }
- httpMethod = HttpExtension.POST.getMethod().toString();
- }
- // FIXME Ignore, fix to EMPTY.
- if (urlParameters != null && !urlParameters.isEmpty()) {
- if (logger.isWarnEnabled()) {
- logger.warn("[CapaHttpSpi] invoke rpc urlParameters[{}] not supported now.",
- urlParameters);
- }
- urlParameters = null;
- }
// parse url path segments
Objects.requireNonNull(pathSegments, "pathSegments");
@@ -112,7 +98,7 @@ protected CompletableFuture> doInvokeApi(String httpMethod,
// spi invoke
CompletableFuture> invokeSpiApi =
- invokeSpiApi(appId, method, requestData, headers, type, rpcServiceOptions);
+ invokeSpiApi(appId, method, requestData, httpMethod, headers, urlParameters, type, rpcServiceOptions);
invokeSpiApi.whenComplete((tHttpResponse, throwable) -> {
if (throwable != null) {
if (logger.isWarnEnabled()) {
@@ -141,6 +127,9 @@ protected CompletableFuture> doInvokeApi(String httpMethod,
/**
* Override to get the configuration of the corresponding appId.
+ *
+ * @param appId the app id
+ * @return the rpc service options
*/
protected RpcServiceOptions getRpcServiceOptions(String appId) {
CapaSpiOptionsLoader capaSpiOptionsLoader = CapaSpiProperties.getSpiOptionsLoader();
@@ -154,15 +143,20 @@ protected RpcServiceOptions getRpcServiceOptions(String appId) {
* @param appId the app id
* @param method the invoke method
* @param requestData the request data
+ * @param httpMethod the http method
* @param headers the headers
+ * @param urlParameters the url parameters
* @param type the response type
* @param rpcServiceOptions the rpc service options
* @return the async completable future
*/
- protected abstract CompletableFuture> invokeSpiApi(String appId,
- String method,
- Object requestData,
- Map headers,
- TypeRef type,
- RpcServiceOptions rpcServiceOptions);
+ protected abstract CompletableFuture> invokeSpiApi(
+ String appId,
+ String method,
+ Object requestData,
+ String httpMethod,
+ Map headers,
+ Map> urlParameters,
+ TypeRef type,
+ RpcServiceOptions rpcServiceOptions);
}
diff --git a/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaContextAsyncWrapperSpi.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaContextAsyncWrapperSpi.java
new file mode 100644
index 0000000..8062b67
--- /dev/null
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaContextAsyncWrapperSpi.java
@@ -0,0 +1,26 @@
+/*
+ * 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 group.rxcloud.capa.spi.telemetry;
+
+import group.rxcloud.capa.component.telemetry.context.CapaContextAsyncWrapper;
+
+/**
+ * SPI Capa context async wrapper.
+ */
+public abstract class CapaContextAsyncWrapperSpi implements CapaContextAsyncWrapper {
+
+}
diff --git a/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaReadWriteSpanSpi.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaReadWriteSpanSpi.java
new file mode 100644
index 0000000..a317306
--- /dev/null
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaReadWriteSpanSpi.java
@@ -0,0 +1,31 @@
+/*
+ * 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 group.rxcloud.capa.spi.telemetry;
+
+import group.rxcloud.capa.component.telemetry.trace.CapaReadWriteSpan;
+import io.opentelemetry.sdk.trace.ReadWriteSpan;
+
+/**
+ * SPI Capa read write span.
+ */
+public abstract class CapaReadWriteSpanSpi extends CapaReadWriteSpan {
+
+ public CapaReadWriteSpanSpi(String tracerName, String version, String schemaUrl,
+ ReadWriteSpan span) {
+ super(tracerName, version, schemaUrl, span);
+ }
+}
diff --git a/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaSpanBuilderSpi.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaSpanBuilderSpi.java
new file mode 100644
index 0000000..f9c3686
--- /dev/null
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaSpanBuilderSpi.java
@@ -0,0 +1,31 @@
+/*
+ * 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 group.rxcloud.capa.spi.telemetry;
+
+import group.rxcloud.capa.component.telemetry.trace.CapaSpanBuilder;
+import io.opentelemetry.api.trace.SpanBuilder;
+
+/**
+ * SPI Capa span builder.
+ */
+public abstract class CapaSpanBuilderSpi extends CapaSpanBuilder {
+
+ public CapaSpanBuilderSpi(String tracerName, String version, String schemaUrl, String spanName,
+ SpanBuilder spanBuilder) {
+ super(tracerName, version, schemaUrl, spanName, spanBuilder);
+ }
+}
diff --git a/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaTracerBuilderSpi.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaTracerBuilderSpi.java
new file mode 100644
index 0000000..3599480
--- /dev/null
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaTracerBuilderSpi.java
@@ -0,0 +1,30 @@
+/*
+ * 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 group.rxcloud.capa.spi.telemetry;
+
+import group.rxcloud.capa.component.telemetry.trace.CapaTracerBuilder;
+import io.opentelemetry.api.trace.TracerBuilder;
+
+/**
+ * SPI Capa tracer builder.
+ */
+public abstract class CapaTracerBuilderSpi extends CapaTracerBuilder {
+
+ public CapaTracerBuilderSpi(String tracerName, TracerBuilder builder) {
+ super(tracerName, builder);
+ }
+}
diff --git a/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaTracerSpi.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaTracerSpi.java
new file mode 100644
index 0000000..53239a5
--- /dev/null
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/CapaTracerSpi.java
@@ -0,0 +1,30 @@
+/*
+ * 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 group.rxcloud.capa.spi.telemetry;
+
+import group.rxcloud.capa.component.telemetry.trace.CapaTracer;
+import io.opentelemetry.api.trace.Tracer;
+
+/**
+ * SPI Capa tracer.
+ */
+public abstract class CapaTracerSpi extends CapaTracer {
+
+ public CapaTracerSpi(String tracerName, String version, String schemaUrl, Tracer tracer) {
+ super(tracerName, version, schemaUrl, tracer);
+ }
+}
diff --git a/sdk/src/main/java/group/rxcloud/capa/metrics/CapaMetricsClient.java b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/ContextPropagatorLoaderSpi.java
similarity index 70%
rename from sdk/src/main/java/group/rxcloud/capa/metrics/CapaMetricsClient.java
rename to sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/ContextPropagatorLoaderSpi.java
index c062ab3..148165d 100644
--- a/sdk/src/main/java/group/rxcloud/capa/metrics/CapaMetricsClient.java
+++ b/sdk-spi/src/main/java/group/rxcloud/capa/spi/telemetry/ContextPropagatorLoaderSpi.java
@@ -14,18 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package group.rxcloud.capa.metrics;
+package group.rxcloud.capa.spi.telemetry;
-import group.rxcloud.cloudruntimes.client.DefaultCloudRuntimesClient;
-import reactor.core.publisher.Mono;
+import group.rxcloud.capa.component.telemetry.context.ContextPropagatorLoader;
-public interface CapaMetricsClient extends DefaultCloudRuntimesClient {
- @Override
- default Mono shutdown() {
- return Mono.empty();
- }
+/**
+ * SPI context propagator loader.
+ */
+public abstract class ContextPropagatorLoaderSpi implements ContextPropagatorLoader {
- @Override
- void close();
}
diff --git a/sdk-spi/src/test/java/group/rxcloud/capa/spi/configstore/CapaConfigStoreSpiTest.java b/sdk-spi/src/test/java/group/rxcloud/capa/spi/configstore/CapaConfigStoreSpiTest.java
index c32c34a..b747a87 100644
--- a/sdk-spi/src/test/java/group/rxcloud/capa/spi/configstore/CapaConfigStoreSpiTest.java
+++ b/sdk-spi/src/test/java/group/rxcloud/capa/spi/configstore/CapaConfigStoreSpiTest.java
@@ -67,15 +67,15 @@ public void testSubscribe_Success() {
Flux> subscribeFlux = configStoreSpiImpl.subscribe(constructSubscribeReq(), TypeRef.STRING);
SubscribeResp resp = subscribeFlux.blockFirst();
Assertions.assertNotNull(resp);
- Assertions.assertEquals("12345",resp.getAppId());
+ Assertions.assertEquals("12345", resp.getAppId());
- Assertions.assertEquals(2,resp.getItems().size());
+ Assertions.assertEquals(2, resp.getItems().size());
ConfigurationItem firstConfigurationItem = resp.getItems().get(0);
- Assertions.assertEquals("testKey1",firstConfigurationItem.getKey());
+ Assertions.assertEquals("testKey1", firstConfigurationItem.getKey());
Assertions.assertNull(firstConfigurationItem.getContent());
- Assertions.assertEquals("testGroup",firstConfigurationItem.getGroup());
- Assertions.assertEquals("testLabel",firstConfigurationItem.getLabel());
+ Assertions.assertEquals("testGroup", firstConfigurationItem.getGroup());
+ Assertions.assertEquals("testLabel", firstConfigurationItem.getLabel());
Assertions.assertNotNull(firstConfigurationItem.getLabel());
Assertions.assertEquals(2, firstConfigurationItem.getTags().size());
@@ -114,12 +114,12 @@ private GetRequest constructGetRequest() {
return getRequest;
}
- private SubscribeReq constructSubscribeReq(){
+ private SubscribeReq constructSubscribeReq() {
SubscribeReq req = new SubscribeReq();
req.setAppId("12345");
req.setGroup("testGroup");
req.setLabel("testLabel");
- req.setKeys(Lists.newArrayList("testKey1","testKey2"));
+ req.setKeys(Lists.newArrayList("testKey1", "testKey2"));
Map metaDataMap = new HashMap<>();
metaDataMap.put("cluster", "default");
diff --git a/sdk-spi/src/test/java/group/rxcloud/capa/spi/http/CapaSerializeHttpSpiTest.java b/sdk-spi/src/test/java/group/rxcloud/capa/spi/http/CapaSerializeHttpSpiTest.java
index 351a9a4..b8dafe3 100644
--- a/sdk-spi/src/test/java/group/rxcloud/capa/spi/http/CapaSerializeHttpSpiTest.java
+++ b/sdk-spi/src/test/java/group/rxcloud/capa/spi/http/CapaSerializeHttpSpiTest.java
@@ -1,301 +1,311 @@
-/*
- * 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 group.rxcloud.capa.spi.http;
-
-import group.rxcloud.capa.component.http.CapaHttp;
-import group.rxcloud.capa.component.http.HttpResponse;
-import group.rxcloud.capa.infrastructure.exceptions.CapaException;
-import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
-import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
-import group.rxcloud.capa.infrastructure.serializer.ObjectSerializer;
-import group.rxcloud.capa.spi.http.config.RpcServiceOptions;
-import group.rxcloud.cloudruntimes.utils.TypeRef;
-import okhttp3.*;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import reactor.util.context.Context;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-public class CapaSerializeHttpSpiTest {
-
- private OkHttpClient okHttpClient;
-
- private TestCapaSerializeHttpSpi capaSerializeHttpSpi;
-
- private CapaObjectSerializer defaultObjectSerializer;
-
- @BeforeEach
- public void setUp() {
- okHttpClient = new OkHttpClient.Builder().build();
- defaultObjectSerializer = new DefaultObjectSerializer();
- capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, defaultObjectSerializer);
- }
-
- @Test
- public void testGetRequestWithSerialize_Success() throws IOException {
- byte[] serializerRequest = capaSerializeHttpSpi.getRequestWithSerialize("Object");
- String request = defaultObjectSerializer.deserialize(serializerRequest, TypeRef.STRING);
-
- Assertions.assertEquals("Object", request);
- }
-
- @Test
- public void testGetRequestWithSerialize_FailWhenThrowException() {
- capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestIOExceptionObjectSerializer());
- Assertions.assertThrows(CapaException.class, () -> {
- capaSerializeHttpSpi.getRequestWithSerialize("Object");
- });
-
- capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestRuntimeExceptionObjectSerializer());
- Assertions.assertThrows(CapaException.class, () -> {
- capaSerializeHttpSpi.getRequestWithSerialize("Object");
- });
- }
-
- @Test
- public void testGetRequestBodyWithSerialize_SuccessWhenHeaderHasValue() {
- Map headers = new HashMap<>();
- headers.put("content-type", "application/json");
-
- RequestBody requestBody = capaSerializeHttpSpi.getRequestBodyWithSerialize("Object", headers);
- String type = requestBody.contentType().type();
- String subtype = requestBody.contentType().subtype();
- Assertions.assertEquals("application", type);
- Assertions.assertEquals("json", subtype);
- }
-
- @Test
- public void testGetRequestBodyWithSerialize_SuccessWhenHeaderIsNull() {
- RequestBody requestBody = capaSerializeHttpSpi.getRequestBodyWithSerialize(null, null);
- String type = requestBody.contentType().type();
- String subtype = requestBody.contentType().subtype();
- Assertions.assertEquals("application", type);
- Assertions.assertEquals("json", subtype);
- }
-
- @Test
- public void testGetRequestHeaderWithParams_SuccessWhenHeaderHasValue() {
- Map headersParams = new HashMap<>();
- headersParams.put("key", "value");
- Headers requestHeaderWithParams = capaSerializeHttpSpi.getRequestHeaderWithParams(headersParams);
- String value = requestHeaderWithParams.get("key");
- Assertions.assertEquals("value", value);
- }
-
- @Test
- public void testGetRequestHeaderWithParams_SuccessWhenHeaderIsNull() {
- Headers requestHeaderWithParams = capaSerializeHttpSpi.getRequestHeaderWithParams(null);
- String value = requestHeaderWithParams.get("key");
- Assertions.assertNull(value);
- }
-
- @Test
- public void testDoAsyncInvoke0_Success() {
- Request request = new Request.Builder().url("https://www.url/").build();
-
- CompletableFuture> responseFuture = capaSerializeHttpSpi.doAsyncInvoke0(
- request,
- TypeRef.STRING);
- responseFuture.cancel(true);
- }
-
- @Test
- public void testGetResponseBodyWithDeserialize_Success() {
- HttpResponse httpResponse = new HttpResponse<>(null, null, 200);
- HttpResponse deserializeHttpResponse = capaSerializeHttpSpi.getResponseBodyWithDeserialize(
- TypeRef.STRING,
- httpResponse);
-
- int statusCode = deserializeHttpResponse.getStatusCode();
- Assertions.assertEquals(200, statusCode);
- }
-
- @Test
- public void testGetResponseBodyWithDeserialize_FailWhenThrowException() {
- HttpResponse httpResponse = new HttpResponse<>(null, null, 200);
- capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestIOExceptionObjectSerializer());
- Assertions.assertThrows(CapaException.class, () -> {
- capaSerializeHttpSpi.getResponseBodyWithDeserialize(TypeRef.STRING, httpResponse);
- });
-
- capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestRuntimeExceptionObjectSerializer());
- Assertions.assertThrows(CapaException.class, () -> {
- capaSerializeHttpSpi.getResponseBodyWithDeserialize(TypeRef.STRING, httpResponse);
- });
- }
-
- @Test
- public void testOnResponseInSerializationResponseFutureCallback_Success() throws IOException {
- CompletableFuture> future = new CompletableFuture<>();
- CapaSerializeHttpSpi.SerializationResponseFutureCallback responseFutureCallback =
- new CapaSerializeHttpSpi.SerializationResponseFutureCallback(future);
-
- Request request = new Request.Builder().url("https://www.url/").build();
- ResponseBody responseBody = ResponseBody.create(new byte[1],
- MediaType.get("application/json; charset=utf-8"));
-
- Response response = new Response.Builder()
- .request(request)
- .protocol(Protocol.HTTP_1_1)
- .message("message")
- .code(200)
- .build();
- responseFutureCallback.onResponse(null, response);
- future.cancel(true);
-
- response = new Response.Builder()
- .request(request)
- .protocol(Protocol.HTTP_1_1)
- .message("message")
- .code(200)
- .body(responseBody)
- .build();
- responseFutureCallback.onResponse(null, response);
- future.cancel(true);
- }
-
-
- @Test
- public void testGetRpcServiceOptions_Success() {
- RpcServiceOptions rpcServiceOptions = capaSerializeHttpSpi.getRpcServiceOptions("appId");
- String className = rpcServiceOptions.getClass().getName();
- Assertions.assertEquals("group.rxcloud.capa.spi.http.config.TestRpcServiceOptions", className);
- }
-
- @Test
- public void testDoInvokeApi_Success() throws ExecutionException, InterruptedException {
- String[] pathSegments = new String[]{
- CapaHttp.API_VERSION,
- "invoke", "appId",
- "method", "method"};
-
- Map> urlParameters = new HashMap<>();
- urlParameters.put("key", new ArrayList<>());
-
- Map headers = new HashMap<>();
- headers.put("content-type", "application/json");
-
- Context context = Context.of("content", "value");
-
- CompletableFuture> responseCompletableFuture = capaSerializeHttpSpi.doInvokeApi(
- "httpMethod",
- pathSegments,
- urlParameters,
- "requestData",
- headers,
- context,
- TypeRef.STRING);
-
- HttpResponse httpResponse = responseCompletableFuture.get();
- int statusCode = httpResponse.getStatusCode();
- Assertions.assertEquals(200, statusCode);
- }
-
- /**
- * serializer/deserializer for request/response objects used in tests only
- */
- private class TestRuntimeExceptionObjectSerializer extends ObjectSerializer implements CapaObjectSerializer {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public byte[] serialize(Object o) {
- throw new RuntimeException("test serialize exception");
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public T deserialize(byte[] data, TypeRef type) {
- throw new RuntimeException("test deserialize exception");
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getContentType() {
- return "";
- }
- }
-
-
- /**
- * serializer/deserializer for request/response objects used in tests only
- */
- private class TestIOExceptionObjectSerializer extends ObjectSerializer implements CapaObjectSerializer {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public byte[] serialize(Object o) throws IOException {
- throw new IOException("test serialize ioexception");
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public T deserialize(byte[] data, TypeRef type) throws IOException {
- throw new IOException("test deserialize ioexception");
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getContentType() {
- return "";
- }
- }
-
-
- /**
- * The test capa http invoker.
- */
- private class TestCapaSerializeHttpSpi extends CapaSerializeHttpSpi {
-
- public TestCapaSerializeHttpSpi(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
- super(httpClient, objectSerializer);
- }
-
- @Override
- protected CompletableFuture> invokeSpiApi(String appId,
- String method,
- Object requestData,
- Map headers,
- TypeRef type,
- RpcServiceOptions rpcServiceOptions) {
- return CompletableFuture.supplyAsync(
- () -> {
- return new HttpResponse<>(null, null, 200);
- },
- Runnable::run);
- }
- }
-}
+/*
+ * 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 group.rxcloud.capa.spi.http;
+
+import group.rxcloud.capa.component.http.CapaHttp;
+import group.rxcloud.capa.component.http.HttpResponse;
+import group.rxcloud.capa.infrastructure.exceptions.CapaException;
+import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
+import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
+import group.rxcloud.capa.infrastructure.serializer.ObjectSerializer;
+import group.rxcloud.capa.spi.http.config.RpcServiceOptions;
+import group.rxcloud.cloudruntimes.utils.TypeRef;
+import okhttp3.Headers;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Protocol;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import reactor.util.context.Context;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+public class CapaSerializeHttpSpiTest {
+
+ private OkHttpClient okHttpClient;
+
+ private TestCapaSerializeHttpSpi capaSerializeHttpSpi;
+
+ private CapaObjectSerializer defaultObjectSerializer;
+
+ @BeforeEach
+ public void setUp() {
+ okHttpClient = new OkHttpClient.Builder().build();
+ defaultObjectSerializer = new DefaultObjectSerializer();
+ capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, defaultObjectSerializer);
+ }
+
+ @Test
+ public void testGetRequestWithSerialize_Success() throws IOException {
+ byte[] serializerRequest = capaSerializeHttpSpi.getRequestWithSerialize("Object");
+ String request = defaultObjectSerializer.deserialize(serializerRequest, TypeRef.STRING);
+
+ Assertions.assertEquals("Object", request);
+ }
+
+ @Test
+ public void testGetRequestWithSerialize_FailWhenThrowException() {
+ capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestIOExceptionObjectSerializer());
+ Assertions.assertThrows(CapaException.class, () -> {
+ capaSerializeHttpSpi.getRequestWithSerialize("Object");
+ });
+
+ capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestRuntimeExceptionObjectSerializer());
+ Assertions.assertThrows(CapaException.class, () -> {
+ capaSerializeHttpSpi.getRequestWithSerialize("Object");
+ });
+ }
+
+ @Test
+ public void testGetRequestBodyWithSerialize_SuccessWhenHeaderHasValue() {
+ Map headers = new HashMap<>();
+ headers.put("content-type", "application/json");
+
+ RequestBody requestBody = capaSerializeHttpSpi.getRequestBodyWithSerialize("Object", headers);
+ String type = requestBody.contentType().type();
+ String subtype = requestBody.contentType().subtype();
+ Assertions.assertEquals("application", type);
+ Assertions.assertEquals("json", subtype);
+ }
+
+ @Test
+ public void testGetRequestBodyWithSerialize_SuccessWhenHeaderIsNull() {
+ RequestBody requestBody = capaSerializeHttpSpi.getRequestBodyWithSerialize(null, null);
+ String type = requestBody.contentType().type();
+ String subtype = requestBody.contentType().subtype();
+ Assertions.assertEquals("application", type);
+ Assertions.assertEquals("json", subtype);
+ }
+
+ @Test
+ public void testGetRequestHeaderWithParams_SuccessWhenHeaderHasValue() {
+ Map headersParams = new HashMap<>();
+ headersParams.put("key", "value");
+ Headers requestHeaderWithParams = capaSerializeHttpSpi.getRequestHeaderWithParams(headersParams);
+ String value = requestHeaderWithParams.get("key");
+ Assertions.assertEquals("value", value);
+ }
+
+ @Test
+ public void testGetRequestHeaderWithParams_SuccessWhenHeaderIsNull() {
+ Headers requestHeaderWithParams = capaSerializeHttpSpi.getRequestHeaderWithParams(null);
+ String value = requestHeaderWithParams.get("key");
+ Assertions.assertNull(value);
+ }
+
+ @Test
+ public void testDoAsyncInvoke0_Success() {
+ Request request = new Request.Builder().url("https://www.url/").build();
+
+ CompletableFuture> responseFuture = capaSerializeHttpSpi.doAsyncInvoke0(
+ request,
+ TypeRef.STRING);
+ responseFuture.cancel(true);
+ }
+
+ @Test
+ public void testGetResponseBodyWithDeserialize_Success() {
+ HttpResponse httpResponse = new HttpResponse<>(null, null, 200);
+ HttpResponse deserializeHttpResponse = capaSerializeHttpSpi.getResponseBodyWithDeserialize(
+ TypeRef.STRING,
+ httpResponse);
+
+ int statusCode = deserializeHttpResponse.getStatusCode();
+ Assertions.assertEquals(200, statusCode);
+ }
+
+ @Test
+ public void testGetResponseBodyWithDeserialize_FailWhenThrowException() {
+ HttpResponse httpResponse = new HttpResponse<>(null, null, 200);
+ capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestIOExceptionObjectSerializer());
+ Assertions.assertThrows(CapaException.class, () -> {
+ capaSerializeHttpSpi.getResponseBodyWithDeserialize(TypeRef.STRING, httpResponse);
+ });
+
+ capaSerializeHttpSpi = new TestCapaSerializeHttpSpi(okHttpClient, new TestRuntimeExceptionObjectSerializer());
+ Assertions.assertThrows(CapaException.class, () -> {
+ capaSerializeHttpSpi.getResponseBodyWithDeserialize(TypeRef.STRING, httpResponse);
+ });
+ }
+
+ @Test
+ public void testOnResponseInSerializationResponseFutureCallback_Success() throws IOException {
+ CompletableFuture> future = new CompletableFuture<>();
+ CapaSerializeHttpSpi.SerializationResponseFutureCallback responseFutureCallback =
+ new CapaSerializeHttpSpi.SerializationResponseFutureCallback(future);
+
+ Request request = new Request.Builder().url("https://www.url/").build();
+ ResponseBody responseBody = ResponseBody.create(new byte[1],
+ MediaType.get("application/json; charset=utf-8"));
+
+ Response response = new Response.Builder()
+ .request(request)
+ .protocol(Protocol.HTTP_1_1)
+ .message("message")
+ .code(200)
+ .build();
+ responseFutureCallback.onResponse(null, response);
+ future.cancel(true);
+
+ response = new Response.Builder()
+ .request(request)
+ .protocol(Protocol.HTTP_1_1)
+ .message("message")
+ .code(200)
+ .body(responseBody)
+ .build();
+ responseFutureCallback.onResponse(null, response);
+ future.cancel(true);
+ }
+
+
+ @Test
+ public void testGetRpcServiceOptions_Success() {
+ RpcServiceOptions rpcServiceOptions = capaSerializeHttpSpi.getRpcServiceOptions("appId");
+ String className = rpcServiceOptions.getClass().getName();
+ Assertions.assertEquals("group.rxcloud.capa.spi.http.config.TestRpcServiceOptions", className);
+ }
+
+ @Test
+ public void testDoInvokeApi_Success() throws ExecutionException, InterruptedException {
+ String[] pathSegments = new String[]{
+ CapaHttp.API_VERSION,
+ "invoke", "appId",
+ "method", "method"};
+
+ Map> urlParameters = new HashMap<>();
+ urlParameters.put("key", new ArrayList<>());
+
+ Map headers = new HashMap<>();
+ headers.put("content-type", "application/json");
+
+ Context context = Context.of("content", "value");
+
+ CompletableFuture> responseCompletableFuture = capaSerializeHttpSpi.doInvokeApi(
+ "httpMethod",
+ pathSegments,
+ urlParameters,
+ "requestData",
+ headers,
+ context,
+ TypeRef.STRING);
+
+ HttpResponse httpResponse = responseCompletableFuture.get();
+ int statusCode = httpResponse.getStatusCode();
+ Assertions.assertEquals(200, statusCode);
+ }
+
+ /**
+ * serializer/deserializer for request/response objects used in tests only
+ */
+ private class TestRuntimeExceptionObjectSerializer extends ObjectSerializer implements CapaObjectSerializer {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte[] serialize(Object o) {
+ throw new RuntimeException("test serialize exception");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T deserialize(byte[] data, TypeRef type) {
+ throw new RuntimeException("test deserialize exception");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getContentType() {
+ return "";
+ }
+ }
+
+
+ /**
+ * serializer/deserializer for request/response objects used in tests only
+ */
+ private class TestIOExceptionObjectSerializer extends ObjectSerializer implements CapaObjectSerializer {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte[] serialize(Object o) throws IOException {
+ throw new IOException("test serialize ioexception");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public T deserialize(byte[] data, TypeRef type) throws IOException {
+ throw new IOException("test deserialize ioexception");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getContentType() {
+ return "";
+ }
+ }
+
+
+ /**
+ * The test capa http invoker.
+ */
+ private class TestCapaSerializeHttpSpi extends CapaSerializeHttpSpi {
+
+ public TestCapaSerializeHttpSpi(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
+ super(httpClient, objectSerializer);
+ }
+
+ @Override
+ protected CompletableFuture> invokeSpiApi(
+ String appId,
+ String method,
+ Object requestData,
+ String httpMethod,
+ Map headers,
+ Map> urlParameters,
+ TypeRef type,
+ RpcServiceOptions rpcServiceOptions) {
+ return CompletableFuture.supplyAsync(
+ () -> {
+ return new HttpResponse<>(null, null, 200);
+ },
+ Runnable::run);
+ }
+ }
+}
diff --git a/sdk-springboot/pom.xml b/sdk-springboot/pom.xml
index a6790d7..8febac5 100644
--- a/sdk-springboot/pom.xml
+++ b/sdk-springboot/pom.xml
@@ -23,7 +23,7 @@
capa-parentgroup.rxcloud
- 1.0.6.RELEASE
+ 1.0.7.RELEASEsdk-springboot
diff --git a/sdk/pom.xml b/sdk/pom.xml
index 62a8172..b1e9a06 100644
--- a/sdk/pom.xml
+++ b/sdk/pom.xml
@@ -23,7 +23,7 @@
group.rxcloudcapa-parent
- 1.0.6.RELEASE
+ 1.0.7.RELEASEcapa-sdk
diff --git a/sdk/src/main/java/group/rxcloud/capa/configuration/AbstractCapaConfigurationClient.java b/sdk/src/main/java/group/rxcloud/capa/configuration/AbstractCapaConfigurationClient.java
index b43d6d5..e11cbaa 100644
--- a/sdk/src/main/java/group/rxcloud/capa/configuration/AbstractCapaConfigurationClient.java
+++ b/sdk/src/main/java/group/rxcloud/capa/configuration/AbstractCapaConfigurationClient.java
@@ -34,6 +34,13 @@
*/
public abstract class AbstractCapaConfigurationClient implements CapaConfigurationClient {
+ protected List registryNames;
+
+ @Override
+ public List registryNames() {
+ return registryNames;
+ }
+
@Override
public Mono saveConfiguration(SaveConfigurationRequest saveConfigurationRequest) {
return Mono.error(new UnsupportedOperationException("unsupported save configuration"));
diff --git a/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClient.java b/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClient.java
index edd780f..aa213e1 100644
--- a/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClient.java
+++ b/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClient.java
@@ -63,7 +63,6 @@ public interface CapaConfigurationClient extends DefaultCloudRuntimesClient {
@Override
Mono deleteConfiguration(ConfigurationRequestItem configurationRequestItem);
-
@Override
default Mono shutdown() {
return Mono.empty();
diff --git a/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClientStore.java b/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClientStore.java
index 67454d9..2a143e4 100644
--- a/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClientStore.java
+++ b/sdk/src/main/java/group/rxcloud/capa/configuration/CapaConfigurationClientStore.java
@@ -28,6 +28,7 @@
import reactor.core.publisher.Mono;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -50,11 +51,13 @@ public class CapaConfigurationClientStore extends AbstractCapaConfigurationClien
public CapaConfigurationClientStore(List stores) {
if (stores == null || stores.isEmpty()) {
this.configStores = new HashMap<>(2, 1);
+ this.registryNames = Collections.emptyList();
} else {
this.configStores = stores.stream()
.collect(Collectors.toMap(
CapaConfigStore::getStoreName,
Function.identity()));
+ this.registryNames = new ArrayList<>(this.configStores.keySet());
}
}
diff --git a/sdk/src/main/java/group/rxcloud/capa/pubsub/AbstractCapaPubSubClient.java b/sdk/src/main/java/group/rxcloud/capa/pubsub/AbstractCapaPubSubClient.java
index d91d0bd..1c051ec 100644
--- a/sdk/src/main/java/group/rxcloud/capa/pubsub/AbstractCapaPubSubClient.java
+++ b/sdk/src/main/java/group/rxcloud/capa/pubsub/AbstractCapaPubSubClient.java
@@ -19,6 +19,7 @@
import group.rxcloud.cloudruntimes.domain.core.pubsub.PublishEventRequest;
import reactor.core.publisher.Mono;
+import java.util.List;
import java.util.Map;
/**
@@ -28,6 +29,13 @@
*/
public abstract class AbstractCapaPubSubClient implements CapaPubSubClient {
+ protected List registryNames;
+
+ @Override
+ public List registryNames() {
+ return registryNames;
+ }
+
@Override
public Mono publishEvent(String pubsubName, String topicName, Object data) {
PublishEventRequest publishEventRequest = new PublishEventRequest(pubsubName, topicName, data);
diff --git a/sdk/src/main/java/group/rxcloud/capa/pubsub/CapaPubSubClientPubSub.java b/sdk/src/main/java/group/rxcloud/capa/pubsub/CapaPubSubClientPubSub.java
index f7d089f..2816c5b 100644
--- a/sdk/src/main/java/group/rxcloud/capa/pubsub/CapaPubSubClientPubSub.java
+++ b/sdk/src/main/java/group/rxcloud/capa/pubsub/CapaPubSubClientPubSub.java
@@ -22,6 +22,8 @@
import group.rxcloud.cloudruntimes.domain.core.pubsub.PublishEventRequest;
import reactor.core.publisher.Mono;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -44,11 +46,13 @@ public class CapaPubSubClientPubSub extends AbstractCapaPubSubClient {
public CapaPubSubClientPubSub(List pubSubs) {
if (pubSubs == null || pubSubs.isEmpty()) {
this.pubSubs = new HashMap<>(2, 1);
+ this.registryNames = Collections.emptyList();
} else {
this.pubSubs = pubSubs.stream()
.collect(Collectors.toMap(
CapaPubSub::getPubSubName,
Function.identity()));
+ this.registryNames = new ArrayList<>(this.pubSubs.keySet());
}
}
diff --git a/sdk/src/main/java/group/rxcloud/capa/rpc/AbstractCapaRpcClient.java b/sdk/src/main/java/group/rxcloud/capa/rpc/AbstractCapaRpcClient.java
index 38bbd27..ebaf8ef 100644
--- a/sdk/src/main/java/group/rxcloud/capa/rpc/AbstractCapaRpcClient.java
+++ b/sdk/src/main/java/group/rxcloud/capa/rpc/AbstractCapaRpcClient.java
@@ -22,6 +22,7 @@
import group.rxcloud.cloudruntimes.utils.TypeRef;
import reactor.core.publisher.Mono;
+import java.util.List;
import java.util.Map;
/**
@@ -31,6 +32,13 @@
*/
public abstract class AbstractCapaRpcClient implements CapaRpcClient {
+ protected List registryNames;
+
+ @Override
+ public List registryNames() {
+ return registryNames;
+ }
+
@Override
public Mono invokeMethod(String appId, String methodName, Object request, HttpExtension httpExtension, Map metadata, TypeRef type) {
InvokeMethodRequestBuilder builder = new InvokeMethodRequestBuilder(appId, methodName);
diff --git a/sdk/src/main/java/group/rxcloud/capa/rpc/CapaRpcClientHttp.java b/sdk/src/main/java/group/rxcloud/capa/rpc/CapaRpcClientHttp.java
index 6c7ebe8..6e7ea9c 100644
--- a/sdk/src/main/java/group/rxcloud/capa/rpc/CapaRpcClientHttp.java
+++ b/sdk/src/main/java/group/rxcloud/capa/rpc/CapaRpcClientHttp.java
@@ -23,6 +23,7 @@
import group.rxcloud.cloudruntimes.utils.TypeRef;
import reactor.core.publisher.Mono;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -41,6 +42,9 @@ public class CapaRpcClientHttp extends AbstractCapaRpcClient {
public CapaRpcClientHttp(CapaHttp client) {
this.client = client;
+
+ this.registryNames = new ArrayList<>(1);
+ this.registryNames.add("http");
}
@Override
diff --git a/sdk/src/main/java/group/rxcloud/capa/state/CapaStateClient.java b/sdk/src/main/java/group/rxcloud/capa/state/CapaStateClient.java
index 73f19c8..d884c39 100644
--- a/sdk/src/main/java/group/rxcloud/capa/state/CapaStateClient.java
+++ b/sdk/src/main/java/group/rxcloud/capa/state/CapaStateClient.java
@@ -17,14 +17,14 @@
package group.rxcloud.capa.state;
import group.rxcloud.cloudruntimes.client.DefaultCloudRuntimesClient;
-import group.rxcloud.cloudruntimes.domain.core.state.State;
import group.rxcloud.cloudruntimes.domain.core.state.DeleteStateRequest;
+import group.rxcloud.cloudruntimes.domain.core.state.ExecuteStateTransactionRequest;
import group.rxcloud.cloudruntimes.domain.core.state.GetBulkStateRequest;
import group.rxcloud.cloudruntimes.domain.core.state.GetStateRequest;
-import group.rxcloud.cloudruntimes.domain.core.state.ExecuteStateTransactionRequest;
-import group.rxcloud.cloudruntimes.domain.core.state.TransactionalStateOperation;
-import group.rxcloud.cloudruntimes.domain.core.state.StateOptions;
import group.rxcloud.cloudruntimes.domain.core.state.SaveStateRequest;
+import group.rxcloud.cloudruntimes.domain.core.state.State;
+import group.rxcloud.cloudruntimes.domain.core.state.StateOptions;
+import group.rxcloud.cloudruntimes.domain.core.state.TransactionalStateOperation;
import group.rxcloud.cloudruntimes.utils.TypeRef;
import reactor.core.publisher.Mono;
diff --git a/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClient.java b/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClient.java
new file mode 100644
index 0000000..b7f06ff
--- /dev/null
+++ b/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClient.java
@@ -0,0 +1,50 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import group.rxcloud.cloudruntimes.client.DefaultCloudRuntimesClient;
+import io.opentelemetry.api.metrics.Meter;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import reactor.core.publisher.Mono;
+
+public interface CapaTelemetryClient extends DefaultCloudRuntimesClient {
+
+ @Override
+ Mono buildTracer(String tracerName);
+
+ @Override
+ Mono getContextPropagators();
+
+ @Override
+ Mono buildTracer(String tracerName, String version);
+
+ @Override
+ Mono buildTracer(String tracerName, String version, String schemaUrl);
+
+ @Override
+ Mono buildMeter(String meterName);
+
+ @Override
+ Mono buildMeter(String meterName, String version);
+
+ @Override
+ Mono buildMeter(String meterName, String version, String schemaUrl);
+
+ @Override
+ void close();
+}
diff --git a/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClientBuilder.java b/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClientBuilder.java
new file mode 100644
index 0000000..9b5023a
--- /dev/null
+++ b/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClientBuilder.java
@@ -0,0 +1,117 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import group.rxcloud.capa.component.telemetry.context.CapaContextPropagatorBuilder;
+import group.rxcloud.capa.component.telemetry.context.CapaContextPropagatorSettings;
+import group.rxcloud.capa.component.telemetry.context.ContextConfig;
+import group.rxcloud.capa.component.telemetry.metrics.CapaMeterProviderBuilder;
+import group.rxcloud.capa.component.telemetry.metrics.CapaMeterProviderSettings;
+import group.rxcloud.capa.component.telemetry.metrics.MeterConfig;
+import group.rxcloud.capa.component.telemetry.metrics.MetricsReaderConfig;
+import group.rxcloud.capa.component.telemetry.trace.CapaTracerProviderBuilder;
+import group.rxcloud.capa.component.telemetry.trace.CapaTracerProviderSettings;
+import group.rxcloud.capa.component.telemetry.trace.SpanLimitsConfig;
+import group.rxcloud.capa.component.telemetry.trace.TracerConfig;
+import io.opentelemetry.context.propagation.TextMapPropagator;
+import io.opentelemetry.sdk.trace.IdGenerator;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+
+/**
+ * A builder for the {@link CapaTelemetryClient}
+ */
+public class CapaTelemetryClientBuilder implements CapaContextPropagatorSettings, CapaTracerProviderSettings, CapaMeterProviderSettings {
+
+ private final CapaTracerProviderBuilder tracerProviderBuilder = new CapaTracerProviderBuilder();
+
+ private final CapaMeterProviderBuilder meterProviderBuilder = new CapaMeterProviderBuilder();
+
+ private final CapaContextPropagatorBuilder contextPropagatorBuilder = new CapaContextPropagatorBuilder();
+
+ @Override
+ public CapaTelemetryClientBuilder setTracerConfig(TracerConfig tracerConfig) {
+ tracerProviderBuilder.setTracerConfig(tracerConfig);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder setSpanLimits(SpanLimitsConfig spanLimits) {
+ tracerProviderBuilder.setSpanLimits(spanLimits);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder setIdGenerator(IdGenerator idGenerator) {
+ tracerProviderBuilder.setIdGenerator(idGenerator);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder addProcessor(SpanProcessor processor) {
+ tracerProviderBuilder.addProcessor(processor);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder setContextConfig(ContextConfig config) {
+ contextPropagatorBuilder.setContextConfig(config);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder addContextPropagators(TextMapPropagator processor) {
+ contextPropagatorBuilder.addContextPropagators(processor);
+ return this;
+ }
+
+
+ @Override
+ public CapaTelemetryClientBuilder setMeterConfig(MeterConfig config) {
+ meterProviderBuilder.setMeterConfig(config);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder addMetricReaderConfig(MetricsReaderConfig config) {
+ meterProviderBuilder.addMetricReaderConfig(config);
+ return this;
+ }
+
+ @Override
+ public CapaTelemetryClientBuilder setSamplerConfig(SamplerConfig samplerConfig) {
+ meterProviderBuilder.setSamplerConfig(samplerConfig);
+ tracerProviderBuilder.setSamplerConfig(samplerConfig);
+ return this;
+ }
+
+ public CapaTelemetryClient build() {
+ CapaTelemetryClientGlobal client = new CapaTelemetryClientGlobal();
+
+ // context
+ client.setContextPropagators(contextPropagatorBuilder.buildContextPropagators());
+
+ // tracer
+ client.setTracerProvider(tracerProviderBuilder.buildTracerProvider());
+
+ // meter
+ client.setMeterProvider(meterProviderBuilder.buildMeterProvider());
+
+ return client;
+ }
+
+}
diff --git a/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClientGlobal.java b/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClientGlobal.java
new file mode 100644
index 0000000..5755b13
--- /dev/null
+++ b/sdk/src/main/java/group/rxcloud/capa/telemetry/CapaTelemetryClientGlobal.java
@@ -0,0 +1,152 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.metrics.Meter;
+import io.opentelemetry.api.metrics.MeterProvider;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.TracerProvider;
+import io.opentelemetry.context.propagation.ContextPropagators;
+import reactor.core.publisher.Mono;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CapaTelemetryClientGlobal implements CapaTelemetryClient, OpenTelemetry {
+
+ // noop as default.
+ private static volatile CapaTelemetryClientGlobal instance;
+
+ private TracerProvider tracerProvider = TracerProvider.noop();
+
+ private MeterProvider meterProvider = MeterProvider.noop();
+
+ private ContextPropagators contextPropagators = ContextPropagators.noop();
+
+ public static CapaTelemetryClientGlobal getOrCreate() {
+ if (instance == null) {
+ synchronized (CapaTelemetryClientGlobal.class) {
+ if (instance == null) {
+ instance = (CapaTelemetryClientGlobal) new CapaTelemetryClientBuilder().build();
+ GlobalOpenTelemetry.set(instance);
+ }
+ }
+ }
+ return instance;
+ }
+
+ static void set(CapaTelemetryClientGlobal capaTelemetryClient) {
+ instance = capaTelemetryClient;
+ }
+
+ protected List registryNames;
+
+ @Override
+ public List registryNames() {
+ return registryNames;
+ }
+
+ CapaTelemetryClientGlobal() {
+ this.registryNames = new ArrayList<>(1);
+ this.registryNames.add("opentelemetry");
+ }
+
+ @Override
+ public TracerProvider getTracerProvider() {
+ return tracerProvider;
+ }
+
+ void setTracerProvider(TracerProvider tracerProvider) {
+ this.tracerProvider = tracerProvider;
+ }
+
+ public MeterProvider getMeterProvider() {
+ return meterProvider;
+ }
+
+ void setMeterProvider(MeterProvider meterProvider) {
+ this.meterProvider = meterProvider;
+ }
+
+ @Override
+ public ContextPropagators getPropagators() {
+ return contextPropagators;
+ }
+
+ @Override
+ public Mono buildTracer(String tracerName) {
+ return Mono.fromSupplier(() -> {
+ return tracerProvider.tracerBuilder(tracerName).build();
+ });
+ }
+
+ @Override
+ public Mono getContextPropagators() {
+ return Mono.fromSupplier(() -> {
+ return contextPropagators;
+ });
+ }
+
+ void setContextPropagators(ContextPropagators contextPropagators) {
+ this.contextPropagators = contextPropagators;
+ }
+
+ @Override
+ public Mono buildTracer(String tracerName, String version) {
+ return Mono.fromSupplier(() -> {
+ return tracerProvider.tracerBuilder(tracerName).setInstrumentationVersion(version).build();
+ });
+ }
+
+ @Override
+ public Mono buildTracer(String tracerName, String version, String schemaUrl) {
+ return Mono.fromSupplier(() -> {
+ return tracerProvider.tracerBuilder(tracerName).setInstrumentationVersion(version).setSchemaUrl(schemaUrl)
+ .build();
+ });
+ }
+
+ @Override
+ public Mono buildMeter(String meterName) {
+ return Mono.fromSupplier(() -> {
+ return meterProvider.meterBuilder(meterName)
+ .build();
+ });
+ }
+
+ @Override
+ public Mono buildMeter(String meterName, String version) {
+ return Mono.fromSupplier(() -> {
+ return meterProvider.meterBuilder(meterName).setInstrumentationVersion(version)
+ .build();
+ });
+ }
+
+ @Override
+ public Mono buildMeter(String meterName, String version, String schemaUrl) {
+ return Mono.fromSupplier(() -> {
+ return meterProvider.meterBuilder(meterName).setInstrumentationVersion(version).setSchemaUrl(schemaUrl)
+ .build();
+ });
+ }
+
+ @Override
+ public void close() {
+ }
+}
diff --git a/sdk/src/test/java/group/rxcloud/capa/configuration/TestCapaConfigStore.java b/sdk/src/test/java/group/rxcloud/capa/configuration/TestCapaConfigStore.java
index 868837c..c9b0374 100644
--- a/sdk/src/test/java/group/rxcloud/capa/configuration/TestCapaConfigStore.java
+++ b/sdk/src/test/java/group/rxcloud/capa/configuration/TestCapaConfigStore.java
@@ -16,7 +16,13 @@
*/
package group.rxcloud.capa.configuration;
-import group.rxcloud.capa.component.configstore.*;
+import group.rxcloud.capa.component.configstore.CapaConfigStore;
+import group.rxcloud.capa.component.configstore.ConfigurationItem;
+import group.rxcloud.capa.component.configstore.GetRequest;
+import group.rxcloud.capa.component.configstore.StoreConfig;
+import group.rxcloud.capa.component.configstore.SubscribeReq;
+import group.rxcloud.capa.component.configstore.SubscribeResp;
+import group.rxcloud.capa.infrastructure.hook.TelemetryHooks;
import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
import group.rxcloud.cloudruntimes.utils.TypeRef;
import reactor.core.publisher.Flux;
@@ -37,7 +43,7 @@ public class TestCapaConfigStore extends CapaConfigStore {
*
* @param objectSerializer Serializer for transient request/response objects.
*/
- public TestCapaConfigStore(CapaObjectSerializer objectSerializer) {
+ public TestCapaConfigStore(CapaObjectSerializer objectSerializer, TelemetryHooks telemetryHooks) {
super(objectSerializer);
}
diff --git a/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientBuilderTest.java b/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientBuilderTest.java
index 2d10759..178176d 100644
--- a/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientBuilderTest.java
+++ b/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientBuilderTest.java
@@ -1,229 +1,232 @@
-/*
- * 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 group.rxcloud.capa.rpc;
-
-import group.rxcloud.capa.component.http.CapaHttp;
-import group.rxcloud.capa.component.http.HttpResponse;
-import group.rxcloud.capa.infrastructure.exceptions.CapaException;
-import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
-import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
-import group.rxcloud.capa.rpc.domain.InvokeMethodRequestBuilder;
-import group.rxcloud.cloudruntimes.domain.core.invocation.HttpExtension;
-import group.rxcloud.cloudruntimes.domain.core.invocation.InvokeMethodRequest;
-import group.rxcloud.cloudruntimes.utils.TypeRef;
-import okhttp3.OkHttpClient;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import reactor.core.publisher.Mono;
-import reactor.util.context.Context;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-
-public class CapaRpcClientBuilderTest {
-
- private CapaRpcClientHttp capaRpcClientHttp;
-
- private OkHttpClient okHttpClient;
-
- private DefaultObjectSerializer defaultObjectSerializer;
-
- @BeforeEach
- public void setUp() {
- okHttpClient = new OkHttpClient.Builder().build();
- defaultObjectSerializer = new DefaultObjectSerializer();
- capaRpcClientHttp = new CapaRpcClientHttp(new TestCapaHttp(okHttpClient, defaultObjectSerializer));
- }
-
- @Test
- public void testInvokeMethod_FailWhenAppIdIsEmpty() {
- InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("", "method").build();
-
- Mono stringMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
-
- Assertions.assertThrows(IllegalArgumentException.class, () -> {
- stringMono.block();
- });
- }
-
- @Test
- public void testInvokeMethod_FailWhenMethodIsEmpty() {
- InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("appId", "").build();
-
- Mono stringMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
-
- Assertions.assertThrows(IllegalArgumentException.class, () -> {
- stringMono.block();
- });
- }
-
- @Test
- public void testInvokeMethod_FailWhenHttpExtensionIsNull() {
- InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("appId", "method")
- .withHttpExtension(null)
- .build();
-
- Mono stringMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
-
- Assertions.assertThrows(IllegalArgumentException.class, () -> {
- stringMono.block();
- });
- }
-
- @Test
- public void testInvokeMethod_Success() {
- Map metadata = new HashMap<>();
- metadata.put("key", "value");
-
- InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("appId", "method")
- .withHttpExtension(HttpExtension.POST)
- .withMetadata(metadata)
- .build();
-
- Mono responseMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
- String response = responseMono.block();
-
- Assertions.assertNull(response);
- }
-
- @Test
- public void testAbstractInvokeMethod_Success() {
- Map metadata = new HashMap<>();
- metadata.put("key", "value");
-
- Mono responseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- "request",
- HttpExtension.POST,
- metadata,
- String.class);
- String response = responseMono.block();
- Assertions.assertNull(response);
-
- responseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- "request",
- HttpExtension.POST,
- TypeRef.STRING);
- response = responseMono.block();
- Assertions.assertNull(response);
-
- responseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- "request",
- HttpExtension.POST,
- String.class);
- response = responseMono.block();
- Assertions.assertNull(response);
-
- responseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- HttpExtension.POST,
- metadata,
- String.class);
- response = responseMono.block();
- Assertions.assertNull(response);
-
- responseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- HttpExtension.POST,
- metadata,
- TypeRef.STRING);
- response = responseMono.block();
- Assertions.assertNull(response);
-
- Mono voidResponseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- "request",
- HttpExtension.POST,
- metadata);
- voidResponseMono.block();
-
- voidResponseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- "request",
- HttpExtension.POST);
- voidResponseMono.block();
-
- voidResponseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- HttpExtension.POST,
- metadata);
- voidResponseMono.block();
-
- Mono byteResponseMono = capaRpcClientHttp.invokeMethod("appId",
- "method",
- new byte[1],
- HttpExtension.POST,
- metadata);
- byte[] byteResponse = byteResponseMono.block();
- Assertions.assertNull(byteResponse);
-
- }
-
- @Test
- public void testShutdown_Success() {
- Mono shutdown = capaRpcClientHttp.shutdown();
- shutdown.block();
- }
-
- @Test
- public void testClose_Success() {
- capaRpcClientHttp.close();
- }
-
- @Test
- public void testClose_FailWhenThrowException() {
-
- capaRpcClientHttp = new CapaRpcClientHttp(new ExceptionCapaHttp(okHttpClient, defaultObjectSerializer));
-
- Assertions.assertThrows(CapaException.class, () -> {
- capaRpcClientHttp.close();
- });
- }
-
- /**
- * The capa http invoker used in tests only.
- */
- private class ExceptionCapaHttp extends CapaHttp {
-
- public ExceptionCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
- super(httpClient, objectSerializer);
- }
-
- @Override
- protected CompletableFuture> doInvokeApi(String httpMethod,
- String[] pathSegments,
- Map> urlParameters,
- Object requestData,
- Map headers,
- Context context,
- TypeRef type) {
- return null;
- }
-
- @Override
- public void close() {
- throw new RuntimeException() {
- };
- }
- }
-}
+/*
+ * 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 group.rxcloud.capa.rpc;
+
+import group.rxcloud.capa.component.http.CapaHttp;
+import group.rxcloud.capa.component.http.HttpResponse;
+import group.rxcloud.capa.infrastructure.exceptions.CapaException;
+import group.rxcloud.capa.infrastructure.hook.ConfigurationHooks;
+import group.rxcloud.capa.infrastructure.hook.TelemetryHooks;
+import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
+import group.rxcloud.capa.infrastructure.serializer.DefaultObjectSerializer;
+import group.rxcloud.capa.rpc.domain.InvokeMethodRequestBuilder;
+import group.rxcloud.cloudruntimes.domain.core.invocation.HttpExtension;
+import group.rxcloud.cloudruntimes.domain.core.invocation.InvokeMethodRequest;
+import group.rxcloud.cloudruntimes.utils.TypeRef;
+import okhttp3.OkHttpClient;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import reactor.core.publisher.Mono;
+import reactor.util.context.Context;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+
+public class CapaRpcClientBuilderTest {
+
+ private CapaRpcClientHttp capaRpcClientHttp;
+
+ private OkHttpClient okHttpClient;
+
+ private DefaultObjectSerializer defaultObjectSerializer;
+
+ @BeforeEach
+ public void setUp() {
+ okHttpClient = new OkHttpClient.Builder().build();
+ defaultObjectSerializer = new DefaultObjectSerializer();
+ capaRpcClientHttp = new CapaRpcClientHttp(new TestCapaHttp(okHttpClient, defaultObjectSerializer));
+ }
+
+ @Test
+ public void testInvokeMethod_FailWhenAppIdIsEmpty() {
+ InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("", "method").build();
+
+ Mono stringMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ stringMono.block();
+ });
+ }
+
+ @Test
+ public void testInvokeMethod_FailWhenMethodIsEmpty() {
+ InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("appId", "").build();
+
+ Mono stringMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ stringMono.block();
+ });
+ }
+
+ @Test
+ public void testInvokeMethod_FailWhenHttpExtensionIsNull() {
+ InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("appId", "method")
+ .withHttpExtension(null)
+ .build();
+
+ Mono stringMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ stringMono.block();
+ });
+ }
+
+ @Test
+ public void testInvokeMethod_Success() {
+ Map metadata = new HashMap<>();
+ metadata.put("key", "value");
+
+ InvokeMethodRequest methodRequest = new InvokeMethodRequestBuilder("appId", "method")
+ .withHttpExtension(HttpExtension.POST)
+ .withMetadata(metadata)
+ .build();
+
+ Mono responseMono = capaRpcClientHttp.invokeMethod(methodRequest, TypeRef.STRING);
+ String response = responseMono.block();
+
+ Assertions.assertNull(response);
+ }
+
+ @Test
+ public void testAbstractInvokeMethod_Success() {
+ Map metadata = new HashMap<>();
+ metadata.put("key", "value");
+
+ Mono responseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ "request",
+ HttpExtension.POST,
+ metadata,
+ String.class);
+ String response = responseMono.block();
+ Assertions.assertNull(response);
+
+ responseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ "request",
+ HttpExtension.POST,
+ TypeRef.STRING);
+ response = responseMono.block();
+ Assertions.assertNull(response);
+
+ responseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ "request",
+ HttpExtension.POST,
+ String.class);
+ response = responseMono.block();
+ Assertions.assertNull(response);
+
+ responseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ HttpExtension.POST,
+ metadata,
+ String.class);
+ response = responseMono.block();
+ Assertions.assertNull(response);
+
+ responseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ HttpExtension.POST,
+ metadata,
+ TypeRef.STRING);
+ response = responseMono.block();
+ Assertions.assertNull(response);
+
+ Mono voidResponseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ "request",
+ HttpExtension.POST,
+ metadata);
+ voidResponseMono.block();
+
+ voidResponseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ "request",
+ HttpExtension.POST);
+ voidResponseMono.block();
+
+ voidResponseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ HttpExtension.POST,
+ metadata);
+ voidResponseMono.block();
+
+ Mono byteResponseMono = capaRpcClientHttp.invokeMethod("appId",
+ "method",
+ new byte[1],
+ HttpExtension.POST,
+ metadata);
+ byte[] byteResponse = byteResponseMono.block();
+ Assertions.assertNull(byteResponse);
+
+ }
+
+ @Test
+ public void testShutdown_Success() {
+ Mono shutdown = capaRpcClientHttp.shutdown();
+ shutdown.block();
+ }
+
+ @Test
+ public void testClose_Success() {
+ capaRpcClientHttp.close();
+ }
+
+ @Test
+ public void testClose_FailWhenThrowException() {
+
+ capaRpcClientHttp = new CapaRpcClientHttp(new ExceptionCapaHttp(okHttpClient, defaultObjectSerializer, null, null));
+
+ Assertions.assertThrows(CapaException.class, () -> {
+ capaRpcClientHttp.close();
+ });
+ }
+
+ /**
+ * The capa http invoker used in tests only.
+ */
+ private class ExceptionCapaHttp extends CapaHttp {
+
+ public ExceptionCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializer,
+ TelemetryHooks telemetryHooks, ConfigurationHooks configurationHooks) {
+ super(httpClient, objectSerializer);
+ }
+
+ @Override
+ protected CompletableFuture> doInvokeApi(String httpMethod,
+ String[] pathSegments,
+ Map> urlParameters,
+ Object requestData,
+ Map headers,
+ Context context,
+ TypeRef type) {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ throw new RuntimeException() {
+ };
+ }
+ }
+}
diff --git a/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientHttpTest.java b/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientHttpTest.java
index c78ce02..68640a6 100644
--- a/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientHttpTest.java
+++ b/sdk/src/test/java/group/rxcloud/capa/rpc/CapaRpcClientHttpTest.java
@@ -1,44 +1,44 @@
-/*
- * 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 group.rxcloud.capa.rpc;
-
-import group.rxcloud.capa.component.http.CapaHttpBuilder;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.function.Supplier;
-
-public class CapaRpcClientHttpTest {
-
- @Test
- public void testStructure_Success() {
- CapaRpcClientBuilder capaRpcClientBuilder = new CapaRpcClientBuilder();
- Assertions.assertNotNull(capaRpcClientBuilder);
-
- Supplier capaHttpBuilderSupplier = () -> new CapaHttpBuilder();
- CapaRpcClientBuilder rpcClientBuilder = new CapaRpcClientBuilder(capaHttpBuilderSupplier);
- Assertions.assertNotNull(rpcClientBuilder);
- }
-
- @Test
- public void testBuild_Success() {
- CapaRpcClientBuilder capaRpcClientBuilder = new CapaRpcClientBuilder();
- CapaRpcClient client = capaRpcClientBuilder.build();
-
- Assertions.assertNotNull(client);
- }
-}
+/*
+ * 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 group.rxcloud.capa.rpc;
+
+import group.rxcloud.capa.component.http.CapaHttpBuilder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.function.Supplier;
+
+public class CapaRpcClientHttpTest {
+
+ @Test
+ public void testStructure_Success() {
+ CapaRpcClientBuilder capaRpcClientBuilder = new CapaRpcClientBuilder();
+ Assertions.assertNotNull(capaRpcClientBuilder);
+
+ Supplier capaHttpBuilderSupplier = () -> new CapaHttpBuilder();
+ CapaRpcClientBuilder rpcClientBuilder = new CapaRpcClientBuilder(capaHttpBuilderSupplier);
+ Assertions.assertNotNull(rpcClientBuilder);
+ }
+
+ @Test
+ public void testBuild_Success() {
+ CapaRpcClientBuilder capaRpcClientBuilder = new CapaRpcClientBuilder();
+ CapaRpcClient client = capaRpcClientBuilder.build();
+
+ Assertions.assertNotNull(client);
+ }
+}
diff --git a/sdk/src/test/java/group/rxcloud/capa/rpc/TestCapaHttp.java b/sdk/src/test/java/group/rxcloud/capa/rpc/TestCapaHttp.java
index dbd32df..823e31f 100644
--- a/sdk/src/test/java/group/rxcloud/capa/rpc/TestCapaHttp.java
+++ b/sdk/src/test/java/group/rxcloud/capa/rpc/TestCapaHttp.java
@@ -1,53 +1,53 @@
-/*
- * 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 group.rxcloud.capa.rpc;
-
-import group.rxcloud.capa.component.http.CapaHttp;
-import group.rxcloud.capa.component.http.HttpResponse;
-import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
-import group.rxcloud.cloudruntimes.utils.TypeRef;
-import okhttp3.OkHttpClient;
-import reactor.util.context.Context;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * The capa http invoker used in tests only.
- */
-public class TestCapaHttp extends CapaHttp {
-
- public TestCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
- super(httpClient, objectSerializer);
- }
-
- @Override
- protected CompletableFuture> doInvokeApi(String httpMethod,
- String[] pathSegments,
- Map> urlParameters,
- Object requestData,
- Map headers,
- Context context,
- TypeRef type) {
- return CompletableFuture.supplyAsync(
- () -> {
- return new HttpResponse<>(null, null, 200);
- },
- Runnable::run);
- }
-}
+/*
+ * 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 group.rxcloud.capa.rpc;
+
+import group.rxcloud.capa.component.http.CapaHttp;
+import group.rxcloud.capa.component.http.HttpResponse;
+import group.rxcloud.capa.infrastructure.serializer.CapaObjectSerializer;
+import group.rxcloud.cloudruntimes.utils.TypeRef;
+import okhttp3.OkHttpClient;
+import reactor.util.context.Context;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * The capa http invoker used in tests only.
+ */
+public class TestCapaHttp extends CapaHttp {
+
+ public TestCapaHttp(OkHttpClient httpClient, CapaObjectSerializer objectSerializer) {
+ super(httpClient, objectSerializer);
+ }
+
+ @Override
+ protected CompletableFuture> doInvokeApi(String httpMethod,
+ String[] pathSegments,
+ Map> urlParameters,
+ Object requestData,
+ Map headers,
+ Context context,
+ TypeRef type) {
+ return CompletableFuture.supplyAsync(
+ () -> {
+ return new HttpResponse<>(null, null, 200);
+ },
+ Runnable::run);
+ }
+}
diff --git a/sdk/src/test/java/group/rxcloud/capa/rpc/domain/InvokeMethodRequestBuilderTest.java b/sdk/src/test/java/group/rxcloud/capa/rpc/domain/InvokeMethodRequestBuilderTest.java
index cdd9b5d..a17b102 100644
--- a/sdk/src/test/java/group/rxcloud/capa/rpc/domain/InvokeMethodRequestBuilderTest.java
+++ b/sdk/src/test/java/group/rxcloud/capa/rpc/domain/InvokeMethodRequestBuilderTest.java
@@ -1,86 +1,86 @@
-/*
- * 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 group.rxcloud.capa.rpc.domain;
-
-import group.rxcloud.cloudruntimes.domain.core.invocation.HttpExtension;
-import group.rxcloud.cloudruntimes.domain.core.invocation.InvokeMethodRequest;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-
-public class InvokeMethodRequestBuilderTest {
-
- private InvokeMethodRequestBuilder invokeMethodRequestBuilder;
-
- @BeforeEach
- public void setUp() {
- invokeMethodRequestBuilder = new InvokeMethodRequestBuilder("appId", "method");
- }
-
- @Test
- public void testWithContentType_Success() {
- InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withContentType("application/json");
- Assertions.assertNotNull(requestBuilder);
- }
-
- @Test
- public void testWithBody_Success() {
- InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withBody("body");
- Assertions.assertNotNull(requestBuilder);
- }
-
- @Test
- public void testWithHttpExtension_Success() {
- InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withHttpExtension(HttpExtension.POST);
- Assertions.assertNotNull(requestBuilder);
- }
-
- @Test
- public void testWithMetadata_Success() {
- Map metadata = new HashMap<>();
- metadata.put("key", "value");
-
- InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withMetadata(metadata);
- Assertions.assertNotNull(requestBuilder);
- }
-
- @Test
- public void testBuild_Success() {
- Map metadata = new HashMap<>();
- metadata.put("key", "value");
-
- InvokeMethodRequest invokeMethodRequest = invokeMethodRequestBuilder
- .withContentType("application/json")
- .withBody("body")
- .withHttpExtension(HttpExtension.POST)
- .withMetadata(metadata)
- .build();
-
- Assertions.assertEquals("appId", invokeMethodRequest.getAppId());
- Assertions.assertEquals("method", invokeMethodRequest.getMethod());
- Assertions.assertEquals("application/json", invokeMethodRequest.getContentType());
- Assertions.assertEquals("body", invokeMethodRequest.getBody());
- Assertions.assertEquals(HttpExtension.POST, invokeMethodRequest.getHttpExtension());
-
- Map requestMetadata = invokeMethodRequest.getMetadata();
- Assertions.assertEquals("value", requestMetadata.get("key"));
- }
-}
+/*
+ * 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 group.rxcloud.capa.rpc.domain;
+
+import group.rxcloud.cloudruntimes.domain.core.invocation.HttpExtension;
+import group.rxcloud.cloudruntimes.domain.core.invocation.InvokeMethodRequest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class InvokeMethodRequestBuilderTest {
+
+ private InvokeMethodRequestBuilder invokeMethodRequestBuilder;
+
+ @BeforeEach
+ public void setUp() {
+ invokeMethodRequestBuilder = new InvokeMethodRequestBuilder("appId", "method");
+ }
+
+ @Test
+ public void testWithContentType_Success() {
+ InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withContentType("application/json");
+ Assertions.assertNotNull(requestBuilder);
+ }
+
+ @Test
+ public void testWithBody_Success() {
+ InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withBody("body");
+ Assertions.assertNotNull(requestBuilder);
+ }
+
+ @Test
+ public void testWithHttpExtension_Success() {
+ InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withHttpExtension(HttpExtension.POST);
+ Assertions.assertNotNull(requestBuilder);
+ }
+
+ @Test
+ public void testWithMetadata_Success() {
+ Map metadata = new HashMap<>();
+ metadata.put("key", "value");
+
+ InvokeMethodRequestBuilder requestBuilder = invokeMethodRequestBuilder.withMetadata(metadata);
+ Assertions.assertNotNull(requestBuilder);
+ }
+
+ @Test
+ public void testBuild_Success() {
+ Map metadata = new HashMap<>();
+ metadata.put("key", "value");
+
+ InvokeMethodRequest invokeMethodRequest = invokeMethodRequestBuilder
+ .withContentType("application/json")
+ .withBody("body")
+ .withHttpExtension(HttpExtension.POST)
+ .withMetadata(metadata)
+ .build();
+
+ Assertions.assertEquals("appId", invokeMethodRequest.getAppId());
+ Assertions.assertEquals("method", invokeMethodRequest.getMethod());
+ Assertions.assertEquals("application/json", invokeMethodRequest.getContentType());
+ Assertions.assertEquals("body", invokeMethodRequest.getBody());
+ Assertions.assertEquals(HttpExtension.POST, invokeMethodRequest.getHttpExtension());
+
+ Map requestMetadata = invokeMethodRequest.getMetadata();
+ Assertions.assertEquals("value", requestMetadata.get("key"));
+ }
+}
diff --git a/sdk/src/test/java/group/rxcloud/capa/telemetry/CapaTelemetryClientBuilderTest.java b/sdk/src/test/java/group/rxcloud/capa/telemetry/CapaTelemetryClientBuilderTest.java
new file mode 100644
index 0000000..d79bf17
--- /dev/null
+++ b/sdk/src/test/java/group/rxcloud/capa/telemetry/CapaTelemetryClientBuilderTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import group.rxcloud.capa.component.telemetry.SamplerConfig;
+import group.rxcloud.capa.component.telemetry.context.ContextConfig;
+import group.rxcloud.capa.component.telemetry.metrics.MeterConfig;
+import group.rxcloud.capa.component.telemetry.metrics.MetricsReaderConfig;
+import group.rxcloud.capa.component.telemetry.trace.SpanLimitsConfig;
+import group.rxcloud.capa.component.telemetry.trace.TracerConfig;
+import io.opentelemetry.api.metrics.LongCounter;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
+import io.opentelemetry.sdk.trace.IdGenerator;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * @author: chenyijiang
+ * @date: 2021/11/26 13:33
+ */
+public class CapaTelemetryClientBuilderTest {
+
+ @Test
+ public void build() {
+ CapaTelemetryClient client = new CapaTelemetryClientBuilder().build();
+ assertNotNull(client.getContextPropagators().block());
+ assertNotNull(client.buildTracer("aaa").block());
+ assertNotNull(client.buildTracer("aaa", "ccc", "fff").block());
+ assertNotNull(client.buildTracer("aaa", "sss").block());
+ assertNotNull(client.buildMeter("bbb").block());
+ assertNotNull(client.buildMeter("bbb", "shdas", "dasoi").block());
+ assertNotNull(client.buildMeter("bbb", "dhasiug").block());
+ }
+
+ @Test
+ public void buildManual() throws InterruptedException {
+ MetricsReaderConfig readerConfig = new MetricsReaderConfig();
+ readerConfig.setExporterType(MetricTestExporter.class.getName());
+ readerConfig.setName("metric-reader");
+ readerConfig.setExportInterval(1, TimeUnit.SECONDS);
+ CapaTelemetryClient capaTelemetryClient = new CapaTelemetryClientBuilder()
+ .addProcessor(new TraceProcessor())
+ .setSamplerConfig(SamplerConfig.DEFAULT_CONFIG)
+ .setSpanLimits(new SpanLimitsConfig())
+ .setIdGenerator(IdGenerator.random())
+ .setTracerConfig(new TracerConfig())
+ .setMeterConfig(new MeterConfig())
+ .addMetricReaderConfig(readerConfig)
+ .setContextConfig(new ContextConfig())
+ .addContextPropagators(W3CTraceContextPropagator.getInstance())
+ .build();
+
+ // tracer
+ Tracer tracer = capaTelemetryClient.buildTracer("tracer-test")
+ .block();
+
+ LongCounter counter = capaTelemetryClient.buildMeter("meter-test")
+ .block()
+ .counterBuilder("counter-test")
+ .build();
+
+ Span span = tracer.spanBuilder("span-test")
+ .setAttribute("key1", 1)
+ .setAttribute("key2", 2)
+ .startSpan();
+ // working
+ for (int i = 0; i < 10; i++) {
+ Thread.sleep(200);
+ counter.add(i);
+ }
+
+ span.end();
+ }
+}
\ No newline at end of file
diff --git a/sdk/src/test/java/group/rxcloud/capa/telemetry/CapaTelemetryClientGlobalTest.java b/sdk/src/test/java/group/rxcloud/capa/telemetry/CapaTelemetryClientGlobalTest.java
new file mode 100644
index 0000000..579d125
--- /dev/null
+++ b/sdk/src/test/java/group/rxcloud/capa/telemetry/CapaTelemetryClientGlobalTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import io.opentelemetry.api.GlobalOpenTelemetry;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author: chenyijiang
+ * @date: 2021/11/26 14:12
+ */
+public class CapaTelemetryClientGlobalTest {
+
+ @Test
+ public void getOrCreate() {
+ CapaTelemetryClient client = CapaTelemetryClientGlobal.getOrCreate();
+ assertTrue(client instanceof CapaTelemetryClientGlobal);
+ assertNotNull(client.getContextPropagators());
+ assertNotNull(((CapaTelemetryClientGlobal) client).getPropagators());
+ assertNotNull(((CapaTelemetryClientGlobal) client).getMeterProvider());
+ assertNotNull(((CapaTelemetryClientGlobal) client).getTracerProvider());
+ assertNotNull(GlobalOpenTelemetry.get());
+ assertEquals(client, CapaTelemetryClientGlobal.getOrCreate());
+ }
+}
\ No newline at end of file
diff --git a/sdk/src/test/java/group/rxcloud/capa/telemetry/MetricTestExporter.java b/sdk/src/test/java/group/rxcloud/capa/telemetry/MetricTestExporter.java
new file mode 100644
index 0000000..6149cf5
--- /dev/null
+++ b/sdk/src/test/java/group/rxcloud/capa/telemetry/MetricTestExporter.java
@@ -0,0 +1,42 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import io.opentelemetry.sdk.common.CompletableResultCode;
+import io.opentelemetry.sdk.metrics.data.MetricData;
+import io.opentelemetry.sdk.metrics.export.MetricExporter;
+
+import java.util.Collection;
+
+public class MetricTestExporter implements MetricExporter {
+
+ @Override
+ public CompletableResultCode export(Collection metrics) {
+ metrics.forEach(System.out::println);
+ return CompletableResultCode.ofSuccess();
+ }
+
+ @Override
+ public CompletableResultCode flush() {
+ return CompletableResultCode.ofSuccess();
+ }
+
+ @Override
+ public CompletableResultCode shutdown() {
+ return CompletableResultCode.ofSuccess();
+ }
+}
\ No newline at end of file
diff --git a/sdk/src/test/java/group/rxcloud/capa/telemetry/TraceProcessor.java b/sdk/src/test/java/group/rxcloud/capa/telemetry/TraceProcessor.java
new file mode 100644
index 0000000..ab579b0
--- /dev/null
+++ b/sdk/src/test/java/group/rxcloud/capa/telemetry/TraceProcessor.java
@@ -0,0 +1,45 @@
+/*
+ * 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 group.rxcloud.capa.telemetry;
+
+import io.opentelemetry.context.Context;
+import io.opentelemetry.sdk.trace.ReadWriteSpan;
+import io.opentelemetry.sdk.trace.ReadableSpan;
+import io.opentelemetry.sdk.trace.SpanProcessor;
+
+public class TraceProcessor implements SpanProcessor {
+
+ @Override
+ public void onStart(Context context, ReadWriteSpan span) {
+
+ }
+
+ @Override
+ public boolean isStartRequired() {
+ return false;
+ }
+
+ @Override
+ public void onEnd(ReadableSpan span) {
+ System.out.println(span.toSpanData());
+ }
+
+ @Override
+ public boolean isEndRequired() {
+ return true;
+ }
+}
\ No newline at end of file