use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.
the class HttpProtocol method recv_internal.
@Override
public CommMessage recv_internal(InputStream istream, OutputStream ostream) throws IOException {
HttpMessage message = new HttpParser(istream).parse();
String charset = HttpUtils.getCharset(null, message);
CommMessage retVal = null;
DecodedMessage decodedMessage = new DecodedMessage();
HttpUtils.recv_checkForChannelClosing(message, channel());
if (checkBooleanParameter(Parameters.DEBUG)) {
boolean showContent = false;
if (getParameterFirstValue(Parameters.DEBUG).getFirstChild("showContent").intValue() > 0 && message.size() > 0) {
showContent = true;
}
Interpreter.getInstance().logInfo(getDebugMessage(message, charset, showContent));
}
// tracer
Interpreter.getInstance().tracer().trace(() -> {
try {
final String traceMessage = getDebugMessage(message, charset, message.size() > 0);
return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE RECEIVED", message.requestPath(), traceMessage, null);
} catch (IOException e) {
return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE RECEIVED", message.requestPath(), e.getMessage(), null);
}
});
recv_checkForStatusCode(message);
encoding = message.getProperty("accept-encoding");
headRequest = inInputPort && message.isHead();
String contentType = DEFAULT_CONTENT_TYPE;
if (message.getProperty("content-type") != null) {
contentType = message.getProperty("content-type").split(";", 2)[0].toLowerCase();
}
// URI parameter parsing
if (message.requestPath() != null) {
boolean strictEncoding = checkStringParameter(Parameters.JSON_ENCODING, "strict");
recv_parseQueryString(message, decodedMessage.value, contentType, strictEncoding);
}
recv_parseRequestFormat(contentType);
if (!message.isResponse()) {
recv_checkReceivingOperation(message, decodedMessage);
}
/* https://tools.ietf.org/html/rfc7231#section-4.3 */
if (!message.isGet() && !message.isHead()) {
// body parsing
if (message.size() > 0) {
recv_parseMessage(message, decodedMessage, contentType, charset);
}
}
if (!message.isResponse()) {
recv_checkDefaultOp(message, decodedMessage);
}
if (checkBooleanParameter(Parameters.CONCURRENT)) {
String messageId = message.getProperty(Headers.JOLIE_MESSAGE_ID);
if (messageId != null) {
try {
decodedMessage.id = Long.parseLong(messageId);
} catch (NumberFormatException e) {
}
}
}
if (message.isResponse()) {
String responseHeader = "";
if (hasParameter(Parameters.RESPONSE_HEADER) || hasOperationSpecificParameter(inputId, Parameters.RESPONSE_HEADER)) {
if (hasOperationSpecificParameter(inputId, Parameters.RESPONSE_HEADER)) {
responseHeader = getOperationSpecificStringParameter(inputId, Parameters.RESPONSE_HEADER);
} else {
responseHeader = getStringParameter(Parameters.RESPONSE_HEADER);
}
for (Entry<String, String> param : message.properties()) {
decodedMessage.value.getFirstChild(responseHeader).getFirstChild(param.getKey()).setValue(param.getValue());
}
decodedMessage.value.getFirstChild(responseHeader).getFirstChild(Parameters.STATUS_CODE).setValue(message.statusCode());
}
recv_checkForSetCookie(message, decodedMessage.value);
retVal = new CommMessage(decodedMessage.id, inputId, decodedMessage.resourcePath, decodedMessage.value, null);
} else if (message.isError() == false) {
recv_checkForMessageProperties(message, decodedMessage);
retVal = new CommMessage(decodedMessage.id, decodedMessage.operationName, decodedMessage.resourcePath, decodedMessage.value, null);
}
if (retVal != null && "/".equals(retVal.resourcePath()) && channel().parentPort() != null && (channel().parentPort().getInterface().containsOperation(retVal.operationName()) || (channel().parentInputPort() != null && channel().parentInputPort().getAggregatedOperation(retVal.operationName()) != null))) {
try {
// The message is for this service
boolean hasInput = false;
OneWayTypeDescription oneWayTypeDescription = null;
if (channel().parentInputPort() != null) {
if (channel().parentInputPort().getAggregatedOperation(retVal.operationName()) != null) {
oneWayTypeDescription = channel().parentInputPort().getAggregatedOperation(retVal.operationName()).getOperationTypeDescription().asOneWayTypeDescription();
hasInput = true;
}
}
if (!hasInput) {
Interface iface = channel().parentPort().getInterface();
oneWayTypeDescription = iface.oneWayOperations().get(retVal.operationName());
}
if (oneWayTypeDescription != null) {
// We are receiving a One-Way message
oneWayTypeDescription.requestType().cast(retVal.value());
} else {
hasInput = false;
RequestResponseTypeDescription rrTypeDescription = null;
if (channel().parentInputPort() != null) {
if (channel().parentInputPort().getAggregatedOperation(retVal.operationName()) != null) {
rrTypeDescription = channel().parentInputPort().getAggregatedOperation(retVal.operationName()).getOperationTypeDescription().asRequestResponseTypeDescription();
hasInput = true;
}
}
if (!hasInput) {
Interface iface = channel().parentPort().getInterface();
rrTypeDescription = iface.requestResponseOperations().get(retVal.operationName());
}
if (retVal.isFault()) {
Type faultType = rrTypeDescription.faults().get(retVal.fault().faultName());
if (faultType != null) {
faultType.cast(retVal.value());
}
} else {
if (message.isResponse()) {
rrTypeDescription.responseType().cast(retVal.value());
} else {
rrTypeDescription.requestType().cast(retVal.value());
}
}
}
} catch (TypeCastingException e) {
// TODO: do something here?
}
}
return retVal;
}
use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.
the class HttpProtocol method send_appendGenericHeaders.
private void send_appendGenericHeaders(CommMessage message, EncodedContent encodedContent, String charset, StringBuilder headerBuilder) throws IOException {
if (!checkBooleanParameter(Parameters.KEEP_ALIVE, true)) {
if (// we may do this only in input (server) mode
inInputPort)
channel().setToBeClosed(true);
headerBuilder.append("Connection: close").append(HttpUtils.CRLF);
}
if (checkBooleanParameter(Parameters.CONCURRENT, true)) {
headerBuilder.append(Headers.JOLIE_MESSAGE_ID).append(": ").append(message.id()).append(HttpUtils.CRLF);
}
headerBuilder.append(Headers.JOLIE_RESOURCE_PATH).append(": ").append(message.resourcePath()).append(HttpUtils.CRLF);
String contentType = getStringParameter(Parameters.CONTENT_TYPE);
if (contentType.length() > 0) {
encodedContent.contentType = contentType;
}
encodedContent.contentType = encodedContent.contentType.toLowerCase();
headerBuilder.append("Content-Type: ").append(encodedContent.contentType);
if (charset != null) {
headerBuilder.append("; charset=").append(charset.toLowerCase());
}
headerBuilder.append(HttpUtils.CRLF);
if (encodedContent.content != null) {
String transferEncoding = getStringParameter(Parameters.CONTENT_TRANSFER_ENCODING);
if (transferEncoding.length() > 0) {
headerBuilder.append("Content-Transfer-Encoding: ").append(transferEncoding).append(HttpUtils.CRLF);
}
String contentDisposition = getStringParameter(Parameters.CONTENT_DISPOSITION);
if (contentDisposition.length() > 0) {
encodedContent.contentDisposition = contentDisposition;
headerBuilder.append("Content-Disposition: ").append(encodedContent.contentDisposition).append(HttpUtils.CRLF);
}
boolean compression = encoding != null && checkBooleanParameter(Parameters.COMPRESSION, true);
String compressionTypes = getStringParameter(Parameters.COMPRESSION_TYPES, "text/html text/css text/plain text/xml text/x-js application/json application/javascript application/x-www-form-urlencoded application/xhtml+xml application/xml x-font/otf x-font/ttf application/x-font-ttf").toLowerCase();
if (compression && !compressionTypes.equals("*") && !compressionTypes.contains(encodedContent.contentType)) {
compression = false;
}
if (compression) {
Interpreter.getInstance().tracer().trace(() -> {
try {
final String traceMessage = encodedContent.content.toString(charset);
return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP COMPRESSING MESSAGE", message.resourcePath(), traceMessage, null);
} catch (UnsupportedEncodingException e) {
return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP COMPRESSING MESSAGE", message.resourcePath(), e.getMessage(), null);
}
});
encodedContent.content = HttpUtils.encode(encoding, encodedContent.content, headerBuilder);
}
headerBuilder.append("Content-Length: ").append(encodedContent.content.size()).append(HttpUtils.CRLF);
} else {
headerBuilder.append("Content-Length: 0").append(HttpUtils.CRLF);
}
}
use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.
the class HttpProtocol method send_internal.
@Override
public void send_internal(OutputStream ostream, CommMessage message, InputStream istream) throws IOException {
Method method = send_getRequestMethod(message);
String charset = HttpUtils.getCharset(getStringParameter(Parameters.CHARSET, "utf-8"), null);
String format = send_getFormat();
String contentType = null;
StringBuilder headerBuilder = new StringBuilder();
if (inInputPort) {
// We're responding to a request
send_appendResponseHeaders(message, headerBuilder);
send_appendResponseUserHeader(message, headerBuilder);
send_appendHeader(headerBuilder);
} else {
// We're sending a notification or a solicit
String qsFormat = "";
if (method == Method.GET && getParameterFirstValue(Parameters.METHOD).hasChildren("queryFormat")) {
if (getParameterFirstValue(Parameters.METHOD).getFirstChild("queryFormat").strValue().equals("json")) {
qsFormat = format = "json";
contentType = ContentTypes.APPLICATION_JSON;
}
}
send_appendRequestUserHeader(message, headerBuilder);
send_appendRequestHeaders(message, method, qsFormat, headerBuilder);
}
EncodedContent encodedContent = send_encodeContent(message, method, charset, format);
if (contentType != null) {
encodedContent.contentType = contentType;
}
send_appendGenericHeaders(message, encodedContent, charset, headerBuilder);
headerBuilder.append(HttpUtils.CRLF);
send_logDebugInfo(headerBuilder, encodedContent, charset);
Interpreter.getInstance().tracer().trace(() -> {
try {
final String traceMessage = prepareSendDebugString(headerBuilder, encodedContent, charset, true);
return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE SENT", message.resourcePath(), traceMessage, null);
} catch (UnsupportedEncodingException e) {
return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE SENT", message.resourcePath(), e.getMessage(), null);
}
});
inputId = message.operationName();
ostream.write(headerBuilder.toString().getBytes(HttpUtils.URL_DECODER_ENC));
if (encodedContent.content != null && !headRequest) {
ostream.write(encodedContent.content.getBytes());
}
headRequest = false;
}
use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.
the class SoapProtocol method recv_internal.
/*
* private Schema getRecvMessageValidationSchema() throws IOException { List< Source > sources = new
* ArrayList< Source >(); Definition definition = getWSDLDefinition(); if ( definition != null ) {
* Types types = definition.getTypes(); if ( types != null ) { List< ExtensibilityElement > list =
* types.getExtensibilityElements(); for( ExtensibilityElement element : list ) { if ( element
* instanceof SchemaImpl ) { sources.add( new DOMSource( ((SchemaImpl)element).getElement() ) ); } }
* } } SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI
* ); try { return schemaFactory.newSchema( sources.toArray( new Source[sources.size()] ) ); }
* catch( SAXException e ) { throw new IOException( e ); } }
*/
public CommMessage recv_internal(InputStream istream, OutputStream ostream) throws IOException {
HttpParser parser = new HttpParser(istream);
HttpMessage message = parser.parse();
String charset = HttpUtils.getCharset(null, message);
HttpUtils.recv_checkForChannelClosing(message, channel());
if (inInputPort && message.type() != HttpMessage.Type.POST) {
throw new UnsupportedMethodException("Only HTTP method POST allowed!", Method.POST);
}
encoding = message.getProperty("accept-encoding");
CommMessage retVal = null;
String messageId = "";
FaultException fault = null;
Value value = Value.create();
try {
if (message.size() > 0) {
if (checkBooleanParameter("debug")) {
interpreter.logInfo("[SOAP debug] Receiving:\n" + new String(message.content(), charset));
}
SOAPMessage soapMessage = messageFactory.createMessage();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
/*
* Schema messageSchema = getRecvMessageValidationSchema(); if ( messageSchema != null ) {
* factory.setIgnoringElementContentWhitespace( true ); factory.setSchema( messageSchema ); }
*/
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource src = new InputSource(new ByteArrayInputStream(message.content()));
src.setEncoding(charset);
Document doc = builder.parse(src);
DOMSource dom = new DOMSource(doc);
soapMessage.getSOAPPart().setContent(dom);
/*
* if ( checkBooleanParameter( "debugAfter" ) ) { ByteArrayOutputStream tmpStream = new
* ByteArrayOutputStream(); soapMessage.writeTo( tmpStream ); interpreter.logInfo(
* "[SOAP debug] Receiving:\n" + tmpStream.toString() ); }
*/
SOAPFault soapFault = soapMessage.getSOAPBody().getFault();
if (soapFault == null) {
Element soapValueElement = getFirstElement(soapMessage.getSOAPBody());
messageId = soapValueElement.getLocalName();
if (!channel().parentPort().getInterface().containsOperation(messageId)) {
String[] soapAction = message.getPropertyOrEmptyString("soapaction").replaceAll("\"", "").split("/");
messageId = soapAction[soapAction.length - 1];
if (checkBooleanParameter("debug")) {
interpreter.logInfo("Operation from SoapAction:" + messageId);
}
}
// explanation: https://github.com/jolie/jolie/issues/5
xmlNodeToValue(value, soapValueElement, checkBooleanParameter("dropRootValue", false));
ValueVector schemaPaths = getParameterVector("schema");
if (schemaPaths.size() > 0) {
List<Source> sources = new LinkedList<>();
Value schemaPath;
for (int i = 0; i < schemaPaths.size(); i++) {
schemaPath = schemaPaths.get(i);
if (schemaPath.getChildren("validate").first().intValue() > 0) {
sources.add(new StreamSource(new File(schemaPaths.get(i).strValue())));
}
}
if (!sources.isEmpty()) {
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(sources.toArray(new Source[0]));
schema.newValidator().validate(new DOMSource(soapMessage.getSOAPBody().getFirstChild()));
}
}
} else {
String faultName = "UnknownFault";
Value faultValue = Value.create();
Detail d = soapFault.getDetail();
if (d != null) {
Node n = d.getFirstChild();
if (n != null) {
faultName = n.getLocalName();
xmlNodeToValue(faultValue, n, true);
} else {
faultValue.setValue(soapFault.getFaultString());
}
}
fault = new FaultException(faultName, faultValue);
}
}
String resourcePath = recv_getResourcePath(message);
if (message.isResponse()) {
if (fault != null && message.statusCode() == 500) {
fault = new FaultException("InternalServerError", "");
}
retVal = new CommMessage(CommMessage.GENERIC_ID, inputId, resourcePath, value, fault);
} else if (!message.isError()) {
if (messageId.isEmpty()) {
throw new IOException("Received SOAP Message without a specified operation");
}
retVal = new CommMessage(CommMessage.GENERIC_ID, messageId, resourcePath, value, fault);
}
final String mId = messageId;
interpreter.tracer().trace(() -> {
final StringBuilder traceMessage = new StringBuilder();
try {
traceMessage.append(getHeadersFromHttpMessage(message)).append("\n").append(new String(message.content(), charset));
return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE RECEIVED", mId, traceMessage.toString(), null);
} catch (UnsupportedEncodingException e) {
return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE RECEIVED", mId, e.getMessage(), null);
}
});
} catch (SOAPException | ParserConfigurationException e) {
throw new IOException(e);
} catch (SAXException e) {
// TODO support resourcePath
retVal = new CommMessage(CommMessage.GENERIC_ID, messageId, "/", value, new FaultException("TypeMismatch", e));
}
received = true;
if (retVal != null && "/".equals(retVal.resourcePath()) && channel().parentPort() != null && channel().parentPort().getInterface().containsOperation(retVal.operationName())) {
try {
// The message is for this service
Interface iface = channel().parentPort().getInterface();
OneWayTypeDescription oneWayTypeDescription = iface.oneWayOperations().get(retVal.operationName());
if (oneWayTypeDescription != null) {
// We are receiving a One-Way message
if (message.isResponse() == false) {
oneWayTypeDescription.requestType().cast(retVal.value());
}
} else {
RequestResponseTypeDescription rrTypeDescription = iface.requestResponseOperations().get(retVal.operationName());
if (retVal.isFault()) {
Type faultType = rrTypeDescription.faults().get(retVal.fault().faultName());
if (faultType != null) {
faultType.cast(retVal.value());
}
} else if (message.isResponse()) {
rrTypeDescription.responseType().cast(retVal.value());
} else {
rrTypeDescription.requestType().cast(retVal.value());
}
}
} catch (TypeCastingException e) {
// TODO: do something here?
}
}
return retVal;
}
use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.
the class SoapProtocol method send_internal.
public void send_internal(OutputStream ostream, CommMessage message, InputStream istream) throws IOException {
final StringBuilder httpMessage = new StringBuilder();
ByteArray content = null;
try {
inputId = message.operationName();
String messageNamespace = getOutputMessageNamespace(message.operationName());
if (received) {
// We're responding to a request
inputId += "Response";
}
SOAPMessage soapMessage = messageFactory.createMessage();
soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
soapMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
setOutputEncodingStyle(soapEnvelope, message.operationName());
SOAPBody soapBody = soapEnvelope.getBody();
SOAPHeader soapHeader = soapEnvelope.getHeader();
Value valueToSend = message.value();
boolean basicAuthentication = false;
String userpass = "";
if (hasOperationSpecificParameter(message.operationName(), Parameters.HTTP_BASIC_AUTHENTICATION) || hasParameter(Parameters.HTTP_BASIC_AUTHENTICATION)) {
Value basicAuthValue = null;
if (hasOperationSpecificParameter(message.operationName(), Parameters.HTTP_BASIC_AUTHENTICATION)) {
basicAuthValue = getOperationSpecificParameterFirstValue(message.operationName(), Parameters.HTTP_BASIC_AUTHENTICATION);
} else {
basicAuthValue = getParameterFirstValue(Parameters.HTTP_BASIC_AUTHENTICATION);
}
userpass = basicAuthValue.getFirstChild("userid").strValue() + ":" + basicAuthValue.getFirstChild("password").strValue();
Base64.Encoder encoder = Base64.getEncoder();
userpass = encoder.encodeToString(userpass.getBytes());
basicAuthentication = true;
}
if (checkBooleanParameter("wsAddressing")) {
// WS-Addressing namespace
soapHeader.addNamespaceDeclaration("wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
// Message ID
Name messageIdName = soapEnvelope.createName("MessageID", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
SOAPHeaderElement messageIdElement = soapHeader.addHeaderElement(messageIdName);
if (received) {
// TODO: remove this after we implement a mechanism for being sure message.id() is the one received
// before.
messageIdElement.setValue("uuid:1");
} else {
messageIdElement.setValue("uuid:" + message.id());
}
// Action element
Name actionName = soapEnvelope.createName("Action", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
SOAPHeaderElement actionElement = soapHeader.addHeaderElement(actionName);
/*
* TODO: the action element could be specified within the parameter. Perhaps wsAddressing.action ?
* We could also allow for giving a prefix or a suffix to the operation name, like
* wsAddressing.action.prefix, wsAddressing.action.suffix
*/
actionElement.setValue(message.operationName());
// From element
Name fromName = soapEnvelope.createName("From", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
SOAPHeaderElement fromElement = soapHeader.addHeaderElement(fromName);
Name addressName = soapEnvelope.createName("Address", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
SOAPElement addressElement = fromElement.addChildElement(addressName);
addressElement.setValue("http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous");
// To element
/*
* if ( operation == null ) { // we are sending a Notification or a Solicit Name toName =
* soapEnvelope.createName("To", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
* SOAPHeaderElement toElement=soapHeader.addHeaderElement(toName);
* toElement.setValue(getURI().getHost()); }
*/
}
if (message.isFault()) {
FaultException f = message.fault();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultCode(soapEnvelope.createQName("Server", soapEnvelope.getPrefix()));
soapFault.setFaultString(f.getMessage());
Detail detail = soapFault.addDetail();
DetailEntry de = detail.addDetailEntry(soapEnvelope.createName(f.faultName(), null, messageNamespace));
valueToSOAPElement(f.value(), de, soapEnvelope);
} else {
XSSchemaSet sSet = getSchemaSet();
XSElementDecl elementDecl;
String messageRootElementName = getOutputMessageRootElementName(message.operationName());
if (sSet == null || (elementDecl = sSet.getElementDecl(messageNamespace, messageRootElementName)) == null) {
Name operationName;
soapEnvelope.addNamespaceDeclaration("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
soapEnvelope.addNamespaceDeclaration("xsd", XMLConstants.W3C_XML_SCHEMA_NS_URI);
if (messageNamespace.isEmpty()) {
operationName = soapEnvelope.createName(messageRootElementName);
} else {
soapEnvelope.addNamespaceDeclaration("jolieMessage", messageNamespace);
operationName = soapEnvelope.createName(messageRootElementName, "jolieMessage", messageNamespace);
}
/*
* if( hasParameter( "header") ) { if ( getParameterFirstValue( "header" ).hasChildren() ) { //
* Prepare SOAP Header getting data from parameter .header SOAPHeader soapHeader =
* soapEnvelope.getHeader();
*
* } }
*/
SOAPBodyElement opBody = soapBody.addBodyElement(operationName);
String[] parameters = getParameterOrder(message.operationName());
if (parameters == null) {
valueToSOAPElement(valueToSend, opBody, soapEnvelope);
} else {
for (String parameterName : parameters) {
valueToSOAPElement(valueToSend.getFirstChild(parameterName), opBody.addChildElement(parameterName), soapEnvelope);
}
}
} else {
initNamespacePrefixes(soapEnvelope);
if (hasParameter(Parameters.ADD_ATTRIBUTE)) {
Value add_parameter = getParameterFirstValue(Parameters.ADD_ATTRIBUTE);
if (add_parameter.hasChildren(Parameters.ENVELOPE)) {
// attributes must be added to the envelope
ValueVector attributes = add_parameter.getFirstChild(Parameters.ENVELOPE).getChildren("attribute");
for (Value att : attributes) {
soapEnvelope.addNamespaceDeclaration(att.getFirstChild("name").strValue(), att.getFirstChild("value").strValue());
}
}
}
boolean wrapped = true;
Value vStyle = getParameterVector(Parameters.STYLE).first();
if ("document".equals(vStyle.strValue())) {
wrapped = vStyle.getFirstChild(Parameters.WRAPPED).boolValue();
}
SOAPElement opBody = soapBody;
if (wrapped) {
List<ExtensibilityElement> listExt;
if (received) {
listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingOutput().getExtensibilityElements();
} else {
listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingInput().getExtensibilityElements();
}
for (ExtensibilityElement extElement : listExt) {
if (extElement instanceof SOAPHeaderImpl) {
SOAPHeaderImpl soapHeaderImpl = (SOAPHeaderImpl) extElement;
if (valueToSend.getChildren(soapHeaderImpl.getPart()).size() > 0) {
Definition definition = getWSDLDefinition();
Message wsdlMessage = definition.getMessage(soapHeaderImpl.getMessage());
XSElementDecl partElementDeclaration = sSet.getElementDecl(wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getNamespaceURI(), wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getLocalPart());
SOAPHeaderElement headerElement = soapHeader.addHeaderElement(soapEnvelope.createName(wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getLocalPart(), wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getPrefix(), wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getNamespaceURI()));
valueToTypedSOAP(valueToSend.getFirstChild(soapHeaderImpl.getPart()), partElementDeclaration, headerElement, soapEnvelope, !wrapped, sSet, partElementDeclaration.getTargetNamespace());
valueToSend.children().remove(soapHeaderImpl.getPart());
}
}
}
opBody = soapBody.addBodyElement(soapEnvelope.createName(messageRootElementName, namespacePrefixMap.get(elementDecl.getOwnerSchema().getTargetNamespace()), null));
// adding forced attributes to operation
if (hasParameter(Parameters.ADD_ATTRIBUTE)) {
Value add_parameter = getParameterFirstValue(Parameters.ADD_ATTRIBUTE);
if (add_parameter.hasChildren(Parameters.OPERATION)) {
ValueVector operations = add_parameter.getChildren(Parameters.OPERATION);
for (Value op : operations) {
if (op.getFirstChild("operation_name").strValue().equals(message.operationName())) {
// attributes must be added to the envelope
Value attribute = op.getFirstChild("attribute");
QName attrName;
if (attribute.hasChildren("prefix")) {
attrName = opBody.createQName(attribute.getFirstChild("name").strValue(), attribute.getFirstChild("prefix").strValue());
} else {
attrName = opBody.createQName(attribute.getFirstChild("name").strValue(), null);
}
opBody.addAttribute(attrName, attribute.getFirstChild("value").strValue());
}
}
}
}
}
// check if the body has been defined with more than one parts
// Operation operation =
// getWSDLPort().getBinding().getPortType().getOperation( message.operationName(), null, null );
// Message wsdlMessage;
List<ExtensibilityElement> listExt;
if (received) {
// We are sending a response
// wsdlMessage = operation.getOutput().getMessage();
listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingOutput().getExtensibilityElements();
} else {
// We are sending a request
// wsdlMessage = operation.getInput().getMessage();
listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingInput().getExtensibilityElements();
}
boolean partsInBody = false;
String partName = "";
for (ExtensibilityElement element : listExt) {
if (element instanceof SOAPBodyImpl) {
SOAPBodyImpl sBodyImpl = (SOAPBodyImpl) element;
if (sBodyImpl.getParts() != null && sBodyImpl.getParts().size() > 0) {
partName = sBodyImpl.getParts().get(0).toString();
partsInBody = true;
}
}
}
if (!partsInBody) {
valueToTypedSOAP(valueToSend, elementDecl, opBody, soapEnvelope, !wrapped, sSet, messageNamespace);
} else {
// we support only body with one element as a root
valueToTypedSOAP(valueToSend.getFirstChild(partName), elementDecl, opBody, soapEnvelope, !wrapped, sSet, messageNamespace);
}
}
}
if (soapEnvelope.getHeader().hasChildNodes() == false) {
// Some service implementations do not like empty headers
soapEnvelope.getHeader().detachNode();
}
ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
soapMessage.writeTo(tmpStream);
content = new ByteArray(tmpStream.toByteArray());
String soapAction = null;
if (received) {
// We're responding to a request
if (message.isFault()) {
httpMessage.append("HTTP/1.1 500 Internal Server Error").append(HttpUtils.CRLF);
} else {
httpMessage.append("HTTP/1.1 200 OK").append(HttpUtils.CRLF);
}
httpMessage.append("Server: Jolie").append(HttpUtils.CRLF);
received = false;
} else {
// We're sending a notification or a solicit
// TODO: fix this to consider resourcePaths
String path = uri.getRawPath();
if (path == null || path.length() == 0) {
path = "*";
}
httpMessage.append("POST ").append(path).append(" HTTP/1.1").append(HttpUtils.CRLF).append("Host: ").append(uri.getHost()).append(HttpUtils.CRLF);
/* basic authentication: code replication from HttpProtocol. Refactoring is needed */
if (basicAuthentication) {
httpMessage.append("Authorization: Basic ").append(userpass).append(HttpUtils.CRLF);
}
/*
* soapAction = "SOAPAction: \"" + messageNamespace + "/" + message.operationName() + '\"' +
* HttpUtils.CRLF;
*/
soapAction = "SOAPAction: \"" + getSoapActionForOperation(message.operationName()) + '\"' + HttpUtils.CRLF;
if (checkBooleanParameter("compression", true)) {
String requestCompression = getStringParameter("requestCompression");
if (requestCompression.equals("gzip") || requestCompression.equals("deflate")) {
encoding = requestCompression;
httpMessage.append("Accept-Encoding: ").append(encoding).append(HttpUtils.CRLF);
} else {
httpMessage.append("Accept-Encoding: gzip, deflate").append(HttpUtils.CRLF);
}
}
}
if (getParameterVector("keepAlive").first().intValue() != 1) {
if (received)
// we may do this only in input (server) mode
channel().setToBeClosed(true);
httpMessage.append("Connection: close").append(HttpUtils.CRLF);
}
ByteArray plainTextContent = content;
if (encoding != null && checkBooleanParameter("compression", true)) {
content = HttpUtils.encode(encoding, content, httpMessage);
}
// httpMessage.append("Content-Type: application/soap+xml; charset=utf-8" + HttpUtils.CRLF);
httpMessage.append("Content-Type: text/xml; charset=utf-8").append(HttpUtils.CRLF);
httpMessage.append("Content-Length: ").append(content.size()).append(HttpUtils.CRLF);
if (soapAction != null) {
httpMessage.append(soapAction);
}
httpMessage.append(HttpUtils.CRLF);
if (getParameterVector("debug").first().intValue() > 0) {
interpreter.logInfo("[SOAP debug] Sending:\n" + httpMessage.toString() + plainTextContent.toString("utf-8"));
}
interpreter.tracer().trace(() -> {
try {
final String traceMessage = httpMessage.toString() + plainTextContent.toString("utf-8");
return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE SENT", message.operationName(), traceMessage, null);
} catch (UnsupportedEncodingException e) {
return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE SENT", message.operationName(), e.getMessage(), null);
}
});
inputId = message.operationName();
} catch (Exception e) {
if (received) {
httpMessage.setLength(0);
try {
SOAPMessage soapMessage = messageFactory.createMessage();
soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
soapMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
setOutputEncodingStyle(soapEnvelope, message.operationName());
SOAPBody soapBody = soapEnvelope.getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultCode(soapEnvelope.createQName("Server", soapEnvelope.getPrefix()));
soapFault.setFaultString("Error found in SOAP/XML format");
ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
soapMessage.writeTo(tmpStream);
content = new ByteArray(tmpStream.toByteArray());
httpMessage.append("HTTP/1.1 500 Internal Server Error").append(HttpUtils.CRLF).append("Server: Jolie").append(HttpUtils.CRLF).append("Connection: close").append(HttpUtils.CRLF).append("Content-Type: text/xml; charset=utf-8").append(HttpUtils.CRLF).append("Content-Length: ").append(content.size()).append(HttpUtils.CRLF).append(HttpUtils.CRLF);
} catch (SOAPException se) {
System.out.println(se.getMessage());
}
} else {
throw new IOException(e);
}
}
ostream.write(httpMessage.toString().getBytes(HttpUtils.URL_DECODER_ENC));
if (content != null) {
ostream.write(content.getBytes());
}
}
Aggregations