* @throws IllegalStateException
* if no VNS_HOST has been specified.
*/
public void open(String service_name) throws ServiceDownException, VNSException {
this.serviceName = service_name;
ResolveResult response = null;
Transportable query = null;
boolean connectFailed = false;
VinciContext myContext = getContext();
boolean usedCache = false;
ArrayList alreadyTried = null;
String vnsHost = myContext.getVNSHost();
int vnsPort = myContext.getVNSPort();
// Check to see if default host/port are being overridden by vns "@" specification in service
// name
int atIndex = service_name.indexOf('@');
if (atIndex != -1) {
vnsHost = service_name.substring(atIndex + 1);
int colonIndex = vnsHost.indexOf(':');
if (colonIndex != -1) {
try {
vnsPort = Integer.parseInt(vnsHost.substring(colonIndex + 1));
} catch (NumberFormatException e) {
throw new VNSException("Bad vns port specification in service name: " + service_name);
}
vnsHost = vnsHost.substring(0, colonIndex);
}
}
// ^^ A list of service locations that have already been determined to be
// unavailable.
for (;;) {
try {
response = myContext.getCachedResolveResult(serviceName);
if (response == null) {
usedCache = false;
if (query == null) {
query = ResolveResult.composeQuery(serviceName);
}
response = (ResolveResult) BaseClient.sendAndReceive(query, vnsHost, vnsPort,
ResolveResult.factory, myContext.getVNSResolveTimeout());
myContext.cacheResolveResult(serviceName, response);
} else {
usedCache = true;
Debug.p("Using cached VNS entry.");
}
} catch (IOException e) {
// VNS is inaccessible. See if there is a (stale) cached entry we can use.
if (myContext.areStaleLookupsAllowed()) {
response = myContext.getStaleCachedResolveResult(serviceName);
if (response == null) {
throw new ServiceDownException("VNS inaccessible: " + e);
} else {
Debug.reportException(e);
Debug.p("VNS is not accessible, using STALE cached resolve result.");
}
}
} catch (ServiceException e) {
if (connectFailed) {
throw new ServiceDownException("Could not connect to service: " + serviceName);
}
throw new VNSException(e.getMessage());
}
// Iterate over all available service locations until we find one that
// accepts our connection request.
response.initializeIterator();
while (response.hasMore()) {
ResolveResult.ServiceLocator locator = response.getNext();
if (alreadyTried == null || !alreadyTried.contains(locator.host + ":" + locator.port)) {
try {
open(locator.host, locator.port);
this.instance = locator.instance;
this.level = response.priority;