package ameba.container.server; import ameba.exception.ConfigErrorException; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import static ameba.util.IOUtils.readByteArrayFromResource; /** * <p>Connector class.</p> * * @author icode * @since 0.1.6e * */ public class Connector { /** * Constant <code>CONNECTOR_CONF_PREFIX="connector."</code> */ public static final String CONNECTOR_CONF_PREFIX = "connector."; /** * Constant <code>DEFAULT_NETWORK_HOST="0.0.0.0"</code> */ public static final String DEFAULT_NETWORK_HOST = "0.0.0.0"; private static final Logger logger = LoggerFactory.getLogger(Connector.class); protected URI httpServerBaseUri; protected String host; protected String name; protected boolean ajpEnabled; protected boolean secureEnabled; protected Integer port; protected String sslProtocol; protected boolean sslClientMode; protected boolean sslNeedClientAuth; protected boolean sslWantClientAuth; protected String sslKeyPassword; protected byte[] sslKeyStoreFile; protected String sslKeyStoreType; protected String sslKeyStorePassword; protected String sslKeyStoreProvider; protected String sslKeyManagerFactoryAlgorithm; protected String sslTrustPassword; protected byte[] sslTrustStoreFile; protected String sslTrustStorePassword; protected String sslTrustStoreType; protected String sslTrustStoreProvider; protected String sslTrustManagerFactoryAlgorithm; protected boolean sslConfigReady; protected Map<String, String> rawProperties; /** * <p>Constructor for Connector.</p> */ protected Connector() { } /** * <p>createDefault.</p> * * @param properties a {@link java.util.Map} object. * @return a {@link ameba.container.server.Connector} object. */ public static Connector createDefault(Map<String, String> properties) { Connector.Builder builder = Connector.Builder.create() .rawProperties(properties) .secureEnabled(Boolean.parseBoolean(properties.get("ssl.enabled"))) .sslProtocol(properties.get("ssl.protocol")) .sslClientMode(Boolean.parseBoolean(properties.get("ssl.clientMode"))) .sslNeedClientAuth(Boolean.parseBoolean(properties.get("ssl.needClientAuth"))) .sslWantClientAuth(Boolean.parseBoolean(properties.get("ssl.wantClientAuth"))) .sslKeyManagerFactoryAlgorithm(properties.get("ssl.key.manager.factory.algorithm")) .sslKeyPassword(properties.get("ssl.key.password")) .sslKeyStoreProvider(properties.get("ssl.key.store.provider")) .sslKeyStoreType(properties.get("ssl.key.store.type")) .sslKeyStorePassword(properties.get("ssl.key.store.password")) .sslTrustManagerFactoryAlgorithm(properties.get("ssl.Trust.manager.factory.algorithm")) .sslTrustPassword(properties.get("ssl.trust.password")) .sslTrustStoreProvider(properties.get("ssl.trust.store.provider")) .sslTrustStoreType(properties.get("ssl.trust.store.type")) .sslTrustStorePassword(properties.get("ssl.trust.store.password")) .ajpEnabled(Boolean.parseBoolean(properties.get("ajp.enabled"))) .host(StringUtils.defaultIfBlank(properties.get("host"), "0.0.0.0")) .port(Integer.valueOf(StringUtils.defaultIfBlank(properties.get("port"), "80"))) .name(properties.get("name")); String keyStoreFile = properties.get("ssl.key.store.file"); if (StringUtils.isNotBlank(keyStoreFile)) try { builder.sslKeyStoreFile(readByteArrayFromResource(keyStoreFile)); } catch (IOException e) { logger.error("读取sslKeyStoreFile出错", e); } String trustStoreFile = properties.get("ssl.trust.store.file"); if (StringUtils.isNotBlank(trustStoreFile)) try { builder.sslTrustStoreFile(readByteArrayFromResource(trustStoreFile)); } catch (IOException e) { logger.error("读取sslTrustStoreFile出错", e); } return builder.build(); } /** * <p>createDefaultConnectors.</p> * * @param properties a {@link java.util.Map} object. * @return a {@link java.util.List} object. */ public static List<Connector> createDefaultConnectors(Map<String, Object> properties) { List<Connector> connectors = Lists.newArrayList(); Map<String, Map<String, String>> propertiesMap = Maps.newLinkedHashMap(); for (String key : properties.keySet()) { if (key.startsWith(Connector.CONNECTOR_CONF_PREFIX)) { String oKey = key; key = key.substring(Connector.CONNECTOR_CONF_PREFIX.length()); int index = key.indexOf("."); if (index == -1) { throw new ConfigErrorException("connector configure error, format connector.{connectorName}.{property}"); } String name = key.substring(0, index); Map<String, String> pr = propertiesMap.get(name); if (pr == null) { pr = Maps.newLinkedHashMap(); propertiesMap.put(name, pr); pr.put("name", name); } pr.put(key.substring(index + 1), String.valueOf(properties.get(oKey))); } } connectors.addAll(propertiesMap.values().stream().map(Connector::createDefault).collect(Collectors.toList())); return connectors; } /** * <p>Getter for the field <code>host</code>.</p> * * @return a {@link java.lang.String} object. */ public String getHost() { return host; } /** * <p>Getter for the field <code>port</code>.</p> * * @return a {@link java.lang.Integer} object. */ public Integer getPort() { return port; } /** * <p>Getter for the field <code>httpServerBaseUri</code>.</p> * * @return a {@link java.net.URI} object. */ public URI getHttpServerBaseUri() { return httpServerBaseUri; } /** * <p>isSecureEnabled.</p> * * @return a boolean. */ public boolean isSecureEnabled() { return secureEnabled; } /** * <p>isSslClientMode.</p> * * @return a boolean. */ public boolean isSslClientMode() { return sslClientMode; } /** * <p>isSslNeedClientAuth.</p> * * @return a boolean. */ public boolean isSslNeedClientAuth() { return sslNeedClientAuth; } /** * <p>isSslWantClientAuth.</p> * * @return a boolean. */ public boolean isSslWantClientAuth() { return sslWantClientAuth; } /** * <p>Getter for the field <code>sslKeyPassword</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslKeyPassword() { return sslKeyPassword; } /** * <p>Getter for the field <code>sslKeyStoreFile</code>.</p> * * @return an array of byte. */ public byte[] getSslKeyStoreFile() { return sslKeyStoreFile; } /** * <p>Getter for the field <code>sslKeyStoreType</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslKeyStoreType() { return sslKeyStoreType; } /** * <p>Getter for the field <code>sslKeyStorePassword</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslKeyStorePassword() { return sslKeyStorePassword; } /** * <p>Getter for the field <code>sslTrustPassword</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslTrustPassword() { return sslTrustPassword; } /** * <p>Getter for the field <code>sslTrustStoreFile</code>.</p> * * @return an array of byte. */ public byte[] getSslTrustStoreFile() { return sslTrustStoreFile; } /** * <p>Getter for the field <code>sslTrustStorePassword</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslTrustStorePassword() { return sslTrustStorePassword; } /** * <p>Getter for the field <code>sslTrustStoreType</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslTrustStoreType() { return sslTrustStoreType; } /** * <p>isSslConfigReady.</p> * * @return a boolean. */ public boolean isSslConfigReady() { return sslConfigReady; } /** * <p>Getter for the field <code>sslProtocol</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslProtocol() { return sslProtocol; } /** * <p>Getter for the field <code>sslKeyStoreProvider</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslKeyStoreProvider() { return sslKeyStoreProvider; } /** * <p>Getter for the field <code>sslTrustStoreProvider</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslTrustStoreProvider() { return sslTrustStoreProvider; } /** * <p>Getter for the field <code>sslKeyManagerFactoryAlgorithm</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslKeyManagerFactoryAlgorithm() { return sslKeyManagerFactoryAlgorithm; } /** * <p>Getter for the field <code>sslTrustManagerFactoryAlgorithm</code>.</p> * * @return a {@link java.lang.String} object. */ public String getSslTrustManagerFactoryAlgorithm() { return sslTrustManagerFactoryAlgorithm; } /** * <p>isAjpEnabled.</p> * * @return a boolean. */ public boolean isAjpEnabled() { return ajpEnabled; } /** * <p>Getter for the field <code>name</code>.</p> * * @return a {@link java.lang.String} object. */ public String getName() { return name; } /** * <p>Getter for the field <code>rawProperties</code>.</p> * * @return a {@link java.util.Map} object. */ public Map<String, String> getRawProperties() { return rawProperties; } public static class Builder { Connector connector; private Builder(Connector connector) { this.connector = connector; } private Builder() { this(new Connector()); } public static Builder from(Connector connector) { return new Builder(connector); } public static Builder create() { return new Builder(); } public String getHost() { return connector.getHost(); } public URI getHttpServerBaseUri() { return connector.getHttpServerBaseUri(); } public boolean isSslWantClientAuth() { return connector.isSslWantClientAuth(); } public String getSslTrustStoreProvider() { return connector.getSslTrustStoreProvider(); } public String getSslKeyStoreProvider() { return connector.getSslKeyStoreProvider(); } public String getSslTrustManagerFactoryAlgorithm() { return connector.getSslTrustManagerFactoryAlgorithm(); } public String getSslProtocol() { return connector.getSslProtocol(); } public boolean isAjpEnabled() { return connector.isAjpEnabled(); } public Integer getPort() { return connector.getPort(); } public boolean isSslClientMode() { return connector.isSslClientMode(); } public byte[] getSslTrustStoreFile() { return connector.getSslTrustStoreFile(); } public String getSslTrustStorePassword() { return connector.getSslTrustStorePassword(); } public String getSslTrustPassword() { return connector.getSslTrustPassword(); } public String getSslKeyStoreType() { return connector.getSslKeyStoreType(); } public boolean isSslConfigReady() { return connector.isSslConfigReady(); } public String getSslTrustStoreType() { return connector.getSslTrustStoreType(); } public byte[] getSslKeyStoreFile() { return connector.getSslKeyStoreFile(); } public String getSslKeyStorePassword() { return connector.getSslKeyStorePassword(); } public String getSslKeyManagerFactoryAlgorithm() { return connector.getSslKeyManagerFactoryAlgorithm(); } public boolean isSslNeedClientAuth() { return connector.isSslNeedClientAuth(); } public boolean isSecureEnabled() { return connector.isSecureEnabled(); } public String getSslKeyPassword() { return connector.getSslKeyPassword(); } public Builder host(String host) { this.connector.host = host; return this; } public Builder ajpEnabled(boolean ajpEnabled) { connector.ajpEnabled = ajpEnabled; return this; } public Builder secureEnabled(boolean secureEnabled) { connector.secureEnabled = secureEnabled; return this; } public Builder port(Integer port) { connector.port = port; return this; } public Builder sslProtocol(String sslProtocol) { connector.sslProtocol = sslProtocol; return this; } public Builder sslClientMode(boolean sslClientMode) { connector.sslClientMode = sslClientMode; return this; } public Builder sslNeedClientAuth(boolean sslNeedClientAuth) { connector.sslNeedClientAuth = sslNeedClientAuth; return this; } public Builder sslWantClientAuth(boolean sslWantClientAuth) { connector.sslWantClientAuth = sslWantClientAuth; return this; } public Builder sslKeyPassword(String sslKeyPassword) { connector.sslKeyPassword = sslKeyPassword; return this; } public Builder sslKeyStoreFile(byte[] sslKeyStoreFile) { connector.sslKeyStoreFile = sslKeyStoreFile; return this; } public Builder sslKeyStoreType(String sslKeyStoreType) { connector.sslKeyStoreType = sslKeyStoreType; return this; } public Builder sslKeyStorePassword(String sslKeyStorePassword) { connector.sslKeyStorePassword = sslKeyStorePassword; return this; } public Builder sslKeyStoreProvider(String sslKeyStoreProvider) { connector.sslKeyStoreProvider = sslKeyStoreProvider; return this; } public Builder sslKeyManagerFactoryAlgorithm(String sslKeyManagerFactoryAlgorithm) { connector.sslKeyManagerFactoryAlgorithm = sslKeyManagerFactoryAlgorithm; return this; } public Builder sslTrustPassword(String sslTrustPassword) { connector.sslTrustPassword = sslTrustPassword; return this; } public void sslTrustStoreFile(byte[] sslTrustStoreFile) { connector.sslTrustStoreFile = sslTrustStoreFile; } public Builder sslTrustStorePassword(String sslTrustStorePassword) { connector.sslTrustStorePassword = sslTrustStorePassword; return this; } public Builder sslTrustStoreType(String sslTrustStoreType) { connector.sslTrustStoreType = sslTrustStoreType; return this; } public Builder sslTrustStoreProvider(String sslTrustStoreProvider) { connector.sslTrustStoreProvider = sslTrustStoreProvider; return this; } public Builder sslTrustManagerFactoryAlgorithm(String sslTrustManagerFactoryAlgorithm) { connector.sslTrustManagerFactoryAlgorithm = sslTrustManagerFactoryAlgorithm; return this; } public Builder name(String name) { connector.name = name; return this; } public Builder rawProperties(Map<String, String> properties) { connector.rawProperties = ImmutableMap.copyOf(properties); return this; } public Connector build() { if (connector.httpServerBaseUri == null) { //config server base uri connector.httpServerBaseUri = URI.create( "http" + (isSecureEnabled() ? "s" : "") + "://" + connector.getHost() + ":" + connector.port + "/"); } if (connector.secureEnabled && connector.sslKeyStoreFile != null && StringUtils.isNotBlank(connector.sslKeyPassword) && StringUtils.isNotBlank(connector.sslKeyStorePassword)) { connector.sslConfigReady = true; } return connector; } } }