/* * 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.mock; import com.eviware.soapui.SoapUI; import com.eviware.soapui.config.AttachmentConfig; import com.eviware.soapui.config.MockResponseConfig; import com.eviware.soapui.impl.support.AbstractMockResponse; import com.eviware.soapui.impl.wsdl.HttpAttachmentPart; import com.eviware.soapui.impl.wsdl.WsdlContentPart; import com.eviware.soapui.impl.wsdl.WsdlHeaderPart; import com.eviware.soapui.impl.wsdl.WsdlOperation; import com.eviware.soapui.impl.wsdl.submit.filters.RemoveEmptyContentRequestFilter; import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils; import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.BodyPartAttachment; import com.eviware.soapui.impl.wsdl.support.CompressedStringSupport; import com.eviware.soapui.impl.wsdl.support.FileAttachment; import com.eviware.soapui.impl.wsdl.support.HelpUrls; import com.eviware.soapui.impl.wsdl.support.IconAnimator; import com.eviware.soapui.impl.wsdl.support.MockFileAttachment; import com.eviware.soapui.impl.wsdl.support.WsdlAttachment; import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils; import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion; import com.eviware.soapui.impl.wsdl.support.wsa.WsaConfig; import com.eviware.soapui.impl.wsdl.support.wsa.WsaContainer; import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils; import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext; import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils; import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils.SoapHeader; import com.eviware.soapui.impl.wsdl.support.wss.OutgoingWss; import com.eviware.soapui.model.ModelItem; import com.eviware.soapui.model.iface.Attachment; import com.eviware.soapui.model.iface.Attachment.AttachmentEncoding; import com.eviware.soapui.model.iface.MessagePart; import com.eviware.soapui.model.iface.Operation; import com.eviware.soapui.model.mock.MockRequest; import com.eviware.soapui.model.propertyexpansion.PropertyExpansion; import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils; import com.eviware.soapui.settings.CommonSettings; import com.eviware.soapui.settings.WsdlSettings; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.Tools; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.types.StringToStringsMap; import com.eviware.soapui.support.xml.XmlUtils; import org.apache.commons.httpclient.HttpStatus; import org.apache.log4j.Logger; import org.apache.ws.security.WSSecurityException; import org.apache.xmlbeans.SchemaGlobalElement; import org.apache.xmlbeans.SchemaType; import org.apache.xmlbeans.XmlException; import org.w3c.dom.Document; import javax.swing.ImageIcon; import javax.wsdl.BindingOperation; import javax.wsdl.BindingOutput; import javax.wsdl.Message; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; /** * A WsdlMockResponse contained by a WsdlMockOperation * * @author ole.matzura */ public class WsdlMockResponse extends AbstractMockResponse<MockResponseConfig> implements WsaContainer { private final static Logger log = Logger.getLogger(WsdlMockResponse.class); public final static String MOCKRESULT_PROPERTY = WsdlMockResponse.class.getName() + "@mockresult"; public final static String HEADERS_PROPERTY = WsdlMockResponse.class.getName() + "@headers"; public final static String DISABLE_MULTIPART_ATTACHMENTS = WsdlMockResponse.class.getName() + "@disable-multipart-attachments"; public static final String FORCE_MTOM = WsdlMockResponse.class.getName() + "@force_mtom"; public static final String ENABLE_INLINE_FILES = WsdlMockResponse.class.getName() + "@enable_inline_files"; public final static String RESPONSE_DELAY_PROPERTY = WsdlMockResponse.class.getName() + "@response-delay"; public static final String STRIP_WHITESPACES = WsdlMockResponse.class.getName() + "@strip-whitespaces"; public static final String REMOVE_EMPTY_CONTENT = WsdlMockResponse.class.getName() + "@remove_empty_content"; public static final String ENCODE_ATTACHMENTS = WsdlMockResponse.class.getName() + "@encode_attachments"; public static final String OUGOING_WSS = WsdlMockResponse.class.getName() + "@outgoing-wss"; public static final String ICON_NAME = "/mockResponse.gif"; protected List<FileAttachment<WsdlMockResponse>> attachments = new ArrayList<FileAttachment<WsdlMockResponse>>(); private List<HttpAttachmentPart> definedAttachmentParts; private IconAnimator<WsdlMockResponse> iconAnimator; private WsaConfig wsaConfig; public WsdlMockResponse(WsdlMockOperation operation, MockResponseConfig config) { super(config, operation, ICON_NAME); for (AttachmentConfig ac : getConfig().getAttachmentList()) { attachments.add(new MockFileAttachment(ac, this)); } if (!config.isSetEncoding()) { config.setEncoding("UTF-8"); } iconAnimator = new IconAnimator<WsdlMockResponse>(this, "/mockResponse.gif", "/exec_request.png", 4); } @Override public void setConfig(MockResponseConfig config) { super.setConfig(config); if (wsaConfig != null) { if (config.isSetWsaConfig()) { wsaConfig.setConfig(config.getWsaConfig()); } else { wsaConfig = null; } } } public Attachment[] getAttachments() { return attachments.toArray(new Attachment[attachments.size()]); } protected String getContentType(Operation operation, String encoding) { SoapVersion soapVersion = ((WsdlOperation) operation).getInterface().getSoapVersion(); return soapVersion.getContentTypeHttpHeader(encoding, null); } @Override public ImageIcon getIcon() { return iconAnimator.getIcon(); } public WsdlMockOperation getMockOperation() { return (WsdlMockOperation) getParent(); } @Override public String getScriptHelpUrl() { return HelpUrls.MOCKRESPONSE_SCRIPT_HELP_URL; } public MessagePart[] getRequestParts() { try { List<MessagePart> result = new ArrayList<MessagePart>(); result.addAll(Arrays.asList(getMockOperation().getOperation().getDefaultRequestParts())); if (getMockResult() != null) { result.addAll(AttachmentUtils.extractAttachmentParts((WsdlOperation) getMockOperation().getOperation(), getMockResult() .getMockRequest().getRequestContent(), true, false, isMtomEnabled())); } return result.toArray(new MessagePart[result.size()]); } catch (Exception e) { SoapUI.logError(e); return new MessagePart[0]; } } public MessagePart[] getResponseParts() { try { // init WsdlOperation op = (WsdlOperation) getMockOperation().getOperation(); if (op == null || op.isUnidirectional()) { return new MessagePart[0]; } List<MessagePart> result = new ArrayList<MessagePart>(); WsdlContext wsdlContext = op.getInterface().getWsdlContext(); BindingOperation bindingOperation = op.findBindingOperation(wsdlContext.getDefinition()); if (bindingOperation == null) { return new MessagePart[0]; } // header parts BindingOutput bindingOutput = bindingOperation.getBindingOutput(); List<SoapHeader> headers = bindingOutput == null ? new ArrayList<SoapHeader>() : WsdlUtils .getSoapHeaders(bindingOutput.getExtensibilityElements()); for (int i = 0; i < headers.size(); i++) { SoapHeader header = headers.get(i); Message message = wsdlContext.getDefinition().getMessage(header.getMessage()); if (message == null) { log.error("Missing message for header: " + header.getMessage()); continue; } javax.wsdl.Part part = message.getPart(header.getPart()); if (part != null) { SchemaType schemaType = WsdlUtils.getSchemaTypeForPart(wsdlContext, part); SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart(wsdlContext, part); if (schemaType != null) { result.add(new WsdlHeaderPart(part.getName(), schemaType, part.getElementName(), schemaElement)); } } else { log.error("Missing part for header; " + header.getPart()); } } // content parts javax.wsdl.Part[] parts = WsdlUtils.getOutputParts(bindingOperation); for (int i = 0; i < parts.length; i++) { javax.wsdl.Part part = parts[i]; if (!WsdlUtils.isAttachmentOutputPart(part, bindingOperation)) { SchemaType schemaType = WsdlUtils.getSchemaTypeForPart(wsdlContext, part); SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart(wsdlContext, part); if (schemaType != null) { result.add(new WsdlContentPart(part.getName(), schemaType, part.getElementName(), schemaElement)); } } } result.addAll(Arrays.asList(getDefinedAttachmentParts())); return result.toArray(new MessagePart[result.size()]); } catch (Exception e) { SoapUI.logError(e); return new MessagePart[0]; } } public Attachment attachFile(File file, boolean cache) throws IOException { FileAttachment<WsdlMockResponse> fileAttachment = new MockFileAttachment(file, cache, this); attachments.add(fileAttachment); notifyPropertyChanged(ATTACHMENTS_PROPERTY, null, fileAttachment); return fileAttachment; } public int getAttachmentCount() { return attachments.size(); } public WsdlAttachment getAttachmentAt(int index) { return attachments.get(index); } public void removeAttachment(Attachment attachment) { int ix = attachments.indexOf(attachment); attachments.remove(ix); try { notifyPropertyChanged(ATTACHMENTS_PROPERTY, attachment, null); } finally { getConfig().removeAttachment(ix); } } public HttpAttachmentPart[] getDefinedAttachmentParts() { if (definedAttachmentParts == null) { try { WsdlOperation operation = (WsdlOperation) getMockOperation().getOperation(); if (operation == null) { definedAttachmentParts = new ArrayList<HttpAttachmentPart>(); } else { UISupport.setHourglassCursor(); definedAttachmentParts = AttachmentUtils.extractAttachmentParts(operation, getResponseContent(), true, true, isMtomEnabled()); } } catch (Exception e) { log.warn(e.toString()); } finally { UISupport.resetCursor(); } } return definedAttachmentParts.toArray(new HttpAttachmentPart[definedAttachmentParts.size()]); } public HttpAttachmentPart getAttachmentPart(String partName) { HttpAttachmentPart[] parts = getDefinedAttachmentParts(); for (HttpAttachmentPart part : parts) { if (part.getName().equals(partName)) { return part; } } return null; } public Attachment[] getAttachmentsForPart(String partName) { List<Attachment> result = new ArrayList<Attachment>(); for (Attachment attachment : attachments) { if (attachment.getPart().equals(partName)) { result.add(attachment); } } return result.toArray(new Attachment[result.size()]); } @Override public String getContentType() { return getContentType(getOperation(), getEncoding()); } public boolean isMtomEnabled() { return getSettings().getBoolean(WsdlSettings.ENABLE_MTOM); } public void setMtomEnabled(boolean mtomEnabled) { boolean old = isMtomEnabled(); getSettings().setBoolean(WsdlSettings.ENABLE_MTOM, mtomEnabled); definedAttachmentParts = null; notifyPropertyChanged(MTOM_NABLED_PROPERTY, old, mtomEnabled); } protected String executeSpecifics(MockRequest request, String responseContent, WsdlMockRunContext context) throws IOException, WSSecurityException { if (this.getWsaConfig().isWsaEnabled()) { WsdlOperation operation = getMockOperation().getOperation(); WsaUtils wsaUtils = new WsaUtils(responseContent, getSoapVersion(), operation, context); responseContent = wsaUtils.addWSAddressingMockResponse(this, (WsdlMockRequest) request); } String outgoingWss = getOutgoingWss(); if (StringUtils.isNullOrEmpty(outgoingWss)) { outgoingWss = getMockOperation().getMockService().getOutgoingWss(); } if (StringUtils.hasContent(outgoingWss)) { OutgoingWss outgoing = getMockOperation().getMockService().getProject().getWssContainer() .getOutgoingWssByName(outgoingWss); if (outgoing != null) { Document dom = XmlUtils.parseXml(responseContent); outgoing.processOutgoing(dom, context); StringWriter writer = new StringWriter(); XmlUtils.serialize(dom, writer); responseContent = writer.toString(); } } return responseContent; } @SuppressWarnings("unchecked") public Attachment addAttachment(Attachment attachment) { if (attachment instanceof BodyPartAttachment) { try { BodyPartAttachment att = (BodyPartAttachment) attachment; AttachmentConfig newConfig = getConfig().addNewAttachment(); newConfig.setData(Tools.readAll(att.getInputStream(), 0).toByteArray()); newConfig.setContentId(att.getContentID()); newConfig.setContentType(att.getContentType()); newConfig.setName(att.getName()); FileAttachment<WsdlMockResponse> newAttachment = new MockFileAttachment(newConfig, this); attachments.add(newAttachment); return newAttachment; } catch (Exception e) { SoapUI.logError(e); } } else if (attachment instanceof FileAttachment) { AttachmentConfig oldConfig = ((FileAttachment<WsdlMockResponse>) attachment).getConfig(); AttachmentConfig newConfig = (AttachmentConfig) getConfig().addNewAttachment().set(oldConfig); FileAttachment<WsdlMockResponse> newAttachment = new MockFileAttachment(newConfig, this); attachments.add(newAttachment); return newAttachment; } return null; } public void setResponseDelay(long delay) { long oldDelay = getResponseDelay(); if (delay == 0) { getSettings().clearSetting(RESPONSE_DELAY_PROPERTY); } else { getSettings().setLong(RESPONSE_DELAY_PROPERTY, delay); } notifyPropertyChanged(RESPONSE_DELAY_PROPERTY, oldDelay, delay); } public long getResponseDelay() { return getSettings().getLong(RESPONSE_DELAY_PROPERTY, 0); } public long getContentLength() { return getResponseContent() == null ? 0 : getResponseContent().length(); } public boolean isMultipartEnabled() { return !getSettings().getBoolean(DISABLE_MULTIPART_ATTACHMENTS); } public void setMultipartEnabled(boolean multipartEnabled) { getSettings().setBoolean(DISABLE_MULTIPART_ATTACHMENTS, multipartEnabled); } public void setEntitizeProperties(boolean entitizeProperties) { getSettings().setBoolean(CommonSettings.ENTITIZE_PROPERTIES, entitizeProperties); } public boolean isForceMtom() { return getSettings().getBoolean(FORCE_MTOM); } public void setForceMtom(boolean forceMtom) { boolean old = getSettings().getBoolean(FORCE_MTOM); getSettings().setBoolean(FORCE_MTOM, forceMtom); notifyPropertyChanged(FORCE_MTOM, old, forceMtom); } protected String removeEmptyContent(String responseContent) { if (isRemoveEmptyContent()) { responseContent = RemoveEmptyContentRequestFilter.removeEmptyContent(responseContent, getSoapVersion() .getEnvelopeNamespace(), true); } return responseContent; } @Override public void setResponseContent(String responseContent) { super.setResponseContent(responseContent); handleFault(responseContent); } private void handleFault(String responseContent) { try { if (SoapUtils.isSoapFault(responseContent)) { setResponseHttpStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); } } catch (XmlException e) { SoapUI.logError(e); } } public boolean isRemoveEmptyContent() { return getSettings().getBoolean(REMOVE_EMPTY_CONTENT); } public void setRemoveEmptyContent(boolean removeEmptyContent) { boolean old = getSettings().getBoolean(REMOVE_EMPTY_CONTENT); getSettings().setBoolean(REMOVE_EMPTY_CONTENT, removeEmptyContent); notifyPropertyChanged(REMOVE_EMPTY_CONTENT, old, removeEmptyContent); } public boolean isEncodeAttachments() { return getSettings().getBoolean(ENCODE_ATTACHMENTS); } public void setEncodeAttachments(boolean encodeAttachments) { boolean old = getSettings().getBoolean(ENCODE_ATTACHMENTS); getSettings().setBoolean(ENCODE_ATTACHMENTS, encodeAttachments); notifyPropertyChanged(ENCODE_ATTACHMENTS, old, encodeAttachments); } public boolean isStripWhitespaces() { return getSettings().getBoolean(STRIP_WHITESPACES); } public void setStripWhitespaces(boolean stripWhitespaces) { boolean old = getSettings().getBoolean(STRIP_WHITESPACES); getSettings().setBoolean(STRIP_WHITESPACES, stripWhitespaces); notifyPropertyChanged(STRIP_WHITESPACES, old, stripWhitespaces); } public boolean isInlineFilesEnabled() { return getSettings().getBoolean(WsdlMockResponse.ENABLE_INLINE_FILES); } public void setInlineFilesEnabled(boolean inlineFilesEnabled) { getSettings().setBoolean(WsdlMockResponse.ENABLE_INLINE_FILES, inlineFilesEnabled); } @Override public void beforeSave() { super.beforeSave(); CompressedStringSupport.setString(getConfig().getResponseContent(), getResponseContent()); } public void addAttachmentsChangeListener(PropertyChangeListener listener) { addPropertyChangeListener(ATTACHMENTS_PROPERTY, listener); } public boolean isReadOnly() { return false; } public void removeAttachmentsChangeListener(PropertyChangeListener listener) { removePropertyChangeListener(ATTACHMENTS_PROPERTY, listener); } public SoapVersion getSoapVersion() { if( getMockOperation().getOperation() == null ) { return SoapVersion.Soap11; } return getMockOperation().getOperation().getInterface().getSoapVersion(); } public PropertyExpansion[] getPropertyExpansions() { List<PropertyExpansion> result = new ArrayList<PropertyExpansion>(); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(this, this, "responseContent")); StringToStringsMap responseHeaders = getResponseHeaders(); for (Map.Entry<String, List<String>> headerEntry : responseHeaders.entrySet()) { for (String value : headerEntry.getValue()) { result.addAll(PropertyExpansionUtils.extractPropertyExpansions(this, new ResponseHeaderHolder(headerEntry.getKey(), value, this), "value")); } } addWsaPropertyExpansions(result, getWsaConfig(), this); return result.toArray(new PropertyExpansion[result.size()]); } public void addWsaPropertyExpansions(List<PropertyExpansion> result, WsaConfig wsaConfig, ModelItem modelItem) { result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "action")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "from")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "to")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "replyTo")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "replyToRefParams")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "faultTo")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "faultToRefParams")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "relatesTo")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "relationshipType")); result.addAll(PropertyExpansionUtils.extractPropertyExpansions(modelItem, wsaConfig, "messageID")); } public static class ResponseHeaderHolder { private final String key; private final String oldValue; private WsdlMockResponse mockResponse; public ResponseHeaderHolder(String key, String oldValue, WsdlMockResponse mockResponse) { this.key = key; this.oldValue = oldValue; this.mockResponse = mockResponse; } public String getValue() { return oldValue; } public void setValue(String value) { StringToStringsMap valueMap = mockResponse.getResponseHeaders(); valueMap.replace(key, oldValue, value); mockResponse.setResponseHeaders(valueMap); } } public String getOutgoingWss() { return getConfig().getOutgoingWss(); } public void setOutgoingWss(String outgoingWss) { String old = getOutgoingWss(); getConfig().setOutgoingWss(outgoingWss); notifyPropertyChanged(OUGOING_WSS, old, outgoingWss); } public String getPropertiesLabel() { return "Custom Properties"; } public AttachmentEncoding getAttachmentEncoding(String partName) { HttpAttachmentPart attachmentPart = getAttachmentPart(partName); if (attachmentPart == null) { return AttachmentUtils.getAttachmentEncoding(getOperation(), partName, true); } else { return AttachmentUtils.getAttachmentEncoding(getOperation(), attachmentPart, true); } } public WsaConfig getWsaConfig() { if (wsaConfig == null) { if (!getConfig().isSetWsaConfig()) { getConfig().addNewWsaConfig(); } wsaConfig = new WsaConfig(getConfig().getWsaConfig(), this); // wsaConfig.setGenerateMessageId(true); } return wsaConfig; } public boolean isWsAddressing() { return getConfig().getUseWsAddressing(); } public void setWsAddressing(boolean wsAddressing) { boolean old = getConfig().getUseWsAddressing(); getConfig().setUseWsAddressing(wsAddressing); notifyPropertyChanged("wsAddressing", old, wsAddressing); } public boolean isWsaEnabled() { return isWsAddressing(); } public void setWsaEnabled(boolean arg0) { setWsAddressing(arg0); } public WsdlOperation getOperation() { return ((WsdlMockOperation) getMockOperation()).getOperation(); } public void setOperation(WsdlOperation operation) { ((WsdlMockOperation) getMockOperation()).setOperation(operation); } protected String mockresultProperty() { return MOCKRESULT_PROPERTY; } }