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/14 00:39:54 UTC
svn commit: r734276 - in /ode/sandbox/simpel/src:
main/antlr/org/apache/ode/simpel/antlr/
main/java/org/apache/ode/embed/messaging/ main/java/org/apache/ode/rest/
main/java/org/apache/ode/simpel/omodel/ test/java/org/apache/ode/simpel/
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" +