package rocks.inspectit.agent.java.config.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import rocks.inspectit.agent.java.config.IConfigurationStorage; import rocks.inspectit.agent.java.config.StorageException; import rocks.inspectit.agent.java.logback.LogInitializer; import rocks.inspectit.agent.java.spring.SpringConfiguration; import rocks.inspectit.shared.all.instrumentation.config.impl.AgentConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.ExceptionSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.InstrumentationDefinition; import rocks.inspectit.shared.all.instrumentation.config.impl.JmxSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.MethodSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.PlatformSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.RetransformationStrategy; import rocks.inspectit.shared.all.instrumentation.config.impl.StrategyConfig; import rocks.inspectit.shared.all.pattern.IMatchPattern; import rocks.inspectit.shared.all.spring.logger.Log; /** * New version of the {@link IConfigurationStorage} that reads configuration from the * {@link AgentConfig}. * * @author Ivan Senic * @author Patrice Bouillet * @author Eduard Tudenhoefner * @author Alfred Krauss */ @Component public class ConfigurationStorage implements IConfigurationStorage, InitializingBean { /** * The logger of the class. */ @Log Logger log; /** * {@link SpringConfiguration} to process the received configuration. */ @Autowired private SpringConfiguration springConfiguration; /** * The name of the property for the agent name. */ static final String AGENT_NAME_PROPERTY = "inspectit.agent.name"; /** * The name of the property for the repository IP. */ static final String REPOSITORY_PROPERTY = "inspectit.repository"; /** * Default agent name used. */ private static final String DEFAULT_AGENT_NAME = "inspectIT"; /** * The repository configuration is used to store the needed information to connect to a remote * CMR. */ private RepositoryConfig repository; /** * The name of the agent. */ private String agentName; /** * Agent configuration. */ private AgentConfig agentConfiguration; /** * {@inheritDoc} */ @Override public final void setRepository(String host, int port) throws StorageException { if ((null == host) || "".equals(host)) { throw new StorageException("Repository host name cannot be null or empty!"); } if (port < 1) { throw new StorageException("Repository port has to be greater than 0!"); } // can not reset repository if (null == repository) { this.repository = new RepositoryConfig(host, port); } if (log.isInfoEnabled()) { log.info("Repository definition added. Host: " + host + " Port: " + port); } } /** * {@inheritDoc} */ @Override public RepositoryConfig getRepositoryConfig() { return repository; } /** * {@inheritDoc} */ @Override public final void setAgentName(String name) throws StorageException { if ((null == name) || "".equals(name)) { throw new StorageException("Agent name cannot be null or empty!"); } // don't allow reseting if (null == agentName) { agentName = name; // when we know the name init the logging LogInitializer.setAgentNameAndInitLogging(name); } if (log.isInfoEnabled()) { log.info("Agent name set to: " + name); } } /** * {@inheritDoc} */ @Override public String getAgentName() { return agentName; } /** * Sets {@link #agentConfiguration}. * * @param agentConfiguration * New value for {@link #agentConfiguration} * @throws StorageException * If registration of the components defined in the configuration fails. * @see SpringConfiguration#registerComponents(IConfigurationStorage) */ @Override public void setAgentConfiguration(AgentConfig agentConfiguration) throws StorageException { if (null == this.agentConfiguration) { this.agentConfiguration = agentConfiguration; } try { springConfiguration.registerComponents(this); } catch (Exception e) { throw new StorageException("Registration of the configured components failed.", e); } if (log.isInfoEnabled()) { log.info("Agent configuration added with following configuration interface properties:"); String[] lines = agentConfiguration.getConfigurationInfo().split("\n"); for (String line : lines) { log.info(line); } log.info("Class-cache exists on the server: " + agentConfiguration.isClassCacheExistsOnCmr()); if (agentConfiguration.isClassCacheExistsOnCmr()) { log.info("Number of initially instrumented classes: " + agentConfiguration.getInitialInstrumentationResults().size()); } } } /** * {@inheritDoc} */ @Override public StrategyConfig getBufferStrategyConfig() throws StorageException { ensureConfigurationExists(); StrategyConfig bufferStrategy = agentConfiguration.getBufferStrategyConfig(); if (null == bufferStrategy) { throw new StorageException("Buffer strategy not defined in the agent configuration."); } return bufferStrategy; } /** * {@inheritDoc} */ @Override public StrategyConfig getSendingStrategyConfig() throws StorageException { ensureConfigurationExists(); StrategyConfig sendingStrategy = agentConfiguration.getSendingStrategyConfig(); if (null == sendingStrategy) { throw new StorageException("Sending strategy not defined in the agent configuration."); } return sendingStrategy; } /** * {@inheritDoc} */ @Override public List<MethodSensorTypeConfig> getMethodSensorTypes() throws StorageException { ensureConfigurationExists(); List<MethodSensorTypeConfig> result = new ArrayList<MethodSensorTypeConfig>(); if (CollectionUtils.isNotEmpty(agentConfiguration.getMethodSensorTypeConfigs())) { result.addAll(agentConfiguration.getMethodSensorTypeConfigs()); } // exception sensor is also method sensor type if (null != agentConfiguration.getExceptionSensorTypeConfig()) { result.add(agentConfiguration.getExceptionSensorTypeConfig()); } // special sensors are also method sensor types if (CollectionUtils.isNotEmpty(agentConfiguration.getSpecialMethodSensorTypeConfigs())) { result.addAll(agentConfiguration.getSpecialMethodSensorTypeConfigs()); } return result; } /** * {@inheritDoc} */ @Override public ExceptionSensorTypeConfig getExceptionSensorType() throws StorageException { ensureConfigurationExists(); return agentConfiguration.getExceptionSensorTypeConfig(); } /** * {@inheritDoc} */ @Override public List<PlatformSensorTypeConfig> getPlatformSensorTypes() throws StorageException { ensureConfigurationExists(); List<PlatformSensorTypeConfig> result = new ArrayList<PlatformSensorTypeConfig>(1); if (CollectionUtils.isNotEmpty(agentConfiguration.getPlatformSensorTypeConfigs())) { result.addAll(agentConfiguration.getPlatformSensorTypeConfigs()); } return result; } /** * {@inheritDoc} */ @Override public List<JmxSensorTypeConfig> getJmxSensorTypes() throws StorageException { ensureConfigurationExists(); List<JmxSensorTypeConfig> result = new ArrayList<JmxSensorTypeConfig>(1); if (null != agentConfiguration.getJmxSensorTypeConfig()) { result.add(agentConfiguration.getJmxSensorTypeConfig()); } return result; } /** * {@inheritDoc} */ @Override public RetransformationStrategy getRetransformStrategy() throws StorageException { ensureConfigurationExists(); return agentConfiguration.getRetransformationStrategy(); } /** * {@inheritDoc} */ @Override public boolean isExceptionSensorActivated() throws StorageException { ensureConfigurationExists(); return null != agentConfiguration.getExceptionSensorTypeConfig(); } /** * {@inheritDoc} */ @Override public boolean isEnhancedExceptionSensorActivated() throws StorageException { ensureConfigurationExists(); if (isExceptionSensorActivated()) { return agentConfiguration.getExceptionSensorTypeConfig().isEnhanced(); } return false; } /** * {@inheritDoc} */ @Override public Collection<IMatchPattern> getIgnoreClassesPatterns() throws StorageException { ensureConfigurationExists(); if (CollectionUtils.isNotEmpty(agentConfiguration.getExcludeClassesPatterns())) { return Collections.unmodifiableCollection(agentConfiguration.getExcludeClassesPatterns()); } else { return Collections.emptyList(); } } /** * {@inheritDoc} */ @Override public boolean isClassCacheExistsOnCmr() throws StorageException { ensureConfigurationExists(); return agentConfiguration.isClassCacheExistsOnCmr(); } /** * {@inheritDoc} */ @Override public Map<Collection<String>, InstrumentationDefinition> getInitialInstrumentationResults() throws StorageException { ensureConfigurationExists(); return agentConfiguration.getInitialInstrumentationResults(); } /** * Checks if the JVM parameters have the repository and agent information. */ private void loadConfigurationFromJvmParameters() { // check if the information about the repository and agent is provided with the JVM params String repositoryProperty = System.getProperty(REPOSITORY_PROPERTY); if (null != repositoryProperty) { String[] repositoryIpHost = repositoryProperty.split(":"); if (repositoryIpHost.length == 2) { String repositoryIp = repositoryIpHost[0]; String repositoryPort = repositoryIpHost[1]; if (StringUtils.isNotBlank(repositoryIp) && StringUtils.isNotBlank(repositoryPort)) { log.info("Repository information found in the JVM parameters: IP=" + repositoryIp + " Port=" + repositoryPort); try { int port = Integer.parseInt(repositoryPort); setRepository(repositoryIp, port); } catch (Exception e) { log.warn("Repository could not be defined from the data in the JVM parameters", e); } } } } // agent name String agentName = System.getProperty(AGENT_NAME_PROPERTY); if (StringUtils.isNotBlank(agentName)) { try { log.info("Agent name found in the JVM parameters: AgentName=" + agentName); setAgentName(agentName); } catch (Exception e) { log.warn("Agent name could not be defined from the data in the JVM parameters", e); } } else { try { setAgentName(DEFAULT_AGENT_NAME); } catch (StorageException e) { log.warn("Agent name could not be defined from default agent name", e); } } } /** * Helper method to ensure that {@link #agentConfiguration} is not <code>null</code>. * * @throws StorageException * If configuration is null. */ private void ensureConfigurationExists() throws StorageException { if (null == agentConfiguration) { throw new StorageException("Agent configuration is not set in the Configuration storage"); } } /** * {@inheritDoc} */ @Override public void afterPropertiesSet() throws Exception { loadConfigurationFromJvmParameters(); if ((null == repository) || StringUtils.isEmpty(agentName)) { throw new BeanInitializationException("inspectIT agent must be initialized with IP and port of the CMR via JVM parameters."); } } }