ws.wamp.jawampa.WampClientBuilder.java Source code

Java tutorial

Introduction

Here is the source code for ws.wamp.jawampa.WampClientBuilder.java

Source

/*
 * Copyright 2014 Matthias Einwag
 *
 * The jawampa authors license 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 ws.wamp.jawampa;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.net.URI;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;

import ws.wamp.jawampa.auth.client.ClientSideAuthentication;
import ws.wamp.jawampa.client.ClientConfiguration;
import ws.wamp.jawampa.connection.IWampClientConnectionConfig;
import ws.wamp.jawampa.connection.IWampConnector;
import ws.wamp.jawampa.connection.IWampConnectorProvider;
import ws.wamp.jawampa.internal.UriValidator;

/**
 * WampClientBuilder is the builder object which allows to create
 * {@link WampClient} objects.<br>
 * New clients have to be configured with the member methods before
 * a client can be created with the {@link #build build()} method.
 */
public class WampClientBuilder {

    private String uri;
    private String realm;

    private int nrReconnects = 0;
    private int reconnectInterval = DEFAULT_RECONNECT_INTERVAL;
    private boolean useStrictUriValidation = false;
    private boolean closeOnErrors = true;
    private EnumSet<WampRoles> roles;
    private List<WampSerialization> serializations = new ArrayList<WampSerialization>();
    private String authId = null;
    private List<ClientSideAuthentication> authMethods = new ArrayList<ClientSideAuthentication>();

    private IWampClientConnectionConfig connectionConfiguration = null;
    private IWampConnectorProvider connectorProvider = null;

    private ObjectMapper objectMapper = null;

    /** The default reconnect interval in milliseconds.<br>This is set to 5s */
    public static final int DEFAULT_RECONNECT_INTERVAL = 5000;
    /** The minimum reconnect interval in milliseconds.<br>This is set to 100ms */
    public static final int MIN_RECONNECT_INTERVAL = 100;

    /**
     * Construct a new WampClientBuilder object.
     */
    public WampClientBuilder() {
        // Add the default roles
        roles = EnumSet.of(WampRoles.Caller, WampRoles.Callee, WampRoles.Publisher, WampRoles.Subscriber);

        WampSerialization.addDefaultSerializations(serializations);
    }

    /**
     * Builds a new {@link WampClient WAMP client} from the information given in this builder.<br>
     * At least the uri of the router and the name of the realm have to be
     * set for a proper operation.
     * @return The created WAMP client
     * @throws WampError if any parameter is not invalid
     */
    public WampClient build() throws Exception {
        if (uri == null)
            throw new ApplicationError(ApplicationError.INVALID_URI);

        URI routerUri;
        try {
            routerUri = new URI(uri);
        } catch (Throwable t) {
            throw new ApplicationError(ApplicationError.INVALID_URI);
        }

        if (realm == null)
            throw new ApplicationError(ApplicationError.INVALID_REALM);

        try {
            UriValidator.validate(realm, useStrictUriValidation);
        } catch (Exception e) {
            throw new ApplicationError(ApplicationError.INVALID_REALM);
        }

        if (roles.size() == 0) {
            throw new ApplicationError(ApplicationError.INVALID_ROLES);
        }

        // Build the roles array from the roles set
        WampRoles[] rolesArray = new WampRoles[roles.size()];
        int i = 0;
        for (WampRoles r : roles) {
            rolesArray[i] = r;
            i++;
        }

        if (serializations.size() == 0) {
            throw new ApplicationError(ApplicationError.INVALID_SERIALIZATIONS);
        }

        if (connectorProvider == null)
            throw new ApplicationError(ApplicationError.INVALID_CONNECTOR_PROVIDER);

        // Build a connector that can be used by the client afterwards
        // This can throw!
        IWampConnector connector = connectorProvider.createConnector(routerUri, connectionConfiguration,
                serializations);

        // Use default object mapper
        if (objectMapper == null)
            objectMapper = new ObjectMapper();

        ClientConfiguration clientConfig = new ClientConfiguration(closeOnErrors, authId, authMethods, routerUri,
                realm, useStrictUriValidation, rolesArray, nrReconnects, reconnectInterval, connectorProvider,
                connector, objectMapper);

        return new WampClient(clientConfig);
    }

    /**
     * Sets the address of the router to which the new client shall connect.
     * @param uri The address of the router, e.g. ws://wamp.ws/ws
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withUri(String uri) {
        this.uri = uri;
        return this;
    }

    /**
     * Sets the name of the realm on the router which shall be used for the session.
     * @param realm The name of the realm to which shall be connected.
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withRealm(String realm) {
        this.realm = realm;
        return this;
    }

    /**
     * Adjusts the roles that this client should have in the session.<br>
     * By default a client will have all roles (caller, callee, publisher, subscriber).
     * Use this function to adjust the roles if not all are needed.
     * @param roles The set of roles that the client should fulfill in the session.
     * At least one role is required, otherwise the session can not be established.
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withRoles(WampRoles[] roles) {
        this.roles.clear();
        if (roles == null)
            return this; // Will throw on build()
        for (WampRoles role : roles) {
            this.roles.add(role);
        }
        return this;
    }

    /**
     * Assigns a connector provider to the WampClient. This provider will be used to
     * establish connections to the server.<br>
     * By using a different ConnectorProvider a different transport framework can be used
     * for data exchange between client and server.
     * @param provider The {@link IWampConnectorProvider} that should be used
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withConnectorProvider(IWampConnectorProvider provider) {
        this.connectorProvider = provider;
        return this;
    }

    /**
     * Assigns additional configuration data for a connection that should be used.<br>
     * The type of this configuration data depends on the used {@link IWampConnectorProvider}.<br>
     * Depending on the provider this might be null or not.
     * @param configuration The {@link IWampClientConnectionConfig} that should be used
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withConnectionConfiguration(IWampClientConnectionConfig configuration) {
        this.connectionConfiguration = configuration;
        return this;
    }

    /**
     * Adjusts the serializations that this client supports in the session.<br>
     * By default a client will have all serializations (JSON, MessagePack).<br>
     * The order of the list indicates client preference to the router during
     * negotiation.<br>
     * Use this function to adjust the serializations if not all are needed or
     * a different order is desired.
     * @param serializations The set of serializations that the client supports.
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withSerializations(WampSerialization[] serializations) throws ApplicationError {
        this.serializations.clear();
        if (serializations == null)
            return this; // Will throw on build()
        for (WampSerialization serialization : serializations) {
            if (serialization == WampSerialization.Invalid)
                throw new ApplicationError(ApplicationError.INVALID_SERIALIZATIONS);
            if (!this.serializations.contains(serialization))
                this.serializations.add(serialization);
        }
        return this;
    }

    /**
     * Allows to activate or deactivate the validation of all WAMP Uris according to the
     * strict URI validation rules which are described in the WAMP specification.
     * By default the loose Uri validation rules will be used.
     * @param useStrictUriValidation true if strict Uri validation rules shall be applied,
     * false if loose Uris shall be used.
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withStrictUriValidation(boolean useStrictUriValidation) {
        this.useStrictUriValidation = useStrictUriValidation;
        return this;
    }

    /**
     * Sets whether the client should be closed when an error besides
     * a connection loss happens.<br>
     * Other reasons are the reception of invalid messages from the remote
     * or the abortion of the session by the remote.<br>
     * When this flag is set to true no reconnect attempts will be performed.
     * <br>
     * The default is true. This is to avoid endless reconnects in case of
     * a malfunctioning remote. 
     * @param closeOnErrors True if the client should be closed on such
     * errors, false if not.
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withCloseOnErrors(boolean closeOnErrors) {
        this.closeOnErrors = closeOnErrors;
        return this;
    }

    /**
     * Sets the amount of reconnect attempts to perform to a dealer.
     * @param nrReconnects The amount of connects to perform. Must be > 0.
     * @return The {@link WampClientBuilder} object
     * @throws WampError if the nr of reconnects is negative
     */
    public WampClientBuilder withNrReconnects(int nrReconnects) throws ApplicationError {
        if (nrReconnects < 0)
            throw new ApplicationError(ApplicationError.INVALID_PARAMETER);
        this.nrReconnects = nrReconnects;
        return this;
    }

    /**
     * Sets the amount of reconnect attempts to perform to a dealer
     * to infinite.
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withInfiniteReconnects() {
        this.nrReconnects = -1;
        return this;
    }

    /**
     * Sets the amount of time that should be waited until a reconnect attempt is performed.<br>
     * The default value is {@link #DEFAULT_RECONNECT_INTERVAL}.
     * @param interval The interval that should be waited until a reconnect attempt<br>
     * is performed. The interval must be bigger than {@link #MIN_RECONNECT_INTERVAL}.
     * @param unit The unit of the interval
     * @return The {@link WampClientBuilder} object
     * @throws WampError If the interval is invalid
     */
    public WampClientBuilder withReconnectInterval(int interval, TimeUnit unit) throws ApplicationError {
        long intervalMs = unit.toMillis(interval);
        if (intervalMs < MIN_RECONNECT_INTERVAL || intervalMs > Integer.MAX_VALUE)
            throw new ApplicationError(ApplicationError.INVALID_RECONNECT_INTERVAL);
        this.reconnectInterval = (int) intervalMs;
        return this;
    }

    /**
     * Set the authId to use. If not called, no authId is used.
     * @param authId the authId
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withAuthId(String authId) {
        this.authId = authId;
        return this;
    }

    /**
     * Use a specific auth method. Can be called multiple times to specify multiple
     * supported auth methods. If this method is not called, anonymous auth is used.
     * @param authMethod The {@link ClientSideAuthentication} to add
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withAuthMethod(ClientSideAuthentication authMethod) {
        this.authMethods.add(authMethod);
        return this;
    }

    /**
     * Set custom, pre-configured {@link ObjectMapper}.
     * This instance will be used instead of default for serialization and deserialization.
     * @param objectMapper The {@link ObjectMapper} instance
     * @return The {@link WampClientBuilder} object
     */
    public WampClientBuilder withObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        return this;
    }

}