/*
* Copyright (c) 2005-2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you 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.registry.eventing.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.ListenerManager;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.AxisFault;
import org.osgi.service.component.ComponentContext;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.wso2.carbon.email.verification.util.EmailVerifcationSubscriber;
import org.wso2.carbon.email.verification.util.Util;
import org.wso2.carbon.registry.event.core.EventBroker;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.jdbc.handlers.filters.URLMatcher;
import org.wso2.carbon.registry.core.jdbc.handlers.HandlerLifecycleManager;
import org.wso2.carbon.registry.eventing.RegistryEventDispatcher;
import org.wso2.carbon.registry.eventing.RegistryEventingConstants;
import org.wso2.carbon.registry.eventing.services.EventingService;
import org.wso2.carbon.registry.eventing.services.EventingServiceImpl;
import org.wso2.carbon.registry.eventing.services.SubscriptionEmailVerficationService;
import org.wso2.carbon.registry.eventing.handlers.RegistryEventingHandler;
import org.wso2.carbon.registry.eventing.handlers.SubscriptionManagerHandler;
import org.wso2.carbon.registry.eventing.handlers.erbsm.EmbeddedRegistryBasedSubscriptionManagerResourceRelocateHandler;
import org.wso2.carbon.registry.eventing.exceptions.ActivationException;
import org.wso2.carbon.registry.app.RemoteRegistryService;
import org.wso2.carbon.registry.common.eventing.NotificationService;
import org.wso2.carbon.registry.extensions.jmx.Events;
import org.wso2.carbon.utils.ConfigurationContextService;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.NetworkUtils;
import org.wso2.carbon.email.verification.util.EmailVerifierConfig;
import java.io.File;
import java.net.SocketException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
/**
* @scr.component name="org.wso2.carbon.registry.eventing" immediate="true"
* @scr.reference name="configuration.context.service"
* interface="org.wso2.carbon.utils.ConfigurationContextService" cardinality="1..1"
* policy="dynamic" bind="setConfigurationContextService" unbind="unsetConfigurationContextService"
* @scr.reference name="registry.service"
* interface="org.wso2.carbon.registry.core.service.RegistryService" cardinality="1..1"
* policy="dynamic" bind="setRegistryService" unbind="unsetRegistryService"
* @scr.reference name="listener.manager.service"
* interface="org.apache.axis2.engine.ListenerManager" cardinality="1..1" policy="dynamic"
* bind="setListenerManager" unbind="unsetListenerManager"
* @scr.reference name="eventbroker.service"
* interface="org.wso2.carbon.registry.event.core.EventBroker"
* cardinality="1..1" policy="dynamic"
* bind="setEventBroker" unbind="unsetEventBroker"
* @scr.reference name="email.verification.service"
* interface="org.wso2.carbon.email.verification.util.EmailVerifcationSubscriber"
* cardinality="1..1" policy="dynamic"
* bind="setEmailVerificationSubscriber" unbind="unsetEmailVerificationSubscriber"
* @scr.reference name="registry.events.jmx.service"
* interface="org.wso2.carbon.registry.extensions.jmx.Events" cardinality="0..1"
* policy="dynamic" bind="setEvents" unbind="unsetEvents"
*/
public class RegistryEventingServiceComponent {
private static Log log = LogFactory.getLog(RegistryEventingServiceComponent.class);
private boolean configurationDone = false;
private Registry registry = null;
private ConfigurationContextService configurationContextService = null;
private ListenerManager listenerManager = null;
private boolean initialized = false;
private String endpoint = null;
private ServiceRegistration eventingServiceRegistration = null;
private ServiceRegistration notificationServiceRegistration = null;
private ServiceRegistration emailVerificationServiceRegistration = null;
private EventingServiceImpl service = null;
private BundleContext bundleContext = null;
private String eventingRoot = "/repository/components/org.wso2.carbon.event/";
private String defaultClass = "org.wso2.carbon.registry.eventing.template.RegistryNotification";
protected void activate(ComponentContext context) {
bundleContext = context.getBundleContext();
initialize();
registerEventingService();
log.debug("Registry Eventing bundle is activated ");
}
private void registerEventingService() {
if (listenerManager != null && eventingServiceRegistration == null && bundleContext != null) {
service = new EventingServiceImpl();
eventingServiceRegistration = bundleContext.registerService(EventingService.class.getName(), service, null);
notificationServiceRegistration = bundleContext.registerService(NotificationService.class.getName(), service, null);
emailVerificationServiceRegistration = bundleContext.registerService(
SubscriptionEmailVerficationService.class.getName(), service, null);
EventingDataHolder.getInstance().setRegistryEventingService(service);
log.debug("Successfully setup the Eventing OGSi Service");
}
}
private void unregisterEventingService() {
if (eventingServiceRegistration != null) {
EventingDataHolder.getInstance().setRegistryEventingService(null);
eventingServiceRegistration.unregister();
eventingServiceRegistration = null;
notificationServiceRegistration.unregister();
notificationServiceRegistration = null;
emailVerificationServiceRegistration.unregister();
emailVerificationServiceRegistration = null;
service = null;
log.debug("Successfully unregistered the Eventing OGSi Service");
}
}
protected void deactivate(ComponentContext context) {
unregisterEventingService();
log.debug("Registry Eventing bundle is deactivated ");
}
protected void setConfigurationContextService(ConfigurationContextService configurationContextService) {
log.debug("The Configuration Context Service was set");
this.configurationContextService = configurationContextService;
if (configurationContextService != null) {
EventingDataHolder.getInstance().setConfigurationContext(configurationContextService.getServerConfigContext());
}
}
protected void unsetConfigurationContextService(ConfigurationContextService configurationContextService) {
EventingDataHolder.getInstance().setConfigurationContext(null);
}
protected void setRegistryService(RegistryService registryService) {
EventingDataHolder.getInstance().setRegistryService(registryService);
}
private void setupEmailVerification() {
if (EventingDataHolder.getInstance().getEmailVerificationSubscriber() == null) {
return;
}
EmailVerifierConfig emailVerifierConfig = EventingDataHolder.getInstance().getEmailVerifierConfig();
if (emailVerifierConfig == null) {
String fileName = CarbonUtils.getCarbonConfigDirPath() + File.separator +
"notifications-email-verification.xml";
if ((new File(fileName)).exists()) {
emailVerifierConfig = Util.loadeMailVerificationConfig(fileName);
}
if (emailVerifierConfig == null) {
emailVerifierConfig = new EmailVerifierConfig();
}
if (emailVerifierConfig.getEmailBody() == null) {
emailVerifierConfig.setEmailBody("To complete your subscription process, please " +
"click on the link below to verify your e-mail address.");
}
if (emailVerifierConfig.getEmailFooter() == null) {
emailVerifierConfig.setEmailFooter("This message is automatically generated " +
"by the WSO2 Carbon Registry.");
}
if (emailVerifierConfig.getTargetEpr() == null) {
String registryURL = EventingDataHolder.getInstance().getDefaultEventingServiceURL();
if (registryURL != null && registryURL.indexOf(
"/services/RegistryEventingService") > -1) {
registryURL = registryURL.substring(0, registryURL.length() -
"/services/RegistryEventingService".length()) +
"/carbon";
}
if (registryURL == null) {
log.error("Unable to obtain registry URL");
emailVerifierConfig = null;
return;
}
if (!registryURL.endsWith("/")) {
registryURL = registryURL + "/";
}
emailVerifierConfig.setTargetEpr(registryURL +
"info/subscription-email-verification.jsp");
}
if (emailVerifierConfig.getSubject() == null) {
emailVerifierConfig.setSubject("E-mail Address Verification");
}
if (emailVerifierConfig.getRedirectPath() == null) {
emailVerifierConfig.setRedirectPath("../info/subscription-email-verified.jsp");
}
log.debug("The E-mail Verfication Component Configuration has been done.");
EventingDataHolder.getInstance().setEmailVerifierConfig(emailVerifierConfig);
}
}
protected void unsetEmailVerificationSubscriber(EmailVerifcationSubscriber emailVerificationSubscriber) {
EventingDataHolder.getInstance().setEmailVerificationSubscriber(null);
}
protected void setEmailVerificationSubscriber(EmailVerifcationSubscriber emailVerificationSubscriber) {
EventingDataHolder.getInstance().setEmailVerificationSubscriber(emailVerificationSubscriber);
}
private void setSubscriptionConfiguration(){
NotificationConfig config = new NotificationConfig();
String fileName = CarbonUtils.getCarbonConfigDirPath() + File.separator + "registry.xml";
if ((new File(fileName)).exists()) {
config = loadeNotificationConfig(fileName);
}
if (config == null) {
config = new NotificationConfig();
}
String serverURL = EventingDataHolder.getInstance().getDefaultEventingServiceURL();
if (serverURL != null && serverURL.indexOf(
"/services/RegistryEventingService") > -1) {
serverURL = serverURL.substring(0, serverURL.length() -"/services/RegistryEventingService".length());
}
if (config.getConfigurationClass() == null) {
config.setConfigurationClass(defaultClass);
}
if (config.getStoreURL() == null){
config.setStoreURL(serverURL+"/store");
}
if (config.getPublisherURL() == null){
config.setPublisherURL(serverURL+"/publisher");
}
if (config.getConsoleURL() == null) {
config.setConsoleURL(serverURL+"/carbon");
}
EventingDataHolder.getInstance().setNotificationConfig(config);
}
private NotificationConfig loadeNotificationConfig(String configFilename) {
NotificationConfig config = new NotificationConfig();
File configFile = new File(configFilename);
if (!configFile.exists()) {
log.error("Configuration File is not present at: " + configFilename);
return null;
}
try {
XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader( new FileInputStream(configFile));
StAXOMBuilder builder = new StAXOMBuilder(parser);
OMElement documentElement = builder.getDocumentElement();
OMElement notificationConfig = documentElement.getFirstChildWithName(new QName("notificationConfiguration"));
if (notificationConfig != null) { //registry.xml need an <notificationConfiguration> </notificationConfiguration> entry to continue
Iterator it = notificationConfig.getChildElements();
while (it.hasNext()) {
OMElement element = (OMElement) it.next();
if ("class".equals(element.getLocalName())) {
config.setConfigurationClass(element.getText());
} else if ("storeURL".equals(element.getLocalName())) {
config.setStoreURL(element.getText());
} else if ("publisherURL".equals(element.getLocalName())) {
config.setPublisherURL(element.getText());
} else if ("consoleURL".equals(element.getLocalName())) {
config.setConsoleURL(element.getText());
}
}
}
return config;
} catch (Exception e) {
String msg = "Error in loading configuration : " +
configFilename + ".";
log.error(msg, e);
return null;
}
}
protected void unsetRegistryService(RegistryService registryService) {
EventingDataHolder.getInstance().setRegistryService(null);
}
protected void setEventBroker(EventBroker eventBroker) {
EventingDataHolder.getInstance().setRegistryEventBrokerService(eventBroker);
}
protected void unsetEventBroker(EventBroker eventBroker) {
EventingDataHolder.getInstance().setRegistryEventBrokerService(null);
}
protected void setListenerManager(ListenerManager listenerManager) {
this.listenerManager = listenerManager;
//initialize();
//registerEventingService();
}
protected void setEvents(Events notifications) {
JMXEventsBean implBean = new JMXEventsBean();
notifications.setImplBean(implBean);
EventingDataHolder.getInstance().setEventsBean(implBean);
}
protected void unsetEvents(Events notifications) {
EventingDataHolder.getInstance().setEventsBean(null);
notifications.setImplBean(null);
}
protected void unsetListenerManager(ListenerManager listenerManager) {
this.listenerManager = null;
unregisterEventingService();
}
private void initialize() {
ConfigurationContext serverConfigurationContext = configurationContextService.getServerConfigContext();
if (!configurationDone && listenerManager != null &&
EventingDataHolder.getInstance().getRegistryService() != null) {
String host;
try {
host = NetworkUtils.getLocalHostname();
} catch (SocketException e) {
host = null;
log.warn("An error occured while determining server host", e);
}
if (host == null) {
host = System.getProperty("carbon.local.ip");
log.warn("Unable to obtain server host, using the carbon.local.ip system "
+ "property to determine the ip address.");
}
log.debug("Found Server Host: " + host);
if (serverConfigurationContext != null) {
AxisConfiguration config = serverConfigurationContext.getAxisConfiguration();
if (config != null && config.getTransportIn("https") != null &&
config.getTransportIn("https").getReceiver() != null) {
try {
EndpointReference[] eprArray = config.getTransportIn("https")
.getReceiver().getEPRsForService("RegistryEventingService",
host);
if (eprArray != null && eprArray[0] != null) {
endpoint = eprArray[0].getAddress();
if (endpoint != null && endpoint.endsWith("/")) {
endpoint = endpoint.substring(0, endpoint.length() - 1);
}
} else {
String msg = "Unable to obtain EPR for service. " +
"Attempting to construct EPR based on known parameters.";
log.warn(msg);
}
} catch (AxisFault e) {
String msg = "Error occured while obtaining EPR for service. " +
"Attempting to construct EPR based on known parameters.";
log.warn(msg, e);
}
}
}
if (endpoint == null) {
// Try to an alternate strategy to obtain the endpoint URL based on the ip address
// and the port.
StringBuffer epBuf = new StringBuffer("https://");
String port = null;
try {
port = Integer.toString(CarbonUtils.getTransportPort(serverConfigurationContext, "https"));
} catch (Exception e) {
port = null;
log.warn("Unable to get HTTP port from Server Axis Configuration, using system defined value");
}
if (port == null) {
port = System.getProperty("carbon.https.port");
}
log.debug("Found Server Port: " + port);
if (host != null && port != null) {
epBuf.append(host);
epBuf.append(':');
epBuf.append(port);
AxisConfiguration axisConfig = null;
if (serverConfigurationContext != null) {
axisConfig = serverConfigurationContext.getAxisConfiguration();
}
if (axisConfig != null) {
log.debug("Successfully obtained the Axis Configuration");
}
if (axisConfig != null && serverConfigurationContext.getContextRoot() != null) {
String contextRoot = serverConfigurationContext.getContextRoot();
log.debug("Found Context Root: " + contextRoot);
epBuf.append(contextRoot);
if (!contextRoot.endsWith("/")) {
epBuf.append('/');
}
}
if (axisConfig != null && axisConfig.getParameter("servicePath") != null) {
log.debug("Found Service Path: " + axisConfig.getParameter("servicePath").getValue());
epBuf.append((String) axisConfig.getParameter("servicePath").getValue());
epBuf.append('/');
endpoint = epBuf.toString() + RegistryEventingConstants.EVENTING_SERVICE_NAME;
}
}
}
if (endpoint == null) {
String msg = "Failed obtaining server configuration";
log.error(msg);
throw new ActivationException(msg);
}
log.debug("The Registry Eventing Service is available at: " + endpoint);
try {
/*Utils.setRemoteTopicHeaderName(Utils.getRegistryEventBrokerService()
.getSubscriptionManager().getPropertyValue("topicHeaderName"));
Utils.setRemoteTopicHeaderNS(Utils.getRegistryEventBrokerService()
.getSubscriptionManager().getPropertyValue("topicHeaderNS"));
eventingRoot = Utils.getRegistryEventBrokerService()
.getSubscriptionManager().getPropertyValue("subscriptionStoragePath");
Utils.setRemoteSubscriptionStoreContext(eventingRoot);*/
setupHandlers();
setupDispatchers();
setupEmailVerification();
setSubscriptionConfiguration();
log.debug("Successfully instantiated the Registry Event Source");
} catch (Exception e) {
String msg = "Error Instantiating Registry Event Source";
log.error(msg);
throw new ActivationException(msg);
}
configurationDone = true;
}
}
// TODO: This is hack to set the Registry Dispatcher. Get rid of this once message formatting is
// available.
private void setupDispatchers() throws Exception {
RegistryEventDispatcher dispatcher = new RegistryEventDispatcher();
dispatcher.init(EventingDataHolder.getInstance().getConfigurationContext());
if (EventingDataHolder.getInstance().getRegistryEventBrokerService() != null) {
EventingDataHolder.getInstance().getRegistryEventBrokerService().registerEventDispatcher(
RegistryEventingConstants.TOPIC_PREFIX, dispatcher);
}
}
private void setupHandlers() {
if (Boolean.toString(Boolean.TRUE).equals(System.getProperty("disable.event.handlers"))) {
initialized = true;
log.debug("Default Eventing Handlers have been disabled. Events will not be " +
"generated unless a custom handler has been configured.");
return;
}
RegistryService registryService = EventingDataHolder.getInstance().getRegistryService();
if (registryService instanceof RemoteRegistryService && !initialized) {
initialized = true;
log.warn("Eventing is not available on Remote Registry");
return;
}
if (!initialized && listenerManager != null && registryService != null) {
initialized = true;
try {
// We can't get Registry from Utils, as the MessageContext is not available at
// activation time.
Registry systemRegistry = registryService.getConfigSystemRegistry();
if (registry != null && registry == systemRegistry) {
return;
}
registry = systemRegistry;
if (registry == null ||
registry.getRegistryContext() == null ||
registry.getRegistryContext().getHandlerManager() == null) {
String msg = "Error Initializing Registry Eventing Handler";
log.error(msg);
} else {
URLMatcher filter = new URLMatcher();
filter.setDeletePattern(".*");
filter.setPutPattern(".*");
filter.setPutChildPattern(".*");
filter.setMovePattern(".*");
filter.setCopyPattern(".*");
filter.setRenamePattern(".*");
filter.setCreateVersionPattern(".*");
filter.setApplyTagPattern(".*");
filter.setRemoveTagPattern(".*");
filter.setAddCommentPattern(".*");
filter.setAddAssociationPattern(".*");
filter.setRemoveAssociationPattern(".*");
filter.setRateResourcePattern(".*");
filter.setCreateLinkPattern(".*");
filter.setRemoveLinkPattern(".*");
filter.setRestorePattern(".*");
RegistryEventingHandler handler = new RegistryEventingHandler();
registry.getRegistryContext().getHandlerManager().addHandler(null, filter,
handler, HandlerLifecycleManager.DEFAULT_REPORTING_HANDLER_PHASE);
registry.setEventingServiceURL(null, endpoint);
EventingDataHolder.getInstance().setDefaultEventingServiceURL(endpoint);
log.debug("Successfully Initialized the Registry Eventing Handler");
/*URLMatcher erbSubManagerMountFilter = new URLMatcher();
erbSubManagerMountFilter.setPutPattern(
eventingRoot + "/.*");
SubscriptionManagerHandler erbSubManagerMountHanlder =
new EmbeddedRegistryBasedSubscriptionManagerMountHandler();
registry.getRegistryContext().getHandlerManager().addHandler(null,
erbSubManagerMountFilter, erbSubManagerMountHanlder);
erbSubManagerMountHanlder.init(registry.getRegistryContext(), eventingRoot);
log.debug("Successfully Initialized the Subscription Manager Mount Handler");*/
URLMatcher erbSubManagerRRFilter = new URLMatcher();
erbSubManagerRRFilter.setCopyPattern(".*");
erbSubManagerRRFilter.setRenamePattern(".*");
erbSubManagerRRFilter.setMovePattern(".*");
erbSubManagerRRFilter.setDeletePattern(".*");
SubscriptionManagerHandler erbSubManagerRRHanlder =
new EmbeddedRegistryBasedSubscriptionManagerResourceRelocateHandler();
registry.getRegistryContext().getHandlerManager().addHandler(null,
erbSubManagerRRFilter, erbSubManagerRRHanlder,
HandlerLifecycleManager.DEFAULT_REPORTING_HANDLER_PHASE);
erbSubManagerRRHanlder.init(registry.getRegistryContext(), eventingRoot);
log.debug("Successfully Initialized the Subscription Manager Resource Relocate Handler");
log.info("Successfully Initialized Eventing on Registry");
}
} catch (Exception e) {
String msg = "Error Initializing Eventing on Registry";
log.error(msg, e);
throw new RuntimeException(msg, e);
}
}
}
}