337 lines
12 KiB
Java
Executable File
337 lines
12 KiB
Java
Executable File
/*
|
|
* BEGIN_HEADER - DO NOT EDIT
|
|
*
|
|
* The contents of this file are subject to the terms
|
|
* of the Common Development and Distribution License
|
|
* (the "License"). You may not use this file except
|
|
* in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at
|
|
* https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
|
|
* See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL
|
|
* HEADER in each file and include the License file at
|
|
* https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
|
|
* If applicable add the following below this CDDL HEADER,
|
|
* with the fields enclosed by brackets "[]" replaced with
|
|
* your own identifying information: Portions Copyright
|
|
* [year] [name of copyright owner]
|
|
*/
|
|
|
|
/*
|
|
* @(#)InboundReceiver.java
|
|
*
|
|
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
*
|
|
* END_HEADER - DO NOT EDIT
|
|
*/
|
|
|
|
package com.sun.jbi.jdbcbc;
|
|
|
|
import com.sun.jbi.common.qos.messaging.MessagingChannel;
|
|
import com.sun.jbi.internationalization.Messages;
|
|
import com.sun.jbi.jdbcbc.extensions.JDBCOperationInput;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import javax.jbi.component.ComponentContext;
|
|
import javax.jbi.messaging.*;
|
|
import javax.management.AttributeChangeNotification;
|
|
import javax.management.Notification;
|
|
import javax.management.NotificationListener;
|
|
import javax.wsdl.Binding;
|
|
import javax.wsdl.BindingInput;
|
|
import javax.wsdl.BindingOperation;
|
|
import javax.wsdl.Definition;
|
|
import javax.wsdl.Port;
|
|
import javax.wsdl.Service;
|
|
import javax.wsdl.extensions.ExtensibilityElement;
|
|
import javax.xml.namespace.QName;
|
|
|
|
|
|
/**
|
|
* Wait for responses/requests from the service engine and
|
|
* use thread pools to process them.
|
|
*
|
|
* Thir receiver not only processes "Inbound" requests initiated by the
|
|
* Service engine, but also responses to requests this adapter has sent the SE.
|
|
*/
|
|
class InboundReceiver {
|
|
private static final Messages mMessages = Messages.getMessages(InboundReceiver.class);
|
|
private static final Logger mLogger = Messages.getLogger(InboundReceiver.class);
|
|
|
|
// Pool settings for processing SE "Inbound" requests initated by the SE.
|
|
private int mInboundCorePoolSize;
|
|
private final int mInboundKeepAliveTime = 60 * 10;
|
|
private final TimeUnit mInboundTimeUnit = TimeUnit.SECONDS;
|
|
|
|
// By using an unbounded queue the max pool size becomes irrelevant
|
|
private final int mInboundMaxPoolSize = Integer.MAX_VALUE;
|
|
private ThreadPoolExecutor mInboundPooledExecutor;
|
|
private final MessagingChannel mChannel;
|
|
private final ComponentContext mContext;
|
|
|
|
// This is removed since never used
|
|
//private final Map mEndpoints;
|
|
private final Map<String,InboundMessageProcessor> mActivatedInboundMsgProcs;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
private final NotificationListener listener = new NotificationListener() {
|
|
//@Override
|
|
public void handleNotification(Notification notification, Object obj) {
|
|
if (notification instanceof AttributeChangeNotification) {
|
|
AttributeChangeNotification attrNotif = (AttributeChangeNotification) notification;
|
|
String attrName = attrNotif.getAttributeName();
|
|
|
|
if (attrName.equals("Threads")) {
|
|
Integer newVal = (Integer) (attrNotif.getNewValue());
|
|
setThreads(newVal.intValue());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Construct a receiver for a given binding channel and the relevant endpoints
|
|
* @param bc the binding channel to receive from
|
|
* @param endpoints EndointBean instances with information about the endpoints
|
|
*/
|
|
protected InboundReceiver(final MessagingChannel bc, final Map endpoints,
|
|
final RuntimeConfiguration runtimeConfig, final ComponentContext context) {
|
|
mChannel = bc;
|
|
mContext = context;
|
|
|
|
// Apply existing configuration
|
|
final Integer threadCount = runtimeConfig.getThreads();
|
|
|
|
if (threadCount != null) {
|
|
setThreads(threadCount.intValue());
|
|
}
|
|
|
|
// Subscribe for changes to the configuration
|
|
runtimeConfig.addNotificationListener(listener, null, null);
|
|
|
|
mInboundPooledExecutor = new ThreadPoolExecutor(mInboundCorePoolSize,
|
|
mInboundMaxPoolSize, mInboundKeepAliveTime, mInboundTimeUnit,
|
|
new LinkedBlockingQueue(), Executors.privilegedThreadFactory());
|
|
mInboundPooledExecutor.prestartAllCoreThreads();
|
|
mActivatedInboundMsgProcs = Collections.synchronizedMap(new HashMap<String,InboundMessageProcessor>());
|
|
|
|
//mEndpoints = endpoints;
|
|
}
|
|
|
|
/**
|
|
* Construct a receiver for a given binding channel and the relevant endpoints
|
|
* @param bc the binding channel to receive from
|
|
* @param endpoints EndointBean instances with information about the endpoints
|
|
*/
|
|
/*public InboundReceiver(final DeliveryChannel bc, final Map endpoints,
|
|
final SQLSERuntimeConfiguration runtimeConfig, final ComponentContext context) {
|
|
mChannel = bc;
|
|
mContext = context;
|
|
|
|
// Apply existing configuration
|
|
final Integer threadCount = runtimeConfig.getThreads();
|
|
|
|
if (threadCount != null) {
|
|
setThreads(threadCount.intValue());
|
|
}
|
|
|
|
// Subscribe for changes to the configuration
|
|
runtimeConfig.addNotificationListener(listener, null, null);
|
|
|
|
mInboundPooledExecutor = new ThreadPoolExecutor(mInboundCorePoolSize,
|
|
mInboundMaxPoolSize, mInboundKeepAliveTime, mInboundTimeUnit,
|
|
new LinkedBlockingQueue(), Executors.privilegedThreadFactory());
|
|
mInboundPooledExecutor.prestartAllCoreThreads();
|
|
mActivatedInboundMsgProcs = Collections.synchronizedMap(new HashMap());
|
|
|
|
//mEndpoints = endpoints;
|
|
}*/
|
|
|
|
/**
|
|
* Main receiver loop to process replies and requests of SEs
|
|
*/
|
|
protected void addInboundMessageProcessor(final EndpointBean endpoint)
|
|
throws FaultException, MessagingException {
|
|
synchronized (mActivatedInboundMsgProcs) {
|
|
mLogger.log(Level.INFO, mMessages.getString("SQLSE_C00601.IR_Started"));
|
|
|
|
final Definition defwsdl = (Definition) endpoint.getValueObj(EndpointBean.DESCRIPTOR);
|
|
final String serviceName = endpoint.getValue(EndpointBean.SERVICE_NAME);
|
|
final String endpointName = endpoint.getValue(EndpointBean.ENDPOINT_NAME);
|
|
|
|
List jdbcOper = new ArrayList();
|
|
jdbcOper = getJDBCOperations(defwsdl, serviceName, endpointName);
|
|
|
|
for (final Iterator it = jdbcOper.iterator(); it.hasNext();) {
|
|
final QName opname = (QName) it.next();
|
|
final String key = endpointName + serviceName + opname.toString();
|
|
|
|
if (!mActivatedInboundMsgProcs.containsKey(key)) {
|
|
try {
|
|
final InboundMessageProcessor proc = new InboundMessageProcessor(mChannel,
|
|
endpoint, mContext, opname);
|
|
final Thread task = new Thread(proc);
|
|
task.start();
|
|
// Store the thread in the map
|
|
mActivatedInboundMsgProcs.put(key, proc);
|
|
} catch (final Exception e) {
|
|
mLogger.log(Level.INFO,mMessages.getString("SQLSE_E00602.IR_Exception") +
|
|
e.getMessage());
|
|
}
|
|
}
|
|
} // for
|
|
|
|
InboundReceiver.mLogger.log(Level.INFO, InboundReceiver.mMessages.getString("SQLSE_C00603.IR_Shutdown"));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stops and removes the inbound message processor for each
|
|
* File binding operation per the given end point.
|
|
*
|
|
* @param endpoint A service end point.
|
|
*/
|
|
protected void removeInboundMessageProcessor(final EndpointBean endpoint) {
|
|
synchronized (mActivatedInboundMsgProcs) {
|
|
mLogger.log(Level.INFO, mMessages.getString("SQLSE_C00604.IR_Remove"));
|
|
|
|
final Definition defwsdl = (Definition) endpoint.getValueObj(EndpointBean.DESCRIPTOR);
|
|
final String serviceName = endpoint.getValue(EndpointBean.SERVICE_NAME);
|
|
final String endpointName = endpoint.getValue(EndpointBean.ENDPOINT_NAME);
|
|
List jdbcOper = new ArrayList();
|
|
jdbcOper = getJDBCOperations(defwsdl, serviceName, endpointName);
|
|
|
|
for (final Iterator it = jdbcOper.iterator(); it.hasNext();) {
|
|
final QName opname = (QName) it.next();
|
|
final String key = endpointName + serviceName + opname.toString();
|
|
|
|
if (mActivatedInboundMsgProcs.containsKey(key)) {
|
|
final InboundMessageProcessor proc = mActivatedInboundMsgProcs.get(key);
|
|
// Stop the inbound message processor thread
|
|
proc.stopReceiving();
|
|
// proc.deleteTableTigger(endpoint);
|
|
// Remove the thread from the map
|
|
mActivatedInboundMsgProcs.remove(key);
|
|
} // if
|
|
} // for
|
|
|
|
mLogger.log(Level.INFO, mMessages.getString("SQLSE_C00603.IR_Shutdown"));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the number or processing threads to use
|
|
*/
|
|
protected void setThreads(final int threadCount) {
|
|
mInboundCorePoolSize = threadCount;
|
|
|
|
if (mInboundPooledExecutor != null) {
|
|
mInboundPooledExecutor.setCorePoolSize(threadCount);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stop the receiver thread.
|
|
*/
|
|
protected void stopReceiving() {
|
|
mLogger.log(Level.INFO, mMessages.getString("SQLSE_C00605.IR_Stop"));
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param def
|
|
* @param serviceName
|
|
* @param endpointName
|
|
* @return
|
|
*/
|
|
protected List<QName> getJDBCOperations(final Definition def, final String serviceName,
|
|
final String endpointName) {
|
|
final List<QName> jdbcOperations = new ArrayList<QName>();
|
|
JDBCOperationInput jdbcOperationInput = null;
|
|
final Binding binding = getBinding(def, serviceName, endpointName);
|
|
|
|
if (binding != null) {
|
|
final List bindingOperations = binding.getBindingOperations();
|
|
final Iterator extIter = (bindingOperations == null) ? null
|
|
: bindingOperations.iterator();
|
|
|
|
while ((extIter != null) && extIter.hasNext()) {
|
|
final BindingOperation oper = (BindingOperation) extIter.next();
|
|
jdbcOperationInput = getJDBCOperationInput(oper.getBindingInput());
|
|
|
|
if (jdbcOperationInput.getOperationType()
|
|
.equals(JDBCOperations.OPERATION_TYPE_POLL.toString())) {
|
|
jdbcOperations.add(QName.valueOf(oper.getName()));
|
|
}
|
|
}
|
|
}
|
|
|
|
return jdbcOperations;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param def
|
|
* @param serviceName
|
|
* @param endpointName
|
|
* @return
|
|
*/
|
|
protected Binding getBinding(final Definition def, final String serviceName,
|
|
final String endpointName) {
|
|
final Service svc = def.getService(QName.valueOf(serviceName));
|
|
|
|
if (svc == null) {
|
|
return null;
|
|
}
|
|
|
|
final Port port = svc.getPort(QName.valueOf(endpointName).getLocalPart());
|
|
|
|
if (port == null) {
|
|
return null;
|
|
} else {
|
|
return port.getBinding();
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param bindingInput
|
|
* @return
|
|
*/
|
|
protected JDBCOperationInput getJDBCOperationInput(final BindingInput bindingInput) {
|
|
JDBCOperationInput operationInput = null;
|
|
|
|
final List extElems = bindingInput.getExtensibilityElements();
|
|
|
|
// Look for jdbc:input entries
|
|
final Iterator extIter = (extElems == null) ? null : extElems.iterator();
|
|
|
|
while ((extIter != null) && extIter.hasNext()) {
|
|
final ExtensibilityElement ee = (ExtensibilityElement) extIter.next();
|
|
|
|
if (JDBCOperationInput.class.isInstance(ee)) {
|
|
operationInput = (JDBCOperationInput) ee;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return operationInput;
|
|
}
|
|
}
|