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" +