/* * Copyright 2013-2014 the original author or authors. * * 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 org.springframework.xd.dirt.server.container; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration; import org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.xd.dirt.cluster.ContainerAttributes; import org.springframework.xd.dirt.container.decryptor.DecryptorContext; import org.springframework.xd.dirt.container.decryptor.PropertiesDecryptor; import org.springframework.xd.dirt.server.ApplicationUtils; import org.springframework.xd.dirt.server.MessageBusClassLoaderFactory; import org.springframework.xd.dirt.server.ParentConfiguration; import org.springframework.xd.dirt.server.SharedServerContextConfiguration; import org.springframework.xd.dirt.server.options.ContainerOptions; import org.springframework.xd.dirt.util.BannerUtils; import org.springframework.xd.dirt.util.RuntimeUtils; import org.springframework.xd.dirt.util.XdProfiles; /** * The boot application class for a Container server. * * @author Mark Fisher * @author David Turanski * @author Marius Bogoevici * @author Gunnar Hillert * */ @Configuration @EnableAutoConfiguration(exclude = { BatchAutoConfiguration.class, JmxAutoConfiguration.class, AuditAutoConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, SolrAutoConfiguration.class }) public class ContainerServerApplication implements EnvironmentAware { private static final Logger logger = LoggerFactory.getLogger(ContainerServerApplication.class); public static final String CONTAINER_ATTRIBUTES_PREFIX = "xd.container."; private ConfigurableApplicationContext containerContext; private ConfigurableEnvironment environment; public static void main(String[] args) { new ContainerServerApplication().run(args); } public void dumpContextConfiguration() { ApplicationUtils.dumpContainerApplicationContextConfiguration(this.containerContext); } public ContainerServerApplication run(String... args) { System.out.println(BannerUtils.displayBanner(getClass().getSimpleName(), null)); try { ContainerBootstrapContext bootstrapContext = new ContainerBootstrapContext(new ContainerOptions()); MessageBusClassLoaderFactory classLoaderFactory = new MessageBusClassLoaderFactory(); DecryptorContext decryptorContext = new DecryptorContext(); this.containerContext = new SpringApplicationBuilder(ContainerOptions.class, ParentConfiguration.class) .logStartupInfo(false) .profiles(XdProfiles.CONTAINER_PROFILE) .listeners(bootstrapContext.commandLineListener()) .listeners(classLoaderFactory) .listeners(decryptorContext.propertiesDecryptor()) .child(SharedServerContextConfiguration.class, ContainerOptions.class) .resourceLoader(classLoaderFactory.getResolver()) .logStartupInfo(false) .listeners(bootstrapContext.commandLineListener()) .listeners(decryptorContext.propertiesDecryptor()) .child(ContainerServerApplication.class) .logStartupInfo(false) .listeners( ApplicationUtils.mergeApplicationListeners(bootstrapContext.commandLineListener(), bootstrapContext.pluginContextInitializers())) .child(ContainerConfiguration.class) .listeners(bootstrapContext.commandLineListener()) .listeners(decryptorContext.propertiesDecryptor()) .initializers(new IdInitializer()) .showBanner(false) .run(args); } catch (Exception e) { handleFieldErrors(e); } return this; } @Bean public ContainerAttributes containerAttributes() { final ContainerAttributes containerAttributes = new ContainerAttributes(); setConfiguredContainerAttributes(containerAttributes); final String containerIp = environment.getProperty(CONTAINER_ATTRIBUTES_PREFIX + ContainerAttributes.IP_ADDRESS_KEY); final String containerHostname = environment.getProperty(CONTAINER_ATTRIBUTES_PREFIX + ContainerAttributes.HOST_KEY); containerAttributes.setIp(StringUtils.hasText(containerIp) ? containerIp : RuntimeUtils.getIpAddress()); containerAttributes.setHost(StringUtils.hasText(containerHostname) ? containerHostname : RuntimeUtils.getHost()); containerAttributes.setPid(RuntimeUtils.getPid()); return containerAttributes; } /** * @param containerAttributes */ private void setConfiguredContainerAttributes(ContainerAttributes containerAttributes) { Map<String, String> attributes = new HashMap<String, String>(); for (PropertySource<?> propertySource : environment.getPropertySources()) { if (propertySource instanceof EnumerablePropertySource) { EnumerablePropertySource<?> ps = (EnumerablePropertySource<?>) propertySource; for (String key : ps.getPropertyNames()) { if (key.startsWith(CONTAINER_ATTRIBUTES_PREFIX)) { String attributeKey = key.replaceAll(CONTAINER_ATTRIBUTES_PREFIX, ""); attributes.put(attributeKey, environment.getProperty(key)); } } } } containerAttributes.putAll(attributes); } @Override public void setEnvironment(Environment environment) { Assert.isInstanceOf(ConfigurableEnvironment.class, environment, "unsupported environment type. " + environment.getClass()); this.environment = (ConfigurableEnvironment) environment; } private void handleFieldErrors(Exception e) { if (e.getCause() instanceof BindException) { BindException be = (BindException) e.getCause(); for (FieldError error : be.getFieldErrors()) { logger.error(String.format("the value '%s' is not allowed for property '%s'", error.getRejectedValue(), error.getField())); } } else { e.printStackTrace(); } System.exit(1); } private static class IdInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { ContainerAttributes containerAttributes = applicationContext.getParent().getBean(ContainerAttributes.class); applicationContext.setId(containerAttributes.getId()); } } }