All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dell.doradus.client.RESTConnector Maven / Gradle / Ivy

/*
 * Copyright (C) 2014 Dell, Inc.
 * 
 * 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 com.dell.doradus.client;

import java.util.HashMap;
import java.util.Map;

import com.dell.doradus.common.ContentType;

/**
 * RESTConnector is a class that provides multiple connections to Doradus nodes.
 * It can generate RESTClient objects to different hosts. The class implements
 * a simple round robin strategy for selecting next host for connection.
 * It also provides a snap of connection state (when was connected last time).
 * Usage:
 * 

*

    *
  1. RESTConnector connector = new RESTConnector(port, host1, host2,...);
  2. *
  3. RESTClient client1 = connector.getClient();
  4. *
  5. RESTClient client2 = connector.getClient();
  6. *
  7. Client dClient1 = new Client(client1);
  8. *
  9. Client dClient2 = new Client(client2);
  10. *
  11. ...
  12. *
*/ public class RESTConnector { private ContentType m_defaultContentType = ContentType.APPLICATION_JSON; private boolean m_defaultCompression = false; private Credentials m_credentials; /** * Status of the connection (at the time it was created or refused to connect) */ public static class HostStatus { private boolean m_alive; // Connection was set successfully? private Exception m_failReason; // Reason for connection fail private HostStatus() { this(true, null); } private HostStatus(boolean alive, Exception e) { m_alive = alive; m_failReason = e; } /** * Was the connection with the given host name set successfully? * * @return True if the host for this connection was alive. */ public boolean isAlive() { return m_alive; } /** * What was the reason for the connection fail (null if it was successful). * * @return Returns the reason for the last connect failure or null if it was successful. */ public Exception getReason() { return m_failReason; } } /** * Sets default content/accept type that would be set to REST clients by default. * * @param contentType Content/accept type */ public void setAcceptType(ContentType contentType) { m_defaultContentType = contentType; } /** * Sets default request compression parameter that would be set to REST clients by default. * * @param compression Default compression parameter */ public void setCompression(boolean compression) { m_defaultCompression = compression; } /** * Set the client authentication credentials used for all {@link RESTClient}s created * by this RESTConnector. If the given credentials are null, RESTClients will not use * authentication. * * @param credentials {@link Credentials} to use for RESTClients created by this * connector. Can be null to request unauthenticated connections. */ public void setCredentials(Credentials credentials) { m_credentials = credentials; } /** * An element of the hosts ring */ private static class Cell { String m_hostName; // host HostStatus m_hostStatus; // status of last connection to the host Cell next; // next cell in the ring } private Cell m_cellRing; // ring of cells private final int m_port; // connection port /** * Registers the port and the host names, creates a cells ring, each cell in its * "undefined" state. No exception thrown. * * @param port Connection port * @param hosts Array of connection host names */ public RESTConnector(int port, String... hosts) { m_port = port; for (String host : hosts) { addToRing(host); } } /** * Tries to connect to the "next" host. If no host is available, * IllegalStateException will be raised. * * @return Client for the connection established */ public RESTClient getClient() { return getClient(null); } /** * Tries to connect to the "next" host. If no host is available, * IllegalStateException will be raised. * * @param sslParams parameters needed to establish SSL connection * @return Client for the connection established */ public RESTClient getClient(SSLTransportParameters sslParams) { if (m_cellRing == null) { throw new IllegalStateException("Empty pool"); } Cell currentCell = m_cellRing; StringBuilder errorMessage = new StringBuilder(); do { try { RESTClient client = new RESTClient(sslParams, m_cellRing.m_hostName, m_port); client.setCredentials(m_credentials); m_cellRing.m_hostStatus = new HostStatus(); client.setAcceptType(m_defaultContentType); client.setCompression(m_defaultCompression); return client; } catch (RuntimeException e) { m_cellRing.m_hostStatus = new HostStatus(false, e); errorMessage.append("Couldn\'t connect to " + m_cellRing.m_hostName) .append("; reason: " + e.getMessage() + "\n"); } finally { m_cellRing = m_cellRing.next; } } while (currentCell != m_cellRing); throw new IllegalStateException("No active connections found\n" + errorMessage); } /** * Generates a map of the last state of the attempts of the connections. * Useful in a situation when a getClient method ended in exception, then this * method can show the reasons of refusals. * * @return Map of current connection states. */ public Map getState() { Map map = new HashMap<>(); if (m_cellRing != null) { Cell currentCell = m_cellRing; do { map.put(currentCell.m_hostName, currentCell.m_hostStatus); currentCell = currentCell.next; } while (currentCell != m_cellRing); } return map; } /** * Adds a new host to a cells ring. * @param host Host name to add */ private void addToRing(String host) { Cell newCell = new Cell(); newCell.m_hostName = host; if (m_cellRing == null) { newCell.next = newCell; } else { newCell.next = m_cellRing.next; m_cellRing.next = newCell; } m_cellRing = newCell; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy