// ServerAddress.java
/**
* Copyright (C) 2008 10gen 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.mongodb;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
/**
* mongo server address
*/
public class ServerAddress {
/**
* Creates a ServerAddress with default host and port
* @throws UnknownHostException
*/
public ServerAddress()
throws UnknownHostException {
this( defaultHost() , defaultPort() );
}
/**
* Creates a ServerAddress with default port
* @param host hostname
* @throws UnknownHostException
*/
public ServerAddress( String host )
throws UnknownHostException {
this( host , defaultPort() );
}
/**
* Creates a ServerAddress
* @param host hostname
* @param port mongod port
* @throws UnknownHostException
*/
public ServerAddress( String host , int port )
throws UnknownHostException {
if ( host == null )
host = defaultHost();
host = host.trim();
if ( host.length() == 0 )
host = defaultHost();
int idx = host.indexOf( ":" );
if ( idx > 0 ){
if ( port != defaultPort() )
throw new IllegalArgumentException( "can't specify port in construct and via host" );
port = Integer.parseInt( host.substring( idx + 1 ) );
host = host.substring( 0 , idx ).trim();
}
_host = host;
_port = port;
_all = _getAddress( _host );
_addr = new InetSocketAddress( _all[0] , _port );
}
/**
* Creates a ServerAddress with default port
* @param addr host address
*/
public ServerAddress( InetAddress addr ){
this( new InetSocketAddress( addr , defaultPort() ) );
}
/**
* Creates a ServerAddress
* @param addr host address
* @param port mongod port
*/
public ServerAddress( InetAddress addr , int port ){
this( new InetSocketAddress( addr , port ) );
}
/**
* Creates a ServerAddress
* @param addr inet socket address containing hostname and port
*/
public ServerAddress( InetSocketAddress addr ){
_addr = addr;
_host = _addr.getHostName();
_port = _addr.getPort();
_all = null;
}
// --------
// pairing
// --------
/**
* Determines if the database at this address is paired.
* @return if this address connects to a set of paired databases
*/
boolean isPaired(){
return _all != null && _all.length > 1;
}
/**
* If this is the address of a paired database, returns addresses for
* all of the databases with which it is paired.
* @return the addresses
* @throws RuntimeException if this address is not one of a paired database
*/
List<ServerAddress> explode(){
if ( _all == null || _all.length <= 1 )
throw new RuntimeException( "not replica set mode. num addresses : " + ((_all == null) ? 0 : _all.length) );
List<ServerAddress> s = new ArrayList<ServerAddress>();
for ( int i=0; i<_all.length; i++ ){
s.add( new ServerAddress( _all[i] , _port ) );
}
return s;
}
// --------
// equality, etc...
// --------
/**
* Determines whether this address is the same as a given host.
* @param host the address to compare
* @return if they are the same
*/
public boolean sameHost( String host ){
int idx = host.indexOf( ":" );
int port = defaultPort();
if ( idx > 0 ){
port = Integer.parseInt( host.substring( idx + 1 ) );
host = host.substring( 0 , idx );
}
return
_port == port &&
_host.equalsIgnoreCase( host );
}
@Override
public boolean equals( Object other ){
if ( other instanceof ServerAddress ){
ServerAddress a = (ServerAddress)other;
return
a._port == _port &&
a._host.equals( _host );
}
if ( other instanceof InetSocketAddress ){
return _addr.equals( other );
}
return false;
}
@Override
public int hashCode(){
return _host.hashCode() + _port;
}
/**
* Gets the hostname
* @return
*/
public String getHost(){
return _host;
}
/**
* Gets the port number
* @return
*/
public int getPort(){
return _port;
}
/**
* Gets the underlying socket address
* @return
*/
public InetSocketAddress getSocketAddress(){
return _addr;
}
@Override
public String toString(){
return _host + ":" + _port;
}
final String _host;
final int _port;
InetSocketAddress _addr;
InetAddress[] _all;
// --------
// static helpers
// --------
private static InetAddress[] _getAddress( String host )
throws UnknownHostException {
if ( host.toLowerCase().equals("localhost") ){
return new InetAddress[] { InetAddress.getLocalHost()};
}
return InetAddress.getAllByName( host );
}
/**
* Returns the default database host: db_ip environment variable, or "127.0.0.1"
* @return
*/
public static String defaultHost(){
return "127.0.0.1";
}
/** Returns the default database port: db_port environment variable, or 27017 as a default
* @return
*/
public static int defaultPort(){
return DBPort.PORT;
}
/**
* attempts to update the internal InetAddress by resolving the host name.
* @return true if host resolved to a new IP that is different from old one, false otherwise
* @throws UnknownHostException
*/
boolean updateInetAddr() throws UnknownHostException {
InetSocketAddress oldaddr = _addr;
_all = _getAddress( _host );
_addr = new InetSocketAddress( _all[0] , _port );
if (!_addr.equals(oldaddr))
return true;
return false;
}
}