String hostAddress = context.getComputeResourceManager().getComputeResource().getAddress().getHostAddress();
Configuration config;
try {
config = context.getConfiguration();
} catch (ConfigurationException e) {
throw new ServiceBeanControlException("Unable to obtain configuration for service " +
"[" + context.getServiceElement().getName() + "]",
e);
}
String serviceName = context.getServiceElement().getName();
String opStringName = context.getServiceElement().getOperationalStringName();
String[] groups = context.getServiceElement().getServiceBeanConfig().getGroups();
List<LookupLocator> lookupLocators = new ArrayList<LookupLocator>();
if(context.getServiceElement().getServiceBeanConfig().getLocators()!=null) {
Collections.addAll(lookupLocators, context.getServiceElement().getServiceBeanConfig().getLocators());
}
String globalLocators = System.getProperty(Constants.LOCATOR_PROPERTY_NAME);
if(globalLocators!=null) {
try {
Collections.addAll(lookupLocators, JiniClient.parseLocators(globalLocators));
} catch (MalformedURLException e) {
logger.warn("Configured LookupLocators [{}] are malformed", globalLocators, e);
}
}
String componentName = getServiceComponentName(context);
final Thread currentThread = Thread.currentThread();
ClassLoader currentClassLoader = currentThread.getContextClassLoader();
try {
ClassLoader proxyCL = serviceProxy.getClass().getClassLoader();
currentThread.setContextClassLoader(proxyCL);
if (serviceProxy instanceof Administrable) {
Administrable admin = (Administrable) serviceProxy;
Object adminObject = admin.getAdmin();
if (adminObject instanceof ServiceBeanControl) {
ServiceBeanControl controller = (ServiceBeanControl) adminObject;
controller.advertise();
/* Additional attributes are ignored here, they are obtained
* by the ServiceBeanAdmin.advertise() method */
} else if (adminObject instanceof JoinAdmin) {
Entry[] configuredAttributes = getConfiguredAttributes(componentName,
config,
serviceName,
context.getExportCodebase());
JoinAdmin joinAdmin = (JoinAdmin) adminObject;
ArrayList<Entry> addList = new ArrayList<Entry>();
logger.trace("OperationalString {}", opStringName);
/* Try and add an OperationalStringEntry */
if (opStringName != null && opStringName.length() > 0) {
Entry opStringEntry = loadEntry("org.rioproject.entry.OperationalStringEntry",
joinAdmin, opStringName, proxyCL);
if (opStringEntry != null) {
addList.add(opStringEntry);
logger.debug("Added OperationalStringEntry [{}] for {}",
((OperationalStringEntry)opStringEntry).name, serviceName);
} else {
logger.warn("Unable to obtain the OperationalStringEntry for {}", serviceName);
}
} else {
logger.trace("OperationalString name is {}", (opStringName == null ? "[null]" : "[empty string]"));
}
/* Next, try and add the net.jini.lookup.entry.Host */
Entry hostEntry = loadEntry("net.jini.lookup.entry.Host", joinAdmin, hostAddress, proxyCL);
if (hostEntry != null) {
addList.add(hostEntry);
logger.debug("Added Host [{}] for {}", ((Host)hostEntry).hostName, serviceName);
} else {
logger.warn("Unable to obtain the Host entry for {}", serviceName);
}
/* Process the net.jini.lookup.entry.Name attribute */
try {
Class<?> nameClass = proxyCL.loadClass("net.jini.lookup.entry.Name");
Constructor cons = nameClass.getConstructor(String.class);
Entry name = (Entry) cons.newInstance(serviceName);
boolean add = true;
/* Check if the service already has a Name, if it does
* ensure it is not the same name as the one this
* utility is prepared to add */
Entry[] attributes = joinAdmin.getLookupAttributes();
for (Entry attribute : attributes) {
if (attribute.getClass().getName().equals(nameClass.getName())) {
Field n = attribute.getClass().getDeclaredField("name");
String value = (String) n.get(attribute);
if (value.equals(serviceName))
add = false;
break;
}
}
if (add)
addList.add(name);
} catch (Exception e) {
logger.warn("Name not found, cannot add a Name Entry", e);
}
/* If running forked, add JMX connection entries */
if(logger.isTraceEnabled())
logger.trace("Service: {}, forked? {}", serviceName, forked);
if(forked) {
Collections.addAll(addList, JMXUtil.getJMXConnectionEntries());
}
addList.addAll(context.getServiceBeanConfig().getAdditionalEntries());
/* If any additional attributes (including the
* OperationalString and Name entry already processed) are
* passed in, include them as well */
addList.addAll(Arrays.asList(configuredAttributes));
/* If we have Entry objects to add, add them */
if (!addList.isEmpty()) {
Entry[] adds = addList.toArray(new Entry[addList.size()]);
addAttributes(adds, joinAdmin);
}
/* Apply groups to the JoinAdmin */
if (groups == null || groups.length == 0)
groups = LookupDiscovery.NO_GROUPS;
if (groups != null && groups.length > 0) {
if (groups.length == 1 && groups[0].equals("all")) {
groups = LookupDiscovery.ALL_GROUPS;
} else {
for (int i = 0; i < groups.length; i++) {
if (groups[i].equals("public"))
groups[i] = "";
}
}
}
if (logger.isTraceEnabled()) {
StringBuilder buff = new StringBuilder();
if (groups == null || groups.length == 0) {
buff.append("LookupDiscovery.NO_GROUPS");
} else {
for (int i = 0; i < groups.length; i++) {
if (i > 0)
buff.append(",");
buff.append(groups[i]);
}
}
logger.trace("Setting groups [{}] using JoinAdmin.setLookupGroups", buff.toString());
}
joinAdmin.setLookupGroups(groups);
if (!lookupLocators.isEmpty()) {
if (logger.isTraceEnabled()) {
StringBuilder buff = new StringBuilder();
for (LookupLocator lookupLocator : lookupLocators) {
if (buff.length()>0 )
buff.append(",");
buff.append(lookupLocator.toString());
}
logger.trace("Setting locators [{}] using JoinAdmin.setLookupLocators", buff.toString());
}
joinAdmin.setLookupLocators(lookupLocators.toArray(new LookupLocator[lookupLocators.size()]));
}
} else {
logger.error("Admin must implement JoinAdmin or ServiceBeanControl to be properly advertised");
}
} else {
throw new ServiceBeanControlException(String.format("Unable to obtain mechanism to advertise [%s]", serviceName));
}
} catch (ServiceBeanControlException e) {
/* If we throw a ServiceBeanControlException above, just rethrow it */
throw e;
} catch (Throwable t) {
logger.warn("Advertising ServiceBean, [{}: {}]", t.getClass().getName(), t.getLocalizedMessage());
throw new ServiceBeanControlException("advertise", t);
} finally {
currentThread.setContextClassLoader(currentClassLoader);
}
}