package eu.dnetlib.enabling.tools.registration; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import javax.xml.transform.dom.DOMResult; import javax.xml.ws.Endpoint; import javax.xml.ws.wsaddressing.W3CEndpointReference; import org.antlr.stringtemplate.StringTemplate; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Required; import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException; import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException; import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService; import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException; import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService; import eu.dnetlib.enabling.locators.UniqueServiceLocator; import eu.dnetlib.enabling.tools.HNMLocator; import eu.dnetlib.enabling.tools.NullHNMLocator; import eu.dnetlib.soap.EndpointReferenceBuilder; /** * This class takes care of registering a service. * * TODO: merge the implementation * * @author marko * */ public class ServiceRegistrator { /** * second. */ private static final int SECOND = 0; /** * logger. */ private static final Log log = LogFactory.getLog(ServiceRegistrator.class); // NOPMD // by // marko // on // 11/24/08 // 5:02 // PM /** * locator. */ private UniqueServiceLocator serviceLocator; /** * epr builder. */ private EndpointReferenceBuilder eprBuilder; /** * component which finds an hnm profile. */ private HNMLocator hnmLocator = new NullHNMLocator(); /** * Key-value pairs with service specific parameters which will appear in service profile. */ private Map serviceProperties = new HashMap(); /** * Key-value pairs [name - endpoint] of extra protocols available in service profiles. */ private Map extraProtocols = new HashMap(); /** * this bean helps us resolve service names from service instances. */ private ServiceNameResolver serviceNameResolver = new InterfaceServiceNameResolver(); // NOPMD /** * Register a service schema for a given service. * * @param service * service */ public void registerServiceSchema(final Object service) { registerServiceSchema(serviceNameResolver.getName(service)); } /** * Register a service schema for a particular service. * * @param serviceName * service name */ public void registerServiceSchema(final String serviceName) { try { final InputStream schemaStream = getClass().getResourceAsStream("ServiceProfileSchemaTemplate.st"); if (schemaStream == null) { throw new IllegalStateException("cannot find service profile schema template"); } final StringWriter schemaBuffer = new StringWriter(); IOUtils.copy(schemaStream, schemaBuffer); final StringTemplate schema = new StringTemplate(schemaBuffer.toString()); final String resourceType = serviceName + "ResourceType"; schema.setAttribute("resourceType", resourceType); if (serviceLocator == null) { log.error("************* SERVICE LOCATOR IS NULL:" + serviceName); return; } final ISRegistryService registry = serviceLocator.getService(ISRegistryService.class, true); if (registry == null) { log.error("************* REGISTRY SERVICE IS NULL"); return; } registry.addResourceType(resourceType, schema.toString()); } catch (final ISRegistryException e) { throw new IllegalStateException("cannot register service profile schema", e); } catch (final IOException e) { throw new IllegalStateException("cannot read service profile schema template", e); } } /** * register a given service. * * @param service * infers the service name from the class or annotations * @param endpoint * jaxws endpoint * @return service profile id */ public String registerService(final Object service, final Endpoint endpoint) { return registerService(serviceNameResolver.getName(service), endpoint); } /** * register a service with a given service name. Return null if the service cannot be registered, for example because it's blocked if * the HNM is missing. * * @param serviceName * service name * @param endpoint * jaxws endpoint * @return service profile id, or null if the service cannot be registered because blocked */ public String registerService(final String serviceName, final Endpoint endpoint) { return registerService(serviceName, eprBuilder.getEndpointReference(endpoint)); } /** * register a service with a given service name. * * @param serviceName * service name * @param epr * w3c endpoint reference * @return service profile id */ public String registerService(final String serviceName, final W3CEndpointReference epr) { ensureSchemaExists(serviceName); final DOMResult result = new DOMResult(); epr.writeTo(result); try { final InputStream templateStream = getClass().getResourceAsStream("ServiceProfileTemplate.st"); if (templateStream == null) { throw new IllegalStateException("cannot find service profile template"); } final StringWriter buffer = new StringWriter(); IOUtils.copy(templateStream, buffer); final StringTemplate templ = new StringTemplate(buffer.toString()); final String resourceType = serviceName + "ResourceType"; final String address = result.getNode().getChildNodes().item(0).getChildNodes().item(0).getTextContent(); final String hnmId = hnmLocator.getHNMForUrl(address); // skip registration if there is no HNM yet. if (hnmId == null) { log.warn(String.format("skipping %s service registration, can't find NHM service'", serviceName)); return null; } templ.setAttribute("resourceType", resourceType); templ.setAttribute("serviceName", serviceName); templ.setAttribute("address", address); templ.setAttribute("protocols", getExtraProtocols()); templ.setAttribute("parentId", hnmId); templ.setAttribute("properties", serviceProperties); log.debug("template: " + templ.toString()); final String res = serviceLocator.getService(ISRegistryService.class, true).insertProfileForValidation(resourceType, templ.toString()); Thread.sleep(SECOND); return res; } catch (final IOException e) { throw new IllegalStateException("cannot load service profile template", e); } catch (final ISRegistryException e) { throw new IllegalStateException("cannot register service profile", e); } catch (final InterruptedException e) { throw new IllegalStateException("cannot wait for register service profile", e); } } /** * Check that the service schema for this service already exists, and create it if it doesn't. * * @param serviceName * service name */ protected void ensureSchemaExists(final String serviceName) { try { serviceLocator.getService(ISLookUpService.class).getResourceTypeSchema(serviceName); //serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery( // "//*[local-name() = 'complexType' and @name = 'RESOURCE_TYPEType']//*[local-name() = 'enumeration' and @value = '" + serviceName // + "ResourceType']"); log.warn("schema for " + serviceName + " appears to exist"); } catch (final ISLookUpDocumentNotFoundException e) { log.warn("registering schema for " + serviceName); registerServiceSchema(serviceName); } catch (final ISLookUpException e) { throw new IllegalStateException(e); } } /** * validate the registered profile. * * TODO: XXX: huge hack. used right now to automatically register the blackboard. It won't work anymore once the services are validated * from the GUI * * @param profId * profile id * @param endpoint * service endpoint (hook for possible IS_SN automated registrations) * @return new id. */ public String validateProfile(final String profId, final Endpoint endpoint) { try { Thread.sleep(SECOND); } catch (final InterruptedException e) { throw new IllegalStateException("interrupted", e); } try { return serviceLocator.getService(ISRegistryService.class, true).validateProfile(profId); } catch (final ISRegistryException e) { throw new IllegalStateException("cannot validate service profile", e); } } /** * validate the registered profile. * * @param profId * old profile identifier * @return new profile identifier */ public String validateProfile(final String profId) { return validateProfile(profId, null); } public EndpointReferenceBuilder getEprBuilder() { return eprBuilder; } @Required public void setEprBuilder(final EndpointReferenceBuilder eprBuilder) { this.eprBuilder = eprBuilder; } public HNMLocator getHnmLocator() { return hnmLocator; } public void setHnmLocator(final HNMLocator hnmLocator) { this.hnmLocator = hnmLocator; } public ServiceNameResolver getServiceNameGen() { return serviceNameResolver; } public void setServiceNameGen(final ServiceNameResolver serviceNameGen) { this.serviceNameResolver = serviceNameGen; } public ServiceNameResolver getServiceNameResolver() { return serviceNameResolver; } public void setServiceNameResolver(final ServiceNameResolver serviceNameRes) { this.serviceNameResolver = serviceNameRes; } public Map getServiceProperties() { return serviceProperties; } public void setServiceProperties(final Map serviceProperties) { this.serviceProperties = serviceProperties; } public Map getExtraProtocols() { return extraProtocols; } public void setExtraProtocols(final Map extraProtocols) { this.extraProtocols = extraProtocols; } public UniqueServiceLocator getServiceLocator() { return serviceLocator; } @Required public void setServiceLocator(final UniqueServiceLocator serviceLocator) { this.serviceLocator = serviceLocator; } }