You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2009/06/11 18:57:34 UTC
svn commit: r783847 - in /camel/trunk/components/camel-web: pom.xml
src/main/java/org/apache/camel/web/resources/RouteResource.java
src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
Author: janstey
Date: Thu Jun 11 16:57:34 2009
New Revision: 783847
URL: http://svn.apache.org/viewvc?rev=783847&view=rev
Log:
CAMEL-1655 - Add support for saving Groovy and Ruby route code. Viewing
as Groovy or Ruby is TBD.
Thanks to Xueqiang Mi for this contribution!
Modified:
camel/trunk/components/camel-web/pom.xml
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java
camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
Modified: camel/trunk/components/camel-web/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/pom.xml?rev=783847&r1=783846&r2=783847&view=diff
==============================================================================
--- camel/trunk/components/camel-web/pom.xml (original)
+++ camel/trunk/components/camel-web/pom.xml Thu Jun 11 16:57:34 2009
@@ -73,6 +73,14 @@
<artifactId>camel-spring</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-groovy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-ruby</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>${jersey-version}</version>
Modified: camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java?rev=783847&r1=783846&r2=783847&view=diff
==============================================================================
--- camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java (original)
+++ camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/resources/RouteResource.java Thu Jun 11 16:57:34 2009
@@ -16,12 +16,15 @@
*/
package org.apache.camel.web.resources;
+import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
+import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -39,12 +42,17 @@
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.api.view.Viewable;
+import groovy.lang.GroovyClassLoader;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.ruby.RubyCamel;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.view.RouteDotGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jruby.Main;
/**
* A single Camel Route which is used to implement one or more
@@ -54,11 +62,23 @@
*/
public class RouteResource extends CamelChildResourceSupport {
private static final transient Log LOG = LogFactory.getLog(RouteResource.class);
+ private static final String LANGUAGE_XML = "Xml";
+ private static final String LANGUAGE_GROOVY = "Groovy";
+ private static final String LANGUAGE_RUBY = "Ruby";
+ private static final String LANGUAGE_SCALA = "Scala";
private RouteDefinition route;
private String error = "";
private String id;
+ // what language is used to define this route
+ private String language = LANGUAGE_XML;
+
+ // the route configuration: when language is Xml, the routeDefinition is
+ // null; when language is Groovy/Scala/Ruby, the routeDefinition contains
+ // the route definition class. It must be initialized because RouteResource
+ // is stateless.
+ private String routeDefinition = "";
public RouteResource(RoutesResource routesResource, RouteDefinition route) {
super(routesResource.getContextResource());
@@ -83,15 +103,40 @@
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// TODO fix to use "" namespace prefix
- // using this https://jaxb.dev.java.net/nonav/2.1.10/docs/vendorProperties.html#prefixmapper
+ // using this
+ // https://jaxb.dev.java.net/nonav/2.1.10/docs/vendorProperties.html#prefixmapper
StringWriter buffer = new StringWriter();
marshaller.marshal(route, buffer);
return buffer.toString();
}
/**
- * Returns the Graphviz DOT <a href="http://camel.apache.org/visualisation.html">Visualisation</a>
- * of this route
+ * Returns the language
+ */
+ public String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Returns the content of the route definition class
+ */
+ public String getRouteDefinition() {
+ if (language.equals(LANGUAGE_XML)) {
+ try {
+ return getRouteXml();
+ } catch (JAXBException e) {
+ // e.printStackTrace();
+ return "Error on marshal the route definition!";
+ }
+ } else {
+ return routeDefinition;
+ }
+ }
+
+ /**
+ * Returns the Graphviz DOT <a
+ * href="http://camel.apache.org/visualisation.html">Visualisation</a> of
+ * this route
*/
@GET
@Produces(Constants.DOT_MIMETYPE)
@@ -100,7 +145,6 @@
return generator.getRoutesText(getCamelContext());
}
-
/**
* Allows a route definition to be updated
*/
@@ -115,46 +159,188 @@
getCamelContext().addRouteDefinitions(Collections.singletonList(routeDefinition));
}
+ /**
+ * Allows a routes builder to be updated
+ */
+ public void postRoutes(RouteBuilder builder) throws Exception {
+ // remove current route
+ DefaultCamelContext camelContext = (DefaultCamelContext)getCamelContext();
+ camelContext.removeRouteDefinition(id);
+
+ // lets install the updated routes
+ camelContext.addRoutes(builder);
+ }
/**
* Updates a route definition using form encoded data from a web form
- *
- * @param formData is the form data POSTed typically from a HTML form with the <code>route</code> field used to encode
- * the XML text of the new route definition
+ *
+ * @param formData is the form data POSTed typically from a HTML form with
+ * the <code>route</code> field used to encode the XML text of
+ * the new route definition
*/
@POST
@Consumes("application/x-www-form-urlencoded")
public Response postRouteForm(@Context UriInfo uriInfo, Form formData) throws URISyntaxException {
// TODO replace the Form class with an injected bean?
- String xml = formData.getFirst("route", String.class);
+ String language = formData.getFirst("language", String.class);
+ String body = formData.getFirst("route", String.class);
if (LOG.isDebugEnabled()) {
- LOG.debug("new XML is: " + xml);
+ LOG.debug("new Route is: " + body);
}
- if (xml == null) {
- error = "No XML submitted!";
- } else {
- try {
- JAXBContext context = JAXBContext.newInstance(Constants.JAXB_PACKAGES);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- Object value = unmarshaller.unmarshal(new StringReader(xml));
- if (value instanceof RouteDefinition) {
- RouteDefinition routeDefinition = (RouteDefinition) value;
- postRoute(routeDefinition);
- return Response.seeOther(new URI("/routes")).build();
- } else {
- error = "Posted XML is not a route but is of type " + ObjectHelper.className(value);
- }
- } catch (JAXBException e) {
- error = "Failed to parse XML: " + e.getMessage();
- } catch (Exception e) {
- error = "Failed to install route: " + e.getMessage();
+ LOG.info(body);
+ if (body == null) {
+ error = "No Route submitted!";
+ } else if (language.equals(LANGUAGE_XML)) {
+ return parseXml(body);
+ } else if (language.equals(LANGUAGE_GROOVY)) {
+ return parseGroovy(body);
+ } else if (language.equals(LANGUAGE_RUBY)) {
+ return parseRuby(body);
+ } else if (language.equals(LANGUAGE_SCALA)) {
+ return parseScala(body);
+ }
+ error = "Not supproted language!";
+ return Response.ok(new Viewable("edit", this)).build();
+
+ }
+
+ /**
+ * process the route configuration defined in Xml
+ */
+ private Response parseXml(String xml) {
+ try {
+ JAXBContext context = JAXBContext.newInstance(Constants.JAXB_PACKAGES);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ Object value = unmarshaller.unmarshal(new StringReader(xml));
+ if (value instanceof RouteDefinition) {
+ RouteDefinition routeDefinition = (RouteDefinition)value;
+ postRoute(routeDefinition);
+ return Response.seeOther(new URI("/routes")).build();
+ } else {
+ error = "Posted XML is not a route but is of type " + ObjectHelper.className(value);
+ }
+ } catch (JAXBException e) {
+ error = "Failed to parse XML: " + e.getMessage();
+ } catch (Exception e) {
+ error = "Failed to install route: " + e.getMessage();
+ }
+ // lets re-render the form
+ return Response.ok(new Viewable("edit", this)).build();
+ }
+
+ /**
+ * process the route configuration defined in Groovy class
+ */
+ private Response parseGroovy(String route) {
+ try {
+ // store the route definition
+ File file = storeRoute(route, LANGUAGE_GROOVY);
+
+ // load the definition class into a RouteBuilder instance
+ GroovyClassLoader classLoader = new GroovyClassLoader();
+ Class clazz = classLoader.parseClass(file);
+ RouteBuilder builder = (RouteBuilder)clazz.newInstance();
+ LOG.info("Loaded builder: " + builder);
+
+ postRoutes(builder);
+
+ return Response.seeOther(new URI("/routes")).build();
+
+ } catch (IOException e) {
+ // e.printStackTrace();
+ error = "Failed to store the route: " + e.getMessage();
+ } catch (InstantiationException e) {
+ // e.printStackTrace();
+ error = "Failed to instantiate the route: " + e.getMessage();
+
+ } catch (IllegalAccessException e) {
+ // e.printStackTrace();
+ error = "Failed to instantiate the route: " + e.getMessage();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ error = "Failed to edit the route: " + e.getMessage();
+ }
+ // lets re-render the form
+ return Response.ok(new Viewable("edit", this)).build();
+ }
+
+ /**
+ * process the route configuration defined in Ruby class
+ */
+ private Response parseRuby(String route) {
+ try {
+ // add the script of addRouteBuilder into ruby script
+ route += "\n RubyCamel.addRouteBuilder(RubyRoute.new)";
+
+ // store the route definition
+ File file = storeRoute(route, LANGUAGE_RUBY);
+
+ // execute the ruby script, which will store the RouteBuilder
+ // instances into RubyCamel
+ String[] args = {file.getAbsolutePath()};
+ Main.main(args);
+
+ // get the route builders from the RubyCamel and add them into this
+ // route
+ List<RouteBuilder> list = RubyCamel.getRoutes();
+ for (RouteBuilder builder : list) {
+ postRoutes(builder);
}
+
+ return Response.seeOther(new URI("/routes")).build();
+
+ } catch (IOException e) {
+ // e.printStackTrace();
+ error = "Failed to store the route: " + e.getMessage();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ error = "Failed to edit the route: " + e.getMessage();
+
}
// lets re-render the form
return Response.ok(new Viewable("edit", this)).build();
}
/**
+ * process the route configuration defined in Scala class
+ */
+ private Response parseScala(String route) {
+ try {
+
+ // store the route definition
+ File file = storeRoute(route, LANGUAGE_SCALA);
+
+ // load the definition class
+
+ return Response.seeOther(new URI("/routes")).build();
+
+ } catch (IOException e) {
+ // e.printStackTrace();
+ error = "Failed to store the route: " + e.getMessage();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ error = "Failed to edit the route: " + e.getMessage();
+ }
+ // lets re-render the form
+ return Response.ok(new Viewable("edit", this)).build();
+ }
+
+ /**
+ * Stores the route definition class into a file
+ */
+ private File storeRoute(String route, String language) throws IOException {
+ // create a temporary file to store the route definition class
+ File file = File.createTempFile("Route-", "." + language);
+ FileWriter fw = new FileWriter(file);
+
+ // write the route into the file
+ fw.write(route);
+ fw.flush();
+ fw.close();
+ return file;
+ }
+
+ /**
* Looks up an individual route
*/
@Path("status")
Modified: camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp?rev=783847&r1=783846&r2=783847&view=diff
==============================================================================
--- camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp (original)
+++ camel/trunk/components/camel-web/src/main/webapp/org/apache/camel/web/resources/RouteResource/edit.jsp Thu Jun 11 16:57:34 2009
@@ -1,28 +1,33 @@
<html>
<head>
- <script type='text/javascript' src="<c:url value='/js/dojo/dojo.js'/>"></script>
- <script type='text/javascript' src="<c:url value='/js/bespin/editor/embed.js'/>"></script>
- <script type='text/javascript' src="<c:url value='/js/route.js'/>"></script>
+<script type='text/javascript' src="<c:url value='/js/dojo/dojo.js'/>"></script>
+<script type='text/javascript'
+ src="<c:url value='/js/bespin/editor/embed.js'/>"></script>
+<script type='text/javascript' src="<c:url value='/js/route.js'/>"></script>
- <title>Edit ${it.route.id}</title>
+<title>Edit ${it.route.id}</title>
</head>
<body>
-<form id="routeForm" action="<c:url value="/routes/${it.route.id}"/>" method="post">
+<form id="routeForm" action="<c:url value="/routes/${it.route.id}"/>"
+ method="post">
<table>
- <tr>
- <td>
- <h2>Edit ${it.route.id}</h2>
- </td>
- <td>
- <input type="submit" value="Save">
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <textarea id="route" name="route" style="width: 800px; height: 300px; border: 10px solid #ddd; -moz-border-radius: 10px; -webkit-border-radius: 10px;">${it.routeXml}</textarea>
- </td>
- </tr>
+ <tr>
+ <td>
+ <h2>Edit ${it.route.id}</h2>
+ </td>
+ <td><input type="submit" value="Save"> as <select id="language" name="language">
+ <option value="Xml" selected>XML</option>
+ <option value="Groovy">Groovy</option>
+ <option value="Ruby">Ruby</option>
+ <option value="Scala">Scala</option>
+ </select></td>
+ </tr>
+ <tr>
+ <td colspan="2"><textarea id="route" name="route"
+ style="width: 800px; height: 300px; border: 10px solid #ddd; -moz-border-radius: 10px; -webkit-border-radius: 10px;">${it.routeDefinition}</textarea>
+ </td>
+ </tr>
</table>
<div class="error">${it.error}</div>