Skip to content

Commit

Permalink
Add support for configuring AtomixClient and AtomixReplica with Prope…
Browse files Browse the repository at this point in the history
…rties.
  • Loading branch information
kuujo committed Feb 3, 2016
1 parent 79b4830 commit a1f1663
Show file tree
Hide file tree
Showing 15 changed files with 1,114 additions and 199 deletions.
6 changes: 6 additions & 0 deletions core/pom.xml
Expand Up @@ -48,6 +48,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.atomix.catalyst</groupId>
<artifactId>catalyst-netty</artifactId>
<version>${catalyst.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
10 changes: 10 additions & 0 deletions core/src/main/java/io/atomix/Atomix.java
Expand Up @@ -15,6 +15,7 @@
*/
package io.atomix;

import io.atomix.catalyst.serializer.Serializer;
import io.atomix.catalyst.util.Assert;
import io.atomix.catalyst.util.concurrent.ThreadContext;
import io.atomix.collections.DistributedMap;
Expand Down Expand Up @@ -57,6 +58,15 @@ protected Atomix(ResourceClient client) {
this.client = Assert.notNull(client, "client");
}

/**
* Returns the Atomix serializer.
*
* @return The Atomix serializer.
*/
public Serializer serializer() {
return client.client().serializer();
}

/**
* Gets or creates a distributed map.
*
Expand Down
52 changes: 50 additions & 2 deletions core/src/main/java/io/atomix/AtomixClient.java
Expand Up @@ -19,11 +19,13 @@
import io.atomix.catalyst.transport.Address;
import io.atomix.catalyst.transport.Transport;
import io.atomix.catalyst.util.Assert;
import io.atomix.catalyst.util.PropertiesReader;
import io.atomix.manager.ResourceClient;
import io.atomix.manager.ResourceServer;
import io.atomix.resource.ResourceTypeResolver;

import java.util.Collection;
import java.util.Properties;

/**
* Provides an interface for creating and operating on {@link io.atomix.resource.Resource}s remotely.
Expand Down Expand Up @@ -74,6 +76,28 @@
*/
public class AtomixClient extends Atomix {

/**
* Returns a new Atomix replica builder from the given configuration file.
*
* @param properties The properties file from which to load the replica builder.
* @return The replica builder.
*/
public static Builder builder(String properties) {
return builder(PropertiesReader.load(properties).properties());
}

/**
* Returns a new Atomix replica builder from the given properties.
*
* @param properties The properties from which to load the replica builder.
* @return The replica builder.
*/
public static Builder builder(Properties properties) {
ClientProperties clientProperties = new ClientProperties(properties);
return builder(clientProperties.replicas())
.withTransport(clientProperties.transport());
}

/**
* Returns a new Atomix client builder.
* <p>
Expand All @@ -100,15 +124,39 @@ public static Builder builder(Collection<Address> members) {
return new Builder(ResourceClient.builder(members));
}

/**
* Builds the underlying resource client from the given properties.
*/
private static ResourceClient buildClient(Properties properties) {
ClientProperties clientProperties = new ClientProperties(properties);
return ResourceClient.builder(clientProperties.replicas())
.withTransport(clientProperties.transport())
.build();
}

/**
* Constructs a client from the given properties.
*
* @param properties The properties from which to construct the client.
*/
public AtomixClient(Properties properties) {
this(buildClient(properties));
}

/**
* Constructs a client for the given resource client.
*
* @param client The resource client.
*/
public AtomixClient(ResourceClient client) {
super(client);
}

/**
* Builds an {@link AtomixClient}.
* <p>
* The client builder configures an {@link AtomixClient} to connect to a cluster of {@link ResourceServer}s
* or {@link ResourceReplica}. To create a client builder, use the {@link #builder(Address...)} method.
* The client builder configures an {@link AtomixClient} to connect to a cluster of {@link ResourceServer}s.
* To create a client builder, use the {@link #builder(Address...)} method.
* <pre>
* {@code
* Atomix client = AtomixClient.builder(servers)
Expand Down
89 changes: 89 additions & 0 deletions core/src/main/java/io/atomix/AtomixProperties.java
@@ -0,0 +1,89 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package io.atomix;

import io.atomix.catalyst.transport.Address;
import io.atomix.catalyst.transport.Transport;
import io.atomix.catalyst.util.ConfigurationException;
import io.atomix.catalyst.util.PropertiesReader;
import io.atomix.catalyst.util.QualifiedProperties;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Properties;

/**
* Base class for Atomix properties.
*
* @author <a href="http://github.com/kuujo>Jordan Halterman</a>
*/
public abstract class AtomixProperties {
public static final String TRANSPORT = "transport";
public static final String REPLICA = "replica";

private static final String DEFAULT_TRANSPORT = "io.atomix.catalyst.transport.NettyTransport";

protected final PropertiesReader reader;

protected AtomixProperties(Properties properties) {
this.reader = new PropertiesReader(properties);
}

/**
* Returns the replica transport.
*
* @return The replica transport.
*/
public Transport transport() {
String transportClass = reader.getString(TRANSPORT, DEFAULT_TRANSPORT);
try {
return (Transport) Class.forName(transportClass).getConstructor(Properties.class).newInstance(new QualifiedProperties(reader.properties(), TRANSPORT));
} catch (ClassNotFoundException e) {
throw new ConfigurationException("unknown transport class: " + transportClass, e);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new ConfigurationException("failed to instantiate transport", e);
}
}

/**
* Returns the collection of replicas.
*
* @return The collection of replicas.
*/
public Collection<Address> replicas() {
return reader.getCollection(REPLICA, p -> parseAddress(reader.getString(p)));
}

/**
* Parses an address string.
*
* @param address The address string.
* @return The address.
*/
protected Address parseAddress(String address) {
String[] split = address.split(":");
if (split.length != 2) {
throw new ConfigurationException("malformed address: " + address);
}

try {
return new Address(split[0], Integer.valueOf(split[1]));
} catch (NumberFormatException e) {
throw new ConfigurationException("invalid port number: " + split[1]);
}
}

}

0 comments on commit a1f1663

Please sign in to comment.