diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java index 37df968c5..963d0b643 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java @@ -18,15 +18,18 @@ package org.apache.skywalking.apm.agent.core.conf.dynamic; +import com.google.common.collect.Lists; import io.grpc.Channel; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.function.Function; import java.util.stream.Collectors; import lombok.Getter; import org.apache.skywalking.apm.agent.core.boot.BootService; @@ -128,12 +131,13 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi */ public void handleConfigurationDiscoveryCommand(ConfigurationDiscoveryCommand configurationDiscoveryCommand) { final String responseUuid = configurationDiscoveryCommand.getUuid(); - final List config = configurationDiscoveryCommand.getConfig(); if (responseUuid != null && Objects.equals(this.uuid, responseUuid)) { return; } + List config = readConfig(configurationDiscoveryCommand); + config.forEach(property -> { String propertyKey = property.getKey(); WatcherHolder holder = register.get(propertyKey); @@ -168,6 +172,30 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi LOGGER.trace("Current configurations after the sync, configurations:{}", register.toString()); } + /** + * Read the registered dynamic configuration, compare it with the dynamic configuration information returned by the + * service, and complete the dynamic configuration that has been deleted on the OAP. + * + * @param configurationDiscoveryCommand Describe dynamic configuration information + * @return Adapted dynamic configuration information + */ + private List readConfig(ConfigurationDiscoveryCommand configurationDiscoveryCommand) { + Map commandConfigs = configurationDiscoveryCommand.getConfig() + .stream() + .collect(Collectors.toMap( + KeyStringValuePair::getKey, + Function.identity() + )); + List configList = Lists.newArrayList(); + for (final String name : register.keys()) { + KeyStringValuePair command = commandConfigs.getOrDefault(name, KeyStringValuePair.newBuilder() + .setKey(name) + .build()); + configList.add(command); + } + return configList; + } + /** * get agent dynamic config through gRPC. */ @@ -213,6 +241,10 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi return register.get(name); } + public Set keys() { + return register.keySet(); + } + @Override public String toString() { ArrayList registerTableDescription = new ArrayList<>(register.size()); 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 index a7d95e9db..a84bd5479 100644 --- 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 @@ -18,22 +18,29 @@ package org.apache.skywalking.oap.server.recevier.configuration.discovery; -import java.io.StringReader; +import org.apache.commons.codec.digest.DigestUtils; 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; +import java.io.StringReader; +import java.util.HashMap; + /** * AgentConfigurationsWatcher used to handle dynamic configuration changes. */ public class AgentConfigurationsWatcher extends ConfigChangeWatcher { private volatile String settingsString; private volatile AgentConfigurationsTable agentConfigurationsTable; + private final AgentConfigurations emptyAgentConfigurations; public AgentConfigurationsWatcher(ModuleProvider provider) { super(ConfigurationDiscoveryModule.NAME, provider, "agentConfigurations"); this.settingsString = Const.EMPTY_STRING; this.agentConfigurationsTable = new AgentConfigurationsTable(); + this.emptyAgentConfigurations = new AgentConfigurations( + null, new HashMap<>(), DigestUtils.sha512Hex("EMPTY") + ); } @Override @@ -54,7 +61,20 @@ public class AgentConfigurationsWatcher extends ConfigChangeWatcher { return settingsString; } + /** + * Get service dynamic configuration information, if there is no dynamic configuration information, return to empty + * dynamic configuration to prevent the server from deleted the dynamic configuration, but it does not take effect + * on the agent side. + * + * @param service Service name to be queried + * @return Service dynamic configuration information + */ public AgentConfigurations getAgentConfigurations(String service) { - return agentConfigurationsTable.getAgentConfigurationsCache().get(service); + AgentConfigurations agentConfigurations = agentConfigurationsTable.getAgentConfigurationsCache().get(service); + if (null == agentConfigurations) { + return emptyAgentConfigurations; + } else { + return agentConfigurations; + } } }