diff --git a/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/constants/CommonMiddlewareConstants.java b/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/constants/CommonMiddlewareConstants.java index 8d57aefd0..cba6b3d24 100644 --- a/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/constants/CommonMiddlewareConstants.java +++ b/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/constants/CommonMiddlewareConstants.java @@ -29,6 +29,8 @@ public class CommonMiddlewareConstants { */ public static final String APP_NAME_KEY = "spring.application.name"; + public static final String SOFA_BOOTSTRAP = "sofaBootstrap"; + /** * {@link org.springframework.boot.ResourceBanner#getVersionsMap} */ diff --git a/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/listener/SofaBootstrapRunListener.java b/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/listener/SofaBootstrapRunListener.java new file mode 100644 index 000000000..017968024 --- /dev/null +++ b/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/listener/SofaBootstrapRunListener.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.alipay.sofa.infra.listener; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.springframework.boot.Banner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.config.ConfigFileApplicationListener; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.Ordered; +import org.springframework.core.env.*; +import org.springframework.util.ClassUtils; +import org.springframework.util.StringUtils; + +import com.alipay.sofa.infra.constants.CommonMiddlewareConstants; +import com.alipay.sofa.infra.utils.SOFABootEnvUtils; + +/** + * @author qilong.zql + * @since 3.0.0 + */ +public class SofaBootstrapRunListener implements + ApplicationListener, + Ordered { + private final static String LOGGING_PATH = "logging.path"; + private final static String LOGGING_LEVEL = "logging.level"; + private static AtomicBoolean executed = new AtomicBoolean(false); + + /** + * config log settings + */ + private void assemblyLogSetting(ConfigurableEnvironment environment) { + if (StringUtils.hasText(environment.getProperty(LOGGING_PATH))) { + System.getProperties().setProperty(LOGGING_PATH, environment.getProperty(LOGGING_PATH)); + } + for (PropertySource propertySource : environment.getPropertySources()) { + if (!(propertySource instanceof EnumerablePropertySource)) { + continue; + } + for (String key : ((EnumerablePropertySource) propertySource).getPropertyNames()) { + if (key.startsWith(LOGGING_LEVEL)) { + System.setProperty(key, environment.getProperty(key)); + } + } + } + } + + /** + * config required properties + * @param environment + */ + private void assemblyRequireProperties(ConfigurableEnvironment environment) { + if (StringUtils.hasText(environment.getProperty(CommonMiddlewareConstants.APP_NAME_KEY))) { + System.getProperties().setProperty(CommonMiddlewareConstants.APP_NAME_KEY, + environment.getProperty(CommonMiddlewareConstants.APP_NAME_KEY)); + } + } + + /** + * Mark this environment as SOFA bootstrap environment + * @param environment + */ + private void assemblyEnvironmentMark(ConfigurableEnvironment environment) { + environment.getPropertySources().addFirst( + new MapPropertySource(CommonMiddlewareConstants.SOFA_BOOTSTRAP, + new HashMap())); + } + + /** + * Un-Mark this environment as SOFA bootstrap environment + * @param environment + */ + private void unAssemblyEnvironmentMark(ConfigurableEnvironment environment) { + environment.getPropertySources().remove(CommonMiddlewareConstants.SOFA_BOOTSTRAP); + } + + @Override + public int getOrder() { + return HIGHEST_PRECEDENCE; + } + + public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { + ConfigurableEnvironment environment = event.getEnvironment(); + SpringApplication application = event.getSpringApplication(); + if (SOFABootEnvUtils.isSpringCloud() && executed.compareAndSet(false, true)) { + StandardEnvironment bootstrapEnvironment = new StandardEnvironment(); + for (PropertySource source : event.getEnvironment().getPropertySources()) { + if (source instanceof PropertySource.StubPropertySource) { + continue; + } + bootstrapEnvironment.getPropertySources().addLast(source); + } + List sources = new ArrayList<>(); + for (Object s : application.getSources()) { + if (s instanceof Class) { + sources.add((Class) s); + } else if (s instanceof String) { + sources.add(ClassUtils.resolveClassName((String) s, null)); + } + } + SpringApplication bootstrapApplication = new SpringApplicationBuilder() + .profiles(environment.getActiveProfiles()).bannerMode(Banner.Mode.OFF) + .environment(bootstrapEnvironment).sources(sources.toArray(new Class[] {})) + .registerShutdownHook(false).logStartupInfo(false).web(false).listeners() + .initializers().build(event.getArgs()); + ApplicationEnvironmentPreparedEvent bootstrapEvent = new ApplicationEnvironmentPreparedEvent( + bootstrapApplication, event.getArgs(), bootstrapEnvironment); + for (ApplicationListener listener : application.getListeners()) { + if (listener instanceof ConfigFileApplicationListener) { + listener.onApplicationEvent(bootstrapEvent); + } + } + assemblyLogSetting(bootstrapEnvironment); + assemblyRequireProperties(bootstrapEnvironment); + assemblyEnvironmentMark(environment); + } else { + unAssemblyEnvironmentMark(environment); + } + } +} \ No newline at end of file diff --git a/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/utils/SOFABootEnvUtils.java b/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/utils/SOFABootEnvUtils.java index 4300757d0..e4aad0bd7 100644 --- a/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/utils/SOFABootEnvUtils.java +++ b/infra-sofa-boot-starter/src/main/java/com/alipay/sofa/infra/utils/SOFABootEnvUtils.java @@ -16,11 +16,11 @@ */ package com.alipay.sofa.infra.utils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.alipay.sofa.infra.constants.CommonMiddlewareConstants; import org.springframework.context.ApplicationContextInitializer; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; +import org.springframework.util.ClassUtils; /** * SOFABootEnvUtils @@ -30,13 +30,7 @@ */ public class SOFABootEnvUtils { - /** - * org.springframework.cloud.bootstrap.BootstrapApplicationListener#BOOTSTRAP_PROPERTY_SOURCE_NAME - */ - private static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap"; - - private static final Logger LOGGER = LoggerFactory - .getLogger(SOFABootEnvUtils.class); + private final static String SPRING_CLOUD_MARK_NAME = "org.springframework.cloud.bootstrap.BootstrapConfiguration"; /** * Determine whether the {@link org.springframework.core.env.Environment} is Spring Cloud bootstrap environment. @@ -52,14 +46,14 @@ public class SOFABootEnvUtils { */ public static boolean isSpringCloudBootstrapEnvironment(Environment environment) { if (environment instanceof ConfigurableEnvironment) { - ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment; - if (configurableEnvironment.getPropertySources().contains( - BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - //use app logger - LOGGER.debug("Current application context environment is bootstrap"); - return true; - } + return !((ConfigurableEnvironment) environment).getPropertySources().contains( + CommonMiddlewareConstants.SOFA_BOOTSTRAP) + && isSpringCloud(); } return false; } -} + + public static boolean isSpringCloud() { + return ClassUtils.isPresent(SPRING_CLOUD_MARK_NAME, null); + } +} \ No newline at end of file diff --git a/infra-sofa-boot-starter/src/main/resources/META-INF/spring.factories b/infra-sofa-boot-starter/src/main/resources/META-INF/spring.factories index 0463f3aca..18769a8de 100644 --- a/infra-sofa-boot-starter/src/main/resources/META-INF/spring.factories +++ b/infra-sofa-boot-starter/src/main/resources/META-INF/spring.factories @@ -7,4 +7,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alipay.sofa.infra.autoconfigure.SofaBootInfraAutoConfiguration # EnvironmentPostProcessor -org.springframework.boot.env.EnvironmentPostProcessor=com.alipay.sofa.infra.env.EnvironmentCustomizer \ No newline at end of file +org.springframework.boot.env.EnvironmentPostProcessor=com.alipay.sofa.infra.env.EnvironmentCustomizer + +# SpringApplicationListener +org.springframework.context.ApplicationListener=com.alipay.sofa.infra.listener.SofaBootstrapRunListener \ No newline at end of file diff --git a/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/base/AbstractTestBase.java b/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/base/AbstractTestBase.java index 691fff04d..b71ce9206 100644 --- a/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/base/AbstractTestBase.java +++ b/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/base/AbstractTestBase.java @@ -24,6 +24,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** * 参考文档: http://docs.spring.io/spring-boot/docs/1.4.2.RELEASE/reference/htmlsingle/#boot-features-testing @@ -37,7 +38,7 @@ *

* Created by yangguanchao on 16/11/18. */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @SpringBootTest(classes = SofaBootWebSpringBootApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public abstract class AbstractTestBase { diff --git a/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/utils/SOFABootEnvUtilsTest.java b/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/utils/SOFABootEnvUtilsTest.java index 87190dac0..3ce13359e 100644 --- a/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/utils/SOFABootEnvUtilsTest.java +++ b/infra-sofa-boot-starter/src/test/java/com/alipay/sofa/infra/utils/SOFABootEnvUtilsTest.java @@ -17,9 +17,11 @@ package com.alipay.sofa.infra.utils; import com.alipay.sofa.infra.base.AbstractTestBase; +import com.alipay.sofa.infra.constants.CommonMiddlewareConstants; import org.junit.Test; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import java.util.concurrent.atomic.AtomicLong; @@ -38,29 +40,47 @@ public class SOFABootEnvUtilsTest extends AbstractTestBase implements ApplicationContextInitializer { - private static AtomicLong bootstrapContext = new AtomicLong(0L); + private static AtomicLong bootstrapContext = new AtomicLong(0L); - private static AtomicLong applicatioinContext = new AtomicLong(0L); + private static AtomicLong applicatioinContext = new AtomicLong(0L); + + private static ConfigurableEnvironment bootstrapEnvironment; + + private static ConfigurableEnvironment applicationEnvironment; /** * Method: isSpringCloudBootstrapEnvironment(Environment environment) */ @Test - public void testIsSpringCloudBootstrapEnvironment() throws Exception { + public void testIsSpringCloudBootstrapEnvironment() { Environment environment = ctx.getEnvironment(); assertFalse(SOFABootEnvUtils.isSpringCloudBootstrapEnvironment(environment)); assertEquals(1L, bootstrapContext.get()); assertEquals(1L, applicatioinContext.get()); assertFalse(SOFABootEnvUtils.isSpringCloudBootstrapEnvironment(null)); + assertEquals("infra-test", + bootstrapEnvironment.getProperty(CommonMiddlewareConstants.APP_NAME_KEY)); + assertEquals("infra-test", + applicationEnvironment.getProperty(CommonMiddlewareConstants.APP_NAME_KEY)); + assertEquals("INFO", bootstrapEnvironment.getProperty("logging.level.com.alipay.test")); + assertEquals("INFO", applicationEnvironment.getProperty("logging.level.com.alipay.test")); + assertEquals("WARN", bootstrapEnvironment.getProperty("logging.level.com.test.demo")); + assertEquals("WARN", applicationEnvironment.getProperty("logging.level.com.test.demo")); + assertEquals("./logs", bootstrapEnvironment.getProperty("logging.path")); + assertEquals("./logs", applicationEnvironment.getProperty("logging.path")); + assertEquals(null, bootstrapEnvironment.getProperty("any.key")); + assertEquals("any.value", applicationEnvironment.getProperty("any.key")); } @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { if (SOFABootEnvUtils.isSpringCloudBootstrapEnvironment(configurableApplicationContext .getEnvironment())) { + bootstrapEnvironment = configurableApplicationContext.getEnvironment(); bootstrapContext.incrementAndGet(); return; } + applicationEnvironment = configurableApplicationContext.getEnvironment(); applicatioinContext.incrementAndGet(); } -} +} \ No newline at end of file diff --git a/infra-sofa-boot-starter/src/test/resources/config/application.properties b/infra-sofa-boot-starter/src/test/resources/config/application.properties index 55af06c8c..bd54f5489 100644 --- a/infra-sofa-boot-starter/src/test/resources/config/application.properties +++ b/infra-sofa-boot-starter/src/test/resources/config/application.properties @@ -20,6 +20,7 @@ spring.application.name=infra-test #this application log level logging.level.com.alipay.test=INFO +logging.level.com.test.demo=WARN #color show:you can delete spring.output.ansi.enabled=ALWAYS @@ -32,5 +33,6 @@ logging.path=./logs # In NORMAL mode, use soft balancing supported by config server run.mode=NORMAL +any.key=any.value diff --git a/runtime-sofa-boot-plugin/pom.xml b/runtime-sofa-boot-plugin/pom.xml index e7977afff..f191bdde0 100644 --- a/runtime-sofa-boot-plugin/pom.xml +++ b/runtime-sofa-boot-plugin/pom.xml @@ -39,6 +39,12 @@ runtime-sofa-boot-starter 2.5.1 + + aopalliance + aopalliance + 1.0 + true + @@ -56,28 +62,33 @@ 1500 ${ark.plugin.name} - - + com.alipay.sofa.runtime.integration.activator.SofaRuntimeActivator + com.alipay.sofa.runtime.api.* - com.alipay.sofa.runtime.model + com.alipay.sofa.runtime.client.* + com.alipay.sofa.runtime.component.* + com.alipay.sofa.runtime.constants.* + com.alipay.sofa.runtime.integration.* + com.alipay.sofa.runtime.model.* + com.alipay.sofa.runtime.service.component + com.alipay.sofa.runtime.service.helper com.alipay.sofa.runtime.spi.client com.alipay.sofa.runtime.spi.component com.alipay.sofa.runtime.spi.health com.alipay.sofa.runtime.spi.log + com.alipay.sofa.runtime.spi.binding + com.alipay.sofa.runtime.spi.service com.alipay.sofa.runtime.spi.util - com.alipay.sofa.runtime.client.impl - com.alipay.sofa.runtime.component.impl + org.aopalliance.aop + org.aopalliance.intercept - com.alipay.sofa.runtime.service.component.AbstractContract - com.alipay.sofa.runtime.service.component.Reference - com.alipay.sofa.runtime.service.component.Service - com.alipay.sofa.runtime.spi.binding.AbstractBinding - com.alipay.sofa.runtime.spi.binding.Binding - com.alipay.sofa.runtime.spi.binding.Contract + com.alipay.sofa.runtime.service.binding.JvmBinding + com.alipay.sofa.runtime.SofaFramework + com.alipay.sofa.runtime.SofaRuntimeProperties @@ -87,9 +98,22 @@ org.apache.tomcat.embed - - com.alipay.sofa:infra-sofa-boot-starter - + + hibernate-validator + classmate + jboss-logging + jackson-annotations + jackson-core + jackson-databind + jcl-over-slf4j + jul-to-slf4j + log4j-over-slf4j + logback-core + logback-classic + snakeyaml + validation-api + + diff --git a/runtime-sofa-boot-starter/src/main/java/com/alipay/sofa/runtime/spring/initializer/SofaRuntimeSpringContextInitializer.java b/runtime-sofa-boot-starter/src/main/java/com/alipay/sofa/runtime/spring/initializer/SofaRuntimeSpringContextInitializer.java index 6f08247e3..4e2d4b4ae 100644 --- a/runtime-sofa-boot-starter/src/main/java/com/alipay/sofa/runtime/spring/initializer/SofaRuntimeSpringContextInitializer.java +++ b/runtime-sofa-boot-starter/src/main/java/com/alipay/sofa/runtime/spring/initializer/SofaRuntimeSpringContextInitializer.java @@ -19,6 +19,7 @@ import com.alipay.sofa.common.log.Constants; import com.alipay.sofa.infra.log.space.SofaBootLogSpaceIsolationInit; import com.alipay.sofa.infra.utils.SOFABootEnvUtils; +import com.alipay.sofa.runtime.spi.log.SofaLogger; import com.alipay.sofa.runtime.spi.log.SofaRuntimeLoggerFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; @@ -41,7 +42,6 @@ public void initialize(ConfigurableApplicationContext applicationContext) { + SofaRuntimeLoggerFactory.SOFA_RUNTIME_LOG_SPACE; SofaBootLogSpaceIsolationInit.initSofaBootLogger(environment, runtimeLogLevelKey); - SofaRuntimeLoggerFactory.getLogger(SofaRuntimeSpringContextInitializer.class).info( - "SOFABoot Runtime Starting!"); + SofaLogger.info("SOFABoot Runtime Starting!"); } }