/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.wsdl; import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.support.AbstractHttpRequestInterface; import com.eviware.soapui.impl.wsdl.submit.RequestTransport; import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport; import com.eviware.soapui.model.iface.Response; import com.eviware.soapui.model.iface.Submit; import com.eviware.soapui.model.iface.SubmitContext; import com.eviware.soapui.model.iface.SubmitListener; import org.apache.log4j.Logger; import java.util.List; import java.util.concurrent.Future; /** * Submit implementation for submitting a WsdlRequest * * @author Ole.Matzura */ public final class WsdlSubmit<T extends AbstractHttpRequestInterface<?>> implements Runnable, Submit { private final static Logger logger = Logger.getLogger(WsdlSubmit.class); private T request; private SubmitListener[] listeners; private Status status; private Exception error; private Response response; private volatile Future<?> future; private SubmitContext submitContext; private RequestTransport transport; public WsdlSubmit(T wsdlRequest, SubmitListener[] listeners, RequestTransport transport) { this.request = wsdlRequest; this.transport = transport; List<SubmitListener> regListeners = SoapUI.getListenerRegistry().getListeners(SubmitListener.class); this.listeners = new SubmitListener[listeners.length + regListeners.size()]; for (int c = 0; c < listeners.length; c++) { this.listeners[c] = listeners[c]; } for (int c = 0; c < regListeners.size(); c++) { this.listeners[listeners.length + c] = regListeners.get(c); } error = null; status = Status.INITIALIZED; future = null; } public void submitRequest(SubmitContext submitContext, boolean async) { this.submitContext = submitContext; if (async && future != null) { throw new RuntimeException("Submit already running"); } if (async) { future = SoapUI.getThreadPool().submit(this); } else { run(); } } public void cancel() { if (status == Status.CANCELED) { return; } logger.info("Canceling request..."); if (status == Status.RUNNING) { transport.abortRequest(submitContext); } status = Status.CANCELED; notifyListenersAfterSubmit(); } private void notifyListenersAfterSubmit() { for (SubmitListener listener : listeners) { try { listener.afterSubmit(this, submitContext); } catch (Throwable e) { //NOSONAR SoapUI.logError(e); } } } public void run() { try { submitContext.setProperty(RequestTransport.REQUEST_TRANSPORT, transport); submitContext.setProperty(RequestTransport.WSDL_REQUEST, request); boolean shouldAbort = notifyListenersBeforeSubmit(); if (shouldAbort) { return; } status = Status.RUNNING; response = transport.sendRequest(submitContext, request); if (status != Status.CANCELED) { status = Status.FINISHED; } if (response != null) { if (response.getTimeTaken() == 0) { logger.warn("Request took 0 in thread " + Thread.currentThread().getId() + ", response length = " + response.getContentLength()); } } else { logger.warn("Request does not have a response"); } } catch (Exception e1) { error = e1; if (status != Status.CANCELED) { status = Status.ERROR; logger.error("Exception in request: " + e1); SoapUI.logError(e1); } if (response == null) { response = (Response) submitContext.getProperty(BaseHttpRequestTransport.RESPONSE); } } finally { if (status != Status.CANCELED) { notifyListenersAfterSubmit(); } } } private boolean notifyListenersBeforeSubmit() { for (SubmitListener listener : listeners) { try { if (!listener.beforeSubmit(this, submitContext)) { status = Status.CANCELED; System.err.println("listener cancelled submit..."); return true; } } catch (Throwable e) { SoapUI.logError(e, "Error in SubmitListener"); } } return false; } public T getRequest() { return request; } public Status getStatus() { return status; } public Exception getError() { return error; } public synchronized Status waitUntilFinished() { if (future != null) { if (!future.isDone()) { try { future.get(); } catch (Exception e) { SoapUI.logError(e); } } } else { throw new RuntimeException("cannot wait on null future"); } return getStatus(); } public Response getResponse() { return response; } }