From 97f54114a5e9abff84dae55a44f711f9d8567610 Mon Sep 17 00:00:00 2001 From: zifeihan Date: Tue, 19 Jan 2021 14:53:49 +0800 Subject: [PATCH] Add the implementation of ConfigurationDiscovery on the OAP side. (#6220) --- CHANGES.md | 1 + .../command/CommandDeserializer.java | 2 + .../ConfigurationDiscoveryCommand.java | 92 +++++++++++++++ apm-protocol/apm-network/src/main/proto | 2 +- docs/en/setup/backend/backend-receivers.md | 7 +- .../setup/backend/configuration-vocabulary.md | 1 + docs/en/setup/backend/dynamic-config.md | 1 + .../setup/service-agent/java-agent/README.md | 3 + .../java-agent/configuration-discovery.md | 29 +++++ oap-server/server-bootstrap/pom.xml | 5 + .../src/main/resources/application.yml | 5 + .../pom.xml | 38 ++++++ .../discovery/AgentConfigurations.java | 45 +++++++ .../discovery/AgentConfigurationsReader.java | 75 ++++++++++++ .../discovery/AgentConfigurationsTable.java | 39 ++++++ .../discovery/AgentConfigurationsWatcher.java | 60 ++++++++++ .../ConfigurationDiscoveryModule.java | 34 ++++++ .../ConfigurationDiscoveryModuleConfig.java | 33 ++++++ .../ConfigurationDiscoveryProvider.java | 92 +++++++++++++++ .../ConfigurationDiscoveryServiceHandler.java | 88 ++++++++++++++ ...ing.oap.server.library.module.ModuleDefine | 19 +++ ...g.oap.server.library.module.ModuleProvider | 19 +++ .../AgentConfigurationsReaderTest.java | 56 +++++++++ .../AgentConfigurationsWatcherTest.java | 111 ++++++++++++++++++ .../resources/agent-dynamic-configuration.yml | 22 ++++ oap-server/server-receiver-plugin/pom.xml | 1 + test/e2e/e2e-protocol/src/main/proto | 2 +- 27 files changed, 879 insertions(+), 3 deletions(-) create mode 100644 apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/ConfigurationDiscoveryCommand.java create mode 100644 docs/en/setup/service-agent/java-agent/configuration-discovery.md create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/pom.xml create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurations.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReader.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsTable.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcher.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModule.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModuleConfig.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryProvider.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/handler/grpc/ConfigurationDiscoveryServiceHandler.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReaderTest.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcherTest.java create mode 100644 oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/resources/agent-dynamic-configuration.yml diff --git a/CHANGES.md b/CHANGES.md index dbc8b15590..387c7eada3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -69,6 +69,7 @@ Release Notes. * Fix receiver analysis error count metrics * Log collecting and query implementation * Support Alarm to feishu +* Add the implementation of ConfigurationDiscovery on the OAP side. #### UI * Fix un-removed tags in trace query. diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/CommandDeserializer.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/CommandDeserializer.java index 6465e5fa59..ff8680bcb3 100644 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/CommandDeserializer.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/CommandDeserializer.java @@ -25,6 +25,8 @@ public class CommandDeserializer { final String commandName = command.getCommand(); if (ProfileTaskCommand.NAME.equals(commandName)) { return ProfileTaskCommand.DESERIALIZER.deserialize(command); + } else if (ConfigurationDiscoveryCommand.NAME.equals(commandName)) { + return ConfigurationDiscoveryCommand.DESERIALIZER.deserialize(command); } throw new UnsupportedCommandException(command); } diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/ConfigurationDiscoveryCommand.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/ConfigurationDiscoveryCommand.java new file mode 100644 index 0000000000..a1bb63fffb --- /dev/null +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/command/ConfigurationDiscoveryCommand.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.network.trace.component.command; + +import java.util.ArrayList; +import java.util.List; +import org.apache.skywalking.apm.network.common.v3.Command; +import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair; + +public class ConfigurationDiscoveryCommand extends BaseCommand implements Serializable, Deserializable { + public static final Deserializable DESERIALIZER = new ConfigurationDiscoveryCommand( + "", "", new ArrayList<>()); + public static final String NAME = ConfigurationDiscoveryCommand.class.getSimpleName(); + + public static final String UUID_CONST_NAME = "UUID"; + public static final String SERIAL_NUMBER_CONST_NAME = "SerialNumber"; + + /* + * If config is unchanged, then could response the same uuid, and config is not required. + */ + private String uuid; + /* + * The configuration of service. + */ + private List config; + + public ConfigurationDiscoveryCommand(String serialNumber, + String uuid, + List config) { + super(NAME, serialNumber); + this.uuid = uuid; + this.config = config; + } + + @Override + public ConfigurationDiscoveryCommand deserialize(Command command) { + String serialNumber = null; + String uuid = null; + List config = new ArrayList<>(); + + for (final KeyStringValuePair pair : command.getArgsList()) { + if (SERIAL_NUMBER_CONST_NAME.equals(pair.getKey())) { + serialNumber = pair.getValue(); + } else if (UUID_CONST_NAME.equals(pair.getKey())) { + uuid = pair.getValue(); + } else { + config.add(pair); + } + } + return new ConfigurationDiscoveryCommand(serialNumber, uuid, config); + } + + @Override + public Command.Builder serialize() { + final Command.Builder builder = commandBuilder(); + builder.addArgs(KeyStringValuePair.newBuilder().setKey(UUID_CONST_NAME).setValue(uuid)); + builder.addAllArgs(config); + return builder; + } + + public String getUuid() { + return uuid; + } + + public List getConfig() { + return config; + } + + @Override + public String toString() { + return "ConfigurationDiscoveryCommand{" + + "uuid='" + uuid + '\'' + + ", config=" + config + + '}'; + } +} diff --git a/apm-protocol/apm-network/src/main/proto b/apm-protocol/apm-network/src/main/proto index ea906c1ace..101dc50429 160000 --- a/apm-protocol/apm-network/src/main/proto +++ b/apm-protocol/apm-network/src/main/proto @@ -1 +1 @@ -Subproject commit ea906c1ace2b5eaf19b1c36ead0fd6e1489feaeb +Subproject commit 101dc50429c98147b1109cb15c8a6c623e751759 diff --git a/docs/en/setup/backend/backend-receivers.md b/docs/en/setup/backend/backend-receivers.md index e248fcf2e2..2840cde083 100644 --- a/docs/en/setup/backend/backend-receivers.md +++ b/docs/en/setup/backend/backend-receivers.md @@ -17,6 +17,7 @@ We have following receivers, and `default` implementors are provided in our Apac 1. **receiver-meter**. See [details](backend-meter.md). 1. **receiver-browser**. gRPC services to accept browser performance data and error log. 1. **receiver-log**. gRPC services accept log data. +1. **configuration-discovery**. gRPC services handle configurationDiscovery. The sample settings of these receivers should be already in default `application.yml`, and also list here ```yaml @@ -66,6 +67,10 @@ receiver-browser: receiver-log: selector: ${SW_RECEIVER_LOG:default} default: + +configuration-discovery: + selector: ${SW_CONFIGURATION_DISCOVERY:default} + default: ``` ## gRPC/HTTP server for receiver @@ -153,7 +158,7 @@ receiver_jaeger: default: gRPCHost: ${SW_RECEIVER_JAEGER_HOST:0.0.0.0} gRPCPort: ${SW_RECEIVER_JAEGER_PORT:14250} -``` +``` NOTICE, Jaeger receiver is only provided in `apache-skywalking-apm-x.y.z.tar.gz` tar. diff --git a/docs/en/setup/backend/configuration-vocabulary.md b/docs/en/setup/backend/configuration-vocabulary.md index b57b5a6a94..669697b117 100644 --- a/docs/en/setup/backend/configuration-vocabulary.md +++ b/docs/en/setup/backend/configuration-vocabulary.md @@ -260,6 +260,7 @@ core|default|role|Option values, `Mixed/Receiver/Aggregator`. **Receiver** mode | exporter | grpc | targetHost | The host of target grpc server for receiving export data. | SW_EXPORTER_GRPC_HOST | 127.0.0.1 | | - | - | targetPort | The port of target grpc server for receiving export data. | SW_EXPORTER_GRPC_PORT | 9870 | | health-checker | default | checkIntervalSeconds | The period of check OAP internal health status. Unit is second. | SW_HEALTH_CHECKER_INTERVAL_SECONDS | 5 | +| configuration-discovery | default | disableMessageDigest | If true, agent receives the latest configuration every time even without change. In default, OAP uses SHA512 message digest mechanism to detect changes of configuration. | SW_DISABLE_MESSAGE_DIGEST | false ## Notice ยน System Environment Variable name could be declared and changed in the application.yml. The names listed here, diff --git a/docs/en/setup/backend/dynamic-config.md b/docs/en/setup/backend/dynamic-config.md index 3837370735..5f942009cd 100755 --- a/docs/en/setup/backend/dynamic-config.md +++ b/docs/en/setup/backend/dynamic-config.md @@ -13,6 +13,7 @@ Right now, SkyWalking supports following dynamic configurations. |core.default.endpoint-name-grouping| The endpoint name grouping setting, will override `endpoint-name-grouping.yml`. | same as [`endpoint-name-grouping.yml`](endpoint-grouping-rules.md) | |agent-analyzer.default.sampleRate| Trace sampling , override `receiver-trace/default/sampleRate` of `application.yml`. | 10000 | |agent-analyzer.default.slowTraceSegmentThreshold| Setting this threshold about the latency would make the slow trace segments sampled if they cost more time, even the sampling mechanism activated. The default value is `-1`, which means would not sample slow traces. Unit, millisecond. override `receiver-trace/default/slowTraceSegmentThreshold` of `application.yml`. | -1 | +|configuration-discovery.default.agentConfigurations| The ConfigurationDiscovery settings | look at [`configuration-discovery.md`](../service-agent/java-agent/configuration-discovery.md) | This feature depends on upstream service, so it is **DISABLED** by default. diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index f2811d6dd6..5faa98b820 100755 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -164,6 +164,9 @@ property key | Description | Default | `plugin.toolkit.log.grpc.reporter.max_message_size` | Specify the maximum size of log data for grpc client to report to. | `10485760` | `plugin.toolkit.log.grpc.reporter.upstream_timeout` | How long grpc client will timeout in sending data to upstream. Unit is second.|`30` seconds| +## Dynamic Configurations +All configurations above are static, if you need to change some agent settings at runtime, please read [CDS - Configuration Discovery Service document](configuration-discovery.md) for more details. + ## Optional Plugins Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositories. For using these plugins, you need to put the target plugin jar file into `/plugins`. diff --git a/docs/en/setup/service-agent/java-agent/configuration-discovery.md b/docs/en/setup/service-agent/java-agent/configuration-discovery.md new file mode 100644 index 0000000000..ffd6bc1f1a --- /dev/null +++ b/docs/en/setup/service-agent/java-agent/configuration-discovery.md @@ -0,0 +1,29 @@ +# CDS - Configuration Discovery Service + +CDS - Configuration Discovery Service provides the dynamic configuration for the agent, defined in [gRPC](https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent/ConfigurationDiscoveryService.proto). + +## Configuration Format + +The configuration content includes the service name and their configs. The +```yml +configurations: + //service name + serviceA: + // Configurations of service A + // Key and Value are determined by the agent side. + // Check the agent setup doc for all available configurations. + key1: value1 + key2: value2 + ... + serviceB: + ... +``` + +## Available key(s) and value(s) in Java Agent. +Java agent supports the following dynamic configurations. + +| Config Key | Value Description | Value Format Example | Required Plugin(s) | +| :-----------------------: | :----------------------------------------------------------: | :-------------------: | :----------------: | +| agent.sample_n_per_3_secs | The number of sampled traces per 3 seconds | -1 | - | + +* `Required plugin(s)`, the configuration affects only when the required plugins activated. diff --git a/oap-server/server-bootstrap/pom.xml b/oap-server/server-bootstrap/pom.xml index efec58b1c9..b4e0453f7a 100644 --- a/oap-server/server-bootstrap/pom.xml +++ b/oap-server/server-bootstrap/pom.xml @@ -131,6 +131,11 @@ skywalking-log-recevier-plugin ${project.version} + + org.apache.skywalking + configuration-discovery-receiver-plugin + ${project.version} + diff --git a/oap-server/server-bootstrap/src/main/resources/application.yml b/oap-server/server-bootstrap/src/main/resources/application.yml index 7af29a4c01..18ab546952 100755 --- a/oap-server/server-bootstrap/src/main/resources/application.yml +++ b/oap-server/server-bootstrap/src/main/resources/application.yml @@ -413,3 +413,8 @@ health-checker: selector: ${SW_HEALTH_CHECKER:-} default: checkIntervalSeconds: ${SW_HEALTH_CHECKER_INTERVAL_SECONDS:5} + +configuration-discovery: + selector: ${SW_CONFIGURATION_DISCOVERY:-} + default: + disableMessageDigest: ${SW_DISABLE_MESSAGE_DIGEST:false} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/pom.xml b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/pom.xml new file mode 100644 index 0000000000..4aec867989 --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/pom.xml @@ -0,0 +1,38 @@ + + + + + + server-receiver-plugin + org.apache.skywalking + 8.4.0-SNAPSHOT + + 4.0.0 + + configuration-discovery-receiver-plugin + + + + org.apache.skywalking + skywalking-sharing-server-plugin + ${project.version} + + + \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurations.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurations.java new file mode 100644 index 0000000000..24349e8cb5 --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurations.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 org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Dynamic configuration items, save the dynamic configuration of the agent corresponding to the service. + */ +@Setter +@Getter +@ToString +public class AgentConfigurations { + private String service; + private Map configuration; + /** + * The uuid is calculated by the dynamic configuration of the service. + */ + private volatile String uuid; + + public AgentConfigurations(final String service, final Map configuration, final String uuid) { + this.service = service; + this.configuration = configuration; + this.uuid = uuid; + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReader.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReader.java new file mode 100644 index 0000000000..b9ebd2bacb --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReader.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import java.io.InputStream; +import java.io.Reader; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; + +/** + * Used to parse the String configuration to AgentConfigurations. + */ +@Slf4j +public class AgentConfigurationsReader { + private Map yamlData; + + public AgentConfigurationsReader(InputStream inputStream) { + Yaml yaml = new Yaml(new SafeConstructor()); + yamlData = (Map) yaml.load(inputStream); + } + + public AgentConfigurationsReader(Reader io) { + Yaml yaml = new Yaml(new SafeConstructor()); + yamlData = (Map) yaml.load(io); + } + + public AgentConfigurationsTable readAgentConfigurationsTable() { + AgentConfigurationsTable agentConfigurationsTable = new AgentConfigurationsTable(); + try { + if (Objects.nonNull(yamlData)) { + Map configurationsData = (Map) yamlData.get("configurations"); + if (configurationsData != null) { + configurationsData.forEach((k, v) -> { + Map map = (Map) v; + StringBuilder serviceConfigStr = new StringBuilder(); + Map config = new HashMap<>(map.size()); + map.forEach((key, value) -> { + config.put(key.toString(), value.toString()); + + serviceConfigStr.append(key.toString()).append(":").append(value.toString()); + }); + AgentConfigurations agentConfigurations = new AgentConfigurations( + k.toString(), config, DigestUtils.sha512Hex(serviceConfigStr.toString())); + agentConfigurationsTable.getAgentConfigurationsCache() + .put(agentConfigurations.getService(), agentConfigurations); + }); + } + } + } catch (Exception e) { + log.error("Read ConfigurationDiscovery configurations error.", e); + } + return agentConfigurationsTable; + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsTable.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsTable.java new file mode 100644 index 0000000000..7d7666c96a --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsTable.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * Dynamic configuration items, save the dynamic configuration of the agent corresponding to the service. + */ +@Setter +@Getter +@ToString +public class AgentConfigurationsTable { + private Map agentConfigurationsCache; + + public AgentConfigurationsTable() { + this.agentConfigurationsCache = new HashMap<>(); + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcher.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcher.java new file mode 100644 index 0000000000..a7d95e9db2 --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcher.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import java.io.StringReader; +import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher; +import org.apache.skywalking.oap.server.core.Const; +import org.apache.skywalking.oap.server.library.module.ModuleProvider; + +/** + * AgentConfigurationsWatcher used to handle dynamic configuration changes. + */ +public class AgentConfigurationsWatcher extends ConfigChangeWatcher { + private volatile String settingsString; + private volatile AgentConfigurationsTable agentConfigurationsTable; + + public AgentConfigurationsWatcher(ModuleProvider provider) { + super(ConfigurationDiscoveryModule.NAME, provider, "agentConfigurations"); + this.settingsString = Const.EMPTY_STRING; + this.agentConfigurationsTable = new AgentConfigurationsTable(); + } + + @Override + public void notify(ConfigChangeEvent value) { + if (value.getEventType().equals(EventType.DELETE)) { + settingsString = Const.EMPTY_STRING; + this.agentConfigurationsTable = new AgentConfigurationsTable(); + } else { + settingsString = value.getNewValue(); + AgentConfigurationsReader agentConfigurationsReader = + new AgentConfigurationsReader(new StringReader(value.getNewValue())); + this.agentConfigurationsTable = agentConfigurationsReader.readAgentConfigurationsTable(); + } + } + + @Override + public String value() { + return settingsString; + } + + public AgentConfigurations getAgentConfigurations(String service) { + return agentConfigurationsTable.getAgentConfigurationsCache().get(service); + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModule.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModule.java new file mode 100644 index 0000000000..bdd644bbbd --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModule.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 org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import org.apache.skywalking.oap.server.library.module.ModuleDefine; + +public class ConfigurationDiscoveryModule extends ModuleDefine { + public static final String NAME = "configuration-discovery"; + + public ConfigurationDiscoveryModule() { + super(NAME); + } + + @Override + public Class[] services() { + return new Class[0]; + } +} \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModuleConfig.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModuleConfig.java new file mode 100644 index 0000000000..0a9c16472a --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryModuleConfig.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import lombok.Getter; +import lombok.Setter; +import org.apache.skywalking.oap.server.library.module.ModuleConfig; + +public class ConfigurationDiscoveryModuleConfig extends ModuleConfig { + /** + * If true, agent receives the latest configuration every time even without change. + * In default, OAP uses SHA512 message digest mechanism to detect changes of configuration. + */ + @Setter + @Getter + private boolean disableMessageDigest = false; +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryProvider.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryProvider.java new file mode 100644 index 0000000000..603065acca --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/ConfigurationDiscoveryProvider.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import org.apache.skywalking.oap.server.configuration.api.ConfigurationModule; +import org.apache.skywalking.oap.server.configuration.api.DynamicConfigurationService; +import org.apache.skywalking.oap.server.core.server.GRPCHandlerRegister; +import org.apache.skywalking.oap.server.library.module.ModuleConfig; +import org.apache.skywalking.oap.server.library.module.ModuleDefine; +import org.apache.skywalking.oap.server.library.module.ModuleProvider; +import org.apache.skywalking.oap.server.library.module.ModuleStartException; +import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException; +import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule; +import org.apache.skywalking.oap.server.recevier.configuration.discovery.handler.grpc.ConfigurationDiscoveryServiceHandler; + +public class ConfigurationDiscoveryProvider extends ModuleProvider { + + private AgentConfigurationsWatcher agentConfigurationsWatcher; + private ConfigurationDiscoveryModuleConfig configurationDiscoveryModuleConfig; + + @Override + public String name() { + return "default"; + } + + @Override + public Class module() { + return ConfigurationDiscoveryModule.class; + } + + public ConfigurationDiscoveryProvider() { + configurationDiscoveryModuleConfig = new ConfigurationDiscoveryModuleConfig(); + } + + @Override + public ModuleConfig createConfigBeanIfAbsent() { + return configurationDiscoveryModuleConfig; + } + + @Override + public void prepare() throws ServiceNotProvidedException, ModuleStartException { + agentConfigurationsWatcher = new AgentConfigurationsWatcher(this); + } + + @Override + public void start() throws ServiceNotProvidedException, ModuleStartException { + DynamicConfigurationService dynamicConfigurationService = getManager().find(ConfigurationModule.NAME) + .provider() + .getService( + DynamicConfigurationService.class); + dynamicConfigurationService.registerConfigChangeWatcher(agentConfigurationsWatcher); + + /* + * Register ConfigurationDiscoveryServiceHandler to process gRPC requests for ConfigurationDiscovery. + */ + GRPCHandlerRegister grpcHandlerRegister = getManager().find(SharingServerModule.NAME) + .provider() + .getService(GRPCHandlerRegister.class); + grpcHandlerRegister.addHandler(new ConfigurationDiscoveryServiceHandler( + agentConfigurationsWatcher, + configurationDiscoveryModuleConfig.isDisableMessageDigest() + )); + } + + @Override + public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException { + } + + @Override + public String[] requiredModules() { + return new String[] { + ConfigurationModule.NAME, + SharingServerModule.NAME + }; + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/handler/grpc/ConfigurationDiscoveryServiceHandler.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/handler/grpc/ConfigurationDiscoveryServiceHandler.java new file mode 100644 index 0000000000..85d8ab8572 --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/handler/grpc/ConfigurationDiscoveryServiceHandler.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery.handler.grpc; + +import com.google.common.collect.Lists; +import io.grpc.stub.StreamObserver; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.apm.network.agent.dynamic.configuration.v3.ConfigurationDiscoveryServiceGrpc; +import org.apache.skywalking.apm.network.agent.dynamic.configuration.v3.ConfigurationSyncRequest; +import org.apache.skywalking.apm.network.common.v3.Commands; +import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair; +import org.apache.skywalking.apm.network.trace.component.command.ConfigurationDiscoveryCommand; +import org.apache.skywalking.oap.server.library.server.grpc.GRPCHandler; +import org.apache.skywalking.oap.server.recevier.configuration.discovery.AgentConfigurations; +import org.apache.skywalking.oap.server.recevier.configuration.discovery.AgentConfigurationsWatcher; + +/** + * Provide query agent dynamic configuration, through the gRPC protocol, + */ +@Slf4j +public class ConfigurationDiscoveryServiceHandler extends ConfigurationDiscoveryServiceGrpc.ConfigurationDiscoveryServiceImplBase implements GRPCHandler { + + private final AgentConfigurationsWatcher agentConfigurationsWatcher; + + /** + * If the current configuration is true, the requestId and uuid will not be judged, and the dynamic configuration of + * the service corresponding to the agent will be returned directly + */ + private boolean disableMessageDigest = false; + + public ConfigurationDiscoveryServiceHandler(AgentConfigurationsWatcher agentConfigurationsWatcher, + boolean disableMessageDigest) { + this.agentConfigurationsWatcher = agentConfigurationsWatcher; + this.disableMessageDigest = disableMessageDigest; + } + + /* + * Process the request for querying the dynamic configuration of the agent. + * If there is agent dynamic configuration information corresponding to the service, + * the ConfigurationDiscoveryCommand is returned to represent the dynamic configuration information. + */ + @Override + public void fetchConfigurations(final ConfigurationSyncRequest request, + final StreamObserver responseObserver) { + Commands.Builder commandsBuilder = Commands.newBuilder(); + + AgentConfigurations agentConfigurations = agentConfigurationsWatcher.getAgentConfigurations( + request.getService()); + if (null != agentConfigurations) { + if (disableMessageDigest || !Objects.equals(agentConfigurations.getUuid(), request.getUuid())) { + ConfigurationDiscoveryCommand configurationDiscoveryCommand = + newAgentDynamicConfigCommand(agentConfigurations); + commandsBuilder.addCommands(configurationDiscoveryCommand.serialize().build()); + } + } + responseObserver.onNext(commandsBuilder.build()); + responseObserver.onCompleted(); + } + + public ConfigurationDiscoveryCommand newAgentDynamicConfigCommand(AgentConfigurations agentConfigurations) { + List configurationList = Lists.newArrayList(); + agentConfigurations.getConfiguration().forEach((k, v) -> { + KeyStringValuePair.Builder builder = KeyStringValuePair.newBuilder().setKey(k).setValue(v); + configurationList.add(builder.build()); + }); + return new ConfigurationDiscoveryCommand( + UUID.randomUUID().toString(), agentConfigurations.getUuid(), configurationList); + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine new file mode 100644 index 0000000000..ca0bbb51ee --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine @@ -0,0 +1,19 @@ +# +# 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. +# +# + +org.apache.skywalking.oap.server.recevier.configuration.discovery.ConfigurationDiscoveryModule \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider new file mode 100644 index 0000000000..3a34f7eac2 --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider @@ -0,0 +1,19 @@ +# +# 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. +# +# + +org.apache.skywalking.oap.server.recevier.configuration.discovery.ConfigurationDiscoveryProvider \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReaderTest.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReaderTest.java new file mode 100644 index 0000000000..49485c328d --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsReaderTest.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import java.util.Map; +import org.junit.Assert; +import org.junit.Test; + +public class AgentConfigurationsReaderTest { + @Test + public void testReadAgentConfigurations() { + AgentConfigurationsReader reader = new AgentConfigurationsReader( + this.getClass().getClassLoader().getResourceAsStream("agent-dynamic-configuration.yml")); + + Map configurationCache = reader.readAgentConfigurationsTable() + .getAgentConfigurationsCache(); + Assert.assertEquals(2, configurationCache.size()); + AgentConfigurations agentConfigurations0 = configurationCache.get("serviceA"); + Assert.assertEquals("serviceA", agentConfigurations0.getService()); + Assert.assertEquals(2, agentConfigurations0.getConfiguration().size()); + Assert.assertEquals("1000", agentConfigurations0.getConfiguration().get("trace.sample_rate")); + Assert.assertEquals( + "/api/seller/seller/*", agentConfigurations0.getConfiguration().get("trace.ignore_path")); + Assert.assertEquals( + "92670f1ccbdee60e14ffc054d70a5cf3f93f6b5fb1adb83b10bea4fec79b96e7bc5e7b188e231428853721ded42ec756663947316065617f3cfdf51d6dfc8da6", + agentConfigurations0.getUuid() + ); + + AgentConfigurations agentConfigurations1 = configurationCache.get("serviceB"); + Assert.assertEquals("serviceB", agentConfigurations1.getService()); + Assert.assertEquals(2, agentConfigurations1.getConfiguration().size()); + Assert.assertEquals("1000", agentConfigurations1.getConfiguration().get("trace.sample_rate")); + Assert.assertEquals( + "/api/seller/seller/*", agentConfigurations1.getConfiguration().get("trace.ignore_path")); + Assert.assertEquals( + "92670f1ccbdee60e14ffc054d70a5cf3f93f6b5fb1adb83b10bea4fec79b96e7bc5e7b188e231428853721ded42ec756663947316065617f3cfdf51d6dfc8da6", + agentConfigurations0.getUuid() + ); + } +} diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcherTest.java b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcherTest.java new file mode 100644 index 0000000000..2c9c2f0c2e --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/recevier/configuration/discovery/AgentConfigurationsWatcherTest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.oap.server.recevier.configuration.discovery; + +import java.io.IOException; +import java.io.Reader; +import java.util.Map; +import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher; +import org.apache.skywalking.oap.server.library.util.ResourceUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.powermock.reflect.Whitebox; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.spy; + +public class AgentConfigurationsWatcherTest { + @Spy + private AgentConfigurationsWatcher agentConfigurationsWatcher = new AgentConfigurationsWatcher(null); + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testConfigModifyEvent() throws IOException { + AgentConfigurationsTable agentConfigurationsTable = Whitebox.getInternalState( + agentConfigurationsWatcher, "agentConfigurationsTable"); + assertTrue(agentConfigurationsTable.getAgentConfigurationsCache().isEmpty()); + + Reader reader = ResourceUtils.read("agent-dynamic-configuration.yml"); + char[] chars = new char[1024 * 1024]; + int length = reader.read(chars); + + agentConfigurationsWatcher.notify(new ConfigChangeWatcher.ConfigChangeEvent( + new String(chars, 0, length), + ConfigChangeWatcher.EventType.MODIFY + )); + + AgentConfigurationsTable modifyAgentConfigurationsTable = Whitebox.getInternalState( + agentConfigurationsWatcher, "agentConfigurationsTable"); + Map configurationCache = modifyAgentConfigurationsTable.getAgentConfigurationsCache(); + Assert.assertEquals(2, configurationCache.size()); + AgentConfigurations agentConfigurations0 = configurationCache.get("serviceA"); + Assert.assertEquals("serviceA", agentConfigurations0.getService()); + Assert.assertEquals(2, agentConfigurations0.getConfiguration().size()); + Assert.assertEquals("1000", agentConfigurations0.getConfiguration().get("trace.sample_rate")); + Assert.assertEquals( + "/api/seller/seller/*", agentConfigurations0.getConfiguration().get("trace.ignore_path")); + Assert.assertEquals( + "92670f1ccbdee60e14ffc054d70a5cf3f93f6b5fb1adb83b10bea4fec79b96e7bc5e7b188e231428853721ded42ec756663947316065617f3cfdf51d6dfc8da6", + agentConfigurations0.getUuid() + ); + + AgentConfigurations agentConfigurations1 = configurationCache.get("serviceB"); + Assert.assertEquals("serviceB", agentConfigurations1.getService()); + Assert.assertEquals(2, agentConfigurations1.getConfiguration().size()); + Assert.assertEquals("1000", agentConfigurations1.getConfiguration().get("trace.sample_rate")); + Assert.assertEquals( + "/api/seller/seller/*", agentConfigurations1.getConfiguration().get("trace.ignore_path")); + Assert.assertEquals( + "92670f1ccbdee60e14ffc054d70a5cf3f93f6b5fb1adb83b10bea4fec79b96e7bc5e7b188e231428853721ded42ec756663947316065617f3cfdf51d6dfc8da6", + agentConfigurations0.getUuid() + ); + } + + @Test + public void testConfigDeleteEvent() throws IOException { + Reader reader = ResourceUtils.read("agent-dynamic-configuration.yml"); + agentConfigurationsWatcher = spy(new AgentConfigurationsWatcher(null)); + + Whitebox.setInternalState( + agentConfigurationsWatcher, "agentConfigurationsTable", + new AgentConfigurationsReader(reader).readAgentConfigurationsTable() + ); + + agentConfigurationsWatcher.notify( + new ConfigChangeWatcher.ConfigChangeEvent("whatever", ConfigChangeWatcher.EventType.DELETE)); + + AgentConfigurationsTable agentConfigurationsTable = Whitebox.getInternalState( + agentConfigurationsWatcher, "agentConfigurationsTable"); + Map configurationCache = agentConfigurationsTable.getAgentConfigurationsCache(); + + Assert.assertEquals(0, configurationCache.size()); + AgentConfigurations agentConfigurations0 = configurationCache.get("serviceA"); + AgentConfigurations agentConfigurations1 = configurationCache.get("serviceB"); + + Assert.assertNull(null, agentConfigurations0); + Assert.assertNull(null, agentConfigurations1); + } +} \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/resources/agent-dynamic-configuration.yml b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/resources/agent-dynamic-configuration.yml new file mode 100644 index 0000000000..49bb7a1812 --- /dev/null +++ b/oap-server/server-receiver-plugin/configuration-discovery-receiver-plugin/src/test/resources/agent-dynamic-configuration.yml @@ -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. + +configurations: + serviceA: + trace.sample_rate: 1000 + trace.ignore_path: /api/seller/seller/* + serviceB: + trace.sample_rate: 1000 + trace.ignore_path: /api/seller/seller/* \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/pom.xml b/oap-server/server-receiver-plugin/pom.xml index 7a4ecdc904..b4e61f549d 100644 --- a/oap-server/server-receiver-plugin/pom.xml +++ b/oap-server/server-receiver-plugin/pom.xml @@ -43,6 +43,7 @@ skywalking-meter-receiver-plugin skywalking-browser-receiver-plugin skywalking-log-recevier-plugin + configuration-discovery-receiver-plugin diff --git a/test/e2e/e2e-protocol/src/main/proto b/test/e2e/e2e-protocol/src/main/proto index ea906c1ace..101dc50429 160000 --- a/test/e2e/e2e-protocol/src/main/proto +++ b/test/e2e/e2e-protocol/src/main/proto @@ -1 +1 @@ -Subproject commit ea906c1ace2b5eaf19b1c36ead0fd6e1489feaeb +Subproject commit 101dc50429c98147b1109cb15c8a6c623e751759 -- GitLab