From ca9fbfbcdc13892897646352495b88b3e0d62d60 Mon Sep 17 00:00:00 2001 From: JonasKunz Date: Thu, 13 Dec 2018 11:26:36 +0100 Subject: [PATCH] work on #3: Spring initialization and usage for configuration --- CONTRIBUTING.MD | 3 +- build.gradle | 3 + .../rocks/inspectit/oce/agent/AgentMain.java | 2 +- .../inspectit/oce/bootstrap/AgentManager.java | 13 +- .../rocks/inspectit/oce/bootstrap/IAgent.java | 8 +- inspectit-oce-core/build.gradle | 4 +- .../rocks/inspectit/oce/core/AgentImpl.java | 35 +++- .../oce/core/config/ConfigurationCenter.java | 37 +++++ .../config/PropertySourcesInitializer.java | 79 +++++++++ .../oce/core/config/SpringConfiguration.java | 10 ++ .../filebased/DirectoryPropertySource.java | 153 ++++++++++++++++++ .../config/filebased/PropertyFileUtils.java | 41 +++++ .../core/config/model/InspectitConfig.java | 36 +++++ .../config/model/config/ConfigSettings.java | 16 ++ .../model/config/FileBasedConfigSettings.java | 22 +++ .../src/main/resources/config/default.yml | 16 ++ 16 files changed, 468 insertions(+), 10 deletions(-) create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/ConfigurationCenter.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/PropertySourcesInitializer.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/SpringConfiguration.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/DirectoryPropertySource.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/PropertyFileUtils.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/InspectitConfig.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/ConfigSettings.java create mode 100644 inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/FileBasedConfigSettings.java create mode 100644 inspectit-oce-core/src/main/resources/config/default.yml diff --git a/CONTRIBUTING.MD b/CONTRIBUTING.MD index 738096f9c7..02deb27623 100644 --- a/CONTRIBUTING.MD +++ b/CONTRIBUTING.MD @@ -2,4 +2,5 @@ ##IDE We recommend using [IntelliJ](https://www.jetbrains.com/idea/download/#section=windows) as IDE for contributing. We also recommend installing the Gradle Plugin and the [Save Actions Plugin](https://plugins.jetbrains.com/plugin/7642-save-actions). -After installing IntelliJ you can just import the root folder of this repository as a Gradle project. When using the Save Actions Plugin you in addition should to copy the *saveactions_settings.xml* from the *config/ide/intellij/* directory to the .idea folder which is generated on project import. \ No newline at end of file +After installing IntelliJ you can just import the root folder of this repository as a Gradle project. When using the Save Actions Plugin you in addition should to copy the *saveactions_settings.xml* from the *config/ide/intellij/* directory to the .idea folder which is generated on project import. +As we use [Lombok](https://projectlombok.org/) we also recommend installing and enabling the [Lombok Plugin](https://plugins.jetbrains.com/plugin/6317-lombok-plugin) for IntelliJ. \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7646a7e081..a89d11c936 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,8 @@ subprojects { buildTools( 'jarcheck:jarcheck:1.5' ) + compileOnly 'org.projectlombok:lombok:1.18.4' + annotationProcessor 'org.projectlombok:lombok:1.18.4' } compileJava { @@ -28,6 +30,7 @@ subprojects { sourceCompatibility = 1.8 targetCompatibility = 1.8 } + // use jarCheck to make sure all classes in our dependencies are at maximum in version 1.8 task checkDependencyJavaVersions { diff --git a/inspectit-oce-agent/src/main/java/rocks/inspectit/oce/agent/AgentMain.java b/inspectit-oce-agent/src/main/java/rocks/inspectit/oce/agent/AgentMain.java index 9e7602bb3d..e84fe87405 100644 --- a/inspectit-oce-agent/src/main/java/rocks/inspectit/oce/agent/AgentMain.java +++ b/inspectit-oce-agent/src/main/java/rocks/inspectit/oce/agent/AgentMain.java @@ -33,7 +33,7 @@ public static void agentmain(String agentArgs, Instrumentation inst) { public static void premain(String agentArgs, Instrumentation inst) { try { ClassLoader icl = initializeClasspath(inst); - AgentManager.startOrReplaceInspectitCore(icl); + AgentManager.startOrReplaceInspectitCore(icl, agentArgs, inst); } catch (Exception e) { e.printStackTrace(); } diff --git a/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/AgentManager.java b/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/AgentManager.java index 195b8d7653..9264909a3f 100644 --- a/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/AgentManager.java +++ b/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/AgentManager.java @@ -1,5 +1,7 @@ package rocks.inspectit.oce.bootstrap; +import java.lang.instrument.Instrumentation; + /** * Manages the running Agent. This class is responsible for starting and stopping {@link rocks.inspectit.oce.core.AgentImpl} * @@ -9,7 +11,14 @@ public class AgentManager { public static IAgent agentInstance = null; - public static synchronized void startOrReplaceInspectitCore(ClassLoader inspectITClassLoader) { + /** + * If an Agent is already running, invoking this method first stops it. + * Afterwards it tries to start a new Agent from the given Classpath. + * @param inspectITClassLoader the classloader of inspectit-core + * @param agentCmdArgs the command line arguments to pass to the Agent + * @param instrumentation the {@link Instrumentation} to pass to the Agent + */ + public static synchronized void startOrReplaceInspectitCore(ClassLoader inspectITClassLoader, String agentCmdArgs, Instrumentation instrumentation) { if (agentInstance != null) { agentInstance.destroy(); agentInstance = null; @@ -17,7 +26,7 @@ public static synchronized void startOrReplaceInspectitCore(ClassLoader inspectI try { Class implClass = Class.forName("rocks.inspectit.oce.core.AgentImpl", true, inspectITClassLoader); agentInstance = (IAgent) implClass.newInstance(); - agentInstance.start(); + agentInstance.start(agentCmdArgs, instrumentation); } catch (Exception e) { e.printStackTrace(); } diff --git a/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/IAgent.java b/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/IAgent.java index 5d35b4af28..792c045496 100644 --- a/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/IAgent.java +++ b/inspectit-oce-bootstrap/src/main/java/rocks/inspectit/oce/bootstrap/IAgent.java @@ -1,16 +1,20 @@ package rocks.inspectit.oce.bootstrap; +import java.lang.instrument.Instrumentation; + /** * Controller itnerface for the Agent. Its implementation is {@link rocks.inspectit.oce.core.AgentImpl}. * The implementation must provide a default cosntructor without side effects! - * The actual initialization should happen in {@link #start()}, which is called by {@link AgentManager} + * The actual initialization should happen in {@link #start(String, Instrumentation)}, which is called by {@link AgentManager} */ public interface IAgent { /** * Initialized and starts the agent. + * @param agentCmdArgs the command line arguments passed to the Agent + * @param instrumentation the {@link Instrumentation} instance passed to the agent */ - void start(); + void start(String agentCmdArgs, Instrumentation instrumentation); /** * Shuts down and destroys the agent. diff --git a/inspectit-oce-core/build.gradle b/inspectit-oce-core/build.gradle index f963023bff..bd20aa02db 100644 --- a/inspectit-oce-core/build.gradle +++ b/inspectit-oce-core/build.gradle @@ -32,7 +32,9 @@ dependencies { ) implementation( - 'org.slf4j:slf4j-api:1.7.25' + 'org.springframework.boot:spring-boot:2.1.1.RELEASE', + 'org.yaml:snakeyaml:1.23', + 'ch.qos.logback:logback-classic:1.2.3' ) } diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/AgentImpl.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/AgentImpl.java index d9dd927540..a14e4f3c23 100644 --- a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/AgentImpl.java +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/AgentImpl.java @@ -1,16 +1,45 @@ package rocks.inspectit.oce.core; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; import rocks.inspectit.oce.bootstrap.IAgent; +import rocks.inspectit.oce.core.config.PropertySourcesInitializer; +import rocks.inspectit.oce.core.config.SpringConfiguration; +import java.lang.instrument.Instrumentation; + +/** + * Implementation for the {@link IAgent} interface. + * This clas sis responsible forsetting up the spring context for inspectIT. + * + * @author Jonas Kunz + */ +@Slf4j public class AgentImpl implements IAgent { + private AnnotationConfigApplicationContext ctx; + @Override - public void start() { - System.out.println("Starting Agent"); + public void start(String cmdArgs, Instrumentation instrumentation) { + + log.info("Starting inspectIT OCE Agent..."); + ctx = new AnnotationConfigApplicationContext(); + ctx.setClassLoader(AgentImpl.class.getClassLoader()); + ctx.registerShutdownHook(); + + //Allows to use autowiring to acquire the Instrumentation instance + ctx.getBeanFactory().registerSingleton("instrumentation", instrumentation); + + PropertySourcesInitializer.configurePropertySources(ctx); + + ctx.register(SpringConfiguration.class); + ctx.refresh(); } + @Override public void destroy() { - System.out.println("Shutting down Agent"); + log.info("Shutting down inspectIT OCE Agent"); + ctx.close(); } } diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/ConfigurationCenter.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/ConfigurationCenter.java new file mode 100644 index 0000000000..d0b8c297c0 --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/ConfigurationCenter.java @@ -0,0 +1,37 @@ +package rocks.inspectit.oce.core.config; + + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.stereotype.Component; +import rocks.inspectit.oce.core.config.model.InspectitConfig; + +import javax.annotation.PostConstruct; + +/** + * Compoennt responsible for loading and reloading the inspectit configurations. + * The configuration is read from the properties of the spring environment + * + * @author Jonas Kunz + */ +@Component +public class ConfigurationCenter { + + @Autowired + ConfigurableEnvironment env; + + @Getter + private InspectitConfig currentConfiguration; + + /** + * (Re-)loads the {@link InspectitConfig} from the environemnt. + * If any changes are detected an event is generated. + */ + @PostConstruct + public void reloadConfiguration() { + currentConfiguration = InspectitConfig.createFromEnvironment(env); + System.out.println(currentConfiguration); + //TODO: compare with previous config: if any changes are present send an event + } +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/PropertySourcesInitializer.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/PropertySourcesInitializer.java new file mode 100644 index 0000000000..2e1279fc9f --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/PropertySourcesInitializer.java @@ -0,0 +1,79 @@ +package rocks.inspectit.oce.core.config; + +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.io.ClassPathResource; +import rocks.inspectit.oce.core.config.filebased.DirectoryPropertySource; +import rocks.inspectit.oce.core.config.filebased.PropertyFileUtils; +import rocks.inspectit.oce.core.config.model.InspectitConfig; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import java.util.function.BiConsumer; + +/** + * This class is responsible for registering all {@link org.springframework.core.env.PropertySource}s required for the initialization of inspectIT. + * + * @author Jonas Kunz + */ +@Slf4j +public class PropertySourcesInitializer { + + private static final String DEFAULT_CONFIG_PATH = "/config/default.yml"; + private static final String DEFAULT_CONFIG_PROPERTYSOURCE_NAME = "inspectitDefaults"; + + /** + * Sorted list of all configuration sources. + * They are loaded in the given order. The earlier a configuration appears in this list, the higher its priority. + * This means that configurations loaded from items appearing earlier in the list overwrite configurations from items appearing later in the list. + * In contrast items appearing first in the list can provide information for loading items appearing later in the list. + */ + private static final List> configurationInitializationSteps = Arrays.asList( + PropertySourcesInitializer::addFileBasedConfiguration + ); + + /** + * Configures the {@link org.springframework.core.env.PropertySource}s of the given spring context. + * + * @param ctx the spring context + */ + public static void configurePropertySources(AnnotationConfigApplicationContext ctx) { + ConfigurableEnvironment env = ctx.getEnvironment(); + MutablePropertySources propsList = env.getPropertySources(); + addAgentDefaultYaml(propsList); + + for (val initializer : configurationInitializationSteps) { + initializer.accept(env.getPropertySources(), InspectitConfig.createFromEnvironment(env)); + } + + log.info("Registered Configuration Sources:"); + env.getPropertySources().stream().forEach(ps -> log.info(" {}", ps.getName())); + } + + private static void addAgentDefaultYaml(MutablePropertySources propsList) { + ClassPathResource defaultYamlResource = new ClassPathResource(DEFAULT_CONFIG_PATH, PropertySourcesInitializer.class.getClassLoader()); + Properties defaultProps = PropertyFileUtils.readYamlFiles(defaultYamlResource); + propsList.addLast(new PropertiesPropertySource(DEFAULT_CONFIG_PROPERTYSOURCE_NAME, defaultProps)); + } + + private static void addFileBasedConfiguration(MutablePropertySources propsList, InspectitConfig currentConfig) { + String path = currentConfig.getConfig().getFileBased().getPath(); + Path dirPath = Paths.get(path); + Boolean enabled = currentConfig.getConfig().getFileBased().isEnabled(); + boolean fileBasedConfigEnabled = enabled && path != null && !path.isEmpty() && Files.exists(dirPath) && Files.isDirectory(dirPath); + if (fileBasedConfigEnabled) { + log.info("initializing file based configuration from dir: {}", path); + val dps = new DirectoryPropertySource("fileBasedConfig", Paths.get(path)); + propsList.addBefore(DEFAULT_CONFIG_PROPERTYSOURCE_NAME, dps); + dps.reload(propsList); + } + } +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/SpringConfiguration.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/SpringConfiguration.java new file mode 100644 index 0000000000..95ed526721 --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/SpringConfiguration.java @@ -0,0 +1,10 @@ +package rocks.inspectit.oce.core.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan("rocks.inspectit") +public class SpringConfiguration { + +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/DirectoryPropertySource.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/DirectoryPropertySource.java new file mode 100644 index 0000000000..dfc8906f5f --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/DirectoryPropertySource.java @@ -0,0 +1,153 @@ +package rocks.inspectit.oce.core.config.filebased; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.FileSystemResource; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Stream; + +/** + * Special Properties source which adds all .properties and .yml/.yaml files form a directory as property sources. + * No subdirectories are parsed! + * The files are parsed in alphabetical order where the configuration from the first found file wins. + * This is done by adding the DirectoryPropertySource as marker which is followed by all contained files as PropertySources. + * {@link org.springframework.core.env.CompositePropertySource} was not used as this causes issues with the overwriting of Lists. + * + * @author Jonas Kunz + */ +@Slf4j +public class DirectoryPropertySource extends EnumerablePropertySource { + + + private static final List PROPERTIES_ENDINGS = Arrays.asList(".properties"); + private static final List YAML_ENDINGS = Arrays.asList(".yml", ".yaml"); + + @Getter + private Path rootDir; + + /** + * Creates a new DirectoryPropertySource. + * It has to be added to a container manually and then {@link #reload(MutablePropertySources)} has to called to load the actual configurations. + * + * @param name the name of this source + * @param rootDir the root directory to parse + */ + public DirectoryPropertySource(String name, Path rootDir) { + super(name); + this.rootDir = rootDir; + } + + /** + * Removes all previously loaded {@link PropertySource}s generated by this {@link DirectoryPropertySource} in the given container. + * Afterwards parses the directory and generated a {@link PropertySource} for each found config file, which is added after this {@link DirectoryPropertySource} to the container. + * + * @param container the container to update + */ + public void reload(MutablePropertySources container) { + removeChildrenFromContainer(container); + + List childSources = loadContentsToPropertySources(); + + PropertySource previous = this; + for (val pps : childSources) { + container.addAfter(previous.getName(), pps); + previous = pps; + } + } + + private void removeChildrenFromContainer(MutablePropertySources container) { + container.stream() + .filter(ps -> ps instanceof ChildFilePropertySource) + .map(ps -> (ChildFilePropertySource) ps) + .filter(ps -> ps.getOwner() == this) + .map(PropertySource::getName) + .forEach(container::remove); + } + + private List loadContentsToPropertySources() { + Stream files; + try { + files = Files.list(rootDir).filter(p -> !p.toFile().isDirectory()); + } catch (IOException e) { + logger.error("Unable to access config dir", e); + return Collections.emptyList(); + } + //alphabetical order, last loaded file wins + List fileSources = new ArrayList<>(); + files.sorted(Comparator.naturalOrder()).forEachOrdered(file -> { + if (doesFileHaveEnding(file, PROPERTIES_ENDINGS)) { + loadPropertiesFile(file).ifPresent(fileSources::add); + } else if (doesFileHaveEnding(file, YAML_ENDINGS)) { + loadYamlFile(file).ifPresent(fileSources::add); + } + }); + return fileSources; + } + + private Optional loadPropertiesFile(Path file) { + try { + String name = getCombinedName(file); + return Optional.of(new ChildFilePropertySource(name, PropertyFileUtils.readPropertyFiles(new FileSystemResource(file)))); + } catch (Exception e) { + logger.error("Unable to load config file " + file.getFileName() + "!", e); + return Optional.empty(); + } + } + + private Optional loadYamlFile(Path file) { + try { + String name = getCombinedName(file); + return Optional.of(new ChildFilePropertySource(name, PropertyFileUtils.readYamlFiles(new FileSystemResource(file)))); + } catch (Exception e) { + logger.error("Unable to load config file " + file.getFileName() + "!", e); + return Optional.empty(); + } + } + + + private static boolean doesFileHaveEnding(Path path, Collection allowedEndings) { + String filename = path.getFileName().toString().toLowerCase(); + return allowedEndings.stream().anyMatch(ending -> filename.endsWith(ending)); + } + + private String getCombinedName(Path file) { + return getName() + "/" + file.getFileName(); + } + + + @Override + public String[] getPropertyNames() { + return new String[0]; + } + + @Override + public Object getProperty(String name) { + return null; + } + + /** + * Nested class representing a single loaded configuration file + */ + private class ChildFilePropertySource extends PropertiesPropertySource { + + public ChildFilePropertySource(String name, Properties source) { + super(name, source); + } + + /** + * @return the {@link DirectoryPropertySource} to which this file belongs + */ + DirectoryPropertySource getOwner() { + return DirectoryPropertySource.this; + } + } +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/PropertyFileUtils.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/PropertyFileUtils.java new file mode 100644 index 0000000000..8f6633e3e0 --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/filebased/PropertyFileUtils.java @@ -0,0 +1,41 @@ +package rocks.inspectit.oce.core.config.filebased; + +import org.springframework.beans.factory.config.PropertiesFactoryBean; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.io.AbstractResource; + +import java.io.IOException; +import java.util.Properties; + +/** + * @author Jonas Kunz + */ +public class PropertyFileUtils { + + /** + * Reads the given YAML resources into a Properties Object according to Spring rules. + * + * @param resources the resources to load + * @return the generated Properties object + */ + public static Properties readYamlFiles(AbstractResource... resources) { + YamlPropertiesFactoryBean properties = new YamlPropertiesFactoryBean(); + properties.setSingleton(false); + properties.setResources(resources); + return properties.getObject(); + } + + /** + * Reads the given .properties resources into a Properties Object according to Spring rules. + * + * @param resources the resources to load + * @return the generated Properties object + */ + public static Properties readPropertyFiles(AbstractResource... resources) throws IOException { + PropertiesFactoryBean properties = new PropertiesFactoryBean(); + properties.setSingleton(false); + properties.setLocations(resources); + return properties.getObject(); + } + +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/InspectitConfig.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/InspectitConfig.java new file mode 100644 index 0000000000..d965c189be --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/InspectitConfig.java @@ -0,0 +1,36 @@ +package rocks.inspectit.oce.core.config.model; + +import lombok.Data; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.core.env.Environment; +import rocks.inspectit.oce.core.config.ConfigurationCenter; +import rocks.inspectit.oce.core.config.model.config.ConfigSettings; + +/** + * Root element of the configuration model for inspectIT. + * The loading of the configuration is managed by the {@link ConfigurationCenter}. + *

+ * The default values and the structure of the configuration can be found in the /config/default.yml file. + *

+ * Instances of this class should be treated as values, therefore the setters should never be called! + * The setters have to be there to work with the {@link org.springframework.boot.context.properties.bind.Binder}. + * + * @author Jonas Kunz + */ +@Data +public class InspectitConfig { + + /** + * The (symbolic) name of the service being instrumented + */ + String serviceName; + + /** + * Defines all configuration sources. + */ + ConfigSettings config; + + public static InspectitConfig createFromEnvironment(Environment env) { + return Binder.get(env).bind("inspectit", InspectitConfig.class).get(); + } +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/ConfigSettings.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/ConfigSettings.java new file mode 100644 index 0000000000..bd9db35f35 --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/ConfigSettings.java @@ -0,0 +1,16 @@ +package rocks.inspectit.oce.core.config.model.config; + +import lombok.Data; + +/** + * Defines the settings for all configuration sources + */ +@Data +public class ConfigSettings { + + /** + * Settings for file-based configuration input. + */ + FileBasedConfigSettings fileBased; + +} diff --git a/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/FileBasedConfigSettings.java b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/FileBasedConfigSettings.java new file mode 100644 index 0000000000..d7db9266da --- /dev/null +++ b/inspectit-oce-core/src/main/java/rocks/inspectit/oce/core/config/model/config/FileBasedConfigSettings.java @@ -0,0 +1,22 @@ +package rocks.inspectit.oce.core.config.model.config; + +import lombok.Data; + +/** + * If path is not null and enabled is true a {@link rocks.inspectit.oce.core.config.filebased.DirectoryPropertySource} + * will be created for the given path. This configuration has the highest priority, meaning that it will be loaded first + * and can configure other configuration sources. + */ +@Data +public class FileBasedConfigSettings { + /** + * The path to the directory containing the .yml or .properties files. + * Can be null or empty, in which case no file based configuration is used. + */ + String path; + + /** + * Can be used to disable the file based config while the path is still specified. + */ + boolean enabled; +} diff --git a/inspectit-oce-core/src/main/resources/config/default.yml b/inspectit-oce-core/src/main/resources/config/default.yml new file mode 100644 index 0000000000..68a135c651 --- /dev/null +++ b/inspectit-oce-core/src/main/resources/config/default.yml @@ -0,0 +1,16 @@ +inspectit: + + # the name of the service which is being instrumented + service-name: "InspectIT Agent" + + # all configurations sources + config: + # file based configuration - has the highest priority + # loads all .yaml/yml and .properties files in alphabetical order from the given path + # is active when path is not empty or null and enabled is set to true + file-based: + # the path to the directory to scan for configuration files + # scanning happens non-recursive meaning that no subdirectories will be parsed + path: + # can be used to disable the file based configuration while the path is still specified + enabled: true \ No newline at end of file