You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2009/01/29 23:52:23 UTC
svn commit: r739064 - in /ode/sandbox/simpel/src:
main/java/org/apache/ode/embed/messaging/ main/java/org/apache/ode/rest/
main/java/org/apache/ode/simpel/expr/ test/java/org/apache/ode/rest/
Author: mriou
Date: Thu Jan 29 22:52:23 2009
New Revision: 739064
URL: http://svn.apache.org/viewvc?rev=739064&view=rev
Log:
Support for HTTP headers in sent messages. Basic auth. Allows task creation in Singleshot.
Added:
ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/Base64.java
ode/sandbox/simpel/src/test/java/org/apache/ode/rest/SingleshotTest.java
Modified:
ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java
ode/sandbox/simpel/src/main/java/org/apache/ode/rest/ProcessWebResource.java
ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java
ode/sandbox/simpel/src/test/java/org/apache/ode/rest/PostWith201Resource.java
ode/sandbox/simpel/src/test/java/org/apache/ode/rest/RestfulSimPELTest.java
Added: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/Base64.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/Base64.java?rev=739064&view=auto
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/Base64.java (added)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/Base64.java Thu Jan 29 22:52:23 2009
@@ -0,0 +1,332 @@
+package org.apache.ode.embed.messaging;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/**
+ * Temporarily needed for HTTP basic auth. TODO remove once we start using basic auth in Jersey.
+ */
+public class Base64 {
+ private static final char[] S_BASE64CHAR = { 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', '+', '/' };
+
+ private static final char S_BASE64PAD = '=';
+
+ private static final byte[] S_DECODETABLE = new byte[128];
+
+ static {
+ for (int i = 0; i < S_DECODETABLE.length; i++)
+ S_DECODETABLE[i] = Byte.MAX_VALUE; // 127
+ for (int i = 0; i < S_BASE64CHAR.length; i++)
+ // 0 to 63
+ S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i;
+ }
+
+ private static int decode0(char[] ibuf, byte[] obuf, int wp) {
+ int outlen = 3;
+ if (ibuf[3] == S_BASE64PAD)
+ outlen = 2;
+ if (ibuf[2] == S_BASE64PAD)
+ outlen = 1;
+ int b0 = S_DECODETABLE[ibuf[0]];
+ int b1 = S_DECODETABLE[ibuf[1]];
+ int b2 = S_DECODETABLE[ibuf[2]];
+ int b3 = S_DECODETABLE[ibuf[3]];
+ switch (outlen) {
+ case 1:
+ obuf[wp] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+ return 1;
+ case 2:
+ obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+ obuf[wp] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+ return 2;
+ case 3:
+ obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+ obuf[wp++] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+ obuf[wp] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f);
+ return 3;
+ default:
+ throw new RuntimeException("internalError00");
+ }
+ }
+
+ /**
+ *
+ */
+ public static byte[] decode(char[] data, int off, int len) {
+ char[] ibuf = new char[4];
+ int ibufcount = 0;
+ byte[] obuf = new byte[len / 4 * 3 + 3];
+ int obufcount = 0;
+ for (int i = off; i < off + len; i++) {
+ char ch = data[i];
+ if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+ && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+ ibuf[ibufcount++] = ch;
+ if (ibufcount == ibuf.length) {
+ ibufcount = 0;
+ obufcount += decode0(ibuf, obuf, obufcount);
+ }
+ }
+ }
+ if (obufcount == obuf.length)
+ return obuf;
+ byte[] ret = new byte[obufcount];
+ System.arraycopy(obuf, 0, ret, 0, obufcount);
+ return ret;
+ }
+
+ /**
+ *
+ */
+ public static byte[] decode(String data) {
+ char[] ibuf = new char[4];
+ int ibufcount = 0;
+ byte[] obuf = new byte[data.length() / 4 * 3 + 3];
+ int obufcount = 0;
+ for (int i = 0; i < data.length(); i++) {
+ char ch = data.charAt(i);
+ if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+ && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+ ibuf[ibufcount++] = ch;
+ if (ibufcount == ibuf.length) {
+ ibufcount = 0;
+ obufcount += decode0(ibuf, obuf, obufcount);
+ }
+ }
+ }
+ if (obufcount == obuf.length)
+ return obuf;
+ byte[] ret = new byte[obufcount];
+ System.arraycopy(obuf, 0, ret, 0, obufcount);
+ return ret;
+ }
+
+ /**
+ * checks input string for invalid Base64 characters
+ *
+ * @param data
+ * @return true, if String contains only valid Base64 characters. false, otherwise
+ */
+ public static boolean isValidBase64Encoding(String data) {
+ for (int i = 0; i < data.length(); i++) {
+ char ch = data.charAt(i);
+
+ if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+ && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+ //valid character.Do nothing
+ } else if (ch == '\r' || ch == '\n') {
+ //do nothing
+ } else {
+ return false;
+ }
+ }//iterate over all characters in the string
+ return true;
+ }
+
+
+ /**
+ *
+ */
+ public static void decode(char[] data, int off, int len,
+ OutputStream ostream) throws IOException {
+ char[] ibuf = new char[4];
+ int ibufcount = 0;
+ byte[] obuf = new byte[3];
+ for (int i = off; i < off + len; i++) {
+ char ch = data[i];
+ if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+ && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+ ibuf[ibufcount++] = ch;
+ if (ibufcount == ibuf.length) {
+ ibufcount = 0;
+ int obufcount = decode0(ibuf, obuf, 0);
+ ostream.write(obuf, 0, obufcount);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public static void decode(String data, OutputStream ostream)
+ throws IOException {
+ char[] ibuf = new char[4];
+ int ibufcount = 0;
+ byte[] obuf = new byte[3];
+ for (int i = 0; i < data.length(); i++) {
+ char ch = data.charAt(i);
+ if (ch == S_BASE64PAD || ch < S_DECODETABLE.length
+ && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
+ ibuf[ibufcount++] = ch;
+ if (ibufcount == ibuf.length) {
+ ibufcount = 0;
+ int obufcount = decode0(ibuf, obuf, 0);
+ ostream.write(obuf, 0, obufcount);
+ }
+ }
+ }
+ }
+
+ /** Returns base64 representation of specified byte array. */
+ public static String encode(byte[] data) {
+ return encode(data, 0, data.length);
+ }
+
+ /** Returns base64 representation of specified byte array. */
+ public static String encode(byte[] data, int off, int len) {
+ if (len <= 0)
+ return "";
+ char[] out = new char[len / 3 * 4 + 4];
+ int rindex = off;
+ int windex = 0;
+ int rest = len - off;
+ while (rest >= 3) {
+ int i = ((data[rindex] & 0xff) << 16)
+ + ((data[rindex + 1] & 0xff) << 8)
+ + (data[rindex + 2] & 0xff);
+ out[windex++] = S_BASE64CHAR[i >> 18];
+ out[windex++] = S_BASE64CHAR[(i >> 12) & 0x3f];
+ out[windex++] = S_BASE64CHAR[(i >> 6) & 0x3f];
+ out[windex++] = S_BASE64CHAR[i & 0x3f];
+ rindex += 3;
+ rest -= 3;
+ }
+ if (rest == 1) {
+ int i = data[rindex] & 0xff;
+ out[windex++] = S_BASE64CHAR[i >> 2];
+ out[windex++] = S_BASE64CHAR[(i << 4) & 0x3f];
+ out[windex++] = S_BASE64PAD;
+ out[windex++] = S_BASE64PAD;
+ } else if (rest == 2) {
+ int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+ out[windex++] = S_BASE64CHAR[i >> 10];
+ out[windex++] = S_BASE64CHAR[(i >> 4) & 0x3f];
+ out[windex++] = S_BASE64CHAR[(i << 2) & 0x3f];
+ out[windex++] = S_BASE64PAD;
+ }
+ return new String(out, 0, windex);
+ }
+
+ /** Outputs base64 representation of the specified byte array to the specified String Buffer */
+ public static void encode(byte[] data, int off, int len, StringBuffer buffer) {
+ if (len <= 0) {
+ return;
+ }
+
+ char[] out = new char[4];
+ int rindex = off;
+ int rest = len - off;
+ while (rest >= 3) {
+ int i = ((data[rindex] & 0xff) << 16)
+ + ((data[rindex + 1] & 0xff) << 8)
+ + (data[rindex + 2] & 0xff);
+ out[0] = S_BASE64CHAR[i >> 18];
+ out[1] = S_BASE64CHAR[(i >> 12) & 0x3f];
+ out[2] = S_BASE64CHAR[(i >> 6) & 0x3f];
+ out[3] = S_BASE64CHAR[i & 0x3f];
+ buffer.append(out);
+ rindex += 3;
+ rest -= 3;
+ }
+ if (rest == 1) {
+ int i = data[rindex] & 0xff;
+ out[0] = S_BASE64CHAR[i >> 2];
+ out[1] = S_BASE64CHAR[(i << 4) & 0x3f];
+ out[2] = S_BASE64PAD;
+ out[3] = S_BASE64PAD;
+ buffer.append(out);
+ } else if (rest == 2) {
+ int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+ out[0] = S_BASE64CHAR[i >> 10];
+ out[1] = S_BASE64CHAR[(i >> 4) & 0x3f];
+ out[2] = S_BASE64CHAR[(i << 2) & 0x3f];
+ out[3] = S_BASE64PAD;
+ buffer.append(out);
+ }
+ }
+
+ /** Outputs base64 representation of the specified byte array to a byte stream. */
+ public static void encode(byte[] data, int off, int len,
+ OutputStream ostream) throws IOException {
+ if (len <= 0)
+ return;
+ byte[] out = new byte[4];
+ int rindex = off;
+ int rest = len - off;
+ while (rest >= 3) {
+ int i = ((data[rindex] & 0xff) << 16)
+ + ((data[rindex + 1] & 0xff) << 8)
+ + (data[rindex + 2] & 0xff);
+ out[0] = (byte) S_BASE64CHAR[i >> 18];
+ out[1] = (byte) S_BASE64CHAR[(i >> 12) & 0x3f];
+ out[2] = (byte) S_BASE64CHAR[(i >> 6) & 0x3f];
+ out[3] = (byte) S_BASE64CHAR[i & 0x3f];
+ ostream.write(out, 0, 4);
+ rindex += 3;
+ rest -= 3;
+ }
+ if (rest == 1) {
+ int i = data[rindex] & 0xff;
+ out[0] = (byte) S_BASE64CHAR[i >> 2];
+ out[1] = (byte) S_BASE64CHAR[(i << 4) & 0x3f];
+ out[2] = (byte) S_BASE64PAD;
+ out[3] = (byte) S_BASE64PAD;
+ ostream.write(out, 0, 4);
+ } else if (rest == 2) {
+ int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+ out[0] = (byte) S_BASE64CHAR[i >> 10];
+ out[1] = (byte) S_BASE64CHAR[(i >> 4) & 0x3f];
+ out[2] = (byte) S_BASE64CHAR[(i << 2) & 0x3f];
+ out[3] = (byte) S_BASE64PAD;
+ ostream.write(out, 0, 4);
+ }
+ }
+
+ /** Outputs base64 representation of the specified byte array to a character stream. */
+ public static void encode(byte[] data, int off, int len, Writer writer)
+ throws IOException {
+ if (len <= 0)
+ return;
+ char[] out = new char[4];
+ int rindex = off;
+ int rest = len - off;
+ int output = 0;
+ while (rest >= 3) {
+ int i = ((data[rindex] & 0xff) << 16)
+ + ((data[rindex + 1] & 0xff) << 8)
+ + (data[rindex + 2] & 0xff);
+ out[0] = S_BASE64CHAR[i >> 18];
+ out[1] = S_BASE64CHAR[(i >> 12) & 0x3f];
+ out[2] = S_BASE64CHAR[(i >> 6) & 0x3f];
+ out[3] = S_BASE64CHAR[i & 0x3f];
+ writer.write(out, 0, 4);
+ rindex += 3;
+ rest -= 3;
+ output += 4;
+ if (output % 76 == 0)
+ writer.write("\n");
+ }
+ if (rest == 1) {
+ int i = data[rindex] & 0xff;
+ out[0] = S_BASE64CHAR[i >> 2];
+ out[1] = S_BASE64CHAR[(i << 4) & 0x3f];
+ out[2] = S_BASE64PAD;
+ out[3] = S_BASE64PAD;
+ writer.write(out, 0, 4);
+ } else if (rest == 2) {
+ int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff);
+ out[0] = S_BASE64CHAR[i >> 10];
+ out[1] = S_BASE64CHAR[(i >> 4) & 0x3f];
+ out[2] = S_BASE64CHAR[(i << 2) & 0x3f];
+ out[3] = S_BASE64PAD;
+ writer.write(out, 0, 4);
+ }
+ }
+}
Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java?rev=739064&r1=739063&r2=739064&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/embed/messaging/MessageExchangeContextImpl.java Thu Jan 29 22:52:23 2009
@@ -7,7 +7,7 @@
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
+import org.w3c.dom.NodeList;
import javax.wsdl.Operation;
import javax.wsdl.Fault;
@@ -15,7 +15,7 @@
import javax.xml.namespace.QName;
import java.util.Set;
import java.util.HashSet;
-import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
@@ -106,8 +106,10 @@
ClientResponse resp;
WebResource.Builder wr = c.resource(res.getUrl()).path("/").accept(res.getContentType()).type(res.getContentType());
if (restOutMessageExchange.getRequest() != null) {
+ Element payload = restOutMessageExchange.getRequest().getMessage();
+ handleOutHeaders(payload, wr);
resp = wr.method(res.getMethod().toUpperCase(), ClientResponse.class,
- DOMUtils.domToString(unwrapToPayload(restOutMessageExchange.getRequest().getMessage())));
+ DOMUtils.domToString(unwrapToPayload(payload)));
} else resp = wr.method(res.getMethod().toUpperCase(), ClientResponse.class);
if (resp.getStatus() == 204) {
@@ -115,10 +117,29 @@
return;
}
- // TODO check more status
String response = resp.getEntity(String.class);
+
+ if (resp.getStatus() == 401) {
+ QName faultName = new QName("http://ode.apache.org/fault/http/", "http401");
+ Document odeMsg = DOMUtils.newDocument();
+ Element odeMsgEl = odeMsg.createElementNS(null, "message");
+ odeMsg.appendChild(odeMsgEl);
+ Element partElmt = odeMsg.createElement("payload");
+ odeMsgEl.appendChild(partElmt);
+ Element methodElmt = odeMsg.createElementNS(faultName.getNamespaceURI(), faultName.getLocalPart());
+ partElmt.appendChild(methodElmt);
+ methodElmt.setTextContent(response);
+
+ Message responseMsg = restOutMessageExchange.createMessage(null);
+ responseMsg.setMessage(odeMsgEl);
+ restOutMessageExchange.replyWithFault(faultName, responseMsg);
+ return;
+ }
+
+ // TODO handle failure status
+ // TODO allow POST over simple form url-encoded
Element responseXML = null;
- if (response != null && response.length() > 0) {
+ if (response != null && response.trim().length() > 0) {
try {
responseXML = DOMUtils.stringToDOM(response);
} catch (Exception e) {
@@ -187,6 +208,34 @@
return payload;
}
+ private void handleOutHeaders(Element msg, WebResource.Builder wr) {
+ Element root = DOMUtils.getFirstChildElement(DOMUtils.getFirstChildElement(msg));
+ Node headers = DOMUtils.findChildByName(root, new QName(null, "headers"));
+ if (headers != null) {
+ NodeList headerElmts = headers.getChildNodes();
+ for (int m = 0; m < headerElmts.getLength(); m++) {
+ Node n = headerElmts.item(m);
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ if (n.getNodeName().equals("basicAuth")) {
+ Element login = DOMUtils.findChildByName((Element) n, new QName(null, "login"));
+ Element password = DOMUtils.findChildByName((Element) n, new QName(null, "password"));
+ if (login != null && password != null) {
+ // TODO rely on Jersey basic auth once 1.0.2 is released
+ try {
+ byte[] unencoded = (login.getTextContent() + ":" + password.getTextContent()).getBytes("UTF-8");
+ String credString = Base64.encode(unencoded);
+ String authHeader = "Basic " + credString;
+ wr.header("authorization", authHeader);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
private Element withHeaders(Element element) {
Element res = DOMUtils.findChildByName(element, new QName(null, "headers"));
if (res == null) {
Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/rest/ProcessWebResource.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/rest/ProcessWebResource.java?rev=739064&r1=739063&r2=739064&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/rest/ProcessWebResource.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/rest/ProcessWebResource.java Thu Jan 29 22:52:23 2009
@@ -13,6 +13,7 @@
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Context;
+import javax.xml.namespace.QName;
import java.util.List;
import java.util.Map;
@@ -62,7 +63,8 @@
Document doc = DOMUtils.newDocument();
Element docElmt = doc.createElement("document");
Element partElmt = doc.createElement("payload");
- Element rootElmt = doc.createElement("root");
+ // For some reason, this sometimes ends up in assignment as a node with no local name if not ns'd
+ Element rootElmt = doc.createElementNS(null, "root");
doc.appendChild(docElmt);
docElmt.appendChild(partElmt);
partElmt.appendChild(rootElmt);
Modified: ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java?rev=739064&r1=739063&r2=739064&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java (original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/expr/E4XExprRuntime.java Thu Jan 29 22:52:23 2009
@@ -18,6 +18,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
import javax.xml.namespace.QName;
import java.util.*;
@@ -108,7 +109,9 @@
// Only content is copied, need to wrap
Document doc = DOMUtils.newDocument();
Element wrapper = doc.createElement("assignWrapper");
- wrapper.appendChild(doc.importNode(XMLLibImpl.toDomNode(res), true));
+ Node resNode = doc.importNode(XMLLibImpl.toDomNode(res), true);
+ wrapper.appendChild(resNode);
+ if (resNode.getNodeType() == Node.ELEMENT_NODE) mergeHeaders((Element) resNode);
resList.add(wrapper);
} catch (IllegalArgumentException e) {
// Rhino makes it pretty hard to use it sXML impl, XML and XMLList are package level
@@ -197,11 +200,14 @@
// When we're querying on headers, the sub-element is supposed to be right under the
// current. To avoid pollution of the main user variable we store it one level up so
// we're readjusting here.
- if (_expr.getExpr().indexOf(".headers") > 0 && node.getParentNode() != null &&
- node.getParentNode().getNodeType() == Node.ELEMENT_NODE) {
+ if (!forceDelegate && (_expr.getExpr().indexOf(".headers") > 0
+ || (_expr.getLValue() != null && _expr.getLValue().indexOf(".headers") > 0))
+ && node.getParentNode() != null
+ && node.getParentNode().getNodeType() == Node.ELEMENT_NODE) {
Element parent = (Element) node.getParentNode();
Element headers = DOMUtils.findChildByName(parent, new QName(null, "headers"));
- node.appendChild(node.getOwnerDocument().importNode(headers, true));
+ if (headers != null)
+ node.appendChild(node.getOwnerDocument().importNode(headers, true));
}
// Have to remove the xml header otherwise it confuses Rhino
@@ -279,4 +285,29 @@
for (String s : ss) buffer.append(s);
return buffer.toString();
}
+
+ private void mergeHeaders(Element elmt) {
+ // As a convenience during E4X assignment, headers is a subnode of the main node. To avoid pollution
+ // it's actually stored as a subnode of the parent so we move/merge here.
+ NodeList elmtHeadersNL = elmt.getElementsByTagName("headers");
+ if (elmtHeadersNL.getLength() > 0) {
+ Element elmtHeaders = (Element) elmtHeadersNL.item(0);
+ Element parent = (Element) elmt.getParentNode();
+ elmt.removeChild(elmtHeaders);
+ Element parentHeaders = DOMUtils.getElementByID(parent, "headers");
+ if (parentHeaders == null) {
+ parent.appendChild(elmtHeaders);
+ } else {
+ NodeList headerChildren = elmtHeaders.getChildNodes();
+ for (int m = 0; m < headerChildren.getLength(); m++) {
+ Node n = headerChildren.item(m);
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ n.getParentNode().removeChild(n);
+ parentHeaders.appendChild(n);
+ }
+ }
+ }
+ }
+ }
+
}
Modified: ode/sandbox/simpel/src/test/java/org/apache/ode/rest/PostWith201Resource.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/java/org/apache/ode/rest/PostWith201Resource.java?rev=739064&r1=739063&r2=739064&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/java/org/apache/ode/rest/PostWith201Resource.java (original)
+++ ode/sandbox/simpel/src/test/java/org/apache/ode/rest/PostWith201Resource.java Thu Jan 29 22:52:23 2009
@@ -13,6 +13,6 @@
@Consumes("application/xml")
@Produces("application/xml")
public Response post() {
- return Response.status(201).header("Location", "http://foo/bar").build();
+ return Response.status(201).header("Location", "http://foo/bar").entity("<response><appStatus>ok</appStatus></response>").build();
}
}
Modified: ode/sandbox/simpel/src/test/java/org/apache/ode/rest/RestfulSimPELTest.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/java/org/apache/ode/rest/RestfulSimPELTest.java?rev=739064&r1=739063&r2=739064&view=diff
==============================================================================
--- ode/sandbox/simpel/src/test/java/org/apache/ode/rest/RestfulSimPELTest.java (original)
+++ ode/sandbox/simpel/src/test/java/org/apache/ode/rest/RestfulSimPELTest.java Thu Jan 29 22:52:23 2009
@@ -250,7 +250,7 @@
assertEquals(response, "http://foo/bar");
}
- private static final String HELLO_FORM_WORLD =
+ private static final String HELLO_FORM_WORLD = // TODO reply with HTML
"process HelloFormWorld { \n" +
" receive(self) { |form| \n" +
" helloXml = <hello>{\"Hello \" + form.firstname + \" \" + form.lastname}</hello>; \n" +
Added: ode/sandbox/simpel/src/test/java/org/apache/ode/rest/SingleshotTest.java
URL: http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/java/org/apache/ode/rest/SingleshotTest.java?rev=739064&view=auto
==============================================================================
--- ode/sandbox/simpel/src/test/java/org/apache/ode/rest/SingleshotTest.java (added)
+++ ode/sandbox/simpel/src/test/java/org/apache/ode/rest/SingleshotTest.java Thu Jan 29 22:52:23 2009
@@ -0,0 +1,62 @@
+package org.apache.ode.rest;
+
+import org.apache.ode.EmbeddedServer;
+import org.apache.ode.Descriptor;
+import org.junit.Ignore;
+import junit.framework.TestCase;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.ClientResponse;
+
+/**
+ * For now this test requires a running instance of Singleshot, otherwise it will fail.
+ */
+@Ignore
+public class SingleshotTest extends TestCase {
+
+ EmbeddedServer server;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ server = new EmbeddedServer();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ server.stop();
+ }
+
+ private static final String TASK_CREATOR =
+ "shotBase = \"http://localhost:3000\" \n" +
+ "process TaskCreator { \n" +
+ " receive(self) { |task| \n" +
+ " task.headers.basicAuth.login = \"mriou\"; \n" +
+ " task.headers.basicAuth.password = \"secret\"; \n" +
+ " resp = request(shotBase + \"/tasks\", \"POST\", task); \n" +
+ " reply(resp); \n" +
+ " }\n" +
+ "}";
+
+ public void testCreateTask() throws Exception {
+ server.start();
+ Descriptor desc = new Descriptor();
+ desc.setAddress("/taskcreator");
+ server.deploy(TASK_CREATOR, desc);
+
+ ClientConfig cc = new DefaultClientConfig();
+ Client c = Client.create(cc);
+
+ WebResource wr = c.resource("http://localhost:3434/taskcreator");
+ ClientResponse resp = wr.path("/").accept("application/xml").type("application/xml")
+ .post(ClientResponse.class, "<task><title>SimPEL Task</title>" +
+ "<description>Test task created from a SimPEL process.</description>" +
+ "<owner>mriou</owner>" +
+ "<data>{}</data></task>"); // Opening and closing curly literals escaped
+ String response = resp.getEntity(String.class);
+ System.out.println(response);
+ }
+}