use of com.ibm.wsdl.extensions.soap.SOAPHeaderImpl 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