Repository: camel
Updated Branches:
  refs/heads/master c8f2e7ffb -> f8dd9c1c9


CAMEL-7619: Rest DSL - adding support for xml/json binding using Camel's data 
formats. Work in progress.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f8dd9c1c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f8dd9c1c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f8dd9c1c

Branch: refs/heads/master
Commit: f8dd9c1c98f11f0052430765ac6cac5d23584383
Parents: c8f2e7f
Author: Claus Ibsen <davscl...@apache.org>
Authored: Wed Jul 23 13:52:00 2014 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Wed Jul 23 13:52:00 2014 +0200

----------------------------------------------------------------------
 .../apache/camel/model/rest/RestDefinition.java |  4 +-
 .../processor/binding/RestBindingProcessor.java | 58 ++++++++++++++++++++
 .../camel/component/restlet/CountryPojo.java    | 39 +++++++++++++
 .../restlet/RestRestletPojoInOutTest.java       | 53 ++++++++++++++++++
 .../camel/component/restlet/UserService.java    | 33 +++++++++++
 5 files changed, 185 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f8dd9c1c/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java 
b/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index dadd530..c163a1b 100644
--- a/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -150,7 +150,7 @@ public class RestDefinition {
 
         VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
         verb.setClassType(classType);
-        verb.setTypeList(classType.getCanonicalName());
+        verb.setType(classType.getCanonicalName());
         return this;
     }
 
@@ -161,7 +161,7 @@ public class RestDefinition {
         }
 
         VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
-        verb.setType(classType);
+        verb.setTypeList(classType);
         return this;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/f8dd9c1c/camel-core/src/main/java/org/apache/camel/processor/binding/RestBindingProcessor.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/processor/binding/RestBindingProcessor.java
 
b/camel-core/src/main/java/org/apache/camel/processor/binding/RestBindingProcessor.java
index a217c64..7bb9b39 100644
--- 
a/camel-core/src/main/java/org/apache/camel/processor/binding/RestBindingProcessor.java
+++ 
b/camel-core/src/main/java/org/apache/camel/processor/binding/RestBindingProcessor.java
@@ -21,21 +21,34 @@ import java.util.Locale;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.AsyncProcessor;
 import org.apache.camel.Exchange;
+import org.apache.camel.processor.MarshalProcessor;
 import org.apache.camel.processor.UnmarshalProcessor;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.support.ServiceSupport;
+import org.apache.camel.support.SynchronizationAdapter;
 import org.apache.camel.util.AsyncProcessorHelper;
 import org.apache.camel.util.ExchangeHelper;
 import org.apache.camel.util.MessageHelper;
 
+/**
+ * A {@link org.apache.camel.Processor} that binds the REST DSL incoming and 
outgoing messages
+ * from sources of json or xml to Java Objects.
+ * <p/>
+ * The binding uses {@link org.apache.camel.spi.DataFormat} for the actual 
work to transform
+ * from xml/json to Java Objects and reverse again.
+ */
 public class RestBindingProcessor extends ServiceSupport implements 
AsyncProcessor {
 
     private final AsyncProcessor jsonUnmarshal;
     private final AsyncProcessor xmlUnmarshal;
+    private final AsyncProcessor jsonMmarshal;
+    private final AsyncProcessor xmlMmarshal;
 
     public RestBindingProcessor(DataFormat jsonDataFormat, DataFormat 
xmlDataFormat) {
         this.jsonUnmarshal = jsonDataFormat != null ? new 
UnmarshalProcessor(jsonDataFormat) : null;
+        this.jsonMmarshal = jsonDataFormat != null ? new 
MarshalProcessor(jsonDataFormat) : null;
         this.xmlUnmarshal = xmlDataFormat != null ? new 
UnmarshalProcessor(xmlDataFormat) : null;
+        this.xmlMmarshal = xmlDataFormat != null ? new 
MarshalProcessor(xmlDataFormat) : null;
     }
 
     @Override
@@ -56,8 +69,12 @@ public class RestBindingProcessor extends ServiceSupport 
implements AsyncProcess
         boolean isXml = contentType != null && 
contentType.toLowerCase(Locale.US).contains("xml");
         boolean isJson = contentType != null && 
contentType.toLowerCase(Locale.US).contains("json");
         if (isXml && xmlUnmarshal != null) {
+            // add reverse operation
+            exchange.addOnCompletion(new 
RestBindingMarshalOnCompletion(jsonMmarshal, xmlMmarshal, true));
             return xmlUnmarshal.process(exchange, callback);
         } else if (isJson && jsonUnmarshal != null) {
+            // add reverse operation
+            exchange.addOnCompletion(new 
RestBindingMarshalOnCompletion(jsonMmarshal, xmlMmarshal, false));
             return jsonUnmarshal.process(exchange, callback);
         }
 
@@ -66,8 +83,12 @@ public class RestBindingProcessor extends ServiceSupport 
implements AsyncProcess
         isXml = body.startsWith("<") || body.contains("xml");
 
         if (isXml && xmlUnmarshal != null) {
+            // add reverse operation
+            exchange.addOnCompletion(new 
RestBindingMarshalOnCompletion(jsonMmarshal, xmlMmarshal, true));
             return xmlUnmarshal.process(exchange, callback);
         } else if (jsonUnmarshal != null) {
+            // add reverse operation
+            exchange.addOnCompletion(new 
RestBindingMarshalOnCompletion(jsonMmarshal, xmlMmarshal, false));
             return jsonUnmarshal.process(exchange, callback);
         } else {
             // noop
@@ -90,4 +111,41 @@ public class RestBindingProcessor extends ServiceSupport 
implements AsyncProcess
     protected void doStop() throws Exception {
         // noop
     }
+
+    /**
+     * An {@link org.apache.camel.spi.Synchronization} that does the reverse 
operation
+     * of marshalling from POJO to json/xml
+     */
+    private final class RestBindingMarshalOnCompletion extends 
SynchronizationAdapter {
+
+        private final AsyncProcessor jsonMmarshal;
+        private final AsyncProcessor xmlMmarshal;
+        private final boolean wasXml;
+
+        private RestBindingMarshalOnCompletion(AsyncProcessor jsonMmarshal, 
AsyncProcessor xmlMmarshal, boolean wasXml) {
+            this.jsonMmarshal = jsonMmarshal;
+            this.xmlMmarshal = xmlMmarshal;
+            this.wasXml = wasXml;
+        }
+
+        @Override
+        public void onComplete(Exchange exchange) {
+            // only marshal if we succeeded
+
+            // need to prepare exchange first
+            ExchangeHelper.prepareOutToIn(exchange);
+
+            // TODO: add logic to detect what content-type is now
+            // also when we add support for @Produces then use that to 
determine if we should marshal to xml or json
+            try {
+                if (wasXml) {
+                    xmlMmarshal.process(exchange);
+                } else {
+                    jsonMmarshal.process(exchange);
+                }
+            } catch (Throwable e) {
+                exchange.setException(e);
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f8dd9c1c/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/CountryPojo.java
----------------------------------------------------------------------
diff --git 
a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/CountryPojo.java
 
b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/CountryPojo.java
new file mode 100644
index 0000000..e20d3df
--- /dev/null
+++ 
b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/CountryPojo.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.restlet;
+
+public class CountryPojo {
+
+    private String iso;
+    private String country;
+
+    public String getIso() {
+        return iso;
+    }
+
+    public void setIso(String iso) {
+        this.iso = iso;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f8dd9c1c/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletPojoInOutTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletPojoInOutTest.java
 
b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletPojoInOutTest.java
new file mode 100644
index 0000000..bb9e8ba
--- /dev/null
+++ 
b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletPojoInOutTest.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.restlet;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+/**
+ * @version 
+ */
+public class RestRestletPojoInOutTest extends RestletTestSupport {
+
+    @Test
+    public void testRestletPojoInOut() throws Exception {
+        String body = "{\"id\": 123, \"name\": \"Donald Duck\"}";
+        String out = template.requestBody("http://localhost:"; + portNum + 
"/users/lives", body, String.class);
+
+        assertNotNull(out);
+        assertEquals("{\"iso\":\"EN\",\"country\":\"England\"}", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // configure to use restlet on localhost with the given port
+                
restConfiguration().component("restlet").host("localhost").port(portNum);
+
+                // use the rest DSL to define the rest services
+                rest("/users/")
+                    .post("lives").type(UserPojo.class)
+                        .route()
+                        .bean(new UserService(), "livesWhere");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f8dd9c1c/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/UserService.java
----------------------------------------------------------------------
diff --git 
a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/UserService.java
 
b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/UserService.java
new file mode 100644
index 0000000..c1d8766
--- /dev/null
+++ 
b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/UserService.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.restlet;
+
+public class UserService {
+
+    public CountryPojo livesWhere(UserPojo user) {
+        CountryPojo answer = new CountryPojo();
+        if (user.getId() < 500) {
+            answer.setIso("EN");
+            answer.setCountry("England");
+        } else {
+            answer.setIso("SE");
+            answer.setCountry("Sweden");
+        }
+        return answer;
+    }
+
+}

Reply via email to