Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2015-2017 UnboundID Corp.
* All Rights Reserved.
*/
/*
* Copyright (C) 2015-2017 UnboundID Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.util.json;
import java.util.ArrayList;
import java.util.List;
import javax.net.SocketFactory;
import com.unboundid.ldap.sdk.FailoverServerSet;
import com.unboundid.ldap.sdk.FastestConnectServerSet;
import com.unboundid.ldap.sdk.FewestConnectionsServerSet;
import com.unboundid.ldap.sdk.LDAPConnectionOptions;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.RoundRobinServerSet;
import com.unboundid.ldap.sdk.ServerSet;
import com.unboundid.ldap.sdk.SingleServerSet;
import com.unboundid.util.NotMutable;
import com.unboundid.util.ObjectPair;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import static com.unboundid.util.json.JSONMessages.*;
/**
* This class provides a data structure and set of logic for interacting with
* the set of server details in a JSON object provided to the
* {@link LDAPConnectionDetailsJSONSpecification}.
*/
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
final class ServerDetails
{
/**
* The name of the field that provides the address of a directory server
* instance. Its value must be a string.
*/
private static final String FIELD_ADDRESS = "address";
/**
* The name of the field that may be used to provide the failover order for
* use in conjunction with a failover server set. Its value must be an array
* of JSON objects, where each of those objects must have one field, which
* should be one of the following types: failover-set, fastest-connect-set,
* fewest-connections-set, round-robin-set, or single-server.
*/
private static final String FIELD_FAILOVER_ORDER = "failover-order";
/**
* The name of the field that may be used to provide information about a set
* of servers that should be accessed in a manner that selects servers in a
* consistent failover manner. Its value must be a JSON object that must
* contain the failover-order field and may optionally contain the
* maximum-failover-connection-age-millis and re-order-on-failover fields.
*/
private static final String FIELD_FAILOVER_SET = "failover-set";
/**
* The name of the field that may be used to provide information about a set
* of servers that should be accessed in a manner that selects the server that
* accepts a connection first. Its value must be a JSON object that must
* contain only the servers field.
*/
private static final String FIELD_FASTEST_CONNECT_SET = "fastest-connect-set";
/**
* The name of the field that may be used to provide information about a set
* of servers that should be accessed in a manner that selects the server with
* the fewest active connections. Its value must be a JSON object that must
* contain only the servers field.
*/
private static final String FIELD_FEWEST_CONNECTIONS_SET =
"fewest-connections-set";
/**
* The name of the field that may be used to specify the maximum connection
* age (in milliseconds) that should be used for connections created by a
* failover server set when the connection cannot be established to the
* first-choice server. If present, its value must be an integer value that
* is greater than or equal to zero (with a value of zero indicating that no
* maximum age should be enforced for such connections. If it is not present,
* then these connections will be given the associated connection pool's
* maximum connection age.
*/
private static final String FIELD_MAX_FAILOVER_CONN_AGE_MILLIS =
"maximum-failover-connection-age-millis";
/**
* The name of the field that provides the port of a directory server
* instance. Its value must be an integer between 1 and 65535.
*/
private static final String FIELD_PORT = "port";
/**
* The name of the field that may be used to provide information about a set
* of servers that should be accessed in a round-robin fashion. Its value
* must be a JSON object that must contain only the servers field.
*/
private static final String FIELD_ROUND_ROBIN_SET = "round-robin-set";
/**
* The name of the field that may be used to provide information about a
* set of servers to include in a set. Its value must be an array of one or
* more JSON objects, in which each object must contain only the address and
* port fields.
*/
private static final String FIELD_SERVERS = "servers";
/**
* The name of the field that may be used to provide information about a
* single directory server instance. Its value must be a JSON object that
* must contain only the address and port fields.
*/
private static final String FIELD_SINGLE_SERVER = "single-server";
// The server set created from the server details specification.
private final ServerSet serverSet;
/**
* Creates a new set of connection options from the information contained in
* the provided JSON object.
*
* @param connectionDetailsObject The JSON object containing the LDAP
* connection details specification.
* @param securityOptions The parsed security options portion of the
* specification.
* @param connectionOptions The parsed connection options portion of
* the specification.
*
* @throws LDAPException If there is a problem with the server details data
* in the provided JSON object.
*/
ServerDetails(final JSONObject connectionDetailsObject,
final SecurityOptions securityOptions,
final ConnectionOptions connectionOptions)
throws LDAPException
{
final JSONObject o = LDAPConnectionDetailsJSONSpecification.getObject(
connectionDetailsObject,
LDAPConnectionDetailsJSONSpecification.FIELD_SERVER_DETAILS);
serverSet = createServerSet(o,
LDAPConnectionDetailsJSONSpecification.FIELD_SERVER_DETAILS,
securityOptions, connectionOptions);
}
/**
* Creates a server set from the information contained in the provided JSON
* object.
*
* @param o The JSON object to parse as a server set.
* @param fieldName The name of the field whose value contains the
* provided JSON object.
* @param securityOptions The parsed security options portion of the
* specification.
* @param connectionOptions The parsed connection options portion of the
* specification.
*
* @return The server set created from the information in the provided JSON
* object.
*
* @throws LDAPException If the provided JSON object cannot be parsed to
* create a server set.
*/
private static ServerSet createServerSet(final JSONObject o,
final String fieldName,
final SecurityOptions securityOptions,
final ConnectionOptions connectionOptions)
throws LDAPException
{
LDAPConnectionDetailsJSONSpecification.validateAllowedFields(o, fieldName,
FIELD_FAILOVER_SET,
FIELD_FASTEST_CONNECT_SET,
FIELD_FEWEST_CONNECTIONS_SET,
FIELD_ROUND_ROBIN_SET,
FIELD_SINGLE_SERVER);
final SocketFactory socketFactory = securityOptions.getSocketFactory();
final LDAPConnectionOptions ldapConnectionOptions =
connectionOptions.createConnectionOptions(securityOptions);
if (o.getFields().size() != 1)
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_INVALID_FIELD_SET.get(fieldName));
}
// See if it's a failover set definition.
final JSONObject failoverSetObject =
LDAPConnectionDetailsJSONSpecification.getObject(o,
FIELD_FAILOVER_SET);
if (failoverSetObject != null)
{
LDAPConnectionDetailsJSONSpecification.validateAllowedFields(
failoverSetObject, FIELD_FAILOVER_SET,
FIELD_FAILOVER_ORDER,
FIELD_MAX_FAILOVER_CONN_AGE_MILLIS);
final Long maxFailoverConnectionAgeMillis =
LDAPConnectionDetailsJSONSpecification.getLong(failoverSetObject,
FIELD_MAX_FAILOVER_CONN_AGE_MILLIS, null, 0L, null);
final JSONValue orderValue =
failoverSetObject.getField(FIELD_FAILOVER_ORDER);
if (orderValue == null)
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_MISSING_FIELD.get(FIELD_FAILOVER_SET,
FIELD_FAILOVER_ORDER));
}
if (! (orderValue instanceof JSONArray))
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_FIELD_NOT_ARRAY.get(FIELD_FAILOVER_SET,
FIELD_FAILOVER_ORDER));
}
final JSONArray orderArray = (JSONArray) orderValue;
final List orderArrayValues = orderArray.getValues();
if (orderArrayValues.isEmpty())
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_EMPTY_ARRAY.get(FIELD_FAILOVER_SET,
FIELD_FAILOVER_ORDER));
}
final ArrayList failoverSets =
new ArrayList(orderArrayValues.size());
for (final JSONValue v : orderArrayValues)
{
if (! (v instanceof JSONObject))
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_SERVERS_VALUE_NOT_OBJECT.get(
FIELD_FAILOVER_ORDER, FIELD_FAILOVER_SET));
}
failoverSets.add(createServerSet((JSONObject) v, FIELD_FAILOVER_ORDER,
securityOptions, connectionOptions));
}
final FailoverServerSet failoverSet = new FailoverServerSet(failoverSets);
failoverSet.setMaxFailoverConnectionAgeMillis(
maxFailoverConnectionAgeMillis);
return failoverSet;
}
// See if it's a fastest connect set definition.
final JSONObject fastestConnectSetObject =
LDAPConnectionDetailsJSONSpecification.getObject(o,
FIELD_FASTEST_CONNECT_SET);
if (fastestConnectSetObject != null)
{
final ObjectPair servers =
parseServers(fastestConnectSetObject, FIELD_SERVERS);
return new FastestConnectServerSet(servers.getFirst(),
servers.getSecond(), socketFactory, ldapConnectionOptions);
}
// See if it's a fewest connections set definition.
final JSONObject fewestConnectionsSetObject =
LDAPConnectionDetailsJSONSpecification.getObject(o,
FIELD_FEWEST_CONNECTIONS_SET);
if (fewestConnectionsSetObject != null)
{
final ObjectPair servers =
parseServers(fewestConnectionsSetObject, FIELD_SERVERS);
return new FewestConnectionsServerSet(servers.getFirst(),
servers.getSecond(), socketFactory, ldapConnectionOptions);
}
// See if it's a round-robin set definition.
final JSONObject roundRobinSetObject =
LDAPConnectionDetailsJSONSpecification.getObject(o,
FIELD_ROUND_ROBIN_SET);
if (roundRobinSetObject != null)
{
final ObjectPair servers =
parseServers(roundRobinSetObject, FIELD_SERVERS);
return new RoundRobinServerSet(servers.getFirst(),
servers.getSecond(), socketFactory, ldapConnectionOptions);
}
// It must be a single server definition.
final JSONObject singleServerObject =
LDAPConnectionDetailsJSONSpecification.getObject(o,
FIELD_SINGLE_SERVER);
final ObjectPair addressAndPort = parseServer(
singleServerObject, FIELD_SINGLE_SERVER);
return new SingleServerSet(addressAndPort.getFirst(),
addressAndPort.getSecond(), socketFactory, ldapConnectionOptions);
}
/**
* Parses information about a set of servers from the information contained
* in the provided JSON object.
*
* @param o The JSON object to parse.
* @param f The name of the field in which the provided object is a value.
*
* @return An object pair containing the addresses and ports of the servers.
*
* @throws LDAPException If the provided JSON object cannot be parsed to
* obtain information about a set of servers.
*/
private static ObjectPair parseServers(final JSONObject o,
final String f)
throws LDAPException
{
LDAPConnectionDetailsJSONSpecification.validateAllowedFields(o, f,
FIELD_SERVERS);
final JSONValue serversValue = o.getField(FIELD_SERVERS);
if (serversValue == null)
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_MISSING_FIELD.get(f, FIELD_SERVERS));
}
if (! (serversValue instanceof JSONArray))
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_FIELD_NOT_ARRAY.get(f, FIELD_SERVERS));
}
final List serverArrayValues =
((JSONArray) serversValue).getValues();
if (serverArrayValues.isEmpty())
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_EMPTY_ARRAY.get(f, FIELD_SERVERS));
}
int i=0;
final String[] addresses = new String[serverArrayValues.size()];
final int[] ports = new int[addresses.length];
for (final JSONValue v : serverArrayValues)
{
if (! (v instanceof JSONObject))
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_SERVERS_VALUE_NOT_OBJECT.get(FIELD_SERVERS, f));
}
final ObjectPair p = parseServer((JSONObject) v,
FIELD_SERVERS);
addresses[i] = p.getFirst();
ports[i] = p.getSecond();
i++;
}
return new ObjectPair(addresses, ports);
}
/**
* Parses information about a single server from the information contained in
* the provided JSON object.
*
* @param o The JSON object to parse.
* @param f The name of the field in which the provided object is a value.
*
* @return An object pair containing the address and port for the server.
*
* @throws LDAPException If the provided JSON object cannot be parsed to
* obtain information about a server.
*/
private static ObjectPair parseServer(final JSONObject o,
final String f)
throws LDAPException
{
LDAPConnectionDetailsJSONSpecification.validateAllowedFields(o, f,
FIELD_ADDRESS,
FIELD_PORT);
final String address = LDAPConnectionDetailsJSONSpecification.getString(o,
FIELD_ADDRESS, null);
if (address == null)
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_MISSING_FIELD.get(f, FIELD_ADDRESS));
}
final Integer port = LDAPConnectionDetailsJSONSpecification.getInt(o,
FIELD_PORT, null, 1, 65535);
if (port == null)
{
throw new LDAPException(ResultCode.PARAM_ERROR,
ERR_SERVER_DETAILS_MISSING_FIELD.get(f, FIELD_PORT));
}
return new ObjectPair(address, port);
}
/**
* Retrieves the server set.
*
* @return The server set.
*/
ServerSet getServerSet()
{
return serverSet;
}
}