/* * 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.event.output.adapter.sms; 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.transport.base.BaseConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.event.output.adapter.core.EventAdapterUtil; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapter; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterConfiguration; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; import org.wso2.carbon.event.output.adapter.core.exception.TestConnectionNotSupportedException; import org.wso2.carbon.event.output.adapter.sms.internal.ds.SMSEventAdapterServiceValueHolder; import org.wso2.carbon.event.output.adapter.sms.internal.util.SMSEventAdapterConstants; import java.util.Map; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public final class SMSEventAdapter implements OutputEventAdapter { private static final Log log = LogFactory.getLog(SMSEventAdapter.class); private OutputEventAdapterConfiguration eventAdapterConfiguration; private static ThreadPoolExecutor threadPoolExecutor; private Map<String, String> globalProperties; private int tenantId; public SMSEventAdapter(OutputEventAdapterConfiguration eventAdapterConfiguration, Map<String, String> globalProperties) { this.eventAdapterConfiguration = eventAdapterConfiguration; this.globalProperties = globalProperties; } @Override public void init() throws OutputEventAdapterException { tenantId= PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); //ThreadPoolExecutor will be assigned if it is null if (threadPoolExecutor == null) { int minThread; int maxThread; long defaultKeepAliveTime; //If global properties are available those will be assigned else constant values will be assigned if (globalProperties.get(SMSEventAdapterConstants.MIN_THREAD_NAME) != null) { minThread = Integer.parseInt(globalProperties.get(SMSEventAdapterConstants.MIN_THREAD_NAME)); } else { minThread = SMSEventAdapterConstants.MIN_THREAD; } if (globalProperties.get(SMSEventAdapterConstants.MAX_THREAD_NAME) != null) { maxThread = Integer.parseInt(globalProperties.get(SMSEventAdapterConstants.MAX_THREAD_NAME)); } else { maxThread = SMSEventAdapterConstants.MAX_THREAD; } if (globalProperties.get(SMSEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_NAME) != null) { defaultKeepAliveTime = Integer.parseInt(globalProperties.get( SMSEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME_NAME)); } else { defaultKeepAliveTime = SMSEventAdapterConstants.DEFAULT_KEEP_ALIVE_TIME; } threadPoolExecutor = new ThreadPoolExecutor(minThread, maxThread, defaultKeepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1000)); } } @Override public void testConnect() throws TestConnectionNotSupportedException { throw new TestConnectionNotSupportedException("Test connection is not available"); } @Override public void connect() { //not applicable. } @Override public void publish(Object message, Map<String, String> dynamicProperties) { String smsNos = dynamicProperties.get(SMSEventAdapterConstants.ADAPTER_MESSAGE_SMS_NO); if (smsNos != null) { String[] smsNoArray = smsNos.replaceAll(" ", "").split(SMSEventAdapterConstants.SMS_SEPARATOR); //Send sms for each sms no for (String smsNo : smsNoArray) { try { threadPoolExecutor.submit(new SMSSender(smsNo, message.toString())); } catch (RejectedExecutionException e) { EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, "Job queue is full", e, log, tenantId); } } } } @Override public void disconnect() { //Not applicable. } @Override public void destroy() { //Not required. } @Override public boolean isPolled() { return false; } class SMSSender implements Runnable { String smsNo; String message; SMSSender(String smsNo, String message) { this.smsNo = smsNo; this.message = message; } @Override public void run() { OMElement payload = OMAbstractFactory.getOMFactory().createOMElement( BaseConstants.DEFAULT_TEXT_WRAPPER, null); payload.setText(message); ServiceClient serviceClient = null; try { ConfigurationContext configContext = SMSEventAdapterServiceValueHolder.getConfigurationContextService().getClientConfigContext(); if (configContext != null) { serviceClient = new ServiceClient(configContext, null); } else { serviceClient = new ServiceClient(); } Options options = new Options(); options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE); options.setTo(new EndpointReference("sms://" + smsNo)); serviceClient.setOptions(options); serviceClient.fireAndForget(payload); if (log.isDebugEnabled()) { log.debug("Sending SMS to " + smsNo + " , message : " + message); } } catch (Exception ex) { EventAdapterUtil.logAndDrop(eventAdapterConfiguration.getName(), message, "Cannot send to '" + smsNo + "'", ex, log, tenantId); } finally { if (serviceClient != null) { try { serviceClient.cleanup(); } catch (AxisFault axisFault) { log.error("Error while cleaning-up service client resources at Output SMS Adapter '" + eventAdapterConfiguration.getName() + "'", axisFault); } } } } } }