Author: mriou
Date: Tue Jan 13 15:39:53 2009
New Revision: 734276
URL: http://svn.apache.org/viewvc?rev=734276&view=rev
Log:
HTTP request, only GET is tested for now.
Modified:
ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g
ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g
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/omodel/OBuilder.java
ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/RestfulSimPELTest.java
Modified: ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g
URL:
http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g?rev=734276&r1=734275&r2=734276&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g
(original)
+++ ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPEL.g Tue
Jan 13 15:39:53 2009
@@ -9,7 +9,7 @@
ROOT; PROCESS; PICK; SEQUENCE; FLOW; IF; ELSEIF; ELSE; WHILE; UNTIL;
FOREACH; FORALL; INVOKE;
RECEIVE; REPLY; ASSIGN; THROW; WAIT; EXIT; TIMEOUT; TRY; CATCH; CATCH_ALL;
SCOPE; EVENT;
RESOURCE;
- ONEVENT; ONALARM; ONRECEIVE; ONUPDATE; ONQUERY; COMPENSATION; COMPENSATE;
+ REQUEST; ONEVENT; ONALARM; ONRECEIVE; ONUPDATE; ONQUERY; COMPENSATION;
COMPENSATE;
CORRELATION; CORR_MAP; PARTNERLINK; VARIABLE; BLOCK_PARAM;
SIGNAL; JOIN; WITH; MAP;
EXPR; EXT_EXPR; XML_LITERAL; CALL; NAMESPACE; NS; PATH;
@@ -96,7 +96,7 @@
proc_stmt
: pick | flow | if_ex | while_ex | until_ex | foreach | forall |
try_ex | scope_ex | with_ex
- | receive | invoke | ((reply | assign | throw_ex | wait_ex |
exit | signal | join
+ | receive | invoke | request | ((reply | assign | throw_ex |
wait_ex | exit | signal | join
| variables | partner_link) SEMI!);
block : '{' proc_stmt+ '}' -> ^(SEQUENCE proc_stmt+);
@@ -158,10 +158,17 @@
reply : 'reply' '(' ID (',' ID (',' ID)?)? ')' -> ^(REPLY ID (ID ID?)?);
+request
+options {backtrack=true;}
+ : request_base SEMI -> ^(REQUEST request_base)
+ | request_base param_block -> ^(REQUEST request_base) param_block;
+request_base
+ : 'request' '(' expr (',' meth=STRING (',' msg=ID)?)? ')' ->
^(expr $meth? $msg?);
+
assign : path_expr '=' rvalue -> ^(ASSIGN path_expr rvalue);
rvalue
: receive_base -> ^(RECEIVE receive_base)
- | invoke | resource | expr | xml_literal;
+ | invoke | request | resource | expr | xml_literal;
throw_ex: 'throw' '('? ns_id ')'? -> ^(THROW ns_id);
Modified:
ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g
URL:
http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g?rev=734276&r1=734275&r2=734276&view=diff
==============================================================================
---
ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g
(original)
+++
ode/sandbox/simpel/src/main/antlr/org/apache/ode/simpel/antlr/SimPELWalker.g
Tue Jan 13 15:39:53 2009
@@ -228,7 +228,7 @@
scope ReceiveBlock;
: ^(INVOKE ^(p=ID o=ID in=ID?)) {
OBuilder.StructuredActivity<OInvoke> inv =
builder.build(OInvoke.class, $BPELScope::oscope,
- $Parent::activity, text($p), text($o), text($in));
+ $Parent::activity, text($p), text($o), text($in), null);
$ReceiveBlock::activity = inv.getOActivity();
}
(prb=(param_block))?;
@@ -259,6 +259,26 @@
if ($correlation.corr != null)
builder.addCorrelationMatch(rec.getOActivity(), $correlation.corr);
} )
(prb=(param_block))?;
+request
+scope ReceiveBlock ExprContext;
+ : ^(REQUEST {
+ $ExprContext::expr = new SimPELExpr(builder.getProcess());
+ }
+ ^(e=(expr) (meth=STRING msg=ID?)?)) {
+ $ExprContext::expr.setExpr(deepText($e));
+
+ // The request output is the lvalue of the assignment
expression in which this request is enclosed (if it is)
+ OBuilder.StructuredActivity<OInvoke> inv;
+ if (ExprContext_stack.size() > 1)
+ inv = builder.build(OInvoke.class, $BPELScope::oscope,
+ $Parent::activity, $ExprContext::expr, text($meth),
text($msg), $ExprContext[-1]::expr);
+ else
+ inv = builder.build(OInvoke.class, $BPELScope::oscope,
+ $Parent::activity, $ExprContext::expr, text($meth),
text($msg), null);
+
+ $ReceiveBlock::activity = inv.getOActivity();
+ }
+ (prb=(param_block))?;
assign
scope ExprContext;
@@ -270,7 +290,7 @@
}
rv=(rvalue)) {
$ExprContext::expr.setExpr(deepText($rv));
- if (!"RESOURCE".equals($rv.getText()) &&
!"RECEIVE".equals($rv.getText())) {
+ if (!"RESOURCE".equals($rv.getText()) &&
!"RECEIVE".equals($rv.getText()) && !"REQUEST".equals($rv.getText())) {
OBuilder.StructuredActivity<OAssign> assign =
builder.build(OAssign.class, $BPELScope::oscope,
$Parent::activity, $ExprContext::expr);
// The long, winding road of abstraction
@@ -278,7 +298,7 @@
getOActivity().operations.get(0)).from).expression;
}
};
-rvalue : receive | invoke | resource | expr | xmlElement;
+rvalue : receive | invoke | request | resource | expr | xmlElement;
throw_ex: ^(THROW ns_id);
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=734276&r1=734275&r2=734276&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
Tue Jan 13 15:39:53 2009
@@ -7,6 +7,7 @@
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
import javax.wsdl.Operation;
import javax.wsdl.Fault;
@@ -14,6 +15,13 @@
import javax.xml.namespace.QName;
import java.util.Set;
import java.util.HashSet;
+import java.io.IOException;
+
+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;
public class MessageExchangeContextImpl implements MessageExchangeContext {
@@ -36,18 +44,8 @@
Operation invokedOp =
partnerMex.getPortType().getOperation(partnerMex.getOperationName(), null,
null);
try {
// We're placing ourselves in the doc/lit case for now, assuming a
single part with a single root element
- Element message = partnerMex.getRequest().getMessage();
- Element root =
DOMUtils.getFirstChildElement(DOMUtils.getFirstChildElement(message));
- // TODO this assumption only works with SimPEL, in the general
case we could have a NodeList
- // and should therefore send the whole part element
- Node payload;
- if (DOMUtils.getFirstChildElement(root) != null)
- payload = DOMUtils.getFirstChildElement(root);
- else {
- Document doc = DOMUtils.newDocument();
- payload = doc.createTextNode(DOMUtils.getTextContent(root));
- }
- Node response =
_sender.send(partnerMex.getPortType().getQName().getLocalPart(),
invokedOp.getName(), payload);
+ Node response =
_sender.send(partnerMex.getPortType().getQName().getLocalPart(),
+ invokedOp.getName(),
unwrapToPayload(partnerMex.getRequest().getMessage()));
if (invokedOp.getOutput() != null) {
Document responseDoc = DOMUtils.newDocument();
@@ -99,6 +97,47 @@
//To change body of implemented methods use File | Settings | File
Templates.
}
+ public void invokeRestful(RESTOutMessageExchange restOutMessageExchange)
throws ContextException {
+ Resource res = restOutMessageExchange.getTargetResource();
+
+ ClientConfig cc = new DefaultClientConfig();
+ Client c = Client.create(cc);
+
+ ClientResponse resp;
+ WebResource.Builder wr =
c.resource(res.getUrl()).path("/").accept(res.getContentType()).type(res.getContentType());
+ if (restOutMessageExchange.getRequest() != null) {
+ resp = wr.method(res.getMethod().toUpperCase(),
ClientResponse.class,
+
DOMUtils.domToString(unwrapToPayload(restOutMessageExchange.getRequest().getMessage())));
+ } else resp = wr.method(res.getMethod().toUpperCase(),
ClientResponse.class);
+
+ // TODO check status
+ String response = resp.getEntity(String.class);
+ Element responseXML;
+ try {
+ responseXML = DOMUtils.stringToDOM(response);
+ } catch (Exception e) {
+ Document doc = DOMUtils.newDocument();
+ Element failureElmt = doc.createElement("requestFailure");
+ failureElmt.setTextContent(response);
+
restOutMessageExchange.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR,
+ "Can't parse the response to " + res.getUrl(),
failureElmt);
+ return;
+ }
+
+ Document odeMsg = DOMUtils.newDocument();
+ Element odeMsgEl = odeMsg.createElementNS(null, "message");
+ odeMsg.appendChild(odeMsgEl);
+ Element partElmt = odeMsg.createElement("payload");
+ odeMsgEl.appendChild(partElmt);
+ Element methodElmt = odeMsg.createElement(res.getMethod() +
"Response");
+ partElmt.appendChild(methodElmt);
+ methodElmt.appendChild(odeMsg.adoptNode(responseXML));
+
+ Message responseMsg = restOutMessageExchange.createMessage(null);
+ responseMsg.setMessage(odeMsgEl);
+ restOutMessageExchange.reply(responseMsg);
+ }
+
public void cancel(PartnerRoleMessageExchange partnerRoleMessageExchange)
throws ContextException {
//To change body of implemented methods use File | Settings | File
Templates.
}
@@ -113,4 +152,18 @@
styles.add(InvocationStyle.UNRELIABLE);
return styles;
}
+
+ private Node unwrapToPayload(Element message) {
+ Element root =
DOMUtils.getFirstChildElement(DOMUtils.getFirstChildElement(message));
+ // TODO this assumption only works with SimPEL, in the general case we
could have a NodeList
+ // and should therefore send the whole part element
+ Node payload;
+ if (DOMUtils.getFirstChildElement(root) != null)
+ payload = DOMUtils.getFirstChildElement(root);
+ else {
+ Document doc = DOMUtils.newDocument();
+ payload = doc.createTextNode(DOMUtils.getTextContent(root));
+ }
+ return payload;
+ }
}
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=734276&r1=734275&r2=734276&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
Tue Jan 13 15:39:53 2009
@@ -1,19 +1,15 @@
package org.apache.ode.rest;
-import org.apache.ode.bpel.iapi.Resource;
-import org.apache.ode.bpel.iapi.RESTMessageExchange;
import org.apache.ode.bpel.iapi.Message;
+import org.apache.ode.bpel.iapi.RESTInMessageExchange;
import org.apache.ode.embed.ServerLifecycle;
import org.apache.ode.utils.GUID;
import org.apache.ode.utils.DOMUtils;
-import org.xml.sax.SAXException;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
-import javax.xml.namespace.QName;
-import java.io.IOException;
public class ProcessWebResource {
@@ -30,7 +26,7 @@
@GET @Produces("application/xml")
public Response get() {
if (_resource.get) {
- RESTMessageExchange mex =
_serverLifecyle.getServer().createMessageExchange(
+ RESTInMessageExchange mex =
_serverLifecyle.getServer().createMessageExchange(
_resource.toResource("GET"), new GUID().toString());
try {
mex.invokeBlocking();
@@ -55,7 +51,7 @@
@POST @Consumes("application/xml")
public Response post(String content) {
if (_resource.post) {
- RESTMessageExchange mex =
_serverLifecyle.getServer().createMessageExchange(
+ RESTInMessageExchange mex =
_serverLifecyle.getServer().createMessageExchange(
_resource.toResource("POST"), new GUID().toString());
Message request = mex.createMessage(null);
if (content.length() > 0) {
Modified:
ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java
URL:
http://svn.apache.org/viewvc/ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java?rev=734276&r1=734275&r2=734276&view=diff
==============================================================================
--- ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java
(original)
+++ ode/sandbox/simpel/src/main/java/org/apache/ode/simpel/omodel/OBuilder.java
Tue Jan 13 15:39:53 2009
@@ -168,6 +168,7 @@
OPickReceive.OnMessage onMessage = new
OPickReceive.OnMessage(_oprocess);
if (operation == null) {
onMessage.resource =
copyResource(webResources.get(partnerLinkOrResource), "POST");
+ onMessage.resource.setInbound(true);
if (onMessage.resource == null)
throw new RuntimeException("Unknown resource declared in
receive: " + partnerLinkOrResource);
_oprocess.providedResources.add(onMessage.resource);
@@ -211,11 +212,45 @@
};
}
- public SimpleActivity buildInvoke(OInvoke invoke, OScope oscope, String
partnerLink,
- String operation, String incomingMsg) {
- invoke.partnerLink = buildPartnerLink(oscope, partnerLink, operation,
false, incomingMsg != null);
- invoke.operation =
invoke.partnerLink.partnerRolePortType.getOperation(operation, null, null);
- if (incomingMsg != null) invoke.inputVar = resolveVariable(oscope,
incomingMsg, operation, true);
+ public SimpleActivity buildInvoke(OInvoke invoke, OScope oscope, Object
exprOrPlink, String methOrOp, String inputMsg, SimPELExpr outputMsg) {
+ if (exprOrPlink instanceof SimPELExpr) return buildRequest(invoke,
oscope, (SimPELExpr) exprOrPlink, methOrOp, inputMsg, outputMsg);
+ else return buildWSInvoke(invoke, oscope, (String) exprOrPlink,
methOrOp, inputMsg, outputMsg);
+ }
+
+ public SimpleActivity buildRequest(OInvoke invoke, OScope oscope,
SimPELExpr expr, String method, String outgoingMsg, SimPELExpr responseMsg) {
+ if (method != null && (!method.equalsIgnoreCase("get") ||
method.equalsIgnoreCase("put")
+ || method.equalsIgnoreCase("post") ||
method.equalsIgnoreCase("delete")))
+ throw new RuntimeException("Invalid HTTP method: " + method);
+
+ // TODO hack warning: because of the way deepText works in
SimPELWalker, the expr we get is the whole thing
+ // i.e. request(foo+"/order"), the expr should be changed to return
its string instead of the following
+ String exprStr = expr.getExpr();
+ int openParens = exprStr.indexOf("(");
+ int closeExpr = Math.max(exprStr.indexOf(")"), exprStr.indexOf(","));
+ expr.setExpr(exprStr.substring(openParens+1, closeExpr));
+ expr.expressionLanguage = _exprLang;
+
+ invoke.resource = new OResource(_oprocess);
+ invoke.resource.setSubpath(expr);
+ invoke.resource.setMethod(method == null ? "get" : method);
+ invoke.resource.setInbound(false);
+ invoke.resource.setDeclaringScope(oscope);
+ if (outgoingMsg != null)
+ invoke.inputVar = resolveVariable(oscope, outgoingMsg, null, true);
+ if (responseMsg != null)
+ invoke.outputVar = resolveVariable(oscope,
responseMsg.getLValue(), null, false);
+
+ return new SimpleActivity<OInvoke>(invoke);
+ }
+
+ public SimpleActivity buildWSInvoke(OInvoke invoke, OScope oscope, String
plink, String op, String outgoingMsg, SimPELExpr responseMsg) {
+ invoke.partnerLink = buildPartnerLink(oscope, plink, op, false,
outgoingMsg != null);
+ invoke.operation =
invoke.partnerLink.partnerRolePortType.getOperation(op, null, null);
+
+ if (outgoingMsg != null)
+ invoke.inputVar = resolveVariable(oscope, outgoingMsg,
invoke.operation.getName(), true);
+ if (responseMsg != null)
+ invoke.outputVar = resolveVariable(oscope,
responseMsg.getLValue(), invoke.operation.getName(), false);
return new SimpleActivity<OInvoke>(invoke);
}
@@ -302,10 +337,8 @@
}
} else if (oact instanceof OInvoke) {
OInvoke inv = (OInvoke)oact;
- inv.outputVar = resolveVariable(oscope, varName,
inv.operation.getName(), false);
- buildPartnerLink(oscope, inv.partnerLink.name,
inv.operation.getName(), false, false);
- } else if (oact instanceof OCollect) {
- OCollect collect = (OCollect)oact;
+ inv.outputVar = resolveVariable(oscope, varName, inv.operation !=
null ? inv.operation.getName() : null, false);
+ buildPartnerLink(oscope, inv.partnerLink.name, inv.operation !=
null ? inv.operation.getName() : null, false, false);
} else __log.warn("Can't set block parameter on activity " + oact);
}
Modified:
ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/RestfulSimPELTest.java
URL:
http://svn.apache.org/viewvc/ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/RestfulSimPELTest.java?rev=734276&r1=734275&r2=734276&view=diff
==============================================================================
---
ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/RestfulSimPELTest.java
(original)
+++
ode/sandbox/simpel/src/test/java/org/apache/ode/simpel/RestfulSimPELTest.java
Tue Jan 13 15:39:53 2009
@@ -44,6 +44,34 @@
server.stop();
}
+ public static final String CALLING_GET =
+ "var feedBUrl = \"http://feeds.feedburner.com/\"; " +
+ "process CallingGet {\n" +
+ " receive(self) { |query|\n" +
+ " feed = request(feedBUrl + query);\n" +
+ " title = feed.channel.title;\n" +
+ " reply(title);\n" +
+ " }\n" +
+ "}";
+
+ public void testCallingGet() throws Exception {
+ EmbeddedServer server = new EmbeddedServer();
+ server.start();
+ Descriptor desc = new Descriptor();
+ desc.setAddress("/feedget");
+ server.deploy(CALLING_GET, desc);
+
+ ClientConfig cc = new DefaultClientConfig();
+ Client c = Client.create(cc);
+
+ WebResource wr = c.resource("http://localhost:3434/feedget");
+ ClientResponse resp =
wr.path("/").accept("application/xml").type("application/xml")
+ .post(ClientResponse.class, "<simpelWrapper
xmlns=\"http://ode.apache.org/simpel/1.0/definition/CallingGet\">OffTheLip</simpelWrapper>");
+ String response = resp.getEntity(String.class);
+ System.out.println("=> " + response);
+ assertTrue(response.indexOf("Off The Lip") > 0);
+ }
+
private static final String COUNTER =
"process Counter {\n" +
" counter = receive(self); \n" +