Improving email sender functionality

revert-70aa11f8
prabathabey 9 years ago
parent ac9acbef82
commit 535c74a962

@ -83,7 +83,15 @@
org.wso2.carbon.ndatasource.core, org.wso2.carbon.ndatasource.core,
org.apache.axis2.transport.mail, org.apache.axis2.transport.mail,
org.apache.catalina, org.apache.catalina,
org.apache.catalina.core org.apache.catalina.core,
org.apache.commons.collections,
org.apache.velocity,
org.apache.velocity.app,
org.apache.velocity.context,
org.apache.velocity.exception,
org.apache.velocity.runtime.resource,
org.apache.velocity.runtime.resource.loader,
org.apache.commons.io
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.device.mgt.core.internal, !org.wso2.carbon.device.mgt.core.internal,
@ -216,6 +224,14 @@
<groupId>org.wso2.tomcat</groupId> <groupId>org.wso2.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId> <artifactId>tomcat-servlet-api</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
</dependency>
<dependency>
<groupId>commons-io.wso2</groupId>
<artifactId>commons-io</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -21,7 +21,6 @@ package org.wso2.carbon.device.mgt.core.config;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.config.email.NotificationMessagesConfig;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -35,21 +34,17 @@ import javax.xml.validation.SchemaFactory;
import java.io.File; import java.io.File;
/** /**
* Class responsible for the cdm manager configuration initialization. * Class responsible for the cdm configuration initialization.
*/ */
public class DeviceConfigurationManager { public class DeviceConfigurationManager {
private DeviceManagementConfig currentDeviceConfig; private DeviceManagementConfig currentDeviceConfig;
private NotificationMessagesConfig notificationMessagesConfig;
private static DeviceConfigurationManager deviceConfigManager; private static DeviceConfigurationManager deviceConfigManager;
private static final String DEVICE_MGT_CONFIG_PATH = private static final String DEVICE_MGT_CONFIG_PATH =
CarbonUtils.getCarbonConfigDirPath() + File.separator + CarbonUtils.getCarbonConfigDirPath() + File.separator +
DeviceManagementConstants.DataSourceProperties.DEVICE_CONFIG_XML_NAME; DeviceManagementConstants.DataSourceProperties.DEVICE_CONFIG_XML_NAME;
private static final String DEVICE_MGT_CONFIG_SCHEMA_PATH = "resources/config/schema/device-mgt-config-schema.xsd"; private static final String DEVICE_MGT_CONFIG_SCHEMA_PATH = "resources/config/schema/device-mgt-config-schema.xsd";
private static final String NOTIFICATION_MSG_CONFIG_PATH =
CarbonUtils.getCarbonConfigDirPath() + File.separator +
DeviceManagementConstants.NotificationProperties.NOTIFICATION_CONFIG_FILE;
public static DeviceConfigurationManager getInstance() { public static DeviceConfigurationManager getInstance() {
if (deviceConfigManager == null) { if (deviceConfigManager == null) {
@ -63,7 +58,6 @@ public class DeviceConfigurationManager {
} }
public synchronized void initConfig() throws DeviceManagementException { public synchronized void initConfig() throws DeviceManagementException {
try { try {
File deviceMgtConfig = new File(DeviceConfigurationManager.DEVICE_MGT_CONFIG_PATH); File deviceMgtConfig = new File(DeviceConfigurationManager.DEVICE_MGT_CONFIG_PATH);
Document doc = DeviceManagerUtil.convertToDocument(deviceMgtConfig); Document doc = DeviceManagerUtil.convertToDocument(deviceMgtConfig);
@ -76,18 +70,6 @@ public class DeviceConfigurationManager {
} catch (JAXBException e) { } catch (JAXBException e) {
throw new DeviceManagementException("Error occurred while initializing Data Source config", e); throw new DeviceManagementException("Error occurred while initializing Data Source config", e);
} }
try {
File notificationConfig = new File(DeviceConfigurationManager.NOTIFICATION_MSG_CONFIG_PATH);
Document doc = DeviceManagerUtil.convertToDocument(notificationConfig);
/* Un-marshaling Notifications Management configuration */
JAXBContext notificationContext = JAXBContext.newInstance(NotificationMessagesConfig.class);
Unmarshaller unmarshaller = notificationContext.createUnmarshaller();
this.notificationMessagesConfig = (NotificationMessagesConfig) unmarshaller.unmarshal(doc);
} catch(JAXBException e){
throw new DeviceManagementException("Error occurred while initializing Notification settings config", e);
}
} }
private static Schema getSchema() throws DeviceManagementException { private static Schema getSchema() throws DeviceManagementException {
@ -105,8 +87,4 @@ public class DeviceConfigurationManager {
return currentDeviceConfig; return currentDeviceConfig;
} }
public NotificationMessagesConfig getNotificationMessagesConfig() {
return notificationMessagesConfig;
}
} }

@ -1,110 +0,0 @@
/*
* Copyright (c) 2015, 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.device.mgt.core.config.email;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "NotificationMessage")
public class NotificationMessages {
private String header;
private String body;
private String footerLine1;
private String footerLine2;
private String footerLine3;
private String subject;
private String url;
@XmlAttribute(name = "type")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
private String type;
@XmlElement(name = "Header", required = true)
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
@XmlElement(name = "Body", required = true)
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
@XmlElement(name = "Subject", required = true)
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@XmlElement(name = "Url", required = true)
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@XmlElement(name = "Footer1")
public String getFooterLine1() {
return footerLine1;
}
public void setFooterLine1(String footerLine1) {
this.footerLine1 = footerLine1;
}
@XmlElement(name = "Footer2")
public String getFooterLine2() {
return footerLine2;
}
public void setFooterLine2(String footerLine2) {
this.footerLine2 = footerLine2;
}
@XmlElement(name = "Footer3")
public String getFooterLine3() {
return footerLine3;
}
public void setFooterLine3(String footerLine3) {
this.footerLine3 = footerLine3;
}
}

@ -1,39 +0,0 @@
/*
* Copyright (c) 2015, 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.device.mgt.core.config.email;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlRootElement(name = "Notifications")
public class NotificationMessagesConfig {
private List<NotificationMessages> notificationMessagesList;
@XmlElement(name = "NotificationMessage")
public List<NotificationMessages> getNotificationMessagesList() {
return notificationMessagesList;
}
public void setNotificationMessagesList(List<NotificationMessages> notificationMessagesList) {
this.notificationMessagesList = notificationMessagesList;
}
}

@ -0,0 +1,45 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
public class ContentProcessingInterruptedException extends Exception {
private static final long serialVersionUID = -3151279311929070298L;
public ContentProcessingInterruptedException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public ContentProcessingInterruptedException(String message, Throwable cause) {
super(message, cause);
}
public ContentProcessingInterruptedException(String msg) {
super(msg);
}
public ContentProcessingInterruptedException() {
super();
}
public ContentProcessingInterruptedException(Throwable cause) {
super(cause);
}
}

@ -19,13 +19,11 @@ package org.wso2.carbon.device.mgt.core.email;
public final class EmailConstants { public final class EmailConstants {
public static final class EnrolmentEmailConstants { public static final String DOMAIN = "domain-name";
public static final String DOMAIN = "domain-name"; public static final String USERNAME = "user-name";
public static final String USERNAME = "user-name"; public static final String DOWNLOAD_URL = "download-url";
public static final String DOWNLOAD_URL = "downloadUrl"; public static final String ENCODED_SCHEME = "UTF-8";
public static final String ENCODED_SCHEME = "UTF-8"; public static final String PASSWORD = "password";
public static final String PASSWORD = "password"; public static final String FIRST_NAME = "first-name";
public static final String FIRST_NAME = "first-name";
}
} }

@ -0,0 +1,28 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
import java.util.Map;
public interface EmailContentProvider {
EmailData getContent(String path,
Map<String, TypedValue<Class<?>, Object>> params) throws ContentProcessingInterruptedException;
}

@ -0,0 +1,27 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
public class EmailContentProviderFactory {
public static EmailContentProvider getContentProvider() {
return new VelocityBasedEmailContentProvider();
}
}

@ -0,0 +1,77 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
import java.util.*;
public class EmailContext {
private Set<String> recipients;
private Properties properties;
public EmailContext(final Set<String> recipients, final Properties properties) {
if (recipients == null) {
throw new IllegalArgumentException("Recipient list cannot be null");
}
if (recipients.size() == 0) {
throw new IllegalArgumentException("No recipient is configured. Recipient list should carry at " +
"least one recipient");
}
this.recipients = recipients;
if (properties == null) {
throw new IllegalArgumentException("Email Context property bag cannot be null");
}
this.properties = properties;
}
public EmailContext(final String recipient, final Properties properties) {
if (recipient == null || recipient.isEmpty()) {
throw new IllegalArgumentException("Recipient can't be null or empty. Please specify a valid " +
"recipient email address");
}
this.recipients = new HashSet<String>() {{
add(recipient);
}};
if (properties == null) {
throw new IllegalArgumentException("Email Context property bag cannot be null");
}
this.properties = properties;
}
public EmailContext(final Set<String> recipients) {
this(recipients, new Properties());
}
public Set<String> getRecipients() {
return recipients;
}
public Properties getProperties() {
return properties;
}
public String getProperty(String name) {
return (String) properties.get(name);
}
public void addProperty(String name, String value) {
properties.put(name, value);
}
}

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "EmailConfig")
public class EmailData {
private String subject;
private String body;
@XmlElement(name = "Subject", required = true)
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@XmlElement(name = "Body", required = true)
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}

@ -0,0 +1,45 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
public class EmailSendingFailedException extends Exception {
private static final long serialVersionUID = -3151279311929070294L;
public EmailSendingFailedException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public EmailSendingFailedException(String message, Throwable cause) {
super(message, cause);
}
public EmailSendingFailedException(String msg) {
super(msg);
}
public EmailSendingFailedException() {
super();
}
public EmailSendingFailedException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,71 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.resource.loader.ResourceLoader;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.registry.api.Registry;
import org.wso2.carbon.registry.api.RegistryException;
import java.io.*;
public class RegistryBasedResourceLoader extends ResourceLoader {
private static final String EMAIL_CONFIG_BASE_LOCATION = "email-templates";
@Override
public void init(ExtendedProperties extendedProperties) {
}
@Override
public InputStream getResourceStream(String name) throws ResourceNotFoundException {
try {
Registry registry =
CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.SYSTEM_CONFIGURATION);
if (registry == null) {
throw new IllegalStateException("No valid registry instance is attached to the current carbon context");
}
if (!registry.resourceExists(EMAIL_CONFIG_BASE_LOCATION + "/" + name + ".vm")) {
throw new ResourceNotFoundException("Resource '" + name + "' does not exist");
}
org.wso2.carbon.registry.api.Resource resource =
registry.get(EMAIL_CONFIG_BASE_LOCATION + "/" + name + ".vm");
return resource.getContentStream();
} catch (RegistryException e) {
throw new ResourceNotFoundException("Error occurred while retrieving resource", e);
}
}
@Override
public boolean isSourceModified(Resource resource) {
return false;
}
@Override
public long getLastModified(Resource resource) {
return 0;
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
public class TypedValue<T, V> {
private final T type;
private final V value;
public TypedValue(T type, V value) {
this.type = type;
this.value = value;
}
public T getType() {
return type;
}
public V getValue() {
return value;
}
@Override
public int hashCode() {
return (type.hashCode() ^ value.hashCode());
}
@Override
public boolean equals(Object o) {
return o instanceof TypedValue && (this.type == ((TypedValue) o).getType() &&
this.value == ((TypedValue) o).getValue());
}
}

@ -0,0 +1,87 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.ResourceLoader;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.registry.api.Registry;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Map;
public class VelocityBasedEmailContentProvider implements EmailContentProvider {
private VelocityEngine engine;
private static final Log log = LogFactory.getLog(VelocityBasedEmailContentProvider.class);
public VelocityBasedEmailContentProvider() {
engine = new VelocityEngine();
engine.setProperty("resource.loader", "registry");
engine.setProperty("velocimacro.library", "");
engine.setProperty("registry.resource.loader.class",
"org.wso2.carbon.device.mgt.core.email.RegistryBasedResourceLoader");
engine.init();
}
@Override
public EmailData getContent(String name, Map<String,
TypedValue<Class<?>, Object>> params) throws ContentProcessingInterruptedException {
VelocityContext ctx = new VelocityContext();
for (Map.Entry<String, TypedValue<Class<?>, Object>> param : params.entrySet()) {
ctx.put(param.getKey(), param.getValue().getValue());
}
Template template = engine.getTemplate(name);
StringWriter content = new StringWriter();
template.merge(ctx, content);
InputStream is = null;
try {
JAXBContext jaxbCtx = JAXBContext.newInstance(EmailData.class);
Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
is = new ByteArrayInputStream(content.toString().getBytes());
return (EmailData) unmarshaller.unmarshal(is);
} catch (JAXBException e) {
throw new ContentProcessingInterruptedException("Error occurred while parsing email data", e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
log.warn("Error occurred while closing input stream used to convert email configuration " +
"to an internal object model", e);
}
}
}
}
}

@ -0,0 +1,104 @@
/*
* Copyright (c) 2016, 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.device.mgt.core.email.sender;
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.MessageContext;
import org.apache.axis2.transport.base.BaseConstants;
import org.apache.axis2.transport.mail.MailConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.email.EmailConfigurations;
import org.wso2.carbon.device.mgt.core.email.EmailData;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class EmailSender {
private static ThreadPoolExecutor threadPoolExecutor;
static {
EmailConfigurations emailConfig =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig().
getDeviceManagementConfigRepository().getEmailConfigurations();
threadPoolExecutor = new ThreadPoolExecutor(emailConfig.getMinNumOfThread(),
emailConfig.getMaxNumOfThread(), emailConfig.getKeepAliveTime(), TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(emailConfig.getThreadQueueCapacity()));
}
private static final String EMAIL_URI_SCHEME = "mailto:";
private static Log log = LogFactory.getLog(EmailSender.class);
public void sendEmail(EmailData emailData, String... recipients) throws DeviceManagementException {
for (String recipient : recipients) {
threadPoolExecutor
.submit(new EmailSenderTask(recipient, emailData));
}
}
public static class EmailSenderTask implements Runnable {
private String to;
private EmailData data;
EmailSenderTask(String to, EmailData data) {
this.to = to;
this.data = data;
}
public void run() {
Map<String, String> headerMap = new HashMap<>();
headerMap.put(MailConstants.MAIL_HEADER_SUBJECT, data.getSubject());
OMElement payload = OMAbstractFactory.getOMFactory().createOMElement(
BaseConstants.DEFAULT_TEXT_WRAPPER, null);
payload.setText(data.getBody());
try {
ServiceClient serviceClient = new ServiceClient();
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(EMAIL_URI_SCHEME + to));
serviceClient.setOptions(options);
serviceClient.fireAndForget(payload);
if (log.isDebugEnabled()) {
log.debug("Email has been successfully sent to '" + to + "'");
}
} catch (AxisFault e) {
log.error("Error occurred while delivering the message, subject: '" + data.getSubject() +
"', to: '" + to + "'", e);
}
}
}
}

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core.email.sender;
import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.llom.util.AXIOMUtil;
import org.apache.axis2.AxisFault; import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants; import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.addressing.EndpointReference;
@ -31,15 +32,18 @@ import org.apache.axis2.transport.base.BaseConstants;
import org.apache.axis2.transport.mail.MailConstants; import org.apache.axis2.transport.mail.MailConstants;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EmailMessageProperties;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.email.EmailConfigurations; import org.wso2.carbon.device.mgt.core.config.email.EmailConfigurations;
import org.wso2.carbon.device.mgt.core.email.EmailData;
import org.wso2.carbon.device.mgt.core.email.EmailSendingFailedException;
import org.wso2.carbon.device.mgt.core.internal.EmailServiceDataHolder; import org.wso2.carbon.device.mgt.core.internal.EmailServiceDataHolder;
import org.wso2.carbon.device.mgt.core.service.EmailService; import org.wso2.carbon.device.mgt.core.service.EmailService;
import org.wso2.carbon.utils.ConfigurationContextService;
import javax.xml.stream.XMLStreamException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -62,11 +66,9 @@ public class EmailServiceProviderImpl implements EmailService {
private static Log log = LogFactory.getLog(EmailServiceProviderImpl.class); private static Log log = LogFactory.getLog(EmailServiceProviderImpl.class);
@Override @Override
public void sendEmail(EmailMessageProperties emailMessageProperties) throws DeviceManagementException { public void sendEmail(Set<String> recipients, EmailData emailData) throws EmailSendingFailedException {
for (String toAddr : emailMessageProperties.getMailTo()) { for (String recipient : recipients) {
threadPoolExecutor threadPoolExecutor.submit(new EmailSender(recipient, emailData.getSubject(), emailData.getBody()));
.submit(new EmailSender(toAddr, emailMessageProperties.getSubject(),
emailMessageProperties.getMessageBody()));
} }
} }
@ -83,34 +85,42 @@ public class EmailServiceProviderImpl implements EmailService {
} }
public void run() { public void run() {
Map<String, String> headerMap = new HashMap<String, String>(); OMElement payload = null;
headerMap.put(MailConstants.MAIL_HEADER_SUBJECT, subject);
OMElement payload = OMAbstractFactory.getOMFactory().createOMElement(
BaseConstants.DEFAULT_TEXT_WRAPPER, null);
payload.setText(body);
try { try {
ServiceClient serviceClient; payload = AXIOMUtil.stringToOM(body);
ConfigurationContext configContext = EmailServiceDataHolder.getInstance(). } catch (XMLStreamException e) {
getConfigurationContextService().getServerConfigContext(); log.error("Error occurred while converting email body contents to an XML", e);
//Set configuration service client if available, else create new service client }
if (configContext != null) { try {
serviceClient = new ServiceClient(configContext, null); ConfigurationContextService configCtxService =
} else { EmailServiceDataHolder.getInstance().getConfigurationContextService();
if (configCtxService == null) {
serviceClient = new ServiceClient(); throw new IllegalStateException("Configuration Context Service is not available");
} }
ConfigurationContext configCtx = configCtxService.getServerConfigContext();
ServiceClient serviceClient = new ServiceClient(configCtx, null);
Map<String, String> headerMap = new HashMap<>();
headerMap.put(MailConstants.MAIL_HEADER_SUBJECT, subject);
Options options = new Options(); Options options = new Options();
options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE);
options.setProperty(MessageContext.TRANSPORT_HEADERS, headerMap); options.setProperty(MessageContext.TRANSPORT_HEADERS, headerMap);
options.setProperty(MailConstants.TRANSPORT_MAIL_FORMAT, options.setProperty("FORCE_CONTENT_TYPE_BASED_FORMATTER", "true");
MailConstants.TRANSPORT_FORMAT_TEXT); options.setProperty(Constants.Configuration.MESSAGE_TYPE, "text/html");
options.setProperty(Constants.Configuration.CONTENT_TYPE, "text/html");
options.setTo(new EndpointReference(EMAIL_URI_SCHEME + to)); options.setTo(new EndpointReference(EMAIL_URI_SCHEME + to));
serviceClient.setOptions(options); serviceClient.setOptions(options);
serviceClient.fireAndForget(payload); serviceClient.fireAndForget(payload);
log.debug("Sending confirmation mail to " + to); if (log.isDebugEnabled()) {
log.debug("Email has been successfully sent to '" + to + "'");
}
} catch (AxisFault e) { } catch (AxisFault e) {
log.error("Error in delivering the message, subject: '" + subject + "', to: '" + to + "'", e); log.error("Error occurred while delivering the message, subject: '" + subject + "', to: '" + to +
"'", e);
} }
} }
} }
} }

@ -19,13 +19,31 @@
package org.wso2.carbon.device.mgt.core.internal; package org.wso2.carbon.device.mgt.core.internal;
import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.registry.api.Collection;
import org.wso2.carbon.registry.api.Registry;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import org.wso2.carbon.utils.Axis2ConfigurationContextObserver; import org.wso2.carbon.utils.Axis2ConfigurationContextObserver;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import java.io.File;
import java.io.FilenameFilter;
public class DeviceManagementAxis2ConfigContextObserver implements Axis2ConfigurationContextObserver { public class DeviceManagementAxis2ConfigContextObserver implements Axis2ConfigurationContextObserver {
private static final String EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH = "email-templates";
private static final Log log = LogFactory.getLog(DeviceManagementAxis2ConfigContextObserver.class);
@Override @Override
public void creatingConfigurationContext(int tenantId) { public void creatingConfigurationContext(int tenantId) {
} }
@Override @Override
@ -43,4 +61,49 @@ public class DeviceManagementAxis2ConfigContextObserver implements Axis2Configur
} }
private void setupEmailTemplates() throws DeviceManagementException {
File templateDir =
new File(CarbonUtils.getCarbonRepository() + "resources" + File.separator + "email-templates");
if (!templateDir.exists()) {
if (log.isDebugEnabled()) {
log.debug("The directory that is expected to use as the container for all email templates is not " +
"available. Therefore, no template is uploaded to the registry");
}
}
if (templateDir.canRead()) {
File[] templates = templateDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
name = name.toLowerCase();
return name.endsWith(".vm");
}
});
try {
Registry registry =
CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.SYSTEM_CONFIGURATION);
if (!registry.resourceExists(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH)) {
Collection collection = registry.newCollection();
registry.put(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH, collection);
for (File template : templates) {
Resource resource = registry.newResource();
resource.setContent(template);
registry.put(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName(), resource);
}
} else {
for (File template : templates) {
if (!registry.resourceExists(
EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName())) {
Resource resource = registry.newResource();
resource.setContent(template);
registry.put(
EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName(), resource);
}
}
}
} catch (RegistryException e) {
throw new DeviceManagementException("Error occurred while setting up email templates", e);
}
}
}
} }

@ -17,10 +17,13 @@
*/ */
package org.wso2.carbon.device.mgt.core.internal; package org.wso2.carbon.device.mgt.core.internal;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService; import org.wso2.carbon.apimgt.impl.APIManagerConfigurationService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
@ -52,10 +55,20 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
import org.wso2.carbon.device.mgt.core.util.DeviceManagementSchemaInitializer; import org.wso2.carbon.device.mgt.core.util.DeviceManagementSchemaInitializer;
import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.ndatasource.core.DataSourceService;
import org.wso2.carbon.registry.api.Collection;
import org.wso2.carbon.registry.api.Registry;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.ConfigurationContextService; import org.wso2.carbon.utils.ConfigurationContextService;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -108,6 +121,8 @@ public class DeviceManagementServiceComponent {
private static List<DeviceManagerStartupListener> startupListeners = new ArrayList<>(); private static List<DeviceManagerStartupListener> startupListeners = new ArrayList<>();
private DeviceManagementPluginRepository pluginRepository = new DeviceManagementPluginRepository(); private DeviceManagementPluginRepository pluginRepository = new DeviceManagementPluginRepository();
private static final String EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH = "/email-templates";
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected void activate(ComponentContext componentContext) { protected void activate(ComponentContext componentContext) {
try { try {
@ -137,6 +152,9 @@ public class DeviceManagementServiceComponent {
this.setupDeviceManagementSchema(dsConfig); this.setupDeviceManagementSchema(dsConfig);
} }
/* Setting up email templates */
this.setupEmailTemplates();
/* Registering declarative service instances exposed by DeviceManagementServiceComponent */ /* Registering declarative service instances exposed by DeviceManagementServiceComponent */
this.registerServices(componentContext); this.registerServices(componentContext);
@ -181,9 +199,9 @@ public class DeviceManagementServiceComponent {
bundleContext.registerService(DeviceManagementProviderService.class.getName(), deviceManagementProvider, null); bundleContext.registerService(DeviceManagementProviderService.class.getName(), deviceManagementProvider, null);
/* Registering Tenant Configuration Management Service */ /* Registering Tenant Configuration Management Service */
TenantConfigurationManagementService TenantConfigurationManagementService
tenantConfiguration = new TenantConfigurationManagementServiceImpl(); tenantConfiguration = new TenantConfigurationManagementServiceImpl();
bundleContext.registerService(TenantConfigurationManagementService.class.getName(), tenantConfiguration, null); bundleContext.registerService(TenantConfigurationManagementService.class.getName(), tenantConfiguration, null);
/* Registering Notification Service */ /* Registering Notification Service */
NotificationManagementService notificationManagementService NotificationManagementService notificationManagementService
@ -199,7 +217,7 @@ public class DeviceManagementServiceComponent {
DeviceAccessAuthorizationService deviceAccessAuthorizationService = new DeviceAccessAuthorizationServiceImpl(); DeviceAccessAuthorizationService deviceAccessAuthorizationService = new DeviceAccessAuthorizationServiceImpl();
DeviceManagementDataHolder.getInstance().setDeviceAccessAuthorizationService(deviceAccessAuthorizationService); DeviceManagementDataHolder.getInstance().setDeviceAccessAuthorizationService(deviceAccessAuthorizationService);
bundleContext.registerService(DeviceAccessAuthorizationService.class.getName(), bundleContext.registerService(DeviceAccessAuthorizationService.class.getName(),
deviceAccessAuthorizationService, null); deviceAccessAuthorizationService, null);
/* Registering App Management service */ /* Registering App Management service */
try { try {
@ -213,6 +231,78 @@ public class DeviceManagementServiceComponent {
} }
} }
private void setupEmailTemplates() throws DeviceManagementException {
File templateDir =
new File(CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator +
"resources" + File.separator + "email-templates");
if (!templateDir.exists()) {
if (log.isDebugEnabled()) {
log.debug("The directory that is expected to use as the container for all email templates is not " +
"available. Therefore, no template is uploaded to the registry");
}
}
if (templateDir.canRead()) {
File[] templates = templateDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
name = name.toLowerCase();
return name.endsWith(".vm");
}
});
try {
Registry registry =
DeviceManagementDataHolder.getInstance().getRegistryService().getConfigSystemRegistry();
if (!registry.resourceExists(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH)) {
Collection collection = registry.newCollection();
registry.put(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH, collection);
for (File template : templates) {
Resource resource = registry.newResource();
String contents = FileUtils.readFileToString(template);
resource.setContent(contents.getBytes());
registry.put(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName(), resource);
}
} else {
/* Existence of a given resource is not checked consciously, before performing registry.put() below.
* The rationale is that, the only less expensive way that one can check if a resource exists is
* that through registry.resourceExists(), which only checks if 'some' resource exists at the given
* registry path. However, this does not capture scenarios where there can be updated contents to
* the same resource of which the path hasn't changed after it has been initialized for the first
* time. Therefore, whenever the server starts-up, all email templates are updated just to avoid
* the aforementioned problem */
for (File template : templates) {
Resource resource = registry.newResource();
String contents = FileUtils.readFileToString(template);
resource.setContent(contents.getBytes());
registry.put(
EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName(), resource);
}
}
} catch (RegistryException e) {
throw new DeviceManagementException("Error occurred while setting up email templates", e);
} catch (FileNotFoundException e) {
throw new DeviceManagementException("Error occurred while writing template file contents as an " +
"input stream of a resource", e);
} catch (IOException e) {
throw new DeviceManagementException("Error occurred while serializing file contents to a string", e);
}
}
}
private Element parseFile(File file) throws DeviceManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
return doc.getDocumentElement();
} catch (ParserConfigurationException e) {
throw new DeviceManagementException("Error occurred while creating a document builder to parse file '" +
file.getName() + "'", e);
} catch (SAXException | IOException e) {
throw new DeviceManagementException("Error occurred while parsing file '" + file.getName() + "'", e);
}
}
private void setupDeviceManagementSchema(DataSourceConfig config) throws DeviceManagementException { private void setupDeviceManagementSchema(DataSourceConfig config) throws DeviceManagementException {
DeviceManagementSchemaInitializer initializer = new DeviceManagementSchemaInitializer(config); DeviceManagementSchemaInitializer initializer = new DeviceManagementSchemaInitializer(config);
log.info("Initializing device management repository database schema"); log.info("Initializing device management repository database schema");

@ -26,6 +26,7 @@ import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.email.EmailContext;
import java.util.List; import java.util.List;
@ -59,9 +60,9 @@ public interface DeviceManagementProviderService extends OperationManager {
*/ */
PaginationResult getAllDevices(PaginationRequest request) throws DeviceManagementException; PaginationResult getAllDevices(PaginationRequest request) throws DeviceManagementException;
void sendEnrolmentInvitation(EmailMessageProperties config) throws DeviceManagementException; void sendEnrolmentInvitation(EmailContext emailContext) throws DeviceManagementException;
void sendRegistrationEmail(EmailMessageProperties config) throws DeviceManagementException; void sendRegistrationEmail(EmailContext emailContext) throws DeviceManagementException;
FeatureManager getFeatureManager(String deviceType) throws DeviceManagementException; FeatureManager getFeatureManager(String deviceType) throws DeviceManagementException;

@ -30,24 +30,17 @@ import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository; import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.email.EmailConfigurations; import org.wso2.carbon.device.mgt.core.config.email.EmailConfigurations;
import org.wso2.carbon.device.mgt.core.config.email.NotificationMessages;
import org.wso2.carbon.device.mgt.core.dao.*; import org.wso2.carbon.device.mgt.core.dao.*;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.email.EmailConstants; import org.wso2.carbon.device.mgt.core.email.*;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.internal.EmailServiceDataHolder; import org.wso2.carbon.device.mgt.core.internal.EmailServiceDataHolder;
import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener; import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class DeviceManagementProviderServiceImpl implements DeviceManagementProviderService, public class DeviceManagementProviderServiceImpl implements DeviceManagementProviderService,
PluginInitializationListener { PluginInitializationListener {
@ -56,11 +49,13 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
private DeviceTypeDAO deviceTypeDAO; private DeviceTypeDAO deviceTypeDAO;
private EnrollmentDAO enrollmentDAO; private EnrollmentDAO enrollmentDAO;
private DeviceManagementPluginRepository pluginRepository; private DeviceManagementPluginRepository pluginRepository;
private EmailContentProvider contentProvider;
private static Log log = LogFactory.getLog(DeviceManagementProviderServiceImpl.class); private static Log log = LogFactory.getLog(DeviceManagementProviderServiceImpl.class);
public DeviceManagementProviderServiceImpl() { public DeviceManagementProviderServiceImpl() {
this.pluginRepository = new DeviceManagementPluginRepository(); this.pluginRepository = new DeviceManagementPluginRepository();
this.contentProvider = EmailContentProviderFactory.getContentProvider();
initDataAccessObjects(); initDataAccessObjects();
/* Registering a listener to retrieve events when some device management service plugin is installed after /* Registering a listener to retrieve events when some device management service plugin is installed after
* the component is done getting initialized */ * the component is done getting initialized */
@ -517,130 +512,53 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
} }
@Override @Override
public void sendEnrolmentInvitation(EmailMessageProperties emailMessageProperties) public void sendEnrolmentInvitation(EmailContext emailCtx) throws DeviceManagementException {
throws DeviceManagementException { Map<String, TypedValue<Class<?>, Object>> params = new HashMap<>();
List<NotificationMessages> notificationMessages = EmailConfigurations emailConfig =
DeviceConfigurationManager.getInstance().getNotificationMessagesConfig().getNotificationMessagesList(); DeviceConfigurationManager.getInstance().getDeviceManagementConfig().
String messageHeader = ""; getDeviceManagementConfigRepository().getEmailConfigurations();
String messageBody = ""; params.put(EmailConstants.FIRST_NAME,
String messageFooter1 = ""; new TypedValue<Class<?>, Object>(String.class, emailCtx.getProperty("first-name")));
String messageFooter2 = ""; params.put(EmailConstants.DOWNLOAD_URL,
String messageFooter3 = ""; new TypedValue<Class<?>, Object>(String.class,
String url = ""; emailConfig.getlBHostPortPrefix() + emailConfig.getEnrollmentContextPath()));
String subject = "";
for (NotificationMessages notificationMessage : notificationMessages) {
if (org.wso2.carbon.device.mgt.core.DeviceManagementConstants.EmailNotifications.ENROL_NOTIFICATION_TYPE
.equals(notificationMessage.getType())) {
messageHeader = notificationMessage.getHeader();
messageBody = notificationMessage.getBody();
messageFooter1 = notificationMessage.getFooterLine1();
messageFooter2 = notificationMessage.getFooterLine2();
messageFooter3 = notificationMessage.getFooterLine3();
url = notificationMessage.getUrl();
subject = notificationMessage.getSubject();
break;
}
}
StringBuilder messageBuilder = new StringBuilder();
try { try {
EmailData data = contentProvider.getContent("user-enrollment", params);
// Reading the download url from the cdm-config.xml file EmailServiceDataHolder.getInstance().getEmailServiceProvider().sendEmail(emailCtx.getRecipients(), data);
EmailConfigurations emailConfig = } catch (ContentProcessingInterruptedException e) {
DeviceConfigurationManager.getInstance().getDeviceManagementConfig(). throw new DeviceManagementException("Error occurred while processing contents of the " +
getDeviceManagementConfigRepository().getEmailConfigurations(); "enrollment invitation", e);
emailMessageProperties.setEnrolmentUrl(emailConfig.getlBHostPortPrefix() + } catch (EmailSendingFailedException e) {
emailConfig.getEnrollmentContextPath()); throw new DeviceManagementException("Error occurred while sending enrollment invitation", e);
messageHeader = messageHeader.replaceAll("\\{" + EmailConstants.EnrolmentEmailConstants.FIRST_NAME + "\\}",
URLEncoder.encode(emailMessageProperties.getFirstName(),
EmailConstants.EnrolmentEmailConstants.ENCODED_SCHEME));
messageBody = messageBody.trim() + System.getProperty("line.separator") + url.replaceAll("\\{"
+ EmailConstants.EnrolmentEmailConstants.DOWNLOAD_URL + "\\}",
URLDecoder.decode(emailMessageProperties.getEnrolmentUrl(),
EmailConstants.EnrolmentEmailConstants.ENCODED_SCHEME));
messageBuilder.append(messageHeader).append(System.getProperty("line.separator"))
.append(System.getProperty("line.separator"));
messageBuilder.append(messageBody);
messageBuilder.append(System.getProperty("line.separator")).append(System.getProperty("line.separator"));
messageBuilder.append(messageFooter1.trim())
.append(System.getProperty("line.separator")).append(messageFooter2.trim()).append(System
.getProperty("line.separator")).append(messageFooter3.trim());
} catch (IOException e) {
throw new DeviceManagementException("Error replacing tags in email template '" +
emailMessageProperties.getSubject() + "'", e);
} }
emailMessageProperties.setMessageBody(messageBuilder.toString());
emailMessageProperties.setSubject(subject);
EmailServiceDataHolder.getInstance().getEmailServiceProvider().sendEmail(emailMessageProperties);
} }
@Override @Override
public void sendRegistrationEmail(EmailMessageProperties emailMessageProperties) throws DeviceManagementException { public void sendRegistrationEmail(EmailContext emailCtx) throws DeviceManagementException {
List<NotificationMessages> notificationMessages = Map<String, TypedValue<Class<?>, Object>> params = new HashMap<>();
DeviceConfigurationManager.getInstance().getNotificationMessagesConfig().getNotificationMessagesList(); EmailConfigurations emailConfig =
String messageHeader = ""; DeviceConfigurationManager.getInstance().getDeviceManagementConfig().
String messageBody = ""; getDeviceManagementConfigRepository().getEmailConfigurations();
String messageFooter1 = ""; params.put(EmailConstants.FIRST_NAME,
String messageFooter2 = ""; new TypedValue<Class<?>, Object>(String.class, emailCtx.getProperty("first-name")));
String messageFooter3 = ""; params.put(EmailConstants.DOWNLOAD_URL,
String url = ""; new TypedValue<Class<?>, Object>(String.class,
String subject = ""; emailConfig.getlBHostPortPrefix() + emailConfig.getEnrollmentContextPath()));
params.put(EmailConstants.USERNAME,
for (NotificationMessages notificationMessage : notificationMessages) { new TypedValue<Class<?>, Object>(String.class, emailCtx.getProperty("username")));
if (org.wso2.carbon.device.mgt.core.DeviceManagementConstants.EmailNotifications. params.put(EmailConstants.PASSWORD,
USER_REGISTRATION_NOTIFICATION_TYPE.equals(notificationMessage.getType())) { new TypedValue<Class<?>, Object>(String.class, emailCtx.getProperty("password")));
messageHeader = notificationMessage.getHeader(); params.put(EmailConstants.DOMAIN,
messageBody = notificationMessage.getBody(); new TypedValue<Class<?>, Object>(String.class, emailCtx.getProperty("domain")));
messageFooter1 = notificationMessage.getFooterLine1();
messageFooter2 = notificationMessage.getFooterLine2();
messageFooter3 = notificationMessage.getFooterLine3();
url = notificationMessage.getUrl();
subject = notificationMessage.getSubject();
break;
}
}
StringBuilder messageBuilder = new StringBuilder();
try { try {
// Reading the download url from the cdm-config.xml file EmailData data = contentProvider.getContent("user-registration", params);
EmailConfigurations emailConfig = EmailServiceDataHolder.getInstance().getEmailServiceProvider().sendEmail(emailCtx.getRecipients(), data);
DeviceConfigurationManager.getInstance().getDeviceManagementConfig(). } catch (ContentProcessingInterruptedException e) {
getDeviceManagementConfigRepository().getEmailConfigurations(); throw new DeviceManagementException("Error occurred while processing contents of the " +
emailMessageProperties.setEnrolmentUrl(emailConfig.getlBHostPortPrefix() + "enrollment invitation", e);
emailConfig.getEnrollmentContextPath()); } catch (EmailSendingFailedException e) {
messageHeader = messageHeader.replaceAll("\\{" + EmailConstants.EnrolmentEmailConstants.FIRST_NAME + "\\}", throw new DeviceManagementException("Error occurred while sending user registration notification", e);
URLEncoder.encode(emailMessageProperties.getFirstName(),
EmailConstants.EnrolmentEmailConstants.ENCODED_SCHEME));
messageBody = messageBody.trim().replaceAll("\\{" + EmailConstants.EnrolmentEmailConstants
.USERNAME
+ "\\}",
URLEncoder.encode(emailMessageProperties.getUserName(), EmailConstants.EnrolmentEmailConstants
.ENCODED_SCHEME));
messageBody = messageBody.trim().replaceAll("\\{" + EmailConstants.EnrolmentEmailConstants.DOMAIN
+ "\\}",
URLEncoder.encode(emailMessageProperties.getDomainName(), EmailConstants.EnrolmentEmailConstants
.ENCODED_SCHEME));
messageBody = messageBody.replaceAll("\\{" + EmailConstants.EnrolmentEmailConstants.PASSWORD + "\\}",
URLEncoder.encode(emailMessageProperties.getPassword(), EmailConstants.EnrolmentEmailConstants
.ENCODED_SCHEME));
messageBody = messageBody + System.getProperty("line.separator") + url.replaceAll("\\{"
+ EmailConstants.EnrolmentEmailConstants.DOWNLOAD_URL + "\\}",
URLDecoder.decode(emailMessageProperties.getEnrolmentUrl(),
EmailConstants.EnrolmentEmailConstants.ENCODED_SCHEME));
messageBuilder.append(messageHeader).append(System.getProperty("line.separator"));
messageBuilder.append(messageBody).append(System.getProperty("line.separator")).append(
messageFooter1.trim());
messageBuilder.append(System.getProperty("line.separator")).append(messageFooter2.trim());
messageBuilder.append(System.getProperty("line.separator")).append(messageFooter3.trim());
} catch (IOException e) {
throw new DeviceManagementException("Error replacing tags in email template '" +
emailMessageProperties.getSubject() + "'", e);
} }
emailMessageProperties.setMessageBody(messageBuilder.toString());
emailMessageProperties.setSubject(subject);
EmailServiceDataHolder.getInstance().getEmailServiceProvider().sendEmail(emailMessageProperties);
} }
@Override @Override

@ -17,11 +17,13 @@
*/ */
package org.wso2.carbon.device.mgt.core.service; package org.wso2.carbon.device.mgt.core.service;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.core.email.EmailData;
import org.wso2.carbon.device.mgt.common.EmailMessageProperties; import org.wso2.carbon.device.mgt.core.email.EmailSendingFailedException;
import java.util.Set;
public interface EmailService { public interface EmailService {
public void sendEmail(EmailMessageProperties emailMessageProperties) throws DeviceManagementException; void sendEmail(Set<String> recipients, EmailData emailData) throws EmailSendingFailedException;
} }

@ -18,14 +18,17 @@
package org.wso2.carbon.device.mgt.core.service; package org.wso2.carbon.device.mgt.core.service;
import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.core.email.EmailData;
import org.wso2.carbon.device.mgt.common.EmailMessageProperties; import org.wso2.carbon.device.mgt.core.email.EmailSendingFailedException;
import org.wso2.carbon.device.mgt.core.internal.EmailServiceDataHolder; import org.wso2.carbon.device.mgt.core.internal.EmailServiceDataHolder;
public class EmailServiceImpl implements EmailService{ import java.util.Set;
public class EmailServiceImpl implements EmailService {
@Override @Override
public void sendEmail(EmailMessageProperties emailMessageProperties) throws DeviceManagementException { public void sendEmail(Set<String> recipients, EmailData emailData) throws EmailSendingFailedException {
EmailServiceDataHolder.getInstance().getEmailServiceProvider().sendEmail(emailMessageProperties); EmailServiceDataHolder.getInstance().getEmailServiceProvider().sendEmail(recipients, emailData);
} }
} }

@ -1278,7 +1278,16 @@
<artifactId>commons-httpclient</artifactId> <artifactId>commons-httpclient</artifactId>
<version>${commons.httpclient.version}</version> <version>${commons.httpclient.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
</dependency>
<dependency>
<groupId>commons-io.wso2</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -1581,7 +1590,8 @@
<commons.pool.wso2.version>1.5.6.wso2v1</commons.pool.wso2.version> <commons.pool.wso2.version>1.5.6.wso2v1</commons.pool.wso2.version>
<httpcomponents.httpclient.version>4.2.3.wso2v1</httpcomponents.httpclient.version> <httpcomponents.httpclient.version>4.2.3.wso2v1</httpcomponents.httpclient.version>
<commons.httpclient.version>3.1.0.wso2v2</commons.httpclient.version> <commons.httpclient.version>3.1.0.wso2v2</commons.httpclient.version>
<velocity.version>1.7</velocity.version>
<commons-io.version>2.4.0.wso2v1</commons-io.version>
</properties> </properties>
</project> </project>

Loading…
Cancel
Save