/* * Copyright 2004,2005 The Apache Software Foundation. * * 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 org.wso2.carbon.discovery.workers; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.util.AXIOMUtil; import org.apache.axiom.util.UIDGenerator; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.Parameter; import org.apache.axis2.engine.AxisConfiguration; import org.apache.axis2.util.JavaUtils; import org.apache.neethi.Policy; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.RegistryType; import org.wso2.carbon.discovery.DiscoveryConstants; import org.wso2.carbon.discovery.DiscoveryException; import org.wso2.carbon.discovery.DiscoveryOMUtils; import org.wso2.carbon.discovery.config.Config; import org.wso2.carbon.discovery.messages.Notification; import org.wso2.carbon.discovery.messages.TargetService; import org.wso2.carbon.discovery.util.ConfigHolder; import org.wso2.carbon.discovery.util.DiscoveryMgtUtils; import org.wso2.carbon.discovery.util.Util; import org.wso2.carbon.registry.core.Registry; import javax.xml.namespace.QName; import java.net.URI; public class MessageSender { public void sendHello(AxisService service, String discoveryProxyEPR) throws DiscoveryException { sendNotification(service, discoveryProxyEPR, DiscoveryConstants.NOTIFICATION_TYPE_HELLO); } public void sendBye(AxisService service, String discoveryProxyEPR) throws DiscoveryException { sendNotification(service, discoveryProxyEPR, DiscoveryConstants.NOTIFICATION_TYPE_BYE); } private void sendNotification(AxisService service, String discoveryProxyEPR, int notificationType) throws DiscoveryException { if (!isDiscoverable(service)) { return; } Config config = getDiscoveryConfig(service); try { // create the service client object before getting the eprs // in order to get the EPRs ServiceClient serviceClient = initServiceClient(discoveryProxyEPR, notificationType, service.getAxisConfiguration()); // create the hello/bye message and send String uniqueID = getServiceID(config, service); EndpointReference endpointReference = new EndpointReference(uniqueID); TargetService targetService = new TargetService(endpointReference); targetService.setTypes(new QName[] { Util.getTypes(service) }); URI[] scopes = new URI[config.getScopes().size()]; for (int i = 0; i < config.getScopes().size(); i++) { scopes[i] = new URI(config.getScopes().get(i)); } targetService.setScopes(scopes); String[] eprs = service.getEPRs(); URI[] xAddres = new URI[eprs.length]; for (int i = 0; i < eprs.length; i++) { String epr = eprs[i]; if (epr.endsWith("/")) { epr = epr.substring(0, epr.length() - 1); } xAddres[i] = new URI(epr); } targetService.setXAddresses(xAddres); targetService.setMetadataVersion(config.getMetadataVersion()); if(notificationType == DiscoveryConstants.NOTIFICATION_TYPE_HELLO){ serviceClient.addStringHeader( new QName(DiscoveryConstants.DISCOVERY_HEADER_ELEMENT_NAMESPACE, DiscoveryConstants.DISCOVERY_HEADER_SERVICE_NAME, DiscoveryConstants.DISCOVERY_HEADER_ELEMENT_NAMESPACE_PREFIX), getNameForService(service)); serviceClient.addStringHeader(new QName( DiscoveryConstants.DISCOVERY_HEADER_ELEMENT_NAMESPACE, DiscoveryConstants.DISCOVERY_HEADER_WSDL_URI, DiscoveryConstants.DISCOVERY_HEADER_ELEMENT_NAMESPACE_PREFIX), Util.getWsdlInformation(service.getName(), service.getAxisConfiguration())); } Notification notification = new Notification(notificationType, targetService); serviceClient.fireAndForget(DiscoveryOMUtils.toOM(notification, OMAbstractFactory.getOMFactory())); serviceClient.cleanup(); } catch (Exception e) { throw new DiscoveryException("Error while sending the WS-Discovery notification " + "for the service " + getNameForService(service), e); } } private boolean isDiscoverable(AxisService service) { boolean isAdminService = JavaUtils.isTrueExplicitly( service.getParameterValue("adminService")); boolean isHiddenService = JavaUtils.isTrueExplicitly( service.getParameterValue("hiddenService")); boolean isUndiscoverableService = JavaUtils.isTrueExplicitly( service.getParameterValue(DiscoveryConstants.UNDISCOVERABLE_SERVICE)); // do not sent the notifications for either hidden or admin services if (isAdminService || isHiddenService || isUndiscoverableService || service.isClientSide()){ return false; } return true; } private Config getDiscoveryConfig(AxisService service) { Parameter parameter = service.getParameter(DiscoveryConstants.WS_DISCOVERY_PARAMS); Config config; if (parameter != null) { OMElement element = parameter.getParameterElement(); // For a ProxyService, the parameter defined as XML, is returned as a string value. // Until this problem is solved, we'll be adopting the approach below, to make an // attempt to construct the parameter element. if (element == null) { if (parameter.getValue() != null) { try { String wrappedElementText = "<wrapper>" + parameter.getValue() + "</wrapper>"; element = AXIOMUtil.stringToOM(wrappedElementText); } catch (Exception ignored) { } } else { return getDefaultConfig(); } } config = Config.fromOM(element); } else { return getDefaultConfig(); } return config; } private Config getDefaultConfig() { Config config = new Config(); config.setMetadataVersion(DiscoveryConstants.DISCOVERY_DEFAULT_METADATA_VERSION); config.addScope(DiscoveryConstants.DISCOVERY_DEFAULT_SCOPE); return config; } private String getServiceID(Config config, AxisService service) throws Exception { String uniqueID = config.getUniqueId(); if (uniqueID == null) { // Get the unique id from the registry. // Use the service to get hold of the Carbon context of the tenant // to which the service belongs Registry registry = (Registry) PrivilegedCarbonContext.getThreadLocalCarbonContext(). getRegistry(RegistryType.SYSTEM_CONFIGURATION); uniqueID = DiscoveryMgtUtils.getExistingServiceIdOrUpdate(getNameForService(service), UIDGenerator.generateURNString(), registry); } return uniqueID; } private String getNameForService(AxisService service) { return service.getName().replace("/", "-"); } private ServiceClient initServiceClient(String epr, int notificationType, AxisConfiguration axisConf) throws Exception { ConfigurationContext cfgCtx = ConfigHolder.getInstance().getClientConfigurationContext(); ServiceClient serviceClient = new ServiceClient(cfgCtx, null); serviceClient.setTargetEPR(new EndpointReference(epr)); if (notificationType == DiscoveryConstants.NOTIFICATION_TYPE_HELLO) { serviceClient.getOptions().setAction(DiscoveryConstants.WS_DISCOVERY_HELLO_ACTION); } else { serviceClient.getOptions().setAction(DiscoveryConstants.WS_DISCOVERY_BYE_ACTION); } serviceClient.engageModule("addressing"); Registry registry = (Registry)PrivilegedCarbonContext.getThreadLocalCarbonContext().getRegistry( RegistryType.SYSTEM_CONFIGURATION); Policy policy = DiscoveryMgtUtils.getClientSecurityPolicy(registry); if (policy != null) { serviceClient.engageModule("rampart"); serviceClient.getOptions().setProperty( DiscoveryConstants.KEY_RAMPART_POLICY, policy); } return serviceClient; } }