MAILBOX-287 Makes Host available in java8 utils and factorize code between Cassandra and ES
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5b89121b Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5b89121b Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5b89121b Branch: refs/heads/master Commit: 5b89121b53a1d125a298a06f87a1b624189e447c Parents: 9de2075 Author: benwa <[email protected]> Authored: Mon Feb 27 08:58:04 2017 +0700 Committer: benwa <[email protected]> Committed: Tue Feb 28 18:44:33 2017 +0700 ---------------------------------------------------------------------- .../cassandra/init/CassandraNodeIpAndPort.java | 95 --------- .../backends/cassandra/init/ClusterFactory.java | 19 +- .../init/CassandraNodeIpAndPortTest.java | 94 --------- backends-common/elasticsearch/pom.xml | 6 - .../james/backends/es/ClientProviderImpl.java | 57 +----- .../backends/es/ClientProviderImplTest.java | 50 ----- .../modules/mailbox/CassandraSessionModule.java | 8 +- server/container/util-java8/pom.xml | 6 + .../main/java/org/apache/james/util/Host.java | 127 ++++++++++++ .../java/org/apache/james/util/HostTest.java | 202 +++++++++++++++++++ 10 files changed, 354 insertions(+), 310 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java deleted file mode 100644 index b9b3f19..0000000 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPort.java +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************** - * 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 org.apache.james.backends.cassandra.init; - -import java.util.List; - -import com.google.common.base.Objects; -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; - -public class CassandraNodeIpAndPort { - public static final int DEFAULT_CASSANDRA_PORT = 9042; - - public static CassandraNodeIpAndPort parseConfString(String ipAndPort) { - Preconditions.checkNotNull(ipAndPort); - Preconditions.checkArgument(!ipAndPort.isEmpty()); - - List<String> parts = Splitter.on(':') - .trimResults() - .splitToList(ipAndPort); - - if (parts.size() < 1 || parts.size() > 2) { - throw new IllegalArgumentException(ipAndPort + " is not a valid cassandra node"); - } - - String ip = parts.get(0); - int port = getPortFromConfPart(parts); - - return new CassandraNodeIpAndPort(ip, port); - } - - private static int getPortFromConfPart(List<String> parts) { - if (parts.size() == 2) { - return Integer.valueOf(parts.get(1)); - } else { - return DEFAULT_CASSANDRA_PORT; - } - } - - private final String ip; - private final int port; - - public CassandraNodeIpAndPort(String ip, int port) { - this.ip = ip; - this.port = port; - } - - public CassandraNodeIpAndPort(String ip) { - this(ip, DEFAULT_CASSANDRA_PORT); - } - - public String getIp() { - return ip; - } - - public int getPort() { - return port; - } - - @Override - public int hashCode() { - return Objects.hashCode(ip, port); - } - - @Override - public boolean equals(Object object) { - if (object instanceof CassandraNodeIpAndPort) { - CassandraNodeIpAndPort that = (CassandraNodeIpAndPort) object; - return Objects.equal(this.ip, that.ip) && Objects.equal(this.port, that.port); - } - return false; - } - - @Override - public String toString() { - return this.ip + ":" + this.port; - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java index 8660933..56eeebc 100644 --- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java +++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/ClusterFactory.java @@ -22,6 +22,8 @@ package org.apache.james.backends.cassandra.init; import java.util.List; import java.util.Optional; +import org.apache.james.util.Host; + import com.datastax.driver.core.Cluster; import com.datastax.driver.core.QueryOptions; import com.google.common.base.Strings; @@ -30,13 +32,14 @@ import com.google.common.collect.ImmutableList; public class ClusterFactory { private final static String DEFAULT_CLUSTER_IP = "localhost"; + public static final int DEFAULT_CASSANDRA_PORT = 9042; - public static Cluster createClusterForClusterWithPassWord(List<CassandraNodeIpAndPort> servers, String userName, String password, - Optional<Integer> refreshSchemaIntervalMillis) { + public static Cluster createClusterForClusterWithPassWord(List<Host> servers, String userName, String password, + Optional<Integer> refreshSchemaIntervalMillis) { Cluster.Builder clusterBuilder = Cluster.builder(); servers.forEach( - (server) -> clusterBuilder.addContactPoint(server.getIp()).withPort(server.getPort()) + (server) -> clusterBuilder.addContactPoint(server.getHostName()).withPort(server.getPort()) ); if(!Strings.isNullOrEmpty(userName) && !Strings.isNullOrEmpty(password)) { clusterBuilder.withCredentials(userName, password); @@ -47,23 +50,23 @@ public class ClusterFactory { return clusterBuilder.build(); } - public static Cluster createClusterForClusterWithoutPassWord(List<CassandraNodeIpAndPort> servers) { + public static Cluster createClusterForClusterWithoutPassWord(List<Host> servers) { return createClusterForClusterWithPassWord(servers, null, null, Optional.empty()); } public static Cluster createClusterForSingleServerWithPassWord(String ip, int port, String userName, String password) { - return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraNodeIpAndPort(ip, port)), userName, password, Optional.empty()); + return createClusterForClusterWithPassWord(ImmutableList.of(Host.from(ip, port)), userName, password, Optional.empty()); } public static Cluster createClusterForSingleServerWithoutPassWord(String ip, int port) { - return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraNodeIpAndPort(ip, port)), null, null, Optional.empty()); + return createClusterForClusterWithPassWord(ImmutableList.of(Host.from(ip, port)), null, null, Optional.empty()); } public static Cluster createTestingCluster(String ip, int port) { - return createClusterForClusterWithPassWord(ImmutableList.of(new CassandraNodeIpAndPort(ip, port)), null, null, Optional.of(0)); + return createClusterForClusterWithPassWord(ImmutableList.of(Host.from(ip, port)), null, null, Optional.of(0)); } public static Cluster createDefaultSession() { - return createClusterForSingleServerWithoutPassWord(DEFAULT_CLUSTER_IP, CassandraNodeIpAndPort.DEFAULT_CASSANDRA_PORT); + return createClusterForSingleServerWithoutPassWord(DEFAULT_CLUSTER_IP, DEFAULT_CASSANDRA_PORT); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java ---------------------------------------------------------------------- diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java deleted file mode 100644 index 1e97ef3..0000000 --- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/init/CassandraNodeIpAndPortTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************** - * 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 org.apache.james.backends.cassandra.init; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class CassandraNodeIpAndPortTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void parseConfStringShouldParseConfWithIpAndPort() { - //Given - String ipAndPort = "142.145.254.111:44"; - int expectedPort = 44; - String expectedIp = "142.145.254.111"; - - //When - CassandraNodeIpAndPort actual = CassandraNodeIpAndPort.parseConfString(ipAndPort); - - //Then - assertThat(actual).isEqualTo(new CassandraNodeIpAndPort(expectedIp, expectedPort)); - } - - @Test - public void parseConfStringShouldParseConfWithIpOnly() { - //Given - String ipAndPort = "142.145.254.111"; - int expectedPort = CassandraNodeIpAndPort.DEFAULT_CASSANDRA_PORT; - String expectedIp = "142.145.254.111"; - - //When - CassandraNodeIpAndPort actual = CassandraNodeIpAndPort.parseConfString(ipAndPort); - - //Then - assertThat(actual).isEqualTo(new CassandraNodeIpAndPort(expectedIp, expectedPort)); - } - - @Test - public void parseConfStringShouldFailWhenConfigIsAnEmptyString() { - expectedException.expect(IllegalArgumentException.class); - - //Given - String ipAndPort = ""; - - //When - CassandraNodeIpAndPort.parseConfString(ipAndPort); - } - - @Test - public void parseConfStringShouldFailWhenConfigIsANullString() { - expectedException.expect(NullPointerException.class); - - //Given - String ipAndPort = null; - - //When - CassandraNodeIpAndPort.parseConfString(ipAndPort); - } - - - @Test - public void parseConfStringShouldFailWhenConfigIsInvalid() { - expectedException.expect(IllegalArgumentException.class); - - //Given - String ipAndPort = "10.10.10.10:42:43"; - - //When - CassandraNodeIpAndPort.parseConfString(ipAndPort); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/backends-common/elasticsearch/pom.xml ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/pom.xml b/backends-common/elasticsearch/pom.xml index 5bdb565..6d4d16f 100644 --- a/backends-common/elasticsearch/pom.xml +++ b/backends-common/elasticsearch/pom.xml @@ -182,12 +182,6 @@ <artifactId>testcontainers</artifactId> <version>1.1.7</version> </dependency> - <dependency> - <groupId>nl.jqno.equalsverifier</groupId> - <artifactId>equalsverifier</artifactId> - <version>1.7.6</version> - <scope>test</scope> - </dependency> </dependencies> <build> <plugins> http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java index bc378c1..d76b9fa 100644 --- a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java +++ b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/ClientProviderImpl.java @@ -21,6 +21,7 @@ package org.apache.james.backends.es; import java.net.InetAddress; import java.util.Objects; +import org.apache.james.util.Host; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.transport.InetSocketTransportAddress; @@ -35,64 +36,14 @@ import com.google.common.collect.ImmutableList; public class ClientProviderImpl implements ClientProvider { - public static class Host { - private final String host; - private final int port; - - public Host(String host, int port) { - Preconditions.checkNotNull(host, "Host address can not be null"); - Preconditions.checkArgument(!host.isEmpty(), "Host address can not be empty"); - Preconditions.checkArgument(isValidPort(port), "Port should be between ]0, 65535]"); - this.host = host; - this.port = port; - } - - public String getHost() { - return host; - } - - public int getPort() { - return port; - } - - @Override - public final boolean equals(Object o) { - if (o instanceof Host) { - Host that = (Host) o; - - return Objects.equals(this.host, that.host) - && Objects.equals(this.port, that.port); - } - return false; - } - - @Override - public final int hashCode() { - return Objects.hash(host, port); - } - } - public static ClientProviderImpl forHost(String address, Integer port) { isValidPort(port); - return new ClientProviderImpl(ImmutableList.of(new Host(address, port))); + return new ClientProviderImpl(ImmutableList.of(Host.from(address, port))); } public static ClientProviderImpl fromHostsString(String hostsString) { Preconditions.checkNotNull(hostsString, "HostString should not be null"); - return new ClientProviderImpl(parseHosts(hostsString)); - } - - @VisibleForTesting - static ImmutableList<Host> parseHosts(String hostsString) { - return Splitter.on(',').splitToList(hostsString) - .stream() - .map(hostSting -> Splitter.on(':').splitToList(hostSting)) - .map(hostParts -> { - Preconditions.checkArgument(hostParts.size() == 2, "A host should be defined as a : separated pair of address and port"); - return new Host(hostParts.get(0), Integer.valueOf(hostParts.get(1))); - }) - .distinct() - .collect(Guavate.toImmutableList()); + return new ClientProviderImpl(Host.parseHosts(hostsString)); } private static boolean isValidPort(Integer port) { @@ -112,7 +63,7 @@ public class ClientProviderImpl implements ClientProvider { ConsumerChainer<Host> consumer = Throwing.consumer(host -> transportClient .addTransportAddress( new InetSocketTransportAddress( - InetAddress.getByName(host.getHost()), + InetAddress.getByName(host.getHostName()), host.getPort()))); hosts.forEach(consumer.sneakyThrow()); return transportClient; http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplTest.java ---------------------------------------------------------------------- diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplTest.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplTest.java index 5d8f420..a97eb64 100644 --- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplTest.java +++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ClientProviderImplTest.java @@ -19,15 +19,10 @@ package org.apache.james.backends.es; -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.james.backends.es.ClientProviderImpl.Host; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import nl.jqno.equalsverifier.EqualsVerifier; - public class ClientProviderImplTest { @Rule @@ -144,49 +139,4 @@ public class ClientProviderImplTest { ClientProviderImpl.fromHostsString("localhost:9200,localhost"); } - - @Test - public void parseHostsShouldParseMonoHost() { - assertThat(ClientProviderImpl.parseHosts("localhost:9200")) - .containsOnly(new Host("localhost", 9200)); - } - - @Test - public void parseHostsShouldParseMultiHosts() { - assertThat(ClientProviderImpl.parseHosts("localhost:9200,server:9155")) - .containsOnly( - new Host("localhost", 9200), - new Host("server", 9155)); - } - - @Test - public void parseHostsShouldSwallowDuplicates() { - assertThat(ClientProviderImpl.parseHosts("localhost:9200,localhost:9200")) - .containsOnly( - new Host("localhost", 9200)); - } - - @Test - public void parseHostsShouldNotSwallowSameAddressDifferentPort() { - assertThat(ClientProviderImpl.parseHosts("localhost:9200,localhost:9155")) - .containsOnly( - new Host("localhost", 9200), - new Host("localhost", 9155)); - } - - - - @Test - public void parseHostsShouldNotSwallowSamePortDifferentAddress() { - assertThat(ClientProviderImpl.parseHosts("localhost:9200,abcd:9200")) - .containsOnly( - new Host("localhost", 9200), - new Host("abcd", 9200)); - } - - - @Test - public void hostShouldRespectBeanContract() { - EqualsVerifier.forClass(ClientProviderImpl.Host.class).verify(); - } } http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java index a79ff8f..640472f 100644 --- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java +++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/CassandraSessionModule.java @@ -29,12 +29,12 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.james.backends.cassandra.components.CassandraModule; import org.apache.james.backends.cassandra.init.CassandraModuleComposite; -import org.apache.james.backends.cassandra.init.CassandraNodeIpAndPort; import org.apache.james.backends.cassandra.init.CassandraZonedDateTimeModule; import org.apache.james.backends.cassandra.init.ClusterFactory; import org.apache.james.backends.cassandra.init.ClusterWithKeyspaceCreatedFactory; import org.apache.james.backends.cassandra.init.SessionWithInitializedTablesFactory; import org.apache.james.filesystem.api.FileSystem; +import org.apache.james.util.Host; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; @@ -83,7 +83,7 @@ public class CassandraSessionModule extends AbstractModule { @Singleton Cluster provideCluster(CassandraSessionConfiguration cassandraSessionConfiguration, AsyncRetryExecutor executor) throws FileNotFoundException, ConfigurationException, ExecutionException, InterruptedException { PropertiesConfiguration configuration = cassandraSessionConfiguration.getConfiguration(); - List<CassandraNodeIpAndPort> servers = listCassandraServers(configuration); + List<Host> servers = listCassandraServers(configuration); return getRetryer(executor, configuration) .getWithRetry(ctx -> ClusterWithKeyspaceCreatedFactory @@ -95,11 +95,11 @@ public class CassandraSessionModule extends AbstractModule { .get(); } - private List<CassandraNodeIpAndPort> listCassandraServers(PropertiesConfiguration configuration) { + private List<Host> listCassandraServers(PropertiesConfiguration configuration) { String[] ipAndPorts = configuration.getStringArray("cassandra.nodes"); return Arrays.stream(ipAndPorts) - .map(CassandraNodeIpAndPort::parseConfString) + .map(string -> Host.parseConfString(string, ClusterFactory.DEFAULT_CASSANDRA_PORT)) .collect(Guavate.toImmutableList()); } http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/server/container/util-java8/pom.xml ---------------------------------------------------------------------- diff --git a/server/container/util-java8/pom.xml b/server/container/util-java8/pom.xml index 94f38ce..a9a455c 100644 --- a/server/container/util-java8/pom.xml +++ b/server/container/util-java8/pom.xml @@ -154,6 +154,12 @@ <artifactId>testcontainers</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>nl.jqno.equalsverifier</groupId> + <artifactId>equalsverifier</artifactId> + <scope>test</scope> + <version>1.7.6</version> + </dependency> </dependencies> <build> <plugins> http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/server/container/util-java8/src/main/java/org/apache/james/util/Host.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/Host.java b/server/container/util-java8/src/main/java/org/apache/james/util/Host.java new file mode 100644 index 0000000..f6b52e8 --- /dev/null +++ b/server/container/util-java8/src/main/java/org/apache/james/util/Host.java @@ -0,0 +1,127 @@ +/**************************************************************** + * 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 org.apache.james.util; + +import java.util.List; +import java.util.Optional; + +import com.github.steveash.guavate.Guavate; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; + +public class Host { + + public static ImmutableList<Host> parseHosts(String hostsString) { + return Splitter.on(',') + .omitEmptyStrings() + .splitToList(hostsString) + .stream() + .map(Host::parseConfString) + .distinct() + .collect(Guavate.toImmutableList()); + } + + public static Host from(String hostname, int port) { + return new Host(hostname, port); + } + + public static Host parseConfString(String ipAndPort, int defaultPort) { + return parse(ipAndPort, Optional.of(defaultPort)); + } + + public static Host parseConfString(String ipAndPort) { + return parse(ipAndPort, Optional.empty()); + } + + private static Host parse(String ipAndPort, Optional<Integer> defaultPort) { + Preconditions.checkNotNull(ipAndPort); + Preconditions.checkArgument(!ipAndPort.isEmpty()); + + List<String> parts = retrieveHostParts(ipAndPort); + + String ip = parts.get(0); + int port = getPortFromConfPart(parts, defaultPort); + + return new Host(ip, port); + } + + private static List<String> retrieveHostParts(String ipAndPort) { + List<String> parts = Splitter.on(':') + .trimResults() + .splitToList(ipAndPort); + + if (parts.size() < 1 || parts.size() > 2) { + throw new IllegalArgumentException(ipAndPort + " is not a valid cassandra node"); + } + return parts; + } + + private static int getPortFromConfPart(List<String> parts, Optional<Integer> defaultPort) { + if (parts.size() == 2) { + return Integer.valueOf(parts.get(1)); + } if (parts.size() == 1) { + return defaultPort.orElseThrow(() -> new IllegalArgumentException("Host do not have port part but no default port provided")); + } + throw new RuntimeException("A host should be either a hostname or a hostname and a port separated by a ':'"); + } + + private final String hostName; + private final int port; + + @VisibleForTesting + Host(String hostName, int port) { + Preconditions.checkNotNull(hostName, "Hostname could not be null"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(hostName), "Hostname could not be empty"); + Preconditions.checkArgument(port > 0 && port <= 65535, "Port should be between 0 and 65535"); + this.hostName = hostName; + this.port = port; + } + + public String getHostName() { + return hostName; + } + + public int getPort() { + return port; + } + + @Override + public final int hashCode() { + return Objects.hashCode(hostName, port); + } + + @Override + public final boolean equals(Object object) { + if (object instanceof Host) { + Host that = (Host) object; + return Objects.equal(this.hostName, that.hostName) && Objects.equal(this.port, that.port); + } + return false; + } + + @Override + public String toString() { + return this.hostName + ":" + this.port; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/5b89121b/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java ---------------------------------------------------------------------- diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java new file mode 100644 index 0000000..aa4caad --- /dev/null +++ b/server/container/util-java8/src/test/java/org/apache/james/util/HostTest.java @@ -0,0 +1,202 @@ +/**************************************************************** + * 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 org.apache.james.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import nl.jqno.equalsverifier.EqualsVerifier; + +public class HostTest { + + private static final int DEFAULT_PORT = 154; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void parseConfStringShouldParseConfWithIpAndPort() { + //Given + int expectedPort = 44; + String expectedIp = "142.145.254.111"; + String ipAndPort = expectedIp + ":" + 44; + + //When + Host actual = Host.parseConfString(ipAndPort); + + //Then + assertThat(actual).isEqualTo(new Host(expectedIp, expectedPort)); + } + + @Test + public void parseConfStringShouldParseConfWithHostanmeAndPort() { + int expectedPort = 44; + String host = "host"; + + Host actual = Host.parseConfString(host + ":" + expectedPort); + + assertThat(actual).isEqualTo(new Host(host, expectedPort)); + } + + @Test + public void parseConfStringShouldParseConfWithHostOnlyWhenDefaultPortIsProvided() { + //Given + String ipAndPort = "142.145.254.111"; + String expectedIp = "142.145.254.111"; + + //When + Host actual = Host.parseConfString(ipAndPort, DEFAULT_PORT); + + //Then + assertThat(actual).isEqualTo(new Host(expectedIp, DEFAULT_PORT)); + } + + @Test + public void parseConfStringShouldFailWhenConfigIsAnEmptyString() { + expectedException.expect(IllegalArgumentException.class); + + //Given + String ipAndPort = ""; + + //When + Host.parseConfString(ipAndPort); + } + + @Test + public void parseConfStringShouldFailWhenOnlyHostnameAndNoDefaultPort() { + expectedException.expect(IllegalArgumentException.class); + + //Given + String hostname = "hostnameOnly"; + + //When + Host.parseConfString(hostname); + } + + @Test + public void parseConfStringShouldFailWhenNegativePort() { + expectedException.expect(IllegalArgumentException.class); + + Host.parseConfString("host:-1"); + } + + @Test + public void parseConfStringShouldFailWhenZeroPort() { + expectedException.expect(IllegalArgumentException.class); + + Host.parseConfString("host:0"); + } + + @Test + public void parseConfStringShouldFailWhenTooHighPort() { + expectedException.expect(IllegalArgumentException.class); + + Host.parseConfString("host:65536"); + } + + @Test + public void parseConfStringShouldFailWhenConfigIsANullString() { + expectedException.expect(NullPointerException.class); + + //Given + String ipAndPort = null; + + //When + Host.parseConfString(ipAndPort); + } + + + @Test + public void parseConfStringShouldFailWhenConfigIsInvalid() { + expectedException.expect(IllegalArgumentException.class); + + //Given + String ipAndPort = "10.10.10.10:42:43"; + + //When + Host.parseConfString(ipAndPort); + } + + @Test + public void parseHostsShouldParseEmptyString() { + assertThat(Host.parseHosts("")) + .isEmpty(); + } + + @Test + public void parseHostsShouldParseMonoHost() { + assertThat(Host.parseHosts("localhost:9200")) + .containsOnly(new Host("localhost", 9200)); + } + + @Test + public void parseHostsShouldParseMultiHosts() { + assertThat(Host.parseHosts("localhost:9200,server:9155")) + .containsOnly( + new Host("localhost", 9200), + new Host("server", 9155)); + } + + @Test + public void parseHostsShouldNotFailOnMultiComma() { + assertThat(Host.parseHosts("localhost:9200,,server:9155")) + .containsOnly( + new Host("localhost", 9200), + new Host("server", 9155)); + } + + @Test + public void parseHostsShouldFailOnInvalidHost() { + expectedException.expect(NumberFormatException.class); + + Host.parseHosts("localhost:invalid,,server:9155"); + } + + @Test + public void parseHostsShouldSwallowDuplicates() { + assertThat(Host.parseHosts("localhost:9200,localhost:9200")) + .containsOnly( + new Host("localhost", 9200)); + } + + @Test + public void parseHostsShouldNotSwallowSameAddressDifferentPort() { + assertThat(Host.parseHosts("localhost:9200,localhost:9155")) + .containsOnly( + new Host("localhost", 9200), + new Host("localhost", 9155)); + } + + @Test + public void parseHostsShouldNotSwallowSamePortDifferentAddress() { + assertThat(Host.parseHosts("localhost:9200,abcd:9200")) + .containsOnly( + new Host("localhost", 9200), + new Host("abcd", 9200)); + } + + @Test + public void hostShouldRespectBeanContract() { + EqualsVerifier.forClass(Host.class).verify(); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
