/* * Copyright (c) 2014, 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.identity.notification.mgt.email; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.MessageContext; import org.apache.axis2.transport.base.BaseConstants; import org.apache.axis2.transport.mail.MailConstants; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.CarbonConfigurationContextFactory; import org.wso2.carbon.identity.notification.mgt.AbstractNotificationSendingModule; import org.wso2.carbon.identity.notification.mgt.NotificationManagementException; import org.wso2.carbon.identity.notification.mgt.NotificationManagementUtils; import org.wso2.carbon.identity.notification.mgt.bean.ModuleConfiguration; import org.wso2.carbon.identity.notification.mgt.bean.PublisherEvent; import org.wso2.carbon.identity.notification.mgt.bean.Subscription; import org.wso2.carbon.identity.notification.mgt.email.bean.EmailEndpointInfo; import org.wso2.carbon.identity.notification.mgt.email.bean.EmailSubscription; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; /** * This class will be the registering class as a service for email sending module on message sending component. This * is responsible for sending email messages on published events taking care of configured information and dynamic * information which are sent by the publisher */ @SuppressWarnings("unused") public class EmailSendingModule extends AbstractNotificationSendingModule { private static final Log log = LogFactory.getLog(EmailSendingModule.class); /** * Subscription map which has all the subscriptions by email module */ private Map<String, EmailSubscription> subscriptionMap; /** * Logic for sending email on publisher event from Notification Management component * * @param publisherEvent Publisher event from publisher. Includes event name and properties * @throws NotificationManagementException */ @Override public void sendMessage(PublisherEvent publisherEvent) throws NotificationManagementException { // publisher event will not be null, since it is handled by the mgt component EmailSubscription subscription = subscriptionMap.get(publisherEvent.getEventName()); // Message sending will only be done if there is a subscription on this module if (subscription != null) { List<EmailEndpointInfo> endpointInfoList = new ArrayList<EmailEndpointInfo>(subscription.getEmailEndpointInfoList()); PrivilegedCarbonContext.startTenantFlow(); // Send mails for each and every subscribed endpoint of the subscription for (EmailEndpointInfo endpointInfo : endpointInfoList) { Map<String, String> headerMap = new HashMap<String, String>(); headerMap.put(MailConstants.MAIL_HEADER_SUBJECT, getSubject(subscription.getSubscriptionProperties(), endpointInfo.getProperties(), publisherEvent.getEventProperties())); // Read the template configured in endpoint information. String template = endpointInfo.getTemplate(); // If there is no template defined in the endpoint. use default template for which is configured for // subscription. if (StringUtils.isEmpty(template)) { template = subscription.getMailTemplate(); } // If still no template found. The message sending will be aborted to that // particular endpoint. if (template == null) { log.error("No template found to send email to " + endpointInfo.getEmailAddress() + "on event " + publisherEvent.getEventName() + ", sending aborted"); continue; } // Get the message which the place holders are replaced by configurations and // subscription properties. String message = getMessage(template, subscription.getSubscriptionProperties(), endpointInfo.getProperties(), publisherEvent.getEventProperties()); OMElement payload = OMAbstractFactory.getOMFactory().createOMElement(BaseConstants .DEFAULT_TEXT_WRAPPER, null); payload.setText(message); ServiceClient serviceClient; ConfigurationContext configContext = CarbonConfigurationContextFactory.getConfigurationContext(); try { if (configContext != null) { serviceClient = new ServiceClient(configContext, null); } else { serviceClient = new ServiceClient(); } //setting properties for axis2 client Options options = new Options(); options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE); options.setProperty(MessageContext.TRANSPORT_HEADERS, headerMap); options.setProperty(MailConstants.TRANSPORT_MAIL_FORMAT, MailConstants.TRANSPORT_FORMAT_TEXT); options.setTo(new EndpointReference(EmailModuleConstants.MAILTO_LABEL + endpointInfo.getEmailAddress())); serviceClient.setOptions(options); serviceClient.fireAndForget(payload); if (log.isDebugEnabled()) { log.debug("Email has been sent to " + endpointInfo.getEmailAddress() + ", " + "on event " + publisherEvent.getEventName()); } } catch (AxisFault axisFault) { log.error("Error while sending email notification to address " + endpointInfo. getEmailAddress() + "on event " + publisherEvent.getEventName(), axisFault); } } // Ultimately close tenant flow. PrivilegedCarbonContext.endTenantFlow(); } } /** * returns name of the message sending module * * @return Name of the message sending module. i.e EMAIL */ @Override public String getModuleName() { return EmailModuleConstants.MODULE_NAME; } /** * Initialize Email Module with configurations. * * @param configurations Configurations which are relevant to this module. Passed by Notification Management * Component */ @Override public void init(ModuleConfiguration configurations) { List<Subscription> subscriptions = configurations.getSubscriptions(); subscriptionMap = new HashMap<String, EmailSubscription>(); // Create Email Subscription from generic Subscriptions and add to map for (Subscription subscription : subscriptions) { subscriptionMap.put(subscription.getSubscriptionName(), new EmailSubscription(subscription)); } } /** * Checks whether this message sending module is registered for the given name of event * * @return true if subscribed. false if not. */ @Override public boolean isSubscribed(PublisherEvent publisherEvent) throws NotificationManagementException { return publisherEvent != null && subscriptionMap.containsKey(publisherEvent.getEventName()); } /** * Message whose place holders are replaced by configurations and dynamic properties. * * @param mailContent Original content with place holders * @param subscriptionProperties Generic properties which are defined in Event level * @param endpointProperties Configured Properties which are in endpoint level * @param eventProperties Dynamic properties which are coming from the event publisher * @return Message whose place holders are replaced. */ private String getMessage(String mailContent, Properties subscriptionProperties, Properties endpointProperties, Properties eventProperties) { // First replace place holders with configured endpoint properties mailContent = NotificationManagementUtils.replacePlaceHolders(mailContent, "\\{", "\\}", endpointProperties); // Secondly replace place holders with dynamic properties which comes form publisher mailContent = NotificationManagementUtils.replacePlaceHolders(mailContent, "\\{", "\\}", eventProperties); // Thirdly replace place holders with generic properties which are configured in event level. mailContent = NotificationManagementUtils.replacePlaceHolders(mailContent, "\\{", "\\}", subscriptionProperties); return mailContent; } /** * Read the subject of the mail from either configurations or dynamic information * * @param subscriptionProperties Module level event properties * @param endpointProperties endpoint level properties * @param eventProperties dynamic properties which are sent from the publisher * @return Subject of the mail */ private String getSubject(Properties subscriptionProperties, Properties endpointProperties, Properties eventProperties) { String subject = ""; // First priority is given to the endpoint level subject if (endpointProperties != null && endpointProperties.get(EmailModuleConstants.SUBJECT_PROPERTY_LABEL) != null) { subject = endpointProperties.getProperty(EmailModuleConstants.SUBJECT_PROPERTY_LABEL); // If the subject is not found at endpoint level configuration then search in dynamic configurations. } else if (eventProperties != null && StringUtils.isNotEmpty(eventProperties.getProperty(EmailModuleConstants .SUBJECT_PROPERTY_LABEL))) { subject = eventProperties.get(EmailModuleConstants.SUBJECT_PROPERTY_LABEL).toString(); // If subject is not found at any of the above levels. use the default subject which is configured at // subscription level. } else if (subscriptionProperties != null && StringUtils.isNotEmpty(subscriptionProperties.getProperty (EmailModuleConstants.SUBJECT_PROPERTY_LABEL))) { subject = subscriptionProperties.getProperty(EmailModuleConstants.SUBJECT_PROPERTY_LABEL); } return subject; } }