From 9ef74e3755367f8f2052d091caea4b93eaca7389 Mon Sep 17 00:00:00 2001 From: hexiaofeng Date: Thu, 30 May 2024 10:29:35 +0800 Subject: [PATCH] Support load resource from WAR --- .../core/extension/annotation/Extension.java | 2 +- .../live/agent/core/parser/ObjectParser.java | 5 + .../bootstrap/config/ConfigEnvSupplier.java | 60 -------- .../bootstrap/env/AbstractEnvSupplier.java | 124 ++++++++++++++++ .../env/config/ConfigEnvSupplier.java | 41 ++++++ .../env/spring/SpringEnvSupplier.java | 62 ++++++++ .../bootstrap/spring/SpringEnvSupplier.java | 135 ------------------ .../extension/jplug/JExtensionLoader.java | 38 +++-- ...m.jd.live.agent.core.bootstrap.EnvSupplier | 4 +- .../parser/jackson/AbstractJacksonParser.java | 21 +++ .../parser/jackson/JacksonConverter.java | 9 +- .../parser/jackson/JacksonYamlParser.java | 2 +- .../jackson/JsonAnnotationIntrospector.java | 26 +++- .../parser/jackson/SimpleTypeReference.java | 4 + 14 files changed, 319 insertions(+), 214 deletions(-) delete mode 100644 joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/config/ConfigEnvSupplier.java create mode 100644 joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/AbstractEnvSupplier.java create mode 100644 joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/config/ConfigEnvSupplier.java create mode 100644 joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/spring/SpringEnvSupplier.java delete mode 100644 joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/spring/SpringEnvSupplier.java diff --git a/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/extension/annotation/Extension.java b/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/extension/annotation/Extension.java index 8f5b085f6..ee61b9df2 100644 --- a/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/extension/annotation/Extension.java +++ b/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/extension/annotation/Extension.java @@ -36,7 +36,7 @@ * * @return The type (or name) of the extension. */ - String value() default ""; + String[] value() default ""; /** * Specifies the provider or vendor of the extension. This can be used for informational purposes or to distinguish diff --git a/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/parser/ObjectParser.java b/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/parser/ObjectParser.java index 6ea913c38..5ef2ccbce 100644 --- a/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/parser/ObjectParser.java +++ b/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/parser/ObjectParser.java @@ -35,6 +35,11 @@ public interface ObjectParser { */ String YAML = "yaml"; + /** + * Represents the identifier for YAML format. + */ + String YML = "yml"; + /** * Represents the identifier for JSON format. */ diff --git a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/config/ConfigEnvSupplier.java b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/config/ConfigEnvSupplier.java deleted file mode 100644 index 50ff23fb7..000000000 --- a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/config/ConfigEnvSupplier.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright © ${year} ${owner} (${email}) - * - * Licensed 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 com.jd.live.agent.core.bootstrap.config; - -import com.jd.live.agent.bootstrap.classloader.ResourcerType; -import com.jd.live.agent.core.bootstrap.EnvSupplier; -import com.jd.live.agent.core.extension.annotation.Extension; -import com.jd.live.agent.core.inject.annotation.Inject; -import com.jd.live.agent.core.inject.annotation.InjectLoader; -import com.jd.live.agent.core.inject.annotation.Injectable; -import com.jd.live.agent.core.parser.ConfigParser; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.util.Map; - -@Injectable -@Extension("ConfigEnvSupplier") -public class ConfigEnvSupplier implements EnvSupplier { - - private static final String RESOURCE_LIVE_AGENT_PROPERTIES = "liveagent.properties"; - - @Inject("properties") - @InjectLoader(ResourcerType.CORE_IMPL) - private ConfigParser propertiesParser; - - @Override - public void process(Map env) { - URL url = ClassLoader.getSystemClassLoader().getResource(RESOURCE_LIVE_AGENT_PROPERTIES); - if (url != null) { - try { - Map map = parse(url.openStream(), propertiesParser); - map.forEach(env::putIfAbsent); - } catch (Exception ignore) { - } - } - } - - private Map parse(InputStream inputStream, ConfigParser parser) throws Exception { - try (Reader reader = new BufferedReader(new InputStreamReader(inputStream))) { - return parser.parse(reader); - } - } -} diff --git a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/AbstractEnvSupplier.java b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/AbstractEnvSupplier.java new file mode 100644 index 000000000..6a09c4a6c --- /dev/null +++ b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/AbstractEnvSupplier.java @@ -0,0 +1,124 @@ +/* + * Copyright © ${year} ${owner} (${email}) + * + * Licensed 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 com.jd.live.agent.core.bootstrap.env; + +import com.jd.live.agent.bootstrap.classloader.ResourcerType; +import com.jd.live.agent.bootstrap.logger.Logger; +import com.jd.live.agent.bootstrap.logger.LoggerFactory; +import com.jd.live.agent.core.bootstrap.EnvSupplier; +import com.jd.live.agent.core.bootstrap.env.config.ConfigEnvSupplier; +import com.jd.live.agent.core.inject.annotation.Inject; +import com.jd.live.agent.core.inject.annotation.InjectLoader; +import com.jd.live.agent.core.parser.ConfigParser; +import com.jd.live.agent.core.util.StringUtils; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +/** + * AbstractEnvSupplier is an abstract class that provides a mechanism to load environment config + * from various resources using different parsers. + */ +public abstract class AbstractEnvSupplier implements EnvSupplier { + + private static final Logger logger = LoggerFactory.getLogger(ConfigEnvSupplier.class); + + private final String[] resources; + + private final static String[] PREFIX = new String[]{"", "BOOT-INF/classes/", "WEB-INF/classes/"}; + + @Inject + @InjectLoader(ResourcerType.CORE_IMPL) + private Map parsers; + + /** + * Constructs an AbstractEnvSupplier with the specified resources. + * + * @param resources the resource paths to load configuration from. + */ + public AbstractEnvSupplier(String... resources) { + this.resources = resources; + } + + /** + * Retrieves the configuration by iterating through the resources and prefixes. + * + * @return a map containing the configuration, or null if no configuration is found. + */ + protected Map loadConfigs() { + if (resources != null) { + for (String resource : resources) { + for (String prefix : PREFIX) { + Map result = loadConfigs(resource, prefix); + if (result != null) { + return result; + } + } + } + } + return null; + } + + /** + * Retrieves the configuration for a specific resource and prefix. + * + * @param resource the resource path. + * @param prefix the prefix to be added to the resource path. + * @return a map containing the configuration, or null if no configuration is found. + */ + protected Map loadConfigs(String resource, String prefix) { + resource = prefix != null && !prefix.isEmpty() && !resource.startsWith(prefix) + ? StringUtils.url(prefix, resource) + : resource; + int pos = resource.lastIndexOf('.'); + String ext = pos > 0 ? resource.substring(pos + 1) : ""; + ConfigParser parser = parsers.get(ext); + if (parser != null) { + URL url = ClassLoader.getSystemClassLoader().getResource(resource); + if (url != null) { + try { + Map result = parse(url.openStream(), parser); + logger.info("Successfully load config from " + url); + return result; + } catch (Throwable e) { + logger.warn("Failed to load config from " + url, e); + return new HashMap<>(); + } + } + } + return null; + } + + /** + * Parses the input stream using the specified parser. + * + * @param inputStream the input stream to parse. + * @param parser the parser to use for parsing the input stream. + * @return a map containing the parsed configuration. + * @throws Exception if an error occurs during parsing. + */ + protected Map parse(InputStream inputStream, ConfigParser parser) throws Exception { + try (Reader reader = new BufferedReader(new InputStreamReader(inputStream))) { + return parser.parse(reader); + } + } + +} diff --git a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/config/ConfigEnvSupplier.java b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/config/ConfigEnvSupplier.java new file mode 100644 index 000000000..d2c848f76 --- /dev/null +++ b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/config/ConfigEnvSupplier.java @@ -0,0 +1,41 @@ +/* + * Copyright © ${year} ${owner} (${email}) + * + * Licensed 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 com.jd.live.agent.core.bootstrap.env.config; + +import com.jd.live.agent.core.bootstrap.env.AbstractEnvSupplier; +import com.jd.live.agent.core.extension.annotation.Extension; +import com.jd.live.agent.core.inject.annotation.Injectable; + +import java.util.Map; + +@Injectable +@Extension("ConfigEnvSupplier") +public class ConfigEnvSupplier extends AbstractEnvSupplier { + + private static final String RESOURCE_LIVE_AGENT_PROPERTIES = "live-agent.properties"; + + public ConfigEnvSupplier() { + super(RESOURCE_LIVE_AGENT_PROPERTIES); + } + + @Override + public void process(Map env) { + Map map = loadConfigs(); + if (map != null) { + map.forEach(env::putIfAbsent); + } + } +} diff --git a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/spring/SpringEnvSupplier.java b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/spring/SpringEnvSupplier.java new file mode 100644 index 000000000..444e509cd --- /dev/null +++ b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/env/spring/SpringEnvSupplier.java @@ -0,0 +1,62 @@ +/* + * Copyright © ${year} ${owner} (${email}) + * + * Licensed 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 com.jd.live.agent.core.bootstrap.env.spring; + +import com.jd.live.agent.core.bootstrap.env.AbstractEnvSupplier; +import com.jd.live.agent.core.extension.annotation.Extension; +import com.jd.live.agent.core.inject.annotation.Injectable; +import com.jd.live.agent.core.instance.Application; +import com.jd.live.agent.core.util.type.ValuePath; + +import java.util.Map; + +@Injectable +@Extension("SpringEnvSupplier") +public class SpringEnvSupplier extends AbstractEnvSupplier { + + private static final String KEY_SPRING_APPLICATION_NAME = "spring.application.name"; + + private static final String KEY_SPRING_APPLICATION_NAME1 = "spring-application-name"; + + private static final String RESOURCE_SPRINGBOOT_APPLICATION_PROPERTIES = "application.properties"; + + private static final String RESOURCE_SPRINGBOOT_APPLICATION_YAML = "application.yaml"; + + private static final String RESOURCE_SPRINGBOOT_APPLICATION_YML = "application.yml"; + + private static final ValuePath APP_PATH = new ValuePath(KEY_SPRING_APPLICATION_NAME); + + public SpringEnvSupplier() { + super(RESOURCE_SPRINGBOOT_APPLICATION_PROPERTIES, + RESOURCE_SPRINGBOOT_APPLICATION_YAML, + RESOURCE_SPRINGBOOT_APPLICATION_YML); + } + + @Override + public void process(Map env) { + if (!env.containsKey(Application.KEY_APPLICATION_NAME)) { + Map configs = loadConfigs(); + if (configs != null) { + String name = (String) configs.get(KEY_SPRING_APPLICATION_NAME); + name = name == null ? (String) configs.get(KEY_SPRING_APPLICATION_NAME1) : name; + name = name == null ? (String) APP_PATH.get(configs) : name; + if (name != null && !name.isEmpty()) { + env.put(Application.KEY_APPLICATION_NAME, name); + } + } + } + } +} diff --git a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/spring/SpringEnvSupplier.java b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/spring/SpringEnvSupplier.java deleted file mode 100644 index 23db2f2fc..000000000 --- a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/bootstrap/spring/SpringEnvSupplier.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright © ${year} ${owner} (${email}) - * - * Licensed 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 com.jd.live.agent.core.bootstrap.spring; - -import com.jd.live.agent.bootstrap.classloader.ResourcerType; -import com.jd.live.agent.core.bootstrap.EnvSupplier; -import com.jd.live.agent.core.extension.annotation.Extension; -import com.jd.live.agent.core.inject.annotation.Inject; -import com.jd.live.agent.core.inject.annotation.InjectLoader; -import com.jd.live.agent.core.inject.annotation.Injectable; -import com.jd.live.agent.core.instance.Application; -import com.jd.live.agent.core.parser.ConfigParser; -import com.jd.live.agent.core.parser.ObjectParser; -import com.jd.live.agent.core.util.type.ValuePath; -import lombok.Getter; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.util.Map; - -@Injectable -@Extension("SpringEnvSupplier") -public class SpringEnvSupplier implements EnvSupplier { - - private static final String KEY_SPRING_APPLICATION_NAME = "spring.application.name"; - - private static final String RESOURCE_SPRINGBOOT_APPLICATION_PROPERTIES = "application.properties"; - - private static final String RESOURCE_SPRINGBOOT_APPLICATION_YAML = "application.yaml"; - - private static final String RESOURCE_SPRINGBOOT_APPLICATION_YML = "application.yml"; - - private static final String RESOURCE_FAT_SPRINGBOOT_APPLICATION_PROPERTIES = "BOOT-INF/classes/application.properties"; - - private static final String RESOURCE_FAT_SPRINGBOOT_APPLICATION_YAML = "BOOT-INF/classes/application.yaml"; - - private static final String RESOURCE_FAT_SPRINGBOOT_APPLICATION_YML = "BOOT-INF/classes/application.yml"; - - private static final String KEY_SPRING_APPLICATION_NAME1 = "spring-application-name"; - - private static final ValuePath APP_PATH = new ValuePath(KEY_SPRING_APPLICATION_NAME); - - @Inject(ObjectParser.YAML) - @InjectLoader(ResourcerType.CORE_IMPL) - private ConfigParser yamlParser; - - @Inject(ConfigParser.PROPERTIES) - @InjectLoader(ResourcerType.CORE_IMPL) - private ConfigParser propertiesParser; - - private final ApplicationResource[] resources = new ApplicationResource[]{ - new ApplicationResource(RESOURCE_SPRINGBOOT_APPLICATION_PROPERTIES, ResourceType.PROPERTIES), - new ApplicationResource(RESOURCE_SPRINGBOOT_APPLICATION_YAML, ResourceType.YAML), - new ApplicationResource(RESOURCE_SPRINGBOOT_APPLICATION_YML, ResourceType.YAML), - new ApplicationResource(RESOURCE_FAT_SPRINGBOOT_APPLICATION_PROPERTIES, ResourceType.PROPERTIES), - new ApplicationResource(RESOURCE_FAT_SPRINGBOOT_APPLICATION_YAML, ResourceType.YAML), - new ApplicationResource(RESOURCE_FAT_SPRINGBOOT_APPLICATION_YML, ResourceType.YAML), - }; - - @Override - public void process(Map env) { - if (!env.containsKey(Application.KEY_APPLICATION_NAME)) { - String name = getApplicationName(env); - if (name != null && !name.isEmpty()) { - env.put(Application.KEY_APPLICATION_NAME, name); - } - } - } - - protected String getApplicationName(Map env) { - String result = (String) env.getOrDefault(KEY_SPRING_APPLICATION_NAME, (String) env.get(KEY_SPRING_APPLICATION_NAME1)); - if (result == null || result.isEmpty()) { - try { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - for (ApplicationResource resource : resources) { - URL url = classLoader.getResource(resource.getName()); - if (url != null) { - if (resource.getResourceType() == ResourceType.PROPERTIES) { - result = (String) parse(url.openStream(), propertiesParser).get(KEY_SPRING_APPLICATION_NAME); - } else { - result = (String) APP_PATH.get(parse(url.openStream(), yamlParser)); - } - break; - } - } - } catch (Exception ignore) { - } - } - return result; - } - - private Map parse(InputStream inputStream, ConfigParser parser) throws Exception { - try (Reader reader = new BufferedReader(new InputStreamReader(inputStream))) { - return parser.parse(reader); - } - } - - @Getter - private static class ApplicationResource { - - private final String name; - - private final ResourceType resourceType; - - ApplicationResource(String name, ResourceType resourceType) { - this.name = name; - this.resourceType = resourceType; - } - - } - - private enum ResourceType { - - PROPERTIES, - - YAML - - } -} diff --git a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/extension/jplug/JExtensionLoader.java b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/extension/jplug/JExtensionLoader.java index e0fa72acd..f743bc40b 100644 --- a/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/extension/jplug/JExtensionLoader.java +++ b/joylive-core/joylive-core-framework/src/main/java/com/jd/live/agent/core/extension/jplug/JExtensionLoader.java @@ -106,7 +106,7 @@ public List> load(final Class extensible) { // Load class, filtering out those that don't meet the conditions clazz = loadPluginClass(extensible, loader, className); if (clazz != null) { - result.add(createExtension(extensible, clazz, loader)); + result.addAll(createExtension(extensible, clazz, loader)); } } break; @@ -132,22 +132,34 @@ public List> load(final Class extensible) { * @param loader The class loader to use for loading the extension. * @return An {@link ExtensionDesc} object representing the created extension. */ - private ExtensionDesc createExtension(final Class extensible, final Class type, final ClassLoader loader) { + private List> createExtension(final Class extensible, final Class type, final ClassLoader loader) { // Retrieve annotations from extensible type and extension implementation Extensible extensibleAnno = extensible.getAnnotation(Extensible.class); Extension extensionAnno = type.getAnnotation(Extension.class); - // Create a new JExtension instance with the gathered information - JExtension e = new JExtension<>( - new Name<>(extensible, extensibleAnno == null || isEmpty(extensibleAnno.value()) ? extensible.getName() : extensibleAnno.value()), - new Name<>(type, extensionAnno == null || isEmpty(extensionAnno.value()) ? extensible.getName() : extensionAnno.value()), - extensionAnno == null || isEmpty(extensionAnno.provider()) ? extensible.getName() : extensionAnno.provider(), - extensionAnno != null ? extensionAnno.order() : Short.MAX_VALUE, - extensionAnno == null || extensionAnno.singleton(), - loader, - instantiation, - listener); - return e; + String extensibleName = extensibleAnno == null || isEmpty(extensibleAnno.value()) ? extensible.getSimpleName() : extensibleAnno.value(); + String[] values = extensionAnno == null ? null : extensionAnno.value(); + values = values == null || values.length == 0 ? new String[]{extensible.getSimpleName()} : values; + Set names = new HashSet<>(); + for (String value : values) { + names.add(isEmpty(value) ? extensible.getSimpleName() : value); + } + + List> result = new LinkedList<>(); + for (String name : names) { + // Create a new JExtension instance with the gathered information + JExtension ext = new JExtension<>( + new Name<>(extensible, extensibleName), + new Name<>(type, name), + extensionAnno == null || isEmpty(extensionAnno.provider()) ? extensible.getName() : extensionAnno.provider(), + extensionAnno != null ? extensionAnno.order() : Short.MAX_VALUE, + extensionAnno == null || extensionAnno.singleton(), + loader, + instantiation, + listener); + result.add(ext); + } + return result; } protected boolean isEmpty(final String value) { diff --git a/joylive-core/joylive-core-framework/src/main/resources/META-INF/services/com.jd.live.agent.core.bootstrap.EnvSupplier b/joylive-core/joylive-core-framework/src/main/resources/META-INF/services/com.jd.live.agent.core.bootstrap.EnvSupplier index 7c2667985..02ad38fc8 100644 --- a/joylive-core/joylive-core-framework/src/main/resources/META-INF/services/com.jd.live.agent.core.bootstrap.EnvSupplier +++ b/joylive-core/joylive-core-framework/src/main/resources/META-INF/services/com.jd.live.agent.core.bootstrap.EnvSupplier @@ -1,2 +1,2 @@ -com.jd.live.agent.core.bootstrap.spring.SpringEnvSupplier -com.jd.live.agent.core.bootstrap.config.ConfigEnvSupplier \ No newline at end of file +com.jd.live.agent.core.bootstrap.env.spring.SpringEnvSupplier +com.jd.live.agent.core.bootstrap.env.config.ConfigEnvSupplier \ No newline at end of file diff --git a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/AbstractJacksonParser.java b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/AbstractJacksonParser.java index 1799c6e29..59eec7164 100644 --- a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/AbstractJacksonParser.java +++ b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/AbstractJacksonParser.java @@ -29,19 +29,40 @@ import java.io.Writer; import java.util.Map; +/** + * AbstractJacksonParser is an abstract class that implements both ConfigParser and ObjectParser. + * It provides methods to configure and use an ObjectMapper for JSON parsing and serialization. + */ public abstract class AbstractJacksonParser implements ConfigParser, ObjectParser { + /** + * The ObjectMapper instance used for JSON parsing and serialization. + */ protected ObjectMapper mapper; + /** + * Constructs an AbstractJacksonParser and initializes the ObjectMapper with custom configuration. + */ public AbstractJacksonParser() { mapper = configure(new ObjectMapper(createFactory())).registerModules( ObjectMapper.findModules(AbstractJacksonParser.class.getClassLoader())); } + /** + * Creates a JsonFactory instance. Subclasses can override this method to provide a custom JsonFactory. + * + * @return a new JsonFactory instance. + */ protected JsonFactory createFactory() { return null; } + /** + * Configures the given ObjectMapper with custom settings. + * + * @param mapper the ObjectMapper to configure. + * @return the configured ObjectMapper. + */ protected ObjectMapper configure(ObjectMapper mapper) { return mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false). setSerializationInclusion(JsonInclude.Include.NON_NULL). diff --git a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonConverter.java b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonConverter.java index 9ec0bd9ad..13f8aa2a3 100644 --- a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonConverter.java +++ b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonConverter.java @@ -18,9 +18,16 @@ import com.fasterxml.jackson.databind.util.StdConverter; import com.jd.live.agent.core.parser.json.JsonConverter; +/** + * JacksonConverter is a custom converter that extends StdConverter to convert objects of type S to type T. + * It uses a provided JsonConverter to perform the actual conversion. + * + * @param the source type to convert from. + * @param the target type to convert to. + */ public class JacksonConverter extends StdConverter { - private JsonConverter converter; + private final JsonConverter converter; public JacksonConverter(JsonConverter converter) { this.converter = converter; diff --git a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonYamlParser.java b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonYamlParser.java index 444328edf..4abca5d75 100644 --- a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonYamlParser.java +++ b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JacksonYamlParser.java @@ -20,7 +20,7 @@ import com.jd.live.agent.core.extension.annotation.Extension; import com.jd.live.agent.core.parser.ObjectParser; -@Extension(value = ObjectParser.YAML, provider = "jackson") +@Extension(value = {ObjectParser.YAML, ObjectParser.YML}, provider = "jackson") public class JacksonYamlParser extends AbstractJacksonParser { @Override diff --git a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JsonAnnotationIntrospector.java b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JsonAnnotationIntrospector.java index 9897d3c29..ab06fa12d 100644 --- a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JsonAnnotationIntrospector.java +++ b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/JsonAnnotationIntrospector.java @@ -30,8 +30,15 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +/** + * JsonAnnotationIntrospector is a custom JacksonAnnotationIntrospector that provides additional + * functionality for handling custom annotations and converters. + */ public class JsonAnnotationIntrospector extends JacksonAnnotationIntrospector { + /** + * A map of custom converters keyed by their respective classes. + */ protected Map, JacksonConverter> converters = new ConcurrentHashMap<>(); @Override @@ -40,7 +47,18 @@ public Object findDeserializationConverter(Annotated a) { return converter != null ? converter : super.findDeserializationConverter(a); } - protected JacksonConverter getConverter(Annotated a, Class annotationType, Function> func) { + /** + * Retrieves a custom converter based on the specified annotation type and function. + * + * @param the type of the annotation. + * @param a the annotated element. + * @param annotationType the class of the annotation to look for. + * @param func a function to extract the converter class from the annotation. + * @return the custom converter, or null if none is found. + */ + protected JacksonConverter getConverter(Annotated a, + Class annotationType, + Function> func) { T annotation = a.getAnnotation(annotationType); if (annotation != null) { return converters.computeIfAbsent(func.apply(annotation), type -> { @@ -118,6 +136,12 @@ public void findEnumAliases(MapperConfig config, AnnotatedClass annotatedClas } } + /** + * Retrieves the JSON field name for the given annotated element based on the JsonField annotation. + * + * @param a the annotated element. + * @return the property name, or null if no relevant annotation is found. + */ protected PropertyName getJsonField(Annotated a) { JsonField field = a.getAnnotation(JsonField.class); if (field != null) { diff --git a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/SimpleTypeReference.java b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/SimpleTypeReference.java index c6f5d9bc2..f53de7a84 100644 --- a/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/SimpleTypeReference.java +++ b/joylive-implement/joylive-parser/joylive-parser-jackson/src/main/java/com/jd/live/agent/implement/parser/jackson/SimpleTypeReference.java @@ -19,6 +19,10 @@ import java.lang.reflect.Type; +/** + * SimpleTypeReference is a custom implementation of TypeReference that allows specifying a custom Type. + * It provides a way to work with generic type information during JSON serialization and deserialization. + */ public class SimpleTypeReference extends TypeReference { protected final Type type;