int doProvision(ProvisionRequest request,
ServiceResource serviceResource) {
long start = System.currentTimeMillis();
int result = 0;
InstantiatorResource ir = (InstantiatorResource) serviceResource.getResource();
try {
//ir.incrementProvisionCounter(request.getServiceElement());
try {
ServiceProvisionEvent event = new ServiceProvisionEvent(context.getEventSource(),
request.getOpStringManager(),
request.getServiceElement());
event.setSequenceNumber(context.getServiceProvisionEventSequenceNumber().incrementAndGet());
event.setHandback(ir.getHandback());
/*
* Put the instantiate invocation in a for loop, the
* Cybernode may return null if there is a race-condition
* where a service is terminated, the FDH notifies the
* ServiceElementManager of the failure, the
* ProvisionRequest is dispatched (we get to this point),
* and the Cybernode is in the process of doing
* housekeeping related to service termination. If we get
* a null returned, wait the specified time and retry
*/
int numProvisionRetries = 3;
for (int i = 0; i < numProvisionRetries; i++) {
if (logger.isDebugEnabled()) {
String retry = (i == 0 ? "" : ", retry (" + i + ") ");
logger.debug("Allocating {} [{}] ...", retry, LoggingUtil.getLoggingName(request));
}
DeployedService deployedService = ir.getInstantiator().instantiate(event);
if (deployedService != null) {
jsbInstance = deployedService.getServiceBeanInstance();
ir.addDeployedService(deployedService);
logger.info("Allocated [{}]", LoggingUtil.getLoggingName(request));
if (logger.isTraceEnabled()) {
Object service = jsbInstance.getService();
Class serviceClass = service.getClass();
logger.trace("{} ServiceBeanInstance {}, Annotation {}",
LoggingUtil.getLoggingName(request),
jsbInstance,
RMIClassLoader.getClassAnnotation(serviceClass));
}
break;
} else {
logger.debug("{} at [{}] did not allocate [{}], retry ...",
ir.getName(), ir.getHostAddress(), LoggingUtil.getLoggingName(request));
long retryWait = 1000;
try {
Thread.sleep(retryWait);
} catch (InterruptedException ie) {
logger.trace("Interrupted while sleeping [{}] milliseconds for provision retry",
retryWait);
}
}
}
} catch (UnknownEventException e) {
result = ServiceProvisioner.PROVISION_FAILURE;
failureReason = e.getLocalizedMessage();
logger.error(failureReason);
thrown = e;
context.getSelector().dropServiceResource(serviceResource);
} catch (RemoteException e) {
result = ServiceProvisioner.PROVISION_FAILURE;
Throwable t = ThrowableUtil.getRootCause(e);
failureReason = t.getLocalizedMessage();
thrown = e;
} catch (ServiceBeanInstantiationException e) {
if (e.isUninstantiable())
result = ServiceProvisioner.PROVISION_FAILURE | ServiceProvisioner.UNINSTANTIABLE_JSB;
else
result = ServiceProvisioner.PROVISION_FAILURE;
thrown = e;
Throwable t = ThrowableUtil.getRootCause(e);
failureReason = t.getLocalizedMessage();
} catch (Throwable t) {
result = ServiceProvisioner.PROVISION_FAILURE | ServiceProvisioner.UNINSTANTIABLE_JSB;
thrown = t;
t = ThrowableUtil.getRootCause(t);
failureReason = t.getLocalizedMessage();
}
} finally {
if (thrown != null) {
if (!ThrowableUtil.isRetryable(thrown)) {
logger.warn("Drop {} {} from collection, reason: {}",
ir.getName(), ir.getInstantiator(), failureReason, thrown);
context.getSelector().dropServiceResource(serviceResource);
result = ServiceProvisioner.PROVISION_FAILURE | ServiceProvisioner.BAD_CYBERNODE;
} else {
if (logger.isTraceEnabled())
logger.warn("Provisioning [{}] to [{}]",
LoggingUtil.getLoggingName(request), ir.getHostAddress(), thrown);
else
logger.warn("Provisioning [{}] to [{}], {}: {}",
LoggingUtil.getLoggingName(request),
ir.getHostAddress(),
thrown.getClass().getName(),
thrown.getLocalizedMessage());
}
}
ir.decrementProvisionCounter(request.getServiceElement());
long stop = System.currentTimeMillis();
context.getWatch().addValue(stop - start);
}
return (result);
}