/*
* Copyright (c) 2005-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.inbound.endpoint.ext.wsrm.invoker;
import org.apache.cxf.continuations.Continuation;
import org.apache.cxf.continuations.ContinuationProvider;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.service.invoker.AbstractInvoker;
import org.apache.log4j.Logger;
import org.wso2.carbon.inbound.endpoint.ext.wsrm.InboundRMResponseSender;
import org.wso2.carbon.inbound.endpoint.ext.wsrm.RMRequestCallable;
import org.wso2.carbon.inbound.endpoint.ext.wsrm.utils.RMConstants;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
/**
* After the RM protocol messages are processed, the request is processed here
*/
public class InboundRMHttpInvoker extends AbstractInvoker {
private static Logger logger = Logger.getLogger(InboundRMHttpInvoker.class);
private String injectingSequence;
private String onErrorSequence;
private ExecutorService executorService;
private InboundRMResponseSender inboundRMResponseSender;
private Object bean;
/**
* Constructor for the invoker
*
* @param bean An instance of the backend business logic implementing class
* @param injectingSequence The injecting sequence name
* @param onErrorSequence The fault sequence name
*/
public InboundRMHttpInvoker(Object bean, String injectingSequence, String onErrorSequence) {
this.injectingSequence = injectingSequence;
this.onErrorSequence = onErrorSequence;
this.bean = bean;
inboundRMResponseSender = new InboundRMResponseSender();
setExecutorService(Executors.newFixedThreadPool(RMConstants.THREAD_POOL_SIZE));
}
@Override
public Object getServiceObject(Exchange exchange) {
return bean;
}
/**
* This is where the the incoming request from the CXF Bus is paused and handed to Synapse
*
* @param exchange exchange that contains the messages
* @param o the dummy back end object
* @return null
*/
@Override
public Object invoke(Exchange exchange, Object o) {
ContinuationProvider continuationProvider = (ContinuationProvider) exchange.getInMessage().get(ContinuationProvider.class.getName());
final Continuation continuation = continuationProvider.getContinuation();
synchronized (continuation) {
if (continuation.isNew()) {
/*
* This is a new request
* execute a task asynchronously
*/
FutureTask<Boolean> futureTask = new FutureTask<Boolean>(new RMRequestCallable(exchange, continuation,
injectingSequence,
onErrorSequence,
inboundRMResponseSender));
continuation.setObject(futureTask);
continuation.suspend(0);
getExecutorService().execute(futureTask);
} else {
FutureTask futureTask = (FutureTask) continuation.getObject();
if (futureTask.isDone()) {
try {
return futureTask.get();
} catch (Exception e) {
logger.error("Error occurred while waiting for the response through Synapse", e);
}
} else {
continuation.suspend(0);
}
}
}
return null;
}
public ExecutorService getExecutorService() {
return executorService;
}
public final void setExecutorService(ExecutorService executorService) {
this.executorService = executorService;
}
}