Commit 710fa1fd by Jason Song

merge framework foundation

parent 325c0d80
......@@ -15,11 +15,6 @@ public class ApolloInfoController {
return Foundation.app().toString();
}
@RequestMapping("web")
public String getEnv() {
return Foundation.web().toString();
}
@RequestMapping("net")
public String getNet() {
return Foundation.net().toString();
......
......@@ -16,12 +16,6 @@
<github.path>${project.artifactId}</github.path>
</properties>
<dependencies>
<!-- framework foundation -->
<dependency>
<groupId>com.ctrip.framework</groupId>
<artifactId>framework-foundation</artifactId>
</dependency>
<!-- end of framework foundation -->
<!-- json -->
<dependency>
<groupId>com.google.code.gson</groupId>
......
package com.ctrip.framework.apollo.tracer;
import com.ctrip.framework.apollo.core.utils.ServiceBootstrap;
import com.ctrip.framework.apollo.tracer.internals.NullMessageProducerManager;
import com.ctrip.framework.apollo.tracer.spi.MessageProducer;
import com.ctrip.framework.apollo.tracer.spi.MessageProducerManager;
import com.ctrip.framework.apollo.tracer.spi.Transaction;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......
package com.ctrip.framework.foundation;
import com.ctrip.framework.foundation.internals.NullProviderManager;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import com.ctrip.framework.foundation.spi.ProviderManager;
import com.ctrip.framework.foundation.spi.provider.ApplicationProvider;
import com.ctrip.framework.foundation.spi.provider.NetworkProvider;
import com.ctrip.framework.foundation.spi.provider.ServerProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class Foundation {
private static final Logger logger = LoggerFactory.getLogger(Foundation.class);
private static Object lock = new Object();
private static ProviderManager s_manager;
// Encourage early initialization and fail early if it happens.
static {
getManager();
}
private static ProviderManager getManager() {
try {
if (s_manager == null) {
// Double locking to make sure only one thread initializes ProviderManager.
synchronized (lock) {
if (s_manager == null) {
s_manager = ServiceBootstrap.loadFirst(ProviderManager.class);
}
}
}
return s_manager;
} catch (Throwable ex) {
s_manager = new NullProviderManager();
logger.error("Initialize ProviderManager failed.", ex);
return s_manager;
}
}
public static String getProperty(String name, String defaultValue) {
try {
return getManager().getProperty(name, defaultValue);
} catch (Throwable ex) {
logger.error("getProperty for {} failed.", name, ex);
return defaultValue;
}
}
public static NetworkProvider net() {
try {
return getManager().provider(NetworkProvider.class);
} catch (Exception ex) {
logger.error("Initialize NetworkProvider failed.", ex);
return NullProviderManager.provider;
}
}
public static ServerProvider server() {
try {
return getManager().provider(ServerProvider.class);
} catch (Exception ex) {
logger.error("Initialize ServerProvider failed.", ex);
return NullProviderManager.provider;
}
}
public static ApplicationProvider app() {
try {
return getManager().provider(ApplicationProvider.class);
} catch (Exception ex) {
logger.error("Initialize ApplicationProvider failed.", ex);
return NullProviderManager.provider;
}
}
}
package com.ctrip.framework.foundation.internals;
import java.util.LinkedHashMap;
import java.util.Map;
import com.ctrip.framework.foundation.internals.provider.DefaultApplicationProvider;
import com.ctrip.framework.foundation.internals.provider.DefaultNetworkProvider;
import com.ctrip.framework.foundation.internals.provider.DefaultServerProvider;
import com.ctrip.framework.foundation.spi.ProviderManager;
import com.ctrip.framework.foundation.spi.provider.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultProviderManager implements ProviderManager {
private static final Logger logger = LoggerFactory.getLogger(DefaultProviderManager.class);
private Map<Class<? extends Provider>, Provider> m_providers =
new LinkedHashMap<Class<? extends Provider>, Provider>();
public DefaultProviderManager() {
// Load per-application configuration, like app id, from classpath://META-INF/app.properties
Provider applicationProvider = new DefaultApplicationProvider();
applicationProvider.initialize();
register(applicationProvider);
// Load network parameters
Provider networkProvider = new DefaultNetworkProvider();
networkProvider.initialize();
register(networkProvider);
// Load environment (fat, fws, uat, prod ...) and dc, from /opt/settings/server.properties, JVM property and/or OS
// environment variables.
Provider serverProvider = new DefaultServerProvider();
serverProvider.initialize();
register(serverProvider);
}
public synchronized void register(Provider provider) {
m_providers.put(provider.getType(), provider);
}
@Override
@SuppressWarnings("unchecked")
public <T extends Provider> T provider(Class<T> clazz) {
Provider provider = m_providers.get(clazz);
if (provider != null) {
return (T) provider;
} else {
logger.error("No provider [{}] found in DefaultProviderManager, please make sure it is registered in DefaultProviderManager ",
clazz.getName());
return (T) NullProviderManager.provider;
}
}
@Override
public String getProperty(String name, String defaultValue) {
for (Provider provider : m_providers.values()) {
String value = provider.getProperty(name, null);
if (value != null) {
return value;
}
}
return defaultValue;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(512);
if (null != m_providers) {
for (Map.Entry<Class<? extends Provider>, Provider> entry : m_providers.entrySet()) {
sb.append(entry.getValue()).append("\n");
}
}
sb.append("(DefaultProviderManager)").append("\n");
return sb.toString();
}
}
package com.ctrip.framework.foundation.internals;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public enum NetworkInterfaceManager {
INSTANCE;
private InetAddress m_local;
private InetAddress m_localHost;
private NetworkInterfaceManager() {
load();
}
public InetAddress findValidateIp(List<InetAddress> addresses) {
InetAddress local = null;
int maxWeight = -1;
for (InetAddress address : addresses) {
if (address instanceof Inet4Address) {
int weight = 0;
if (address.isSiteLocalAddress()) {
weight += 8;
}
if (address.isLinkLocalAddress()) {
weight += 4;
}
if (address.isLoopbackAddress()) {
weight += 2;
}
// has host name
// TODO fix performance issue when calling getHostName
if (!Objects.equals(address.getHostName(), address.getHostAddress())) {
weight += 1;
}
if (weight > maxWeight) {
maxWeight = weight;
local = address;
}
}
}
return local;
}
public String getLocalHostAddress() {
return m_local.getHostAddress();
}
public String getLocalHostName() {
try {
if (null == m_localHost) {
m_localHost = InetAddress.getLocalHost();
}
return m_localHost.getHostName();
} catch (UnknownHostException e) {
return m_local.getHostName();
}
}
private String getProperty(String name) {
String value = null;
value = System.getProperty(name);
if (value == null) {
value = System.getenv(name);
}
return value;
}
private void load() {
String ip = getProperty("host.ip");
if (ip != null) {
try {
m_local = InetAddress.getByName(ip);
return;
} catch (Exception e) {
System.err.println(e);
// ignore
}
}
try {
List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
List<InetAddress> addresses = new ArrayList<InetAddress>();
InetAddress local = null;
try {
for (NetworkInterface ni : nis) {
if (ni.isUp() && !ni.isLoopback()) {
addresses.addAll(Collections.list(ni.getInetAddresses()));
}
}
local = findValidateIp(addresses);
} catch (Exception e) {
// ignore
}
m_local = local;
} catch (SocketException e) {
// ignore it
}
}
}
package com.ctrip.framework.foundation.internals;
import com.ctrip.framework.foundation.internals.provider.NullProvider;
import com.ctrip.framework.foundation.spi.ProviderManager;
public class NullProviderManager implements ProviderManager {
public static final NullProvider provider = new NullProvider();
@Override
public String getProperty(String name, String defaultValue) {
return defaultValue;
}
@Override
public NullProvider provider(Class clazz) {
return provider;
}
@Override
public String toString() {
return provider.toString();
}
}
package com.ctrip.framework.apollo.core.utils;
package com.ctrip.framework.foundation.internals;
import java.util.Iterator;
import java.util.ServiceLoader;
public class ServiceBootstrap {
public static <S> S loadFirst(Class<S> clazz) {
Iterator<S> iterator = loadAll(clazz);
if (!iterator.hasNext()) {
throw new IllegalStateException(String.format(
"No implementation defined in /META-INF/services/%s, please check whether the file exists and has the right implementation class!",
clazz.getName()));
}
return iterator.next();
}
public static <S> S loadFirst(Class<S> clazz) {
Iterator<S> iterator = loadAll(clazz);
if (!iterator.hasNext()) {
throw new IllegalStateException(String.format(
"No implementation defined in /META-INF/services/%s, please check whether the file exists and has the right implementation class!",
clazz.getName()));
}
return iterator.next();
}
private static <S> Iterator<S> loadAll(Class<S> clazz) {
ServiceLoader<S> loader = ServiceLoader.load(clazz);
private static <S> Iterator<S> loadAll(Class<S> clazz) {
ServiceLoader<S> loader = ServiceLoader.load(clazz);
return loader.iterator();
}
return loader.iterator();
}
}
package com.ctrip.framework.foundation.internals;
public class Utils {
public static boolean isBlank(String str) {
if (str == null || str.length() == 0) {
return true;
}
int length = str.length();
for (int i = 0; i < length; i++) {
char ch = str.charAt(i);
if (!Character.isWhitespace(ch)) {
return false;
}
}
return true;
}
public static boolean isOSWindows() {
String osName = System.getProperty("os.name");
if (Utils.isBlank(osName)) {
return false;
}
return osName.startsWith("Windows");
}
}
/*
* 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.ctrip.framework.foundation.internals.io;
import java.io.Serializable;
/**
* Byte Order Mark (BOM) representation - see {@link BOMInputStream}.
*
* @see BOMInputStream
* @see <a href="http://en.wikipedia.org/wiki/Byte_order_mark">Wikipedia: Byte Order Mark</a>
* @see <a href="http://www.w3.org/TR/2006/REC-xml-20060816/#sec-guessing">W3C: Autodetection of Character Encodings
* (Non-Normative)</a>
* @version $Id: ByteOrderMark.java 1586504 2014-04-10 23:34:37Z ggregory $
* @since 2.0
*/
public class ByteOrderMark implements Serializable {
private static final long serialVersionUID = 1L;
/** UTF-8 BOM */
public static final ByteOrderMark UTF_8 = new ByteOrderMark("UTF-8", 0xEF, 0xBB, 0xBF);
/** UTF-16BE BOM (Big-Endian) */
public static final ByteOrderMark UTF_16BE = new ByteOrderMark("UTF-16BE", 0xFE, 0xFF);
/** UTF-16LE BOM (Little-Endian) */
public static final ByteOrderMark UTF_16LE = new ByteOrderMark("UTF-16LE", 0xFF, 0xFE);
/**
* UTF-32BE BOM (Big-Endian)
*
* @since 2.2
*/
public static final ByteOrderMark UTF_32BE = new ByteOrderMark("UTF-32BE", 0x00, 0x00, 0xFE, 0xFF);
/**
* UTF-32LE BOM (Little-Endian)
*
* @since 2.2
*/
public static final ByteOrderMark UTF_32LE = new ByteOrderMark("UTF-32LE", 0xFF, 0xFE, 0x00, 0x00);
/**
* Unicode BOM character; external form depends on the encoding.
*
* @see <a href="http://unicode.org/faq/utf_bom.html#BOM">Byte Order Mark (BOM) FAQ</a>
* @since 2.5
*/
public static final char UTF_BOM = '\uFEFF';
private final String charsetName;
private final int[] bytes;
/**
* Construct a new BOM.
*
* @param charsetName The name of the charset the BOM represents
* @param bytes The BOM's bytes
* @throws IllegalArgumentException if the charsetName is null or zero length
* @throws IllegalArgumentException if the bytes are null or zero length
*/
public ByteOrderMark(final String charsetName, final int... bytes) {
if (charsetName == null || charsetName.isEmpty()) {
throw new IllegalArgumentException("No charsetName specified");
}
if (bytes == null || bytes.length == 0) {
throw new IllegalArgumentException("No bytes specified");
}
this.charsetName = charsetName;
this.bytes = new int[bytes.length];
System.arraycopy(bytes, 0, this.bytes, 0, bytes.length);
}
/**
* Return the name of the {@link java.nio.charset.Charset} the BOM represents.
*
* @return the character set name
*/
public String getCharsetName() {
return charsetName;
}
/**
* Return the length of the BOM's bytes.
*
* @return the length of the BOM's bytes
*/
public int length() {
return bytes.length;
}
/**
* The byte at the specified position.
*
* @param pos The position
* @return The specified byte
*/
public int get(final int pos) {
return bytes[pos];
}
/**
* Return a copy of the BOM's bytes.
*
* @return a copy of the BOM's bytes
*/
public byte[] getBytes() {
final byte[] copy = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
copy[i] = (byte) bytes[i];
}
return copy;
}
/**
* Indicates if this BOM's bytes equals another.
*
* @param obj The object to compare to
* @return true if the bom's bytes are equal, otherwise false
*/
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof ByteOrderMark)) {
return false;
}
final ByteOrderMark bom = (ByteOrderMark) obj;
if (bytes.length != bom.length()) {
return false;
}
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] != bom.get(i)) {
return false;
}
}
return true;
}
/**
* Return the hashcode for this BOM.
*
* @return the hashcode for this BOM.
* @see Object#hashCode()
*/
@Override
public int hashCode() {
int hashCode = getClass().hashCode();
for (final int b : bytes) {
hashCode += b;
}
return hashCode;
}
/**
* Provide a String representation of the BOM.
*
* @return the length of the BOM's bytes
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(getClass().getSimpleName());
builder.append('[');
builder.append(charsetName);
builder.append(": ");
for (int i = 0; i < bytes.length; i++) {
if (i > 0) {
builder.append(",");
}
builder.append("0x");
builder.append(Integer.toHexString(0xFF & bytes[i]).toUpperCase());
}
builder.append(']');
return builder.toString();
}
}
package com.ctrip.framework.foundation.internals.io;
public class IOUtils {
public static final int EOF = -1;
}
/*
* 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.ctrip.framework.foundation.internals.io;
import static com.ctrip.framework.foundation.internals.io.IOUtils.EOF;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* A Proxy stream which acts as expected, that is it passes the method calls on to the proxied stream and doesn't change
* which methods are being called.
* <p>
* It is an alternative base class to FilterInputStream to increase reusability, because FilterInputStream changes the
* methods being called, such as read(byte[]) to read(byte[], int, int).
* <p>
* See the protected methods for ways in which a subclass can easily decorate a stream with custom pre-, post- or error
* processing functionality.
*
* @version $Id: ProxyInputStream.java 1603493 2014-06-18 15:46:07Z ggregory $
*/
public abstract class ProxyInputStream extends FilterInputStream {
/**
* Constructs a new ProxyInputStream.
*
* @param proxy the InputStream to delegate to
*/
public ProxyInputStream(final InputStream proxy) {
super(proxy);
// the proxy is stored in a protected superclass variable named 'in'
}
/**
* Invokes the delegate's <code>read()</code> method.
*
* @return the byte read or -1 if the end of stream
* @throws IOException if an I/O error occurs
*/
@Override
public int read() throws IOException {
try {
beforeRead(1);
final int b = in.read();
afterRead(b != EOF ? 1 : EOF);
return b;
} catch (final IOException e) {
handleIOException(e);
return EOF;
}
}
/**
* Invokes the delegate's <code>read(byte[])</code> method.
*
* @param bts the buffer to read the bytes into
* @return the number of bytes read or EOF if the end of stream
* @throws IOException if an I/O error occurs
*/
@Override
public int read(final byte[] bts) throws IOException {
try {
beforeRead(bts != null ? bts.length : 0);
final int n = in.read(bts);
afterRead(n);
return n;
} catch (final IOException e) {
handleIOException(e);
return EOF;
}
}
/**
* Invokes the delegate's <code>read(byte[], int, int)</code> method.
*
* @param bts the buffer to read the bytes into
* @param off The start offset
* @param len The number of bytes to read
* @return the number of bytes read or -1 if the end of stream
* @throws IOException if an I/O error occurs
*/
@Override
public int read(final byte[] bts, final int off, final int len) throws IOException {
try {
beforeRead(len);
final int n = in.read(bts, off, len);
afterRead(n);
return n;
} catch (final IOException e) {
handleIOException(e);
return EOF;
}
}
/**
* Invokes the delegate's <code>skip(long)</code> method.
*
* @param ln the number of bytes to skip
* @return the actual number of bytes skipped
* @throws IOException if an I/O error occurs
*/
@Override
public long skip(final long ln) throws IOException {
try {
return in.skip(ln);
} catch (final IOException e) {
handleIOException(e);
return 0;
}
}
/**
* Invokes the delegate's <code>available()</code> method.
*
* @return the number of available bytes
* @throws IOException if an I/O error occurs
*/
@Override
public int available() throws IOException {
try {
return super.available();
} catch (final IOException e) {
handleIOException(e);
return 0;
}
}
/**
* Invokes the delegate's <code>close()</code> method.
*
* @throws IOException if an I/O error occurs
*/
@Override
public void close() throws IOException {
try {
in.close();
} catch (final IOException e) {
handleIOException(e);
}
}
/**
* Invokes the delegate's <code>mark(int)</code> method.
*
* @param readlimit read ahead limit
*/
@Override
public synchronized void mark(final int readlimit) {
in.mark(readlimit);
}
/**
* Invokes the delegate's <code>reset()</code> method.
*
* @throws IOException if an I/O error occurs
*/
@Override
public synchronized void reset() throws IOException {
try {
in.reset();
} catch (final IOException e) {
handleIOException(e);
}
}
/**
* Invokes the delegate's <code>markSupported()</code> method.
*
* @return true if mark is supported, otherwise false
*/
@Override
public boolean markSupported() {
return in.markSupported();
}
/**
* Invoked by the read methods before the call is proxied. The number of bytes that the caller wanted to read (1 for
* the {@link #read()} method, buffer length for {@link #read(byte[])}, etc.) is given as an argument.
* <p>
* Subclasses can override this method to add common pre-processing functionality without having to override all the
* read methods. The default implementation does nothing.
* <p>
* Note this method is <em>not</em> called from {@link #skip(long)} or {@link #reset()}. You need to explicitly
* override those methods if you want to add pre-processing steps also to them.
*
* @since 2.0
* @param n number of bytes that the caller asked to be read
* @throws IOException if the pre-processing fails
*/
protected void beforeRead(final int n) throws IOException {
// no-op
}
/**
* Invoked by the read methods after the proxied call has returned successfully. The number of bytes returned to the
* caller (or -1 if the end of stream was reached) is given as an argument.
* <p>
* Subclasses can override this method to add common post-processing functionality without having to override all the
* read methods. The default implementation does nothing.
* <p>
* Note this method is <em>not</em> called from {@link #skip(long)} or {@link #reset()}. You need to explicitly
* override those methods if you want to add post-processing steps also to them.
*
* @since 2.0
* @param n number of bytes read, or -1 if the end of stream was reached
* @throws IOException if the post-processing fails
*/
protected void afterRead(final int n) throws IOException {
// no-op
}
/**
* Handle any IOExceptions thrown.
* <p>
* This method provides a point to implement custom exception handling. The default behaviour is to re-throw the
* exception.
*
* @param e The IOException thrown
* @throws IOException if an I/O error occurs
* @since 2.0
*/
protected void handleIOException(final IOException e) throws IOException {
throw e;
}
}
package com.ctrip.framework.foundation.internals.provider;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ctrip.framework.foundation.internals.Utils;
import com.ctrip.framework.foundation.internals.io.BOMInputStream;
import com.ctrip.framework.foundation.spi.provider.ApplicationProvider;
import com.ctrip.framework.foundation.spi.provider.Provider;
public class DefaultApplicationProvider implements ApplicationProvider {
private static final Logger logger = LoggerFactory.getLogger(DefaultApplicationProvider.class);
public static final String APP_PROPERTIES_CLASSPATH = "/META-INF/app.properties";
private Properties m_appProperties = new Properties();
private String m_appId;
@Override
public void initialize() {
try {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(APP_PROPERTIES_CLASSPATH);
if (in == null) {
in = DefaultApplicationProvider.class.getResourceAsStream(APP_PROPERTIES_CLASSPATH);
}
if (in == null) {
logger.warn("{} not found from classpath!", APP_PROPERTIES_CLASSPATH);
}
initialize(in);
} catch (Throwable ex) {
logger.error("Initialize DefaultApplicationProvider failed.", ex);
}
}
@Override
public void initialize(InputStream in) {
try {
if (in != null) {
try {
m_appProperties.load(new InputStreamReader(new BOMInputStream(in), StandardCharsets.UTF_8));
} finally {
in.close();
}
}
initAppId();
} catch (Throwable ex) {
logger.error("Initialize DefaultApplicationProvider failed.", ex);
}
}
@Override
public String getAppId() {
return m_appId;
}
@Override
public boolean isAppIdSet() {
return !Utils.isBlank(m_appId);
}
@Override
public String getProperty(String name, String defaultValue) {
if ("app.id".equals(name)) {
String val = getAppId();
return val == null ? defaultValue : val;
} else {
String val = m_appProperties.getProperty(name, defaultValue);
return val == null ? defaultValue : val;
}
}
@Override
public Class<? extends Provider> getType() {
return ApplicationProvider.class;
}
private void initAppId() {
// 1. Get app.id from System Property
m_appId = System.getProperty("app.id");
if (!Utils.isBlank(m_appId)) {
m_appId = m_appId.trim();
logger.info("App ID is set to {} by app.id property from System Property", m_appId);
return;
}
// 2. Try to get app id from app.properties.
m_appId = m_appProperties.getProperty("app.id");
if (!Utils.isBlank(m_appId)) {
m_appId = m_appId.trim();
logger.info("App ID is set to {} by app.id property from {}", m_appId, APP_PROPERTIES_CLASSPATH);
return;
}
m_appId = null;
logger.warn("app.id is not available from System Property and {}. It is set to null", APP_PROPERTIES_CLASSPATH);
}
@Override
public String toString() {
return "appId [" + getAppId() + "] properties: " + m_appProperties + " (DefaultApplicationProvider)";
}
}
package com.ctrip.framework.foundation.internals.provider;
import com.ctrip.framework.foundation.internals.NetworkInterfaceManager;
import com.ctrip.framework.foundation.spi.provider.NetworkProvider;
import com.ctrip.framework.foundation.spi.provider.Provider;
public class DefaultNetworkProvider implements NetworkProvider {
@Override
public String getProperty(String name, String defaultValue) {
if ("host.address".equalsIgnoreCase(name)) {
String val = getHostAddress();
return val == null ? defaultValue : val;
} else if ("host.name".equalsIgnoreCase(name)) {
String val = getHostName();
return val == null ? defaultValue : val;
} else {
return defaultValue;
}
}
@Override
public void initialize() {
}
@Override
public String getHostAddress() {
return NetworkInterfaceManager.INSTANCE.getLocalHostAddress();
}
@Override
public String getHostName() {
return NetworkInterfaceManager.INSTANCE.getLocalHostName();
}
@Override
public Class<? extends Provider> getType() {
return NetworkProvider.class;
}
@Override
public String toString() {
return "hostName [" + getHostName() + "] hostIP [" + getHostAddress() + "] (DefaultNetworkProvider)";
}
}
package com.ctrip.framework.foundation.internals.provider;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import com.ctrip.framework.foundation.internals.Utils;
import com.ctrip.framework.foundation.internals.io.BOMInputStream;
import com.ctrip.framework.foundation.spi.provider.Provider;
import com.ctrip.framework.foundation.spi.provider.ServerProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultServerProvider implements ServerProvider {
private static final Logger logger = LoggerFactory.getLogger(DefaultServerProvider.class);
private static final String SERVER_PROPERTIES_LINUX = "/opt/settings/server.properties";
private static final String SERVER_PROPERTIES_WINDOWS = "C:/opt/settings/server.properties";
private String m_env;
private String m_dc;
private Properties m_serverProperties = new Properties();
@Override
public void initialize() {
try {
String path = Utils.isOSWindows() ? SERVER_PROPERTIES_WINDOWS : SERVER_PROPERTIES_LINUX;
File file = new File(path);
if (file.exists() && file.canRead()) {
logger.info("Loading {}", file.getAbsolutePath());
FileInputStream fis = new FileInputStream(file);
initialize(fis);
return;
}
logger.warn("{} does not exist or is not readable.", path);
initialize(null);
} catch (Throwable ex) {
logger.error("Initialize DefaultServerProvider failed.", ex);
}
}
@Override
public void initialize(InputStream in) {
try {
if (in != null) {
try {
m_serverProperties.load(new InputStreamReader(new BOMInputStream(in), StandardCharsets.UTF_8));
} finally {
in.close();
}
}
initEnvType();
initDataCenter();
} catch (Throwable ex) {
logger.error("Initialize DefaultServerProvider failed.", ex);
}
}
@Override
public String getDataCenter() {
return m_dc;
}
@Override
public boolean isDataCenterSet() {
return m_dc != null;
}
@Override
public String getEnvType() {
return m_env;
}
@Override
public boolean isEnvTypeSet() {
return m_env != null;
}
@Override
public String getProperty(String name, String defaultValue) {
if ("env".equalsIgnoreCase(name)) {
String val = getEnvType();
return val == null ? defaultValue : val;
} else if ("dc".equalsIgnoreCase(name)) {
String val = getDataCenter();
return val == null ? defaultValue : val;
} else {
String val = m_serverProperties.getProperty(name, defaultValue);
return val == null ? defaultValue : val.trim();
}
}
@Override
public Class<? extends Provider> getType() {
return ServerProvider.class;
}
private void initEnvType() {
// 1. Try to get environment from JVM system property
m_env = System.getProperty("env");
if (!Utils.isBlank(m_env)) {
m_env = m_env.trim();
logger.info("Environment is set to [{}] by JVM system property 'env'.", m_env);
return;
}
// 2. Try to get environment from OS environment variable
m_env = System.getenv("ENV");
if (!Utils.isBlank(m_env)) {
m_env = m_env.trim();
logger.info("Environment is set to [{}] by OS env variable 'ENV'.", m_env);
return;
}
// 3. Try to get environment from file "server.properties"
m_env = m_serverProperties.getProperty("env");
if (!Utils.isBlank(m_env)) {
m_env = m_env.trim();
logger.info("Environment is set to [{}] by property 'env' in server.properties.", m_env);
return;
}
// 4. Set environment to null.
m_env = null;
logger.warn("Environment is set to null. Because it is not available in either (1) JVM system property 'env', (2) OS env variable 'ENV' nor (3) property 'env' from the properties InputStream.");
}
private void initDataCenter() {
// 1. Try to get environment from JVM system property
m_dc = System.getProperty("idc");
if (!Utils.isBlank(m_dc)) {
m_dc = m_dc.trim();
logger.info("Data Center is set to [{}] by JVM system property 'idc'.", m_dc);
return;
}
// 2. Try to get idc from OS environment variable
m_dc = System.getenv("IDC");
if (!Utils.isBlank(m_dc)) {
m_dc = m_dc.trim();
logger.info("Data Center is set to [{}] by OS env variable 'IDC'.", m_dc);
return;
}
// 3. Try to get idc from from file "server.properties"
m_dc = m_serverProperties.getProperty("idc");
if (!Utils.isBlank(m_dc)) {
m_dc = m_dc.trim();
logger.info("Data Center is set to [{}] by property 'idc' in server.properties.", m_dc);
return;
}
// 4. Set Data Center to null.
m_dc = null;
logger.warn("Data Center is set to null. Because it is not available in either (1) JVM system property 'idc', (2) OS env variable 'IDC' nor (3) property 'idc' from the properties InputStream.");
}
@Override
public String toString() {
return "environment [" + getEnvType() + "] data center [" + getDataCenter() + "] properties: " + m_serverProperties
+ " (DefaultServerProvider)";
}
}
package com.ctrip.framework.foundation.internals.provider;
import java.io.InputStream;
import com.ctrip.framework.foundation.spi.provider.ApplicationProvider;
import com.ctrip.framework.foundation.spi.provider.NetworkProvider;
import com.ctrip.framework.foundation.spi.provider.Provider;
import com.ctrip.framework.foundation.spi.provider.ServerProvider;
public class NullProvider implements ApplicationProvider, NetworkProvider, ServerProvider {
@Override
public Class<? extends Provider> getType() {
return null;
}
@Override
public String getProperty(String name, String defaultValue) {
return defaultValue;
}
@Override
public void initialize() {
}
@Override
public String getAppId() {
return null;
}
@Override
public boolean isAppIdSet() {
return false;
}
@Override
public String getEnvType() {
return null;
}
@Override
public boolean isEnvTypeSet() {
return false;
}
@Override
public String getDataCenter() {
return null;
}
@Override
public boolean isDataCenterSet() {
return false;
}
@Override
public void initialize(InputStream in) {
}
@Override
public String getHostAddress() {
return null;
}
@Override
public String getHostName() {
return null;
}
@Override
public String toString() {
return "(NullProvider)";
}
}
package com.ctrip.framework.foundation.spi;
import com.ctrip.framework.foundation.spi.provider.Provider;
public interface ProviderManager {
public String getProperty(String name, String defaultValue);
public <T extends Provider> T provider(Class<T> clazz);
}
package com.ctrip.framework.foundation.spi.provider;
import java.io.InputStream;
/**
* Provider for application related properties
*/
public interface ApplicationProvider extends Provider {
/**
* @return the application's app id
*/
public String getAppId();
/**
* @return whether the application's app id is set or not
*/
public boolean isAppIdSet();
/**
* Initialize the application provider with the specified input stream
*/
public void initialize(InputStream in);
}
package com.ctrip.framework.foundation.spi.provider;
/**
* Provider for network related properties
*/
public interface NetworkProvider extends Provider {
/**
* @return the host address, i.e. ip
*/
public String getHostAddress();
/**
* @return the host name
*/
public String getHostName();
}
package com.ctrip.framework.foundation.spi.provider;
public interface Provider {
/**
* @return the current provider's type
*/
public Class<? extends Provider> getType();
/**
* Return the property value with the given name, or {@code defaultValue} if the name doesn't exist.
*
* @param name the property name
* @param defaultValue the default value when name is not found or any error occurred
* @return the property value
*/
public String getProperty(String name, String defaultValue);
/**
* Initialize the provider
*/
public void initialize();
}
package com.ctrip.framework.foundation.spi.provider;
import java.io.IOException;
import java.io.InputStream;
/**
* Provider for server related properties
*/
public interface ServerProvider extends Provider {
/**
* @return current environment or {@code null} if not set
*/
public String getEnvType();
/**
* @return whether current environment is set or not
*/
public boolean isEnvTypeSet();
/**
* @return current data center or {@code null} if not set
*/
public String getDataCenter();
/**
* @return whether data center is set or not
*/
public boolean isDataCenterSet();
/**
* Initialize server provider with the specified input stream
*
* @throws IOException
*/
public void initialize(InputStream in) throws IOException;
}
com.ctrip.framework.foundation.internals.DefaultProviderManager
\ No newline at end of file
package com.ctrip.framework.apollo;
import com.ctrip.framework.apollo.foundation.FoundationTest;
import com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import com.ctrip.framework.apollo.core.MetaDomainTest;
import com.ctrip.framework.apollo.core.utils.ServiceBootstrapTest;
import com.ctrip.framework.apollo.foundation.internals.provider.DefaultApplicationProviderTest;
import com.ctrip.framework.apollo.foundation.internals.provider.DefaultServerProviderTest;
import com.ctrip.framework.apollo.tracer.TracerTest;
import com.ctrip.framework.apollo.tracer.internals.DefaultMessageProducerManagerTest;
import com.ctrip.framework.apollo.tracer.internals.NullMessageProducerManagerTest;
import com.ctrip.framework.apollo.tracer.internals.NullMessageProducerTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
MetaDomainTest.class, ServiceBootstrapTest.class, NullMessageProducerManagerTest.class,
NullMessageProducerTest.class, DefaultMessageProducerManagerTest.class, TracerTest.class})
NullMessageProducerTest.class, DefaultMessageProducerManagerTest.class, TracerTest.class,
DefaultApplicationProviderTest.class, DefaultServerProviderTest.class, FoundationTest.class})
public class AllTests {
}
package com.ctrip.framework.apollo.foundation;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.ctrip.framework.foundation.Foundation;
public class FoundationTest {
private static final String someEnv = "pro";
@BeforeClass
public static void before() {
System.setProperty("env", someEnv);
}
@AfterClass
public static void afterClass() {
System.clearProperty("env");
}
@Test
public void testApp() {
// 获取AppId
String appId = Foundation.app().getAppId();
Assert.assertEquals("110402", appId);
}
@Test
public void testServer() {
// 获取当前环境
String envType = Foundation.server().getEnvType();
Assert.assertEquals(someEnv, envType);
}
@Test
public void testNet() {
// 获取本机IP和HostName
String hostAddress = Foundation.net().getHostAddress();
String hostName = Foundation.net().getHostName();
Assert.assertNotNull("No host address detected.", hostAddress);
Assert.assertNotNull("No host name resolved.", hostName);
}
}
package com.ctrip.framework.apollo.core.utils;
package com.ctrip.framework.apollo.foundation.internals;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import org.junit.Test;
import java.util.ServiceConfigurationError;
......
package com.ctrip.framework.apollo.foundation.internals.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import org.junit.Before;
import org.junit.Test;
import com.ctrip.framework.foundation.internals.provider.DefaultApplicationProvider;
public class DefaultApplicationProviderTest {
private DefaultApplicationProvider defaultApplicationProvider;
String PREDEFINED_APP_ID = "110402";
@Before
public void setUp() throws Exception {
defaultApplicationProvider = new DefaultApplicationProvider();
}
@Test
public void testLoadAppProperties() throws Exception {
defaultApplicationProvider.initialize();
assertEquals(PREDEFINED_APP_ID, defaultApplicationProvider.getAppId());
assertTrue(defaultApplicationProvider.isAppIdSet());
}
@Test
public void testLoadAppPropertiesWithUTF8Bom() throws Exception {
File baseDir = new File("src/test/resources/META-INF");
File appProperties = new File(baseDir, "app-with-utf8bom.properties");
defaultApplicationProvider.initialize(new FileInputStream(appProperties));
assertEquals(PREDEFINED_APP_ID, defaultApplicationProvider.getAppId());
assertTrue(defaultApplicationProvider.isAppIdSet());
}
@Test
public void testLoadAppPropertiesWithSystemProperty() throws Exception {
String someAppId = "someAppId";
System.setProperty("app.id", someAppId);
defaultApplicationProvider.initialize();
System.clearProperty("app.id");
assertEquals(someAppId, defaultApplicationProvider.getAppId());
assertTrue(defaultApplicationProvider.isAppIdSet());
}
@Test
public void testLoadAppPropertiesFailed() throws Exception {
File baseDir = new File("src/test/resources/META-INF");
File appProperties = new File(baseDir, "some-invalid-app.properties");
defaultApplicationProvider.initialize(new FileInputStream(appProperties));
assertEquals(null, defaultApplicationProvider.getAppId());
assertFalse(defaultApplicationProvider.isAppIdSet());
}
}
package com.ctrip.framework.apollo.foundation.internals.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.ctrip.framework.foundation.internals.provider.DefaultServerProvider;
public class DefaultServerProviderTest {
private DefaultServerProvider defaultServerProvider;
@Before
public void setUp() throws Exception {
cleanUp();
defaultServerProvider = new DefaultServerProvider();
}
@After
public void tearDown() throws Exception {
cleanUp();
}
private void cleanUp() {
System.clearProperty("env");
System.clearProperty("idc");
}
@Test
public void testEnvWithSystemProperty() throws Exception {
String someEnv = "someEnv";
String someDc = "someDc";
System.setProperty("env", someEnv);
System.setProperty("idc", someDc);
defaultServerProvider.initialize(null);
assertEquals(someEnv, defaultServerProvider.getEnvType());
assertEquals(someDc, defaultServerProvider.getDataCenter());
}
@Test
public void testWithPropertiesStream() throws Exception {
File baseDir = new File("src/test/resources/properties");
File serverProperties = new File(baseDir, "server.properties");
defaultServerProvider.initialize(new FileInputStream(serverProperties));
assertEquals("SHAJQ", defaultServerProvider.getDataCenter());
assertTrue(defaultServerProvider.isEnvTypeSet());
assertEquals("DEV", defaultServerProvider.getEnvType());
}
@Test
public void testWithUTF8BomPropertiesStream() throws Exception {
File baseDir = new File("src/test/resources/properties");
File serverProperties = new File(baseDir, "server-with-utf8bom.properties");
defaultServerProvider.initialize(new FileInputStream(serverProperties));
assertEquals("SHAJQ", defaultServerProvider.getDataCenter());
assertTrue(defaultServerProvider.isEnvTypeSet());
assertEquals("DEV", defaultServerProvider.getEnvType());
}
@Test
public void testWithPropertiesStreamAndEnvFromSystemProperty() throws Exception {
String prodEnv = "pro";
System.setProperty("env", prodEnv);
File baseDir = new File("src/test/resources/properties");
File serverProperties = new File(baseDir, "server.properties");
defaultServerProvider.initialize(new FileInputStream(serverProperties));
String predefinedDataCenter = "SHAJQ";
assertEquals(predefinedDataCenter, defaultServerProvider.getDataCenter());
assertTrue(defaultServerProvider.isEnvTypeSet());
assertEquals(prodEnv, defaultServerProvider.getEnvType());
}
@Test
public void testWithNoPropertiesStream() throws Exception {
defaultServerProvider.initialize(null);
assertNull(defaultServerProvider.getDataCenter());
assertFalse(defaultServerProvider.isEnvTypeSet());
assertNull(defaultServerProvider.getEnvType());
}
}
com.ctrip.framework.apollo.core.utils.ServiceBootstrapTest$Interface1Impl
\ No newline at end of file
com.ctrip.framework.apollo.core.utils.ServiceBootstrapTest$Interface1Impl
\ No newline at end of file
com.ctrip.framework.apollo.core.utils.ServiceBootstrapTest$SomeImplNotExists
\ No newline at end of file
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest$Interface1Impl
\ No newline at end of file
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest$Interface1Impl
\ No newline at end of file
com.ctrip.framework.apollo.foundation.internals.ServiceBootstrapTest$SomeImplNotExists
\ No newline at end of file
idc=SHAJQ
env=DEV
subenv=Dev123
bigdata=true
tooling=true
pci=true
idc=SHAJQ
env=DEV
subenv=Dev123
bigdata=true
tooling=true
pci=true
......@@ -142,11 +142,6 @@
</dependency>
<!-- ctrip internal dependencies, only used when ctrip profiles are enabled -->
<dependency>
<groupId>com.ctrip.framework</groupId>
<artifactId>framework-foundation</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>2.2.3</version>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment