├── .gitignore
├── .travis.yml
├── LICENSE.txt
├── README.md
├── babel-camel
├── babel-camel-core
│ ├── build.sbt
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── scala
│ │ │ └── io
│ │ │ └── xtech
│ │ │ └── babel
│ │ │ └── camel
│ │ │ ├── CamelDSL.scala
│ │ │ ├── EnricherDSL.scala
│ │ │ ├── ErrorHandlingDSL.scala
│ │ │ ├── HandlerDSL.scala
│ │ │ ├── LogDSL.scala
│ │ │ ├── MarshallerDSL.scala
│ │ │ ├── MulticastWithAggregationDSL.scala
│ │ │ ├── RecipientListDSL.scala
│ │ │ ├── ResequencerDSL.scala
│ │ │ ├── RouteConfigurationDSL.scala
│ │ │ ├── RouteIdDSL.scala
│ │ │ ├── SortDSL.scala
│ │ │ ├── ThrottlerDSL.scala
│ │ │ ├── TransactionDSL.scala
│ │ │ ├── TransformationDSL.scala
│ │ │ ├── ValidationDSL.scala
│ │ │ ├── WireTapDSL.scala
│ │ │ ├── builder
│ │ │ ├── RouteBuilder.scala
│ │ │ └── SpringRouteBuilder.scala
│ │ │ ├── model
│ │ │ ├── Aggregation.scala
│ │ │ ├── AggregationStrategy.scala
│ │ │ ├── CamelMessage.scala
│ │ │ ├── CamelSink.scala
│ │ │ ├── CamelSource.scala
│ │ │ ├── EmptyDefinition.scala
│ │ │ ├── EnrichDefinition.scala
│ │ │ ├── ErrorHandling.scala
│ │ │ ├── ErrorHandlingRouteDefinition.scala
│ │ │ ├── Expression.scala
│ │ │ ├── LogDefinition.scala
│ │ │ ├── MarshallerDefinition.scala
│ │ │ ├── MulticastAggregationDefinition.scala
│ │ │ ├── Predicate.scala
│ │ │ ├── RecipientListDefinition.scala
│ │ │ ├── ResequencerDefinition.scala
│ │ │ ├── RouteConfigurationDefinition.scala
│ │ │ ├── RouteIdDefinition.scala
│ │ │ ├── SortDefinition.scala
│ │ │ ├── ThrottlerDefinition.scala
│ │ │ ├── TransactionDefinition.scala
│ │ │ ├── ValidationDefinition.scala
│ │ │ └── WireTapDefinition.scala
│ │ │ └── parsing
│ │ │ ├── Aggregation.scala
│ │ │ ├── Basics.scala
│ │ │ ├── CamelParsing.scala
│ │ │ ├── Enricher.scala
│ │ │ ├── Handler.scala
│ │ │ ├── Log.scala
│ │ │ ├── Marshaller.scala
│ │ │ ├── RecipientList.scala
│ │ │ ├── Resequencer.scala
│ │ │ ├── RouteConfiguration.scala
│ │ │ ├── RouteId.scala
│ │ │ ├── Sort.scala
│ │ │ ├── Throttler.scala
│ │ │ ├── Transaction.scala
│ │ │ ├── Transformation.scala
│ │ │ ├── Validation.scala
│ │ │ ├── WireTap.scala
│ │ │ └── Wrapper.scala
│ │ └── test
│ │ ├── java
│ │ └── io
│ │ │ └── xtech
│ │ │ └── babel
│ │ │ └── camel
│ │ │ └── javaprocessors
│ │ │ └── JavaProcessors.java
│ │ ├── resources
│ │ ├── META-INF
│ │ │ └── spring
│ │ │ │ ├── context-constructor-injection.xml
│ │ │ │ ├── context-setter-injection.xml
│ │ │ │ └── context.xml
│ │ ├── log4j.properties
│ │ └── schema.sql
│ │ └── scala
│ │ └── io
│ │ └── xtech
│ │ └── babel
│ │ └── camel
│ │ ├── AggregateSpec.scala
│ │ ├── AsSpec.scala
│ │ ├── CamelDSLSpec.scala
│ │ ├── CamelMessageSpec.scala
│ │ ├── CompilationSpec.scala
│ │ ├── EnricherSpec.scala
│ │ ├── HandlerSpec.scala
│ │ ├── IdSpec.scala
│ │ ├── LogSpec.scala
│ │ ├── MarshallerSpec.scala
│ │ ├── MockSpec.scala
│ │ ├── MulticastSpec.scala
│ │ ├── RecipientListSpec.scala
│ │ ├── RequireAsSpec.scala
│ │ ├── ResequencerSpec.scala
│ │ ├── RouteConfigurationSpec.scala
│ │ ├── RouteIdSpec.scala
│ │ ├── SortSpec.scala
│ │ ├── SplitAggregateSpec.scala
│ │ ├── SplitFilterSpec.scala
│ │ ├── SplitSpec.scala
│ │ ├── ThrottlerSpec.scala
│ │ ├── TransactionSpec.scala
│ │ ├── TransformerSpec.scala
│ │ ├── ValidationSpec.scala
│ │ ├── WireTapSpec.scala
│ │ ├── XMLSpec.scala
│ │ ├── builder
│ │ ├── RouteBuilderSpec.scala
│ │ ├── spring
│ │ │ └── MyRouteBuilder.scala
│ │ └── springinjection
│ │ │ └── SetterInjectionRouteBuilder.scala
│ │ ├── choice
│ │ ├── ComplexChoiceSpec.scala
│ │ ├── DemoSpec.scala
│ │ └── SimpleChoiceSpec.scala
│ │ ├── sample
│ │ ├── SamplePhilosophySpec.scala
│ │ └── SampleSpec.scala
│ │ └── test
│ │ ├── SpecsContexts.scala
│ │ └── SpringSpecification.scala
└── babel-camel-mock
│ ├── build.sbt
│ └── src
│ ├── main
│ └── scala
│ │ └── io
│ │ └── xtech
│ │ └── babel
│ │ └── camel
│ │ └── mock
│ │ ├── MockDSL.scala
│ │ └── package.scala
│ └── test
│ └── scala
│ └── io
│ └── xtech
│ └── babel
│ └── camel
│ └── MockSpec.scala
├── babel-doc
├── CLA.md
├── Makefile
├── documentation.sh
├── generate-pdf.sh
├── images
│ ├── architecture-camel.png
│ ├── architecture.png
│ ├── logo-without-pole.png
│ ├── logo.png
│ └── vectorial
│ │ ├── architecture-camel.svg
│ │ ├── architecture.svg
│ │ ├── logo-without-pole.svg
│ │ ├── logo.idraw
│ │ ├── logo.svg
│ │ └── modules.svg
├── make.bat
└── source
│ ├── .gitignore
│ ├── .sphinx
│ └── exts
│ │ ├── .gitignore
│ │ └── includecode.py
│ ├── .static
│ ├── default.css
│ ├── eip.png
│ ├── lambda.png
│ ├── language.png
│ ├── modular.png
│ ├── osgi.png
│ └── type.png
│ ├── .templates
│ └── layout.html
│ ├── _themes
│ └── bootstrap
│ ├── architecture.rst
│ ├── camel
│ ├── basics.rst
│ ├── errormanagement.rst
│ ├── mock.rst
│ ├── routing.rst
│ ├── samples.rst
│ ├── spring.rst
│ └── transformation.rst
│ ├── cameluserguide.rst
│ ├── conf.py
│ ├── dev
│ ├── contribute.rst
│ ├── development.rst
│ ├── extension.rst
│ ├── installation.rst
│ ├── legal.rst
│ └── structure.rst
│ ├── devguide.rst
│ ├── grammar-diagrams
│ ├── handler-1.png
│ ├── handler-1.svg
│ ├── handler-2.png
│ ├── handler-2.svg
│ ├── handler-3.png
│ ├── handler-3.svg
│ ├── handler-4.png
│ └── handler-4.svg
│ ├── grammar.g
│ ├── grammar
│ └── handler.grammar
│ ├── index.rst
│ ├── opinion.rst
│ └── quickstartguide.rst
├── babel-fish
├── build.sbt
└── src
│ ├── main
│ └── scala
│ │ └── io
│ │ └── xtech
│ │ └── babel
│ │ └── fish
│ │ ├── DSL.scala
│ │ ├── DSLHelper.scala
│ │ ├── JVMLanguage.scala
│ │ ├── NamingStrategy.scala
│ │ ├── model
│ │ ├── AggregationDefinition.scala
│ │ ├── BaseDefinition.scala
│ │ ├── ChoiceDefinition.scala
│ │ ├── FilterDefinition.scala
│ │ ├── FromDefinition.scala
│ │ ├── Model.scala
│ │ ├── ScopeDefinition.scala
│ │ ├── SplitterDefinition.scala
│ │ ├── StepDefinition.scala
│ │ └── TransformerDefinition.scala
│ │ └── parsing
│ │ ├── Parser.scala
│ │ └── ParsingException.scala
│ └── test
│ ├── resources
│ └── log4j.properties
│ └── scala
│ └── io
│ └── xtech
│ └── babel
│ └── fish
│ ├── AggregateDSLSpec.scala
│ ├── DSLSpec.scala
│ ├── SplitterDSLSpec.scala
│ └── Test.scala
├── build.sbt
├── notes
├── 0.6.0.markdown
├── 0.7.0.markdown
└── about.markdown
├── pom.xml
├── project
├── Build.scala
├── Dependencies.scala
├── Formatting.scala
├── Publish.scala
└── plugins.sbt
└── src
└── main
└── ls
├── 0.6.json
├── 0.7.0.json
└── 0.8.0.json
/.gitignore:
--------------------------------------------------------------------------------
1 | *.ipr
2 | *.iml
3 | .idea
4 | target/
5 | build/
6 | *.aux
7 | *.nav
8 | *.toc
9 | *.out
10 | *.snm
11 | *.log
12 | *.pdf
13 | atlassian-ide-plugin.xml
14 | .jira-url
15 | .classpath
16 | .project
17 | .settings
18 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: scala
2 |
3 | scala:
4 | - 2.10.5
5 | - 2.11.6
6 |
7 | sbt_args: -no-colors
8 |
9 | env:
10 | global:
11 | - JVM_OPTS="-XX:MaxPermSize=256m -Xmx1024m -XX:ReservedCodeCacheSize=128m"
12 |
13 | script: sbt ++$TRAVIS_SCALA_VERSION clean coverage test
14 |
15 | after_success:
16 | - sbt coverageReport coverageAggregate
17 | - sbt coveralls
18 | - sbt codacyCoverage
19 |
20 |
21 | jdk:
22 | - oraclejdk7
23 | - openjdk7
24 | - oraclejdk8
25 |
26 | notifications:
27 | email:
28 | recipients:
29 | - github@crossing-tech.com
30 | on_success: never #default: change
31 | on_failure: always #default: always
32 | irc: "irc.codehaus.org#babel"
33 |
34 | sudo: false
35 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2014 Crossing-Tech SA
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Babel
2 | =====
3 |
4 | ### Build Status ###
5 |
6 | Master: [](https://travis-ci.org/Crossing-Tech/babel) [](https://coveralls.io/r/Crossing-Tech/babel?branch=master)
7 |
8 | ### Description ###
9 |
10 | Babel is an efficient way to write your integration solution. It stands as a generic Domain Specific Language (DSL) especially made for integration duties.
11 |
12 | Implementation of Babel have been done for [Apache Camel](http://camel.apache.org "Apache Camel website").
13 |
14 | ### Communication ###
15 |
16 | * [Babel documentation](http://crossing-tech.github.io/babel)
17 | * Google Group [Babel User List](https://groups.google.com/forum/#!forum/babel-user)
18 | * IRC: irc.codehaus.org:6697 #babel
19 |
20 | ### Project Requirements ###
21 | * Operating System: GNU/Linux, Mac OS X, Windows
22 | * Java VM: Oracle JDK 6
23 | * Sbt 0.13
24 |
25 | ### Project main dependencies ###
26 | * Scala library (2.14.4)
27 | * Apache camel (2.15.0)
28 |
29 | #### Backward compatibity ####
30 |
31 | Babel provides also artifacts for earlier versions of Apache Camel:
32 |
33 | To use Apache Camel version 2.12.x, use Babel with version 0.7.0-camel-2.12.4
34 |
35 | ### Quick Sbt Start Guide ###
36 |
37 | #### Add Babel to an existing sbt project ####
38 |
39 | To include Babel Camel in an existing Sbt project, just add the following dependency in your configuration file (replacing BABEL_VERSION by the version you want to use):
40 |
41 | ```libraryDependencies += "io.xtech.babel" %% "babel-camel-core" % "BABEL_VERSION"```
42 |
43 | If you are not installing the Babel project locally, you would also need to specify the Sonatype Snapshot repository in your project configuration:
44 |
45 | ```resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"```
46 |
47 | ### Quick Maven Start Guide ###
48 |
49 | #### Add Babel to an existing Maven project ####
50 |
51 | To include Babel Camel in an existing Maven project, just add the following dependency in your pom.xml file (replacing BABEL_VERSION by the version you want to use):
52 |
53 | ```xml
54 |
55 | io.xtech.babel
56 | babel-camel-core
57 | BABEL_VERSION
58 |
59 | ```
60 |
61 |
62 | ### Quick Installation Guide ###
63 |
64 | #### Build Babel from sources with Sbt ####
65 | ```
66 | #in a regular shell:
67 | git clone https://github.com/crossing-tech/babel.git
68 | cd babel
69 | export SBT_OPTS="-XX:MaxPermSize=256m -Xmx1024m"
70 | sbt test publish-local
71 | #or if you want to publish artifacts for maven
72 | sbt test publish-m2
73 | ```
74 |
75 | #### Build Babel from sources with Maven ####
76 | ```
77 | #in a regular shell:
78 | git clone https://github.com/crossing-tech/babel.git
79 | cd babel
80 | export MAVEN_OPTS="-XX:MaxPermSize=256m -Xmx1024m"
81 | mvn -Parchetype install
82 | ```
83 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/build.sbt:
--------------------------------------------------------------------------------
1 |
2 | organization := "io.xtech.babel"
3 |
4 | name := "babel-camel-core"
5 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/ErrorHandlingDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.ErrorHandlingRouteDefinition
12 | import io.xtech.babel.fish.{ BaseDSL, NoDSL }
13 |
14 | import scala.language.implicitConversions
15 | import scala.reflect.ClassTag
16 |
17 | /**
18 | * Adds the routeId keyword to the FromDSL (start of the route).
19 | */
20 | private[camel] class ErrorHandlingDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) {
21 |
22 | /**
23 | * the sub keyword.
24 | * @param errorHandlingChannel a given id for a new sub route.
25 | * @return the possibility to add other steps to the current DSL.
26 | */
27 | def handlingRoute(errorHandlingChannel: String): NoDSL = {
28 | //todo use a macro to ensure id is correct string
29 | require(Option(errorHandlingChannel).exists(_.trim.length > 0), "errorHandling Route can neither be null nor empty")
30 |
31 | val definition = ErrorHandlingRouteDefinition(errorHandlingChannel)
32 | baseDsl.step.next = Some(definition)
33 | new NoDSL {}
34 |
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/MarshallerDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model._
12 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL }
13 | import org.apache.camel.spi.DataFormat
14 |
15 | import scala.language.implicitConversions
16 | import scala.reflect.ClassTag
17 |
18 | /**
19 | * DSL adding the marshalling keywords.
20 | */
21 | private[camel] class MarshallerDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
22 |
23 | /**
24 | * The marshal keyword.
25 | * Defines how to transform inputs using a reference to a Bean.
26 | * @param ref reference of the bean used for the transformation
27 | * @return the possibility to add other steps to the current DSL
28 | */
29 | def marshal(ref: String): BaseDSL[Any] = {
30 |
31 | val props = MarshallerReference(ref)
32 | MarshallerDefinition(props)
33 |
34 | }
35 |
36 | /**
37 | * The marshal keyword.
38 | * Defines how to transform inputs using a dataFormat.
39 | * @param dataFormat used for the transformation
40 | * @return the possibility to add other steps to the current DSL
41 | */
42 | def marshal(dataFormat: DataFormat): BaseDSL[Any] = {
43 |
44 | val props = new MarshallerInstance(dataFormat)
45 | MarshallerDefinition(props)
46 |
47 | }
48 |
49 | /**
50 | * The unmarshal keyword.
51 | * Defines how to transform inputs using a reference to a Bean.
52 | * @param ref reference of the bean used for the transformation
53 | * @return the possibility to add other steps to the current DSL
54 | */
55 | def unmarshal(ref: String): BaseDSL[Any] = {
56 |
57 | val props = new UnmarshallerReference(ref)
58 | MarshallerDefinition(props)
59 |
60 | }
61 |
62 | /**
63 | * The unmarshal keyword.
64 | * Defines how to transform inputs using a dataFormat.
65 | * @param dataFormat used for the transformation
66 | * @return the possibility to add other steps to the current DSL
67 | */
68 | def unmarshal(dataFormat: DataFormat): BaseDSL[Any] = {
69 |
70 | val props = new UnmarshallerInstance(dataFormat)
71 | new MarshallerDefinition(props)
72 |
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/MulticastWithAggregationDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.MulticastAggregationDefinition
12 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL }
13 | import org.apache.camel.processor.aggregate.AggregationStrategy
14 |
15 | import scala.language.implicitConversions
16 | import scala.reflect.ClassTag
17 |
18 | /**
19 | * Adds the wiretap keyword to the BaseDSL.
20 | */
21 | private[camel] class MulticastWithAggregationDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
22 |
23 | /**
24 | * Multicast configuration. Defines how a multicast aggregates its messages.
25 | * @param aggregate the AggregationStrategy used to aggregates messages output by the multicast branches.
26 | * @return the possibility to add other steps to the current DSL
27 | */
28 | def withAggregation(aggregate: AggregationStrategy): BaseDSL[I] = MulticastAggregationDefinition[I](aggregate)
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/RecipientListDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.RecipientListDefinition
12 | import io.xtech.babel.camel.parsing.RecipientlistDSL
13 | import io.xtech.babel.fish.model.{ Expression, Message }
14 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL, MessageExpression }
15 |
16 | import scala.reflect.ClassTag
17 |
18 | private[camel] class RecipientListDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
19 |
20 | /**
21 | * The recipientList defines, using a function, the endpoits where the inputs should be routed.
22 | * @param function which defines the targeted endpoints
23 | * @tparam E
24 | * @return the possibility to add other steps to the current DSL
25 | */
26 | def recipientList[E](function: Message[I] => E): RecipientlistDSL[I] = {
27 |
28 | val definition = RecipientListDefinition(MessageExpression(function))
29 | baseDsl.step.next = Some(definition)
30 | new RecipientlistDSL[I](definition)
31 | }
32 |
33 | /**
34 | * The recipientList defines, using an expression, the endpoits where the inputs should be routed.
35 | * @param expression which defines the targeted endpoints
36 | * @tparam E type the targets (endpoints)
37 | * @return the possibility to add other steps to the current DSL
38 | */
39 | def recipientList[E](expression: Expression[I, E]): RecipientlistDSL[I] = {
40 |
41 | val definition = RecipientListDefinition(expression)
42 | baseDsl.step.next = Some(definition)
43 | new RecipientlistDSL[I](definition)
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/ResequencerDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.ResequencerDefinition
12 | import io.xtech.babel.fish.model.{ Expression, Message }
13 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL, MessageExpression }
14 | import org.apache.camel.model.config.ResequencerConfig
15 |
16 | import scala.language.implicitConversions
17 | import scala.reflect.ClassTag
18 |
19 | /**
20 | * DSL adding the resequence keyword.
21 | */
22 | private[camel] class ResequencerDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
23 |
24 | /**
25 | * The resequencer keyword in the dsl.
26 | * @param function on what part of the message the comparaison are done.
27 | * @param resequencerConfig an implementation of ResequencerConfig
28 | * @tparam E the type of the message, header, or a piece of the message
29 | * @return the possibility to add other steps to the current DSL
30 | */
31 | def resequence[E](function: Message[I] => E, resequencerConfig: ResequencerConfig): BaseDSL[I] = {
32 |
33 | ResequencerDefinition(MessageExpression(function), resequencerConfig)
34 |
35 | }
36 |
37 | /**
38 | * The resequencer keyword in the dsl.
39 | * @param expression on what part of the message the comparaison are done.
40 | * @param resequencerConfig an implementation of ResequencerConfig
41 | * @tparam E the type of the message, header, or a piece of the message
42 | * @return the possibility to add other steps to the current DSL
43 | */
44 | def resequence[E](expression: Expression[I, E], resequencerConfig: ResequencerConfig): BaseDSL[I] = {
45 |
46 | ResequencerDefinition(expression, resequencerConfig)
47 |
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/RouteIdDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.{ IdDefinition, RouteIdDefinition }
12 | import io.xtech.babel.fish.{ BaseDSL, BaseDSL2FromDSL, FromDSL }
13 |
14 | import scala.language.implicitConversions
15 | import scala.reflect.ClassTag
16 |
17 | /**
18 | * Adds the routeId keyword to the FromDSL (start of the route).
19 | */
20 | private[camel] class RouteIdDSL[I: ClassTag](protected val baseDsl: FromDSL[I]) extends BaseDSL2FromDSL[I] {
21 |
22 | /**
23 | * the routeId keyword.
24 | * @param id a given id for a route.
25 | * @return the possibility to add other steps to the current DSL
26 | */
27 | def routeId(id: String): FromDSL[I] = {
28 | require(Option(id).exists(_.trim.length > 0), "routeId can neither be null nor empty")
29 |
30 | RouteIdDefinition(id)
31 | }
32 | }
33 |
34 | private[camel] class IdDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends BaseDSL2FromDSL[I] {
35 | /**
36 | * the id keyword.
37 | * @param id a given id for the previous eip.
38 | * @return the possibility to add other steps to the current DSL
39 | */
40 | def id(id: String): BaseDSL[I] = {
41 | require(Option(id).exists(_.trim.length > 0), "id can neither be null nor empty")
42 |
43 | IdDefinition(id)
44 |
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/SortDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import java.util.{ Comparator, List => JList }
12 |
13 | import io.xtech.babel.camel.model.SortDefinition
14 | import io.xtech.babel.fish.model.{ Expression, Message }
15 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL, MessageExpression }
16 |
17 | import scala.collection.mutable
18 | import scala.language.implicitConversions
19 | import scala.reflect.ClassTag
20 |
21 | /**
22 | * Adds the sort keyword to the BaseDSL.
23 | */
24 | private[camel] class SortDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
25 |
26 | /**
27 | * The sort keyword.
28 | * @param function what element of the message is sorted.
29 | * @param comparator how are the element sorted.
30 | * @tparam O the output type.
31 | * @return the possibility to add other steps to the current DSL
32 | */
33 | def sort[O: ClassTag](function: Message[I] => mutable.IndexedSeq[O], comparator: Comparator[O]): BaseDSL[JList[O]] = {
34 |
35 | SortDefinition(MessageExpression(function), Some(comparator))
36 |
37 | }
38 |
39 | /**
40 | * The sort keyword. This keyword use the default camel comparator.
41 | * @param function what element of the message is sorted.
42 | * @tparam O the output type.
43 | * @return the possibility to add other steps to the current DSL
44 | */
45 | def sort[O: ClassTag](function: Message[I] => mutable.IndexedSeq[O]): BaseDSL[JList[O]] = {
46 |
47 | SortDefinition(MessageExpression(function), None)
48 |
49 | }
50 |
51 | def sort[O: ClassTag, C](expression: Expression[I, O], comparator: Comparator[C]): BaseDSL[JList[O]] = {
52 |
53 | SortDefinition(expression, Some(comparator))
54 |
55 | }
56 |
57 | def sort[O: ClassTag](expression: Expression[I, O]): BaseDSL[JList[O]] = {
58 |
59 | SortDefinition(expression, None)
60 |
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/ThrottlerDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.{ ThrottlerDefinitionExpression, ThrottlerDefinitionLong }
12 | import io.xtech.babel.fish.model.Message
13 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL, MessageExpression }
14 |
15 | import scala.reflect.ClassTag
16 |
17 | /**
18 | * DSL adding the throttle keyword
19 | */
20 | class ThrottlerDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
21 |
22 | /**
23 | * The throttle keyword. Defines the maximal rate that may be use in order to avoid overloading of the rest of the route
24 | * @param perSecond number of allowed messages in 1 second
25 | * @return the possibility to add other steps to the current DSL
26 | */
27 | def throttle(perSecond: Long): BaseDSL[I] = ThrottlerDefinitionLong(perSecond)
28 |
29 | /**
30 | * The throttle keyword. Defines the maximal rate that may be use in order to avoid overloading of the rest of the route
31 | * @param perSecond number of allowed messages in 1 second using a function
32 | * @return the possibility to add other steps to the current DSL
33 | */
34 | def throttle(perSecond: Message[I] => Long): BaseDSL[I] = ThrottlerDefinitionExpression(MessageExpression(perSecond))
35 | }
36 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/TransactionDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.TransactionDefinition
12 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL }
13 |
14 | import scala.language.implicitConversions
15 | import scala.reflect.ClassTag
16 |
17 | /**
18 | * Adds transaction in the Bable Camel DSL.
19 | */
20 | private[camel] class TransactionDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
21 |
22 | /**
23 | * The transacted keyword. Defines that the exchange flow goes through a transaction.
24 | * @return the possibility to add other steps to the current DSL
25 | */
26 | def transacted(): BaseDSL[I] = TransactionDefinition()
27 |
28 | /**
29 | * The transacted keyword. Defines that the exchange flow goes through a transaction.
30 | * @param ref the bean which is responsible for the transaction.
31 | * @return the possibility to add other steps to the current DSL
32 | */
33 | //todo: missing tests for transacted
34 | def transacted(ref: String): BaseDSL[I] = TransactionDefinition(Some(ref))
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/TransformationDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.{ BeanClassExpression, BeanNameExpression, BeanObjectExpression }
12 | import io.xtech.babel.fish.model.TransformerDefinition
13 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL }
14 |
15 | import scala.language.implicitConversions
16 | import scala.reflect._
17 |
18 | /**
19 | * Extentions to the base fish with extensions done with spring beans.
20 | * @param baseDsl the base fish.
21 | * @tparam I the message body type.
22 | */
23 | private[camel] class TransformationDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
24 |
25 | @deprecated("bean keyword is deprecated as it removes type information for the next keyword. " +
26 | "To improve you route typing, please use a process or a processBody with a function.", "version 0.5.0")
27 | def bean(str: String): BaseDSL[Any] = bean(str, None)
28 |
29 | @deprecated("bean keyword is deprecated as it removes type information for the next keyword. " +
30 | "To improve you route typing, please use a process or a processBody with a function.", "version 0.5.0")
31 | def bean(str: String, method: String): BaseDSL[Any] = bean(str, Some(method))
32 |
33 | private[this] def bean(beanRef: String, method: Option[String]): BaseDSL[Any] = {
34 |
35 | TransformerDefinition(BeanNameExpression(beanRef, method))
36 | }
37 |
38 | @deprecated("bean keyword is deprecated as it removes type information for the next keyword. " +
39 | "To improve you route typing, please use a process or a processBody with a function.", "version 0.5.0")
40 | def bean(ref: AnyRef): BaseDSL[Any] = bean(ref, None)
41 |
42 | private[this] def bean(bean: AnyRef, method: Option[String]): BaseDSL[Any] = {
43 |
44 | TransformerDefinition(BeanObjectExpression(bean, method))
45 |
46 | }
47 |
48 | @deprecated("bean keyword is deprecated as it removes type information for the next keyword. " +
49 | "To improve you route typing, please use a process or a processBody with a function.", "version 0.5.0")
50 | def bean(ref: AnyRef, method: String): BaseDSL[Any] = bean(ref, Some(method))
51 |
52 | @deprecated("bean keyword is deprecated as it removes type information for the next keyword. " +
53 | "To improve you route typing, please use a process or a processBody with a function.", "version 0.5.0")
54 | def bean(clazz: Class[_]): BaseDSL[Any] = bean(clazz, None)
55 |
56 | private[this] def bean(clazz: Class[_], method: Option[String]): BaseDSL[Any] = {
57 |
58 | TransformerDefinition(BeanClassExpression(clazz, method))
59 |
60 | }
61 |
62 | @deprecated("bean keyword is deprecated as it removes type information for the next keyword. " +
63 | "To improve you route typing, please use a process or a processBody with a function.", "version 0.5.0")
64 | def bean(clazz: Class[_], method: String): BaseDSL[Any] = bean(clazz, Some(method))
65 |
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/ValidationDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.ValidationDefinition
12 | import io.xtech.babel.fish._
13 | import io.xtech.babel.fish.model.{ Message, Predicate }
14 |
15 | import scala.reflect.ClassTag
16 |
17 | private[camel] class ValidationDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
18 |
19 | /**
20 | * The validate defines, using a function, how messages are validated.
21 | * An exception is thrown if the function returns false.
22 | * @param function which defines how a message is validated
23 | * @return the possibility to add other steps to the current DSL
24 | */
25 | def validate(function: Message[I] => Boolean): BaseDSL[I] = {
26 | ValidationDefinition(MessagePredicate(function))
27 | }
28 |
29 | /**
30 | * The validate defines, using a predicate (ex: simple language), how messages are validated.
31 | * An exception is thrown if the function returns false.
32 | * @param predicate which defines how a message is validated
33 | * @return the possibility to add other steps to the current DSL
34 | */
35 | def validate(predicate: Predicate[I]): BaseDSL[I] = {
36 | ValidationDefinition(predicate)
37 | }
38 |
39 | /**
40 | * The validate defines, using a function, how messages are validated.
41 | * An exception is thrown if the function returns false.
42 | * @param function which defines how a message is validated
43 | * @return the possibility to add other steps to the current DSL
44 | */
45 | def validateBody(function: I => Boolean): BaseDSL[I] = {
46 | ValidationDefinition(BodyPredicate(function))
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/WireTapDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.parsing.Wiring
12 | import io.xtech.babel.camel.model.{ CamelMessage, CamelSink, WireTapDefinition }
13 | import io.xtech.babel.fish.model.{ Message, StepDefinition, TransformerDefinition }
14 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL, MessageTransformationExpression }
15 |
16 | import scala.language.implicitConversions
17 | import scala.reflect.ClassTag
18 |
19 | /**
20 | * Adds the wiretap keyword to the BaseDSL.
21 | */
22 | private[camel] class WireTapDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
23 |
24 | /**
25 | * The wiretap keyword. Defines an endpoint where a copy of exchanges are forwarded, leaving the normal flow of the route.
26 | * @param uri of the endpoint which receives a copy of each exchange
27 | * @return the possibility to add other steps to the current DSL
28 | */
29 | def wiretap(uri: String): BaseDSL[I] = WireTapDefinition[I](CamelSink[I](uri))
30 |
31 | /**
32 | * The sideEffect lets you define a route as parameter that do not modify the output of the sideEffect keyword.
33 | * The side route is run sequentially and before the rest of the route.
34 | * @param w route which does not effect the rest of the route.
35 | * @return
36 | */
37 | def sideEffect(w: (BaseDSL[I]) => BaseDSL[_]): BaseDSL[I] = {
38 | val wireDefinition = new TransformerDefinition(wire)
39 | val dewireDefinition = new TransformerDefinition(dewire)
40 |
41 | baseDsl.step.next = Some(wireDefinition)
42 | val dsl = new BaseDSL[I](wireDefinition)
43 |
44 | w(dsl).step.next = Some(dewireDefinition)
45 | new BaseDSL[I](dewireDefinition)
46 | }
47 |
48 | private def propertyKey(count: Int): String = s"${Wiring.key}-${count + 1}"
49 | private def typeName(implicit ev: ClassTag[I]): String = ev.toString()
50 |
51 | private val wire: MessageTransformationExpression[I, I] = MessageTransformationExpression((msg: Message[I]) => {
52 | val headers = Wiring.getCount(msg)
53 | val wired = HeadersAndBody(msg.headers, msg.body)
54 | msg.asInstanceOf[CamelMessage[I]].withExchangeProperty(propertyKey(headers), wired) //TODO getOrElse
55 | })
56 |
57 | private val dewire: MessageTransformationExpression[I, I] = MessageTransformationExpression((msg: Message[I]) => {
58 | val key = s"${Wiring.key}-${Wiring.getCount(msg) + 1}"
59 | val wired: HeadersAndBody[I] = msg.asInstanceOf[CamelMessage[_]].exchangeProperties.get(key) match {
60 | case Some(w: HeadersAndBody[I]) => w
61 | case Some(other) => throw new WiredUnexpectedBodyType(typeName, other.getClass.getName) //should never happen
62 | case None => throw new WiredEmptyException()
63 | }
64 | msg.withOptionalBody(_ => wired.body).withHeaders(_ => wired.headers).asInstanceOf[CamelMessage[I]].withExchangeProperties(_ - key)
65 | })
66 |
67 | }
68 |
69 | class WiringDefinition() extends StepDefinition
70 |
71 | class WiredEmptyException extends IllegalArgumentException("Expected wired message but was empty in Babel sideEffect")
72 | class WiredUnexpectedBodyType(expected: String, actual: String)
73 | extends IllegalArgumentException(s"Body has not expected type in Babel sideEffect: expected $expected, but was $actual")
74 | case class HeadersAndBody[T](headers: Map[String, Any], body: Option[T])
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/builder/RouteBuilder.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.builder
10 |
11 | import io.xtech.babel.camel._
12 | import io.xtech.babel.camel.model.EmptyDefinition
13 | import io.xtech.babel.fish.model.RouteDefinition
14 | import io.xtech.babel.fish.{ DSL, NoDSL }
15 | import org.apache.camel.model.ModelCamelContext
16 | import org.apache.camel.{ CamelContext, RoutesBuilder, RuntimeCamelException }
17 |
18 | /**
19 | * Facility trait used to implement RouteBuilder in order to be more integrated into Camel.
20 | * This allows Babel Camel routes to be discovered by the Camel route scanner.
21 | */
22 | abstract class RouteBuilder extends DSL with CamelDSL with RoutesBuilder {
23 |
24 | //protected val namingStrategy: NamingStrategy = DefaultNamingStrategy
25 |
26 | /**
27 | * stores the RouteBuilder scope configuration
28 | */
29 | private[this] var handle: Option[EmptyDefinition] = None
30 |
31 | /**
32 | * adds the generated routes to the given Camel Context.
33 | * Used by Spring to populate a Camel Context while scanning the package (though xml configuration)
34 | * @param context to be populated with generated routes
35 | */
36 |
37 | def addRoutesToCamelContext(context: CamelContext): Unit = context match {
38 | case model: ModelCamelContext =>
39 | val definitions = handle.map(new RouteDefinition(_)).toList ::: this.build().toList
40 | val routeBuilder = this.routeBuilder(definitions)(model)
41 | model.addRoutes(routeBuilder)
42 |
43 | case other: CamelContext => throw new RuntimeCamelException("Requires a ModelCamelContext in order to add Babel Fish routes to it.")
44 | }
45 |
46 | /**
47 | * defines a set of rules that are applied on the RouteBuilder itself and not on a route.
48 | * @param block is the rules to be applied to the RouteBuilder
49 | * @return end of DSL: it is not possible to add other keywords to the current DSL.
50 | */
51 | protected def handle(block: HandlingDSL[Any] => Unit): NoDSL = {
52 | val dsl = new GlobalDSL()
53 | handle match {
54 | case None =>
55 | handle = Some(dsl.step)
56 | case Some(h) =>
57 | throw new CamelException.ErorrHandlingDefinedTwice
58 | }
59 | new HandlerDSL[Any](dsl).handle(block)
60 | }
61 |
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/builder/SpringRouteBuilder.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.builder
10 |
11 | import org.apache.camel.CamelContext
12 |
13 | /**
14 | * The SpringRouteBuilder is helpful to define Babel Camel routes which are dealing with Spring Beans.
15 | * As those beans may not have been initialized, the Babel Camel routes should be define in the body of the configure method.
16 | */
17 | trait SpringRouteBuilder extends RouteBuilder {
18 |
19 | /**
20 | * The configure method should contain the Babel Camel route definition.
21 | * It ensures the used Spring Beans are initialized before initializing the route definitions.
22 | * Used by the Camel RouteBuilder to load defined Babel Camel routes in the calling Camel Context.
23 | */
24 |
25 | def configure(): Unit
26 |
27 | override def addRoutesToCamelContext(context: CamelContext): Unit = {
28 | configure()
29 | super.addRoutesToCamelContext(context)
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/AggregationStrategy.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import org.apache.camel.Exchange
12 | import org.apache.camel.processor.aggregate.AggregationStrategy
13 |
14 | /**
15 | * An implementation of the fold operation for camel using an Aggregation Strategy
16 | * @param seed the initial value.
17 | * @param fold the fold function
18 | * @tparam I the input type.
19 | * @tparam O the output type.
20 | */
21 | class FoldBodyAggregationStrategy[I, O](seed: O, fold: (O, I) => O) extends AggregationStrategy {
22 |
23 | def aggregate(oldExchangeParam: Exchange, newExchange: Exchange): Exchange = {
24 |
25 | val oldExchange = Option(oldExchangeParam)
26 |
27 | oldExchange.fold {
28 |
29 | val newBody: I = newExchange.getIn.getBody.asInstanceOf[I]
30 |
31 | val newValue = fold(seed, newBody)
32 | newExchange.getIn.setBody(newValue)
33 | newExchange
34 | }(oldEx => {
35 |
36 | val oldBody: O = oldEx.getIn.getBody.asInstanceOf[O]
37 | val newBody: I = newExchange.getIn.getBody.asInstanceOf[I]
38 |
39 | val v = fold(oldBody, newBody)
40 | oldEx.getIn.setBody(v)
41 | oldEx
42 | })
43 | }
44 |
45 | }
46 |
47 | /**
48 | * An implementation of the reduce operation for camel using an Aggregation Strategy
49 | * @param reduce the reduce function.
50 | * @tparam I the input type.
51 | */
52 | class ReduceBodyAggregationStrategy[I](reduce: (I, I) => I) extends AggregationStrategy {
53 |
54 | def aggregate(oldExchangeParam: Exchange, newExchange: Exchange): Exchange = {
55 |
56 | val oldExchange = Option(oldExchangeParam)
57 |
58 | oldExchange.fold(newExchange)(oldEx => {
59 |
60 | val oldBody: I = oldEx.getIn.getBody.asInstanceOf[I]
61 | val newBody: I = newExchange.getIn.getBody.asInstanceOf[I]
62 |
63 | val newValue = reduce(oldBody, newBody)
64 |
65 | oldEx.getIn.setBody(newValue)
66 |
67 | oldEx
68 | })
69 | }
70 | }
71 |
72 | class EnrichBodyAggregationStrategy[I, O, T](reduce: (I, O) => T) extends AggregationStrategy {
73 | override def aggregate(oldExchangeParam: Exchange, newExchange: Exchange): Exchange = {
74 | val oldExchange = Option(oldExchangeParam)
75 |
76 | oldExchange.fold(newExchange)(oldEx => {
77 |
78 | val oldBody: I = oldEx.getIn.getBody.asInstanceOf[I]
79 | val newBody: O = newExchange.getIn.getBody.asInstanceOf[O]
80 |
81 | val newValue = reduce(oldBody, newBody)
82 |
83 | oldEx.getIn.setBody(newValue)
84 |
85 | oldEx
86 | })
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/CamelSink.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.Sink
12 |
13 | import scala.collection.immutable
14 |
15 | /**
16 | * Sink of a Camel route, implicitly created when calling {{{ to("uri") }}}
17 | * @param uri given to the `to` keyword
18 | */
19 | case class CamelSink[-I](uri: String) extends Sink[I, Any]
20 |
21 | /**
22 | * An utility object used in matchers to extract a Seq of a CamelSink from a Seq of Sink
23 | * Used in the multicast
24 | */
25 | protected[camel] object SeqCamelSink {
26 | def unapplySeq(m: immutable.Seq[Sink[_, _]]): Option[Seq[CamelSink[_]]] = {
27 |
28 | val t = m.collect {
29 | case s: CamelSink[_] => s
30 | }
31 |
32 | Some(t)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/CamelSource.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.Source
12 |
13 | /**
14 | * Source of a Camel route, implicitly created when calling {{{ from("uri") }}}
15 | * @param uri given to the `from` keyword
16 | */
17 | case class CamelSource(uri: String) extends Source[Any]
18 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/EmptyDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ FromDefinition, Source }
12 |
13 | /**
14 | * The EmptySource is used in the EmptyDefinition to specify there is no source to this definition.
15 | * @see io.xtech.babel.camel.model.EmptySource
16 | */
17 | object EmptySource extends Source[Any]
18 |
19 | /**
20 | * The EmptyDefinition takes place of the FromDefinition as beginning of a Route Definition. Such RouteDefinition are
21 | * defining the error management for the whole RouteBuilder.
22 | */
23 | class EmptyDefinition extends FromDefinition(classOf[Any], EmptySource)
24 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/EnrichDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Sink, StepDefinition }
12 | import org.apache.camel.processor.aggregate.AggregationStrategy
13 |
14 | /**
15 | * The definition of the enrichRef keyword in the DSL
16 | */
17 | case class EnrichDefinition[I, O](sink: Sink[I, O], aggregationStrategy: Either[String, AggregationStrategy]) extends StepDefinition
18 |
19 | /**
20 | * The definition of the pollEnrichRef keyword in the DSL
21 | */
22 | case class PollEnrichDefinition[I, O](sink: Sink[I, O], aggregationStrategy: Either[String, AggregationStrategy], timeout: Long = -1) extends StepDefinition
23 |
24 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/ErrorHandlingRouteDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 |
13 | /**
14 | * Declaration of a link to an Error handling Route configuration.
15 | * @param endpoint which connects to the error handling route.
16 | */
17 | case class ErrorHandlingRouteDefinition(endpoint: String) extends StepDefinition
18 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/LogDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 | import org.apache.camel.LoggingLevel
13 |
14 | /**
15 | * Defines the configuration of a log EIP.
16 | *
17 | */
18 | trait LogProps {
19 | def output: String
20 | }
21 |
22 | /**
23 | * defines a log with its output
24 | */
25 | case class LogMessage(output: String) extends LogProps
26 |
27 | /**
28 | * defines a log with its logging level and its output
29 | */
30 | case class LogLoggingLevelMessage(level: LoggingLevel, output: String) extends LogProps
31 |
32 | /**
33 | * defines a log with its logging level, its log name and its output
34 | */
35 | case class LogLoggingLevelLogNameMessage(level: LoggingLevel, LogName: String, output: String) extends LogProps
36 |
37 | /**
38 | * defines a log with its logging level, its log name, a marker and its output
39 | */
40 | case class LogLoggingLevelLogNameMarkerMessage(level: LoggingLevel, LogName: String, marker: String, output: String) extends LogProps
41 |
42 | /**
43 | * Defines a Log EIP.
44 | * @param props the logging information.
45 | * @see io.xtech.babel.camel.LogProps
46 | */
47 | case class LogDefinition(props: LogProps) extends StepDefinition
48 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/MarshallerDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 | import org.apache.camel.spi.DataFormat
13 |
14 | /**
15 | * defines a Marshall EIP.
16 | */
17 | trait MarshallerProps
18 |
19 | case class MarshallerInstance(dataFormat: DataFormat) extends MarshallerProps
20 |
21 | case class MarshallerReference(ref: String) extends MarshallerProps
22 |
23 | case class UnmarshallerInstance(dataFormat: DataFormat) extends MarshallerProps
24 |
25 | case class UnmarshallerReference(ref: String) extends MarshallerProps
26 |
27 | case class MarshallerDefinition(val props: MarshallerProps) extends StepDefinition
28 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/MulticastAggregationDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 | package io.xtech.babel.camel.model
9 |
10 | import io.xtech.babel.fish.model.StepDefinition
11 | import org.apache.camel.processor.aggregate.AggregationStrategy
12 |
13 | /**
14 | * The definition of how a multicast aggregates its messages.
15 | * @param aggregation how multicast is aggregating its messages.
16 | * @tparam I the body type of the input message.
17 | */
18 | case class MulticastAggregationDefinition[I](aggregation: AggregationStrategy) extends StepDefinition
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/Predicate.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Message, Predicate }
12 | import io.xtech.babel.fish.{ BodyPredicate, MessagePredicate }
13 | import org.apache.camel.builder.xml.XPathBuilder
14 | import org.apache.camel.{ Exchange, Predicate => CamelPredicate }
15 |
16 | import scala.util.{ Failure, Success, Try }
17 |
18 | /**
19 | * XPath defines a xpath used for an expression or a predicate.
20 | * @param str
21 | */
22 | case class XPath(str: String) extends Predicate[Any]
23 |
24 | /**
25 | * Wrapper for a scala function in a Camel Predicate.
26 | * @param predicate a predicate function.
27 | * @tparam I The type of the body message.
28 | */
29 | class CamelMessagePredicate[I](predicate: (Message[I] => Boolean)) extends CamelPredicate {
30 |
31 | /**
32 | * @see org.apache.camel.Predicate
33 | */
34 | def matches(exchange: Exchange): Boolean = {
35 | val message = new CamelMessage[I](exchange.getIn)
36 | predicate(message)
37 | }
38 | }
39 |
40 | /**
41 | * Wrapper for a scala function in a Camel Predicate.
42 | * @param predicate a predicate function.
43 | * @tparam I The type of the body message.
44 | */
45 | class CamelBodyPredicate[I](predicate: (I => Boolean)) extends CamelPredicate {
46 |
47 | /**
48 | * @see org.apache.camel.Predicate
49 | */
50 | def matches(exchange: Exchange): Boolean = Try {
51 | predicate(exchange.getIn.getBody.asInstanceOf[I])
52 | } match {
53 | case Success(result) =>
54 | result
55 | case Failure(ex) =>
56 | ex.printStackTrace()
57 | throw ex
58 | }
59 |
60 | }
61 |
62 | /**
63 | * Wrapper for a Camel Predicate.
64 | * Use to allow the use of Camel Predicate which is implicitly transformed into Babel Predicate.
65 | * @param predicate the real Camel Predicate
66 | */
67 | case class CamelPredicateWrapper(predicate: org.apache.camel.Predicate) extends Predicate[Any]
68 |
69 | /**
70 | * Facility object that provides a translation from a Babel predicate to a Camel one.
71 | */
72 | object Predicates {
73 |
74 | def toCamelPredicate[I](predicate: Predicate[I]): CamelPredicate = {
75 | predicate match {
76 | case MessagePredicate(function) => new CamelMessagePredicate(function)
77 | case BodyPredicate(function) => new CamelBodyPredicate(function)
78 | case XPath(xpath) => XPathBuilder.xpath(xpath)
79 | case CamelPredicateWrapper(camelPredicate) => camelPredicate
80 | case _ => throw new Exception(s"unknown type of predicate : $predicate")
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/RecipientListDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Expression, StepDefinition }
12 |
13 | /**
14 | * Defines a RecipientList EIP (Publish and Subscribe)
15 | */
16 | case class RecipientListDefinition[I, E](expression: Expression[I, E]) extends StepDefinition
17 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/ResequencerDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Expression, StepDefinition }
12 | import org.apache.camel.model.config.ResequencerConfig
13 |
14 | /**
15 | * The definition of a resequencer eip.
16 | * @param expression on what part of the message the comparaison are done.
17 | * @param resequencer the configuration of the resquencer.
18 | * @tparam I the type of the message body.
19 | * @tparam E the type of the message, header, or a piece of the message.
20 | */
21 | case class ResequencerDefinition[I, E](expression: Expression[I, E], resequencer: ResequencerConfig) extends StepDefinition
22 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/RouteConfigurationDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 | import org.apache.camel.Route
13 | import org.apache.camel.spi.RoutePolicy
14 |
15 | /*
16 | * Route configuration model
17 | */
18 |
19 | case class AutoStartDefinition(noAutoStart: Boolean) extends StepDefinition
20 |
21 | case class OnExchangeBeginDefinition[I](callback: (Route, CamelMessage[I]) => Unit) extends StepDefinition
22 |
23 | case class OnExchangeDoneDefinition[I](callback: (Route, CamelMessage[I]) => Unit) extends StepDefinition
24 |
25 | case class OnStopDefinition(callback: (Route) => Unit) extends StepDefinition
26 |
27 | case class OnResumeDefinition(callback: (Route) => Unit) extends StepDefinition
28 |
29 | case class OnInitDefinition(callback: (Route) => Unit) extends StepDefinition
30 |
31 | case class OnRemoveDefinition(callback: (Route) => Unit) extends StepDefinition
32 |
33 | case class OnStartDefinition(callback: (Route) => Unit) extends StepDefinition
34 |
35 | case class OnSuspendDefinition(callback: (Route) => Unit) extends StepDefinition
36 |
37 | case class RoutePolicyDefinition(policy: Seq[RoutePolicy]) extends StepDefinition
38 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/RouteIdDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 |
13 | /**
14 | * Declaration of an id for a route.
15 | * @param routeId the route id.
16 | */
17 | case class RouteIdDefinition(val routeId: String) extends StepDefinition
18 |
19 | case class FromIdDefinition(val Id: String) extends StepDefinition
20 |
21 | case class IdDefinition(val Id: String) extends StepDefinition
22 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/SortDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import java.util.Comparator
12 |
13 | import io.xtech.babel.fish.model.{ Expression, StepDefinition }
14 |
15 | /**
16 | * The definition of the sort keyword in the DSL
17 | * @param expression what element of the message is sorted.
18 | * @param comparator how are the element sorted.
19 | * @tparam I input type.
20 | * @tparam O output type.
21 | */
22 | case class SortDefinition[I, O, C](expression: Expression[I, O], comparator: Option[Comparator[C]]) extends StepDefinition
23 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/ThrottlerDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Expression, StepDefinition }
12 |
13 | /**
14 | * Declaration of a throttler definition
15 | * @param perSecond maximal number of message allowed per second
16 | */
17 | case class ThrottlerDefinitionLong(perSecond: Long) extends StepDefinition
18 |
19 | /**
20 | * Declaration of a throttler definition
21 | * @param perSecond expression defining maximal number of message allowed per second
22 | */
23 | case class ThrottlerDefinitionExpression[I](perSecond: Expression[I, Long]) extends StepDefinition
24 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/TransactionDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 |
13 | /**
14 | * The definition of a transaction.
15 | * @param ref a reference.
16 | */
17 | case class TransactionDefinition(ref: Option[String] = None) extends StepDefinition
18 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/ValidationDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Predicate, StepDefinition }
12 |
13 | case class ValidationDefinition[I](expression: Predicate[I]) extends StepDefinition
14 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/model/WireTapDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.model
10 |
11 | import io.xtech.babel.fish.model.{ Sink, StepDefinition }
12 | import org.apache.camel.processor.aggregate.AggregationStrategy
13 |
14 | import scala.collection.immutable
15 |
16 | /**
17 | * Defines a sink where each message is just copied.
18 | */
19 | case class WireTapDefinition[T](sink: CamelSink[T]) extends StepDefinition
20 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Aggregation.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ CamelMessageExpression, Expressions, FoldBodyAggregationStrategy, ReduceBodyAggregationStrategy }
12 | import io.xtech.babel.camel.model.Aggregation._
13 | import io.xtech.babel.fish.model.AggregationDefinition
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.{ AggregateDefinition, ProcessorDefinition }
16 |
17 | import scala.collection.immutable
18 |
19 | /**
20 | * Defines the parsing of aggregation definitions.
21 | */
22 | private[babel] trait Aggregation extends CamelParsing {
23 |
24 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
25 |
26 | // parsing of an aggregation definition
27 | private[this] def parse: Process = {
28 |
29 | // parse a native camel aggregation
30 | case StepInformation(AggregationDefinition(CamelAggregation(correlationExpression, aggregationStrategy, completionStrategies)), camelProcessorDefinition: ProcessorDefinition[_]) => {
31 |
32 | val nextProcDef = camelProcessorDefinition.aggregate(Expressions.toCamelExpression(correlationExpression), aggregationStrategy)
33 |
34 | competion(nextProcDef, completionStrategies)
35 |
36 | nextProcDef
37 | }
38 |
39 | case StepInformation(AggregationDefinition(CamelReferenceAggregation(correlationExpression, ref, completionStrategies)), camelProcessorDefinition: ProcessorDefinition[_]) => {
40 |
41 | val nextProcDef = camelProcessorDefinition.aggregate.expression(Expressions.toCamelExpression(correlationExpression)).aggregationStrategyRef(ref)
42 |
43 | competion(nextProcDef, completionStrategies)
44 |
45 | nextProcDef
46 | }
47 |
48 | // parse a reduce definition
49 | case StepInformation(AggregationDefinition(ReduceBody(reduce, groupBy, completionStrategies)), camelProcessorDefinition: ProcessorDefinition[_]) => {
50 | val aggregationStrategy = new ReduceBodyAggregationStrategy(reduce)
51 |
52 | val nextProcDef = camelProcessorDefinition.aggregate(CamelMessageExpression(groupBy), aggregationStrategy)
53 |
54 | competion(nextProcDef, completionStrategies)
55 |
56 | nextProcDef
57 | }
58 |
59 | // parse a fold definition
60 | case StepInformation(AggregationDefinition(FoldBody(seed, fold, groupBy, completionStrategies)), camelProcessorDefinition: ProcessorDefinition[_]) => {
61 | val aggregationStrategy = new FoldBodyAggregationStrategy(seed, fold)
62 |
63 | val nextProcDef = camelProcessorDefinition.aggregate(CamelMessageExpression(groupBy), aggregationStrategy)
64 |
65 | competion(nextProcDef, completionStrategies)
66 |
67 | nextProcDef
68 | }
69 | }
70 |
71 | private[this] def competion(aggregateDefinition: AggregateDefinition, completionStrategies: immutable.Seq[CompletionStrategy]): Unit = {
72 | for (completion <- completionStrategies) {
73 | completion match {
74 | case CompletionInterval(time) => {
75 | aggregateDefinition.setCompletionInterval(time)
76 | }
77 | case CompletionSize(size) => {
78 | aggregateDefinition.setCompletionSize(size)
79 | }
80 | case CompletionTimeout(time) => {
81 | aggregateDefinition.setCompletionTimeout(time)
82 | }
83 | case ForceCompletionOnStop => {
84 | aggregateDefinition.forceCompletionOnStop()
85 | }
86 | case CompletionFromBatchConsumer => {
87 | aggregateDefinition.completionFromBatchConsumer()
88 | }
89 | }
90 | }
91 | }
92 | }
93 |
94 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/CamelParsing.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.fish.parsing.Parsing
12 | import org.apache.camel.builder.RouteBuilder
13 |
14 | /**
15 | * The CamelParsing is the parent trait of each keyword parser in babel-camel.
16 | */
17 | protected[camel] trait CamelParsing extends Parsing[RouteBuilder]
18 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Enricher.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model._
12 | import io.xtech.babel.camel.{ CamelDSL, EnricherDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.{ EnrichDefinition => CamelEnrichDefinition, PollEnrichDefinition => CamelPollEnrichDefinition, ProcessorDefinition }
16 | import org.apache.camel.processor.aggregate.AggregationStrategy
17 |
18 | import scala.collection.immutable
19 | import scala.language.implicitConversions
20 | import scala.reflect.ClassTag
21 |
22 | /**
23 | * Defines the enrich and pollEnrich keyword in the DSL.
24 | */
25 | private[babel] trait Enricher extends CamelParsing {
26 | self: CamelDSL =>
27 |
28 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
29 |
30 | /**
31 | * Parsing of the enricher feature
32 | */
33 | private[this] def parse: Process = {
34 |
35 | // parsing of the enrichRef keyword
36 | case StepInformation(step @ EnrichDefinition(CamelSink(resourceUri), aggregationRef), camelProcessorDefinition: ProcessorDefinition[_]) => {
37 |
38 | val camelEnrichDefinition = aggregationRef match {
39 | case Left(ref) =>
40 | val definition = new CamelEnrichDefinition(resourceUri)
41 | definition.setAggregationStrategyRef(ref)
42 | definition
43 | case Right(strategy) =>
44 | new CamelEnrichDefinition(strategy, resourceUri)
45 | }
46 |
47 | camelProcessorDefinition.addOutput(camelEnrichDefinition)
48 | camelProcessorDefinition.withId(step)
49 |
50 | }
51 |
52 | // parsing of the pollEnrich keyword
53 | case StepInformation(step @ PollEnrichDefinition(CamelSink(resourceUri), aggregationRef, timeout), camelProcessorDefinition: ProcessorDefinition[_]) => {
54 |
55 | val camelPollEnrichDefinition = aggregationRef match {
56 | case Left(ref) =>
57 | val definition = new CamelPollEnrichDefinition()
58 | definition.setResourceUri(resourceUri)
59 | definition.setAggregationStrategyRef(ref)
60 | definition.setTimeout(timeout)
61 | definition
62 | case Right(strategy) =>
63 | new CamelPollEnrichDefinition(strategy, resourceUri, timeout)
64 | }
65 |
66 | camelProcessorDefinition.addOutput(camelPollEnrichDefinition)
67 | camelProcessorDefinition.withId(step)
68 | }
69 | }
70 |
71 | protected implicit def enrichDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]) = new EnricherDSL(baseDsl)
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Handler.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ ErrorHandling, ErrorHandlingRouteDefinition, OnExceptionDefinition }
12 | import io.xtech.babel.camel.{ CamelDSL, HandlerDSL }
13 | import io.xtech.babel.fish.parsing.StepInformation
14 | import io.xtech.babel.fish.{ BodyPredicate, FromDSL }
15 | import org.apache.camel.builder.RouteBuilder
16 | import org.apache.camel.model.ProcessorDefinition
17 |
18 | import scala.collection.JavaConverters._
19 | import scala.collection.immutable
20 | import scala.language.implicitConversions
21 | import scala.reflect.ClassTag
22 |
23 | /**
24 | * The Exception Handler parser.
25 | */
26 | private[babel] trait Handler extends CamelParsing {
27 | self: CamelDSL =>
28 |
29 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
30 |
31 | /**
32 | * parses the error handling keyword, at both level : Route and RouteBuilder
33 | */
34 | private[this] def parse: Process = {
35 |
36 | //handling at Route level
37 | case s @ StepInformation(exception: OnExceptionDefinition[_], camelProcessorDefinition: ProcessorDefinition[_]) =>
38 | parseOnException(exception, camelProcessorDefinition.onException(exception.exception))
39 | s.buildHelper //if sub exists for this onException, it should be parsed specifically...
40 |
41 | case s @ StepInformation(handler: ErrorHandling, camelProcessorDefinition: ProcessorDefinition[_]) =>
42 | s.buildHelper.getRouteCollection.getRoutes.asScala.lastOption.map(_.setErrorHandlerBuilder(handler.camelErrorHandlerBuilder))
43 | camelProcessorDefinition
44 |
45 | //handling at RouteBuilder level
46 | case s @ StepInformation(exception: OnExceptionDefinition[_], _: RouteBuilder) =>
47 | val camelProcessor = s.buildHelper.onException(exception.exception)
48 | parseOnException(exception, camelProcessor)
49 | (camelProcessor, s.buildHelper)
50 |
51 | case s @ StepInformation(handler: ErrorHandling, _: RouteBuilder) =>
52 | s.buildHelper.errorHandler(handler.camelErrorHandlerBuilder)
53 | s.buildHelper
54 |
55 | case step @ StepInformation(d: ErrorHandlingRouteDefinition, camelProcessor) => {
56 | //is parsed by the previous step, @see parseOnException
57 | }
58 |
59 | }
60 |
61 | private[this] def parseOnException[T <: Throwable, I](exception: OnExceptionDefinition[T], processor: org.apache.camel.model.OnExceptionDefinition): Unit = {
62 | //Warning: predicates and functions here may cause Camel to fail silently (without printing any exception)
63 |
64 | exception.applyToCamel(processor)
65 |
66 | //parse the handlingRoute if any
67 | exception.next.foreach {
68 | case channel: ErrorHandlingRouteDefinition =>
69 | val to = processor.to(channel.endpoint)
70 | namingStrategy.name(channel).foreach(to.id)
71 | to
72 | }
73 | processor.end()
74 | }
75 |
76 | protected implicit def handlerDSLExtension[I: ClassTag](baseDsl: FromDSL[I]): HandlerDSL[I] = new HandlerDSL(baseDsl)
77 |
78 | //used to allow user to define a predicate on exceptions from a boolean
79 | protected implicit def booleanAsPredicate[Any](bool: Boolean): BodyPredicate[Any] = {
80 | BodyPredicate[Any](_ => bool)
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Log.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model._
12 | import io.xtech.babel.camel.{ CamelDSL, LogDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 |
17 | import scala.collection.immutable
18 | import scala.language.implicitConversions
19 | import scala.reflect.ClassTag
20 |
21 | /**
22 | * The log parser.
23 | */
24 | private[babel] trait Log extends CamelParsing {
25 | self: CamelDSL =>
26 |
27 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
28 |
29 | private[this] def parse: Process = {
30 |
31 | case StepInformation(step @ LogDefinition(LogMessage(message)), camelProcessorDefinition: ProcessorDefinition[_]) => {
32 | camelProcessorDefinition.log(message).withId(step)
33 | }
34 |
35 | case StepInformation(step @ LogDefinition(LogLoggingLevelMessage(level, message)), camelProcessorDefinition: ProcessorDefinition[_]) => {
36 | camelProcessorDefinition.log(level, message).withId(step)
37 | }
38 |
39 | case StepInformation(step @ LogDefinition(LogLoggingLevelLogNameMessage(level, name, message)), camelProcessorDefinition: ProcessorDefinition[_]) => {
40 | camelProcessorDefinition.log(level, name, message).withId(step)
41 | }
42 |
43 | case StepInformation(step @ LogDefinition(LogLoggingLevelLogNameMarkerMessage(level, name, marker, message)), camelProcessorDefinition: ProcessorDefinition[_]) => {
44 | camelProcessorDefinition.log(level, name, marker, message).withId(step)
45 | }
46 | }
47 |
48 | protected implicit def logDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): LogDSL[I] = new LogDSL(baseDsl)
49 | }
50 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Marshaller.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model._
12 | import io.xtech.babel.camel.{ CamelDSL, MarshallerDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 |
17 | import scala.collection.immutable
18 | import scala.language.implicitConversions
19 | import scala.reflect.ClassTag
20 |
21 | /**
22 | * The `marshall` / `unmarshall` parser
23 | */
24 | private[babel] trait Marshaller extends CamelParsing {
25 | self: CamelDSL =>
26 |
27 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
28 |
29 | /**
30 | * Parsing of the marshalling feature
31 | */
32 | private[this] def parse: Process = {
33 | case StepInformation(step @ MarshallerDefinition(MarshallerInstance(dataFormat)), camelProcessorDefinition: ProcessorDefinition[_]) => {
34 | camelProcessorDefinition.marshal(dataFormat).withId(step)
35 |
36 | }
37 | case StepInformation(step @ MarshallerDefinition(MarshallerReference(ref)), camelProcessorDefinition: ProcessorDefinition[_]) => {
38 | camelProcessorDefinition.marshal(ref).withId(step)
39 |
40 | }
41 | case StepInformation(step @ MarshallerDefinition(UnmarshallerInstance(dataFormat)), camelProcessorDefinition: ProcessorDefinition[_]) => {
42 | camelProcessorDefinition.unmarshal(dataFormat).withId(step)
43 |
44 | }
45 | case StepInformation(step @ MarshallerDefinition(UnmarshallerReference(ref)), camelProcessorDefinition: ProcessorDefinition[_]) => {
46 | camelProcessorDefinition.unmarshal(ref).withId(step)
47 |
48 | }
49 | }
50 |
51 | protected implicit def marshallerDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]) = new MarshallerDSL(baseDsl)
52 | }
53 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/RecipientList.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ Expressions, RecipientListDefinition }
12 | import io.xtech.babel.camel.{ CamelDSL, RecipientListDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.model.StepDefinition
15 | import io.xtech.babel.fish.parsing.StepInformation
16 | import org.apache.camel.model.ProcessorDefinition
17 |
18 | import scala.collection.immutable
19 | import scala.language.implicitConversions
20 | import scala.reflect.ClassTag
21 |
22 | /**
23 | * The recipientList parser.
24 | */
25 | private[babel] trait RecipientList extends CamelParsing {
26 | self: CamelDSL =>
27 |
28 | // insert the extension in the base fish
29 | protected implicit def recipientListDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]) = new RecipientListDSL(baseDsl)
30 |
31 | // add the recipientList parser to the other parsers
32 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
33 |
34 | private[this] def parse: Process = {
35 | case StepInformation(definition @ RecipientListDefinition(expression), camelProcessorDefinition: ProcessorDefinition[_]) => {
36 |
37 | camelProcessorDefinition.recipientList(Expressions.toCamelExpression(expression)).withId(definition)
38 |
39 | }
40 | }
41 | }
42 |
43 | class RecipientlistDSL[I: ClassTag](step: StepDefinition) extends BaseDSL[I](step)
44 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Resequencer.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ Expressions, ResequencerDefinition }
12 | import io.xtech.babel.camel.{ CamelDSL, ResequencerDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 | import org.apache.camel.model.config.{ BatchResequencerConfig, StreamResequencerConfig }
17 |
18 | import scala.collection.immutable
19 | import scala.language.implicitConversions
20 | import scala.reflect.ClassTag
21 |
22 | /**
23 | * The parser of resequencer definition.
24 | */
25 | private[babel] trait Resequencer extends CamelParsing {
26 | self: CamelDSL =>
27 |
28 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
29 |
30 | private[this] def parse: Process = {
31 |
32 | case StepInformation(step @ ResequencerDefinition(expression, batch: BatchResequencerConfig), camelProcessorDefinition: ProcessorDefinition[_]) => {
33 |
34 | camelProcessorDefinition.resequence(Expressions.toCamelExpression(expression)).batch(batch).withId(step)
35 |
36 | }
37 | case StepInformation(step @ ResequencerDefinition(expression, stream: StreamResequencerConfig), camelProcessorDefinition: ProcessorDefinition[_]) => {
38 |
39 | camelProcessorDefinition.resequence(Expressions.toCamelExpression(expression)).stream(stream).withId(step)
40 |
41 | }
42 | }
43 |
44 | protected implicit def resequencerDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): ResequencerDSL[I] = new ResequencerDSL(baseDsl)
45 | }
46 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/RouteId.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model._
12 | import io.xtech.babel.camel.{ CamelDSL, IdDSL, RouteIdDSL }
13 | import io.xtech.babel.fish.model.FromDefinition
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import io.xtech.babel.fish.{ BaseDSL, FromDSL }
16 | import org.apache.camel.model.{ ProcessorDefinition, RouteDefinition }
17 |
18 | import scala.collection.immutable
19 | import scala.language.implicitConversions
20 | import scala.reflect.ClassTag
21 | import scala.util.Try
22 |
23 | /**
24 | * The routeId parser.
25 | */
26 | private[babel] trait RouteId extends CamelParsing {
27 | self: CamelDSL =>
28 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
29 |
30 | private[this] def parse: Process = {
31 |
32 | case s @ StepInformation(RouteIdDefinition(routeId), camelProcessorDefinition: ProcessorDefinition[_]) => {
33 |
34 | //renames the from id
35 | s.previousStepHelper match {
36 | case from: RouteDefinition =>
37 | Try {
38 | namingStrategy.newRoute()
39 | namingStrategy.routeId = Some(routeId)
40 | namingStrategy.name(FromDefinition(classOf[Any], from.getInputs.get(0).getUri())).foreach(from.id(_))
41 | }
42 | case other: Any =>
43 | namingStrategy.routeId = Some(routeId)
44 | }
45 | camelProcessorDefinition.routeId(routeId)
46 |
47 | }
48 |
49 | case StepInformation(IdDefinition(id), camelProcessorDefinition: ProcessorDefinition[_]) => {
50 |
51 | camelProcessorDefinition.id(id)
52 |
53 | }
54 |
55 | }
56 |
57 | implicit protected def routeIdDSLExtension[I: ClassTag](baseDsl: FromDSL[I]): RouteIdDSL[I] = new RouteIdDSL(baseDsl)
58 |
59 | implicit protected def idDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): IdDSL[I] = new IdDSL(baseDsl)
60 | }
61 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Sort.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ Expressions, SortDefinition }
12 | import io.xtech.babel.camel.{ CamelDSL, SortDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 |
17 | import scala.collection.immutable
18 | import scala.language.implicitConversions
19 | import scala.reflect.ClassTag
20 |
21 | /**
22 | * The sort parser.
23 | */
24 | private[babel] trait Sort extends CamelParsing {
25 | self: CamelDSL =>
26 |
27 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
28 |
29 | private[this] def parse: Process = {
30 |
31 | case StepInformation(step @ SortDefinition(expression, Some(comparator)), camelProcessorDefinition: ProcessorDefinition[_]) => {
32 |
33 | camelProcessorDefinition.sort(Expressions.toJavaListCamelExpression(expression), comparator).withId(step)
34 |
35 | }
36 |
37 | case StepInformation(step @ SortDefinition(expression, None), camelProcessorDefinition: ProcessorDefinition[_]) => {
38 |
39 | camelProcessorDefinition.sort(Expressions.toJavaListCamelExpression(expression)).withId(step)
40 |
41 | }
42 | }
43 |
44 | implicit protected def sortDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): SortDSL[I] = new SortDSL(baseDsl)
45 | }
46 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Throttler.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ Expressions, ThrottlerDefinitionExpression, ThrottlerDefinitionLong }
12 | import io.xtech.babel.camel.{ CamelDSL, ThrottlerDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 |
17 | import scala.reflect.ClassTag
18 |
19 | /**
20 | * Defines the parsing of the throttle keyword.
21 | */
22 | trait Throttler extends CamelParsing {
23 | self: CamelDSL =>
24 |
25 | private val parse: Process = {
26 | case StepInformation(step @ ThrottlerDefinitionLong(perSecond), camelProcessor: ProcessorDefinition[_]) =>
27 | camelProcessor.throttle(perSecond).withId(step)
28 |
29 | case StepInformation(step @ ThrottlerDefinitionExpression(perSecond), camelProcessor: ProcessorDefinition[_]) =>
30 | camelProcessor.throttle(Expressions.toCamelExpression(perSecond)).withId(step)
31 |
32 | }
33 |
34 | abstract override protected def steps = super.steps :+ parse
35 |
36 | protected implicit def throttlerDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]) = new ThrottlerDSL(baseDsl)
37 | }
38 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Transaction.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.TransactionDefinition
12 | import io.xtech.babel.camel.{ CamelDSL, TransactionDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 |
17 | import scala.collection.immutable
18 | import scala.language.implicitConversions
19 | import scala.reflect.ClassTag
20 |
21 | /**
22 | * Defines a transaction in the CamelDSL.
23 | */
24 | private[babel] trait Transaction extends CamelParsing {
25 | self: CamelDSL =>
26 |
27 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
28 |
29 | // parsing of an transaction definition
30 | private[this] def parse: Process = {
31 |
32 | case StepInformation(step @ TransactionDefinition(ref), camelProcessorDefinition: ProcessorDefinition[_]) => {
33 |
34 | val nextCamelProcessor = ref.fold(camelProcessorDefinition.transacted())(ref => camelProcessorDefinition.transacted(ref))
35 | nextCamelProcessor.withId(step)
36 |
37 | }
38 |
39 | }
40 |
41 | protected implicit def transactedDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): TransactionDSL[I] = new TransactionDSL(baseDsl)
42 | }
43 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Transformation.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ BeanClassExpression, BeanNameExpression, BeanObjectExpression }
12 | import io.xtech.babel.camel.{ CamelDSL, TransformationDSL }
13 | import io.xtech.babel.fish.model.{ Message, TransformerDefinition }
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import io.xtech.babel.fish.{ BaseDSL, BodyExpression, MessageTransformationExpression }
16 | import org.apache.camel.model.ProcessorDefinition
17 |
18 | import scala.collection.immutable
19 | import scala.language.implicitConversions
20 | import scala.reflect.ClassTag
21 |
22 | /**
23 | * Parser for the transformation definitions
24 | */
25 | private[babel] trait Transformation extends CamelParsing {
26 | self: CamelDSL =>
27 |
28 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
29 |
30 | /**
31 | * Parses the "processBody" statement.
32 | * @see CamelDSL.StepImplementation
33 | */
34 | private[this] def parse: Process = {
35 |
36 | case StepInformation(step @ TransformerDefinition(BodyExpression(function)), camelProcessorDefinition: ProcessorDefinition[_]) => {
37 |
38 | camelProcessorDefinition.process(bodyFunctionToProcess(function))
39 | camelProcessorDefinition.withId(step)
40 | }
41 |
42 | case StepInformation(step @ TransformerDefinition(MessageTransformationExpression(function)), camelProcessorDefinition: ProcessorDefinition[_]) => {
43 |
44 | camelProcessorDefinition.process(messageFunctionToProcess(function))
45 | camelProcessorDefinition.withId(step)
46 | }
47 |
48 | case StepInformation(step @ TransformerDefinition(BeanNameExpression(beanRef, method)), camelProcessorDefinition: ProcessorDefinition[_]) => {
49 |
50 | method.fold(camelProcessorDefinition.beanRef(beanRef))(methodName => camelProcessorDefinition.beanRef(beanRef, methodName)).withId(step)
51 |
52 | }
53 |
54 | // use an instance of a bean as a transformer
55 | case StepInformation(step @ TransformerDefinition(BeanObjectExpression(obj, method)), camelProcessorDefinition: ProcessorDefinition[_]) => {
56 |
57 | method.fold(camelProcessorDefinition.bean(obj))(m => camelProcessorDefinition.bean(obj, m)).withId(step)
58 | }
59 |
60 | // create a transformer from a class description
61 | case StepInformation(step @ TransformerDefinition(BeanClassExpression(clazz, method)), camelProcessorDefinition: ProcessorDefinition[_]) => {
62 |
63 | method.fold(camelProcessorDefinition.bean(clazz))(m => camelProcessorDefinition.bean(clazz, m)).withId(step)
64 | }
65 | }
66 |
67 | private[this] def bodyFunctionToProcess[I, O](function: (I => O)): org.apache.camel.Processor = new CamelBodyProcessor(function)
68 |
69 | private[this] def messageFunctionToProcess[I, O](function: (Message[I] => Message[O])): org.apache.camel.Processor = new CamelMessageProcessor(function)
70 |
71 | protected implicit def transformationDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): TransformationDSL[I] = new TransformationDSL(baseDsl)
72 | }
73 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Validation.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.{ Predicates, ValidationDefinition }
12 | import io.xtech.babel.camel.{ CamelDSL, ValidationDSL }
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.parsing.StepInformation
15 | import org.apache.camel.model.ProcessorDefinition
16 |
17 | import scala.collection.immutable
18 | import scala.language.implicitConversions
19 | import scala.reflect.ClassTag
20 |
21 | private[babel] trait Validation extends CamelParsing {
22 | self: CamelDSL =>
23 |
24 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
25 |
26 | // parsing of an validation definition
27 | private[this] def parse: Process = {
28 |
29 | case StepInformation(step @ ValidationDefinition(expression), camelProcessorDefinition: ProcessorDefinition[_]) => {
30 | camelProcessorDefinition.validate(Predicates.toCamelPredicate(expression)).withId(step)
31 | }
32 | }
33 |
34 | protected implicit def validationDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]) = new ValidationDSL(baseDsl)
35 | }
36 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/WireTap.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.{ CamelDSL, WireTapDSL }
12 | import io.xtech.babel.camel.model.WireTapDefinition
13 | import io.xtech.babel.fish.BaseDSL
14 | import io.xtech.babel.fish.model.Message
15 | import io.xtech.babel.fish.parsing.StepInformation
16 | import org.apache.camel.model.ProcessorDefinition
17 |
18 | import scala.collection.immutable
19 | import scala.language.implicitConversions
20 | import scala.reflect.ClassTag
21 |
22 | /**
23 | * The wiretap parser.
24 | */
25 | private[babel] trait WireTap extends CamelParsing {
26 | self: CamelDSL =>
27 |
28 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
29 |
30 | private[this] def parse: Process = {
31 |
32 | case StepInformation(step @ WireTapDefinition(sink), camelProcessorDefinition: ProcessorDefinition[_]) => {
33 |
34 | camelProcessorDefinition.wireTap(sink.uri).withId(step)
35 |
36 | }
37 |
38 | }
39 |
40 | protected implicit def wiretapDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]) = new WireTapDSL(baseDsl)
41 | }
42 |
43 | object Wiring {
44 | val key: String = "babel-wiring-body"
45 |
46 | def getCount(msg: Message[_]): Int = {
47 | msg.headers.keys.count(_.startsWith(Wiring.key))
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/main/scala/io/xtech/babel/camel/parsing/Wrapper.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.parsing
10 |
11 | import io.xtech.babel.camel.model.CamelMessage
12 | import io.xtech.babel.fish.model.Message
13 | import org.apache.camel.{ Exchange, InvalidPayloadException, Processor }
14 |
15 | /**
16 | * Wrapper for a scala function in a Camel Processor.
17 | * The function is used to process message bodies.
18 | * @param proc the function that process body messages.
19 | * @tparam I the input type of the function.
20 | * @tparam O the output type of the function.
21 | */
22 | private[camel] class CamelBodyProcessor[I, O](proc: (I => O)) extends Processor {
23 | def process(exchange: Exchange): Unit = {
24 |
25 | val newBody = proc(exchange.getIn.getBody.asInstanceOf[I])
26 | exchange.getIn.setBody(newBody)
27 | }
28 | }
29 |
30 | /**
31 | * Wrapper for a scala function in a Camel Processor.
32 | * The function is used to process messages.
33 | * @param proc the function that process messages.
34 | * @tparam I the input type of the function.
35 | * @tparam O the output type of the function.
36 | */
37 | private[camel] class CamelMessageProcessor[I, O](proc: (Message[I] => Message[O])) extends Processor {
38 | def process(exchange: Exchange): Unit = {
39 |
40 | val msg = new CamelMessage[I](exchange.getIn)
41 | proc(msg)
42 | }
43 | }
44 |
45 | private[camel] object CamelBodyTypeValidation {
46 |
47 | /**
48 | * Mapping between primitive types and wrapped types.
49 | * Used in order to accept, in requireAs, corresponding Scala types.
50 | */
51 | val primitiveToBoxed = Map[Class[_], Class[_]](
52 | classOf[Byte] -> classOf[java.lang.Byte],
53 | classOf[Short] -> classOf[java.lang.Short],
54 | classOf[Char] -> classOf[java.lang.Character],
55 | classOf[Int] -> classOf[java.lang.Integer],
56 | classOf[Long] -> classOf[java.lang.Long],
57 | classOf[Float] -> classOf[java.lang.Float],
58 | classOf[Double] -> classOf[java.lang.Double],
59 | classOf[Boolean] -> classOf[java.lang.Boolean],
60 | classOf[Unit] -> classOf[java.lang.Void]
61 | ).withDefault(identity)
62 | }
63 |
64 | /**
65 | * Processor that checks the validity of the body type
66 | * @param outputClass the required type.
67 | * @tparam O the required type
68 | */
69 | private[camel] class CamelBodyTypeValidation[O](outputClass: Class[O]) extends Processor {
70 |
71 | def process(exchange: Exchange): Unit = {
72 |
73 | exchange.getIn.getMandatoryBody match {
74 | case c: Any if outputClass.isPrimitive & CamelBodyTypeValidation.primitiveToBoxed(outputClass).isAssignableFrom(c.getClass) =>
75 | case c: Any if outputClass.isAssignableFrom(c.getClass) =>
76 | case _ => throw new InvalidPayloadException(exchange, outputClass)
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/java/io/xtech/babel/camel/javaprocessors/JavaProcessors.java:
--------------------------------------------------------------------------------
1 | package io.xtech.babel.camel.javaprocessors;
2 |
3 | import io.xtech.babel.fish.JVMFunction;
4 | import io.xtech.babel.fish.JVMPredicate;
5 |
6 | /**
7 | * Created by babel on 8/24/15.
8 | */
9 | public class JavaProcessors {
10 | public static final JVMFunction append = new JVMFunction() {
11 | public String apply(String input) {
12 | return input + "-";
13 | }
14 | };
15 |
16 | public static final JVMPredicate containsTrue = new JVMPredicate() {
17 | public boolean apply(String input) {
18 | return input.contains("true");
19 | }
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/resources/META-INF/spring/context-constructor-injection.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/resources/META-INF/spring/context-setter-injection.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/resources/META-INF/spring/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
19 |
20 | io.xtech.babel.camel.builder.spring
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | #
3 | # Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | # All rights reserved.
5 | #
6 | # ==================================================================================
7 | #
8 |
9 | #
10 | # The logging properties used for eclipse testing, We want to see debug output on the console.
11 | #
12 | log4j.rootLogger=INFO, out
13 |
14 | # uncomment the following line to turn on Camel debugging
15 | #log4j.logger.org.apache.camel=DEBUG
16 |
17 | # uncomment the following line to turn on ActiveMQ debugging
18 | #log4j.logger.org.apache.activemq=DEBUG
19 |
20 | log4j.logger.org.springframework=ERROR
21 |
22 |
23 | # CONSOLE appender not used by default
24 | log4j.appender.out=org.apache.log4j.ConsoleAppender
25 | log4j.appender.out.layout=org.apache.log4j.PatternLayout
26 | log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
27 | #log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
28 |
29 |
30 | log4j.logger.my.cool.toto=TRACE, Appender
31 | log4j.appender.Appender=io.xtech.babel.camel.Appender
32 |
33 | log4j.logger.my.cool.tata=TRACE, ErrorAppender
34 | log4j.appender.ErrorAppender=io.xtech.babel.camel.ErrorAppender
35 |
36 | log4j.logger.my.cool.titi=TRACE, RBErrorAppender
37 | log4j.appender.RBErrorAppender=io.xtech.babel.camel.RBErrorAppender
38 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/resources/schema.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE USERS(name varchar(256));
2 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/CompilationSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.model.Aggregation.{ CompletionSize, ReduceBody }
12 | import io.xtech.babel.fish.model.Message
13 | import org.specs2.mutable.Specification
14 |
15 | class CompilationSpec extends Specification {
16 |
17 | "The Scala compiler" should {
18 |
19 | "compile this CamelDSL route" in {
20 |
21 | import io.xtech.babel.camel.builder.RouteBuilder
22 |
23 | val reduceBody = ReduceBody((a: Int, b: Int) => a + b, (msg: Message[Int]) => "a", completionStrategies = List(CompletionSize(3)))
24 |
25 | new RouteBuilder {
26 | from("direct:input").as[Int].aggregate(reduceBody).marshal("id").bean("id").to("direct:output")
27 | }
28 |
29 | success
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/LogSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.test.camel
12 | import org.apache.camel.component.mock.MockEndpoint
13 | import org.apache.log4j._
14 | import org.apache.log4j.spi.LoggingEvent
15 | import org.specs2.mutable.SpecificationWithJUnit
16 |
17 | import scala.collection.immutable
18 |
19 | class LogSpec extends SpecificationWithJUnit {
20 | sequential
21 |
22 | "A log" should {
23 |
24 | "ouput correctly" in new camel {
25 |
26 | //#doc:babel-camel-logging
27 |
28 | import io.xtech.babel.camel.builder.RouteBuilder
29 | import org.apache.camel.LoggingLevel
30 |
31 | val routeBuilder = new RouteBuilder {
32 | from("direct:input")
33 | //logs to the Trace level message such as "received ID-3423 -> toto"
34 | .log(LoggingLevel.TRACE, "my.cool.toto", "foo", "received: ${id} -> ${body}")
35 | //logs to the Info level message such as "ID-3423 -> toto"
36 | .log(LoggingLevel.INFO, "${id} -> ${body}")
37 | .to("mock:output")
38 | }
39 | //#doc:babel-camel-logging
40 |
41 | val mock = camelContext.getEndpoint("mock:output", classOf[MockEndpoint])
42 |
43 | mock.expectedBodiesReceived("babel message")
44 |
45 | camelContext.addRoutes(routeBuilder)
46 |
47 | camelContext.start()
48 |
49 | val template = camelContext.createProducerTemplate()
50 | template.sendBody("direct:input", "babel message")
51 | mock.assertIsSatisfied() must not(throwA[Exception])
52 |
53 | SharedLogs.events.size must be_==(1).eventually
54 |
55 | val event = SharedLogs.events.head
56 | event.getLevel === Level.TRACE
57 | event.getLoggerName === "my.cool.toto"
58 | event.getMessage.toString.startsWith("received") must beTrue
59 | event.getMessage.toString.endsWith("babel message") must beTrue
60 |
61 | }
62 |
63 | "be used with a function" in new camel {
64 |
65 | SharedLogs.events = List.empty[LoggingEvent]
66 |
67 | import io.xtech.babel.camel.builder.RouteBuilder
68 | import org.apache.camel.LoggingLevel
69 |
70 | //#doc:babel-camel-logging-functionnal
71 | val routeBuilder = new RouteBuilder {
72 | from("direct:input")
73 | .log(LoggingLevel.TRACE, "my.cool.toto", "foo", msg => "FOO")
74 | .log(msg => s"BAR : ${msg.headers}")
75 | .to("mock:output")
76 | }
77 | //#doc:babel-camel-logging-functionnal
78 |
79 | val mock = camelContext.getEndpoint("mock:output", classOf[MockEndpoint])
80 |
81 | mock.expectedBodiesReceived("babel message")
82 |
83 | camelContext.addRoutes(routeBuilder)
84 |
85 | camelContext.start()
86 |
87 | val template = camelContext.createProducerTemplate()
88 | template.sendBody("direct:input", "babel message")
89 | mock.assertIsSatisfied() must not(throwA[Exception])
90 |
91 | SharedLogs.events.size must be_==(1).eventually
92 |
93 | val event = SharedLogs.events.head
94 | event.getLevel === Level.TRACE
95 | event.getLoggerName === "my.cool.toto"
96 | event.getMessage.toString must be_==("FOO")
97 |
98 | }
99 |
100 | }
101 |
102 | }
103 |
104 | object SharedLogs {
105 | var events: immutable.Seq[LoggingEvent] = List.empty[LoggingEvent]
106 | }
107 |
108 | class Appender extends AppenderSkeleton {
109 |
110 | def append(event: LoggingEvent): Unit = {
111 | SharedLogs.events :+= event
112 | }
113 |
114 | def close(): Unit = {}
115 |
116 | def requiresLayout(): Boolean = false
117 | }
118 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/MockSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.builder.RouteBuilder
12 | import org.apache.camel.impl.DefaultCamelContext
13 | import org.specs2.mutable.SpecificationWithJUnit
14 |
15 | class MockSpec extends SpecificationWithJUnit {
16 | sequential
17 |
18 | "extend the DSL with some sub DSL (mock)" in {
19 |
20 | val camelContext = new DefaultCamelContext()
21 |
22 | //#doc:babel-camel-mock
23 | import io.xtech.babel.camel.mock._
24 |
25 | //The Mock extension is added simply by
26 | // extending the RouteBuilder with
27 | val routeDef = new RouteBuilder with Mock {
28 | //the mock keyword is the same as typing
29 | // to("mock:output1")
30 | from("direct:input").
31 | requireAs[String].
32 | mock("output1").
33 | //the mock keyword keeps the same body type (here: String)
34 | processBody(x => x.toUpperCase).
35 | mock("output2")
36 |
37 | }
38 |
39 | //#doc:babel-camel-mock
40 |
41 | routeDef.addRoutesToCamelContext(camelContext)
42 |
43 | camelContext.start()
44 |
45 | val mockEndpoint1 = camelContext.mockEndpoint("output1")
46 | val mockEndpoint2 = camelContext.getMockEndpoint("output2")
47 |
48 | mockEndpoint1.expectedBodiesReceived("test")
49 | mockEndpoint2.expectedBodiesReceived("TEST")
50 |
51 | val producer = camelContext.createProducerTemplate()
52 |
53 | producer.sendBody("direct:input", "test")
54 |
55 | mockEndpoint1.assertIsSatisfied()
56 | mockEndpoint2.assertIsSatisfied()
57 |
58 | camelContext.shutdown() must not(throwA[Exception])
59 |
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/RouteIdSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.test.camel
12 | import org.specs2.mutable.SpecificationWithJUnit
13 |
14 | class RouteIdSpec extends SpecificationWithJUnit {
15 | sequential
16 |
17 | "A route id" should {
18 |
19 | "be set in a route" in new camel {
20 |
21 | import io.xtech.babel.camel.builder.RouteBuilder
22 |
23 | //#doc:babel-camel-routeId
24 |
25 | val routeBuilder = new RouteBuilder {
26 | from("direct:input").
27 | //the routeId of this route will be "bla"
28 | routeId("bla").
29 | //the routeId keyword needs to be at the beginning of the route
30 | // (enforced by the Babel DSL)
31 | to("mock:output")
32 | }
33 | //#doc:babel-camel-routeId
34 |
35 | camelContext.addRoutes(routeBuilder)
36 |
37 | camelContext.start()
38 |
39 | Option(camelContext.getRouteDefinition("bla")) must beSome
40 | }
41 |
42 | "not be empty" in new camel {
43 |
44 | import io.xtech.babel.camel.builder.RouteBuilder
45 |
46 | //#doc:babel-camel-routeId-exception-1
47 | val route = new RouteBuilder {
48 | from("direct:input").
49 | //a routeId may not be empty
50 | routeId("") must throwA[IllegalArgumentException]
51 | }
52 | //#doc:babel-camel-routeId-exception-1
53 | }
54 |
55 | "not be null" in new camel {
56 |
57 | import io.xtech.babel.camel.builder.RouteBuilder
58 |
59 | //#doc:babel-camel-routeId-exception-2
60 |
61 | val route = new RouteBuilder {
62 | from("direct:input").
63 | //a routeId may not be null
64 | routeId(null) must throwA[IllegalArgumentException]
65 | }
66 |
67 | //#doc:babel-camel-routeId-exception-2
68 | }
69 |
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/ThrottlerSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.builder.RouteBuilder
12 | import io.xtech.babel.camel.mock._
13 | import io.xtech.babel.camel.test.camel
14 | import org.apache.camel.builder.{ RouteBuilder => CRouteBuilder }
15 | import org.apache.camel.component.mock.MockEndpoint
16 | import org.specs2.mutable.SpecificationWithJUnit
17 |
18 | class ThrottlerSpec extends SpecificationWithJUnit {
19 | sequential
20 |
21 | "throttle message flow" in new camel {
22 |
23 | val msgs = 3
24 |
25 | //#doc:babel-camel-throttler
26 |
27 | val routeDef = new RouteBuilder {
28 | from("direct:input").
29 | //throttle message to 1 per second
30 | throttle(1).
31 | to("mock:output")
32 | }
33 | //#doc:babel-camel-throttler
34 |
35 | val nativeRoute = new CRouteBuilder() {
36 | def configure(): Unit = {
37 | from("direct:inputCamel").
38 | throttle(1).
39 | to("mock:output")
40 | }
41 | }
42 |
43 | routeDef.addRoutesToCamelContext(camelContext)
44 | camelContext.addRoutes(nativeRoute)
45 |
46 | camelContext.start()
47 |
48 | val mockEndpoint = camelContext.mockEndpoint("output")
49 |
50 | mockEndpoint.setExpectedMessageCount(msgs)
51 |
52 | val producer = camelContext.createProducerTemplate()
53 |
54 | val initTime = System.currentTimeMillis()
55 | (1 to msgs).foreach(_ => producer.sendBody("direct:inputCamel", "test"))
56 |
57 | mockEndpoint.assertIsSatisfied()
58 | (System.currentTimeMillis() - initTime) must be_>=(1000l)
59 |
60 | mockEndpoint.reset()
61 |
62 | mockEndpoint.setExpectedMessageCount(msgs)
63 |
64 | val camelInitTime = System.currentTimeMillis()
65 | (1 to msgs).foreach(_ => producer.sendBody("direct:input", "test"))
66 |
67 | mockEndpoint.assertIsSatisfied()
68 | (System.currentTimeMillis() - camelInitTime) must be_>=(1000l)
69 | }
70 |
71 | "throttle message flow with a function" in new camel {
72 |
73 | val msgs = 3
74 |
75 | //#doc:babel-camel-throttler
76 |
77 | val routeDef = new RouteBuilder {
78 | from("direct:input").
79 | //throttle message to 1 per second
80 | throttle(_ => 1).
81 | to("mock:output")
82 | }
83 | //#doc:babel-camel-throttler
84 |
85 | val nativeRoute = new CRouteBuilder() {
86 | def configure(): Unit = {
87 | from("direct:inputCamel").
88 | throttle(1).
89 | to("mock:output")
90 | }
91 | }
92 |
93 | routeDef.addRoutesToCamelContext(camelContext)
94 | camelContext.addRoutes(nativeRoute)
95 |
96 | camelContext.start()
97 |
98 | val mockEndpoint = camelContext.getEndpoint("mock:output").asInstanceOf[MockEndpoint]
99 |
100 | mockEndpoint.setExpectedMessageCount(msgs)
101 |
102 | val producer = camelContext.createProducerTemplate()
103 |
104 | val initTime = System.currentTimeMillis()
105 | (1 to msgs).foreach(_ => producer.sendBody("direct:inputCamel", "test"))
106 |
107 | mockEndpoint.assertIsSatisfied()
108 | (System.currentTimeMillis() - initTime) must be_>=(1000l)
109 |
110 | mockEndpoint.reset()
111 |
112 | mockEndpoint.setExpectedMessageCount(msgs)
113 |
114 | val camelInitTime = System.currentTimeMillis()
115 | (1 to msgs).foreach(_ => producer.sendBody("direct:input", "test"))
116 |
117 | mockEndpoint.assertIsSatisfied()
118 | (System.currentTimeMillis() - camelInitTime) must be_>=(1000l)
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/ValidationSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.test.camel
12 | import org.apache.camel.CamelExecutionException
13 | import org.apache.camel.builder.Builder
14 | import org.apache.camel.component.mock.MockEndpoint
15 | import org.specs2.mutable.SpecificationWithJUnit
16 |
17 | class ValidationSpec extends SpecificationWithJUnit {
18 | sequential
19 |
20 | "A validation" should {
21 |
22 | "validate with a predicate" in new camel {
23 |
24 | import io.xtech.babel.camel.builder.RouteBuilder
25 |
26 | //#doc:babel-camel-validate-1
27 |
28 | val routeBuilder = new RouteBuilder {
29 |
30 | from("direct:input").as[Int].
31 | validate(Builder.body().isEqualTo(1)).
32 | to("mock:output")
33 | }
34 | //#doc:babel-camel-validate-1
35 |
36 | camelContext.addRoutes(routeBuilder)
37 |
38 | camelContext.start()
39 |
40 | val mock = camelContext.getEndpoint("mock:output", classOf[MockEndpoint])
41 |
42 | mock.expectedBodiesReceived(1: java.lang.Integer)
43 |
44 | val template = camelContext.createProducerTemplate()
45 |
46 | template.sendBody("direct:input", 1)
47 |
48 | mock.assertIsSatisfied()
49 | }
50 |
51 | "validate with a function taking a message" in new camel {
52 |
53 | import io.xtech.babel.camel.builder.RouteBuilder
54 |
55 | //#doc:babel-camel-validate-2
56 |
57 | val routeBuilder = new RouteBuilder {
58 |
59 | from("direct:input").as[Int].
60 | validate(msg => msg.body == Some(1)).
61 | to("mock:output")
62 | }
63 | //#doc:babel-camel-validate-2
64 |
65 | camelContext.addRoutes(routeBuilder)
66 |
67 | camelContext.start()
68 |
69 | val mock = camelContext.getEndpoint("mock:output", classOf[MockEndpoint])
70 |
71 | mock.expectedBodiesReceived(1: java.lang.Integer)
72 |
73 | val template = camelContext.createProducerTemplate()
74 |
75 | template.sendBody("direct:input", 1)
76 |
77 | mock.assertIsSatisfied()
78 | }
79 |
80 | "validate with a function taking a body" in new camel {
81 |
82 | import io.xtech.babel.camel.builder.RouteBuilder
83 |
84 | //#doc:babel-camel-validate-3
85 |
86 | val routeBuilder = new RouteBuilder {
87 |
88 | from("direct:input").as[Int].
89 | validateBody(body => body == 1).
90 | to("mock:output")
91 | }
92 | //#doc:babel-camel-validate-3
93 |
94 | camelContext.addRoutes(routeBuilder)
95 |
96 | camelContext.start()
97 |
98 | val mock = camelContext.getEndpoint("mock:output", classOf[MockEndpoint])
99 |
100 | mock.expectedBodiesReceived(1: java.lang.Integer)
101 |
102 | val template = camelContext.createProducerTemplate()
103 |
104 | template.sendBody("direct:input", 1)
105 |
106 | mock.assertIsSatisfied()
107 | }
108 |
109 | "through an exception if the message is not valid" in new camel {
110 |
111 | import io.xtech.babel.camel.builder.RouteBuilder
112 |
113 | val routeBuilder = new RouteBuilder {
114 |
115 | from("direct:input").as[Int].
116 | validateBody(body => body == 123).
117 | to("mock:output")
118 | }
119 |
120 | camelContext.addRoutes(routeBuilder)
121 |
122 | camelContext.start()
123 |
124 | val mock = camelContext.getEndpoint("mock:output", classOf[MockEndpoint])
125 |
126 | val template = camelContext.createProducerTemplate()
127 |
128 | template.sendBody("direct:input", 1) must throwAn[CamelExecutionException]
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/WireTapSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import io.xtech.babel.camel.mock._
12 | import io.xtech.babel.camel.test.camel
13 | import org.apache.camel.builder.{ RouteBuilder => CRouteBuilder }
14 | import org.specs2.mutable.SpecificationWithJUnit
15 |
16 | class WireTapSpec extends SpecificationWithJUnit {
17 | sequential
18 |
19 | "create a wire-tap" in new camel {
20 |
21 | val testMessage = "test"
22 | val wireTapMessage = "tap"
23 |
24 | import io.xtech.babel.camel.builder.RouteBuilder
25 |
26 | val routeDef = new RouteBuilder {
27 | //#doc:babel-camel-wiretap
28 | from("direct:input-babel").
29 | //Incoming messages are sent to the direct endpoint
30 | // and to the next mock endpoint
31 | wiretap("direct:babel-tap")
32 | .to("mock:output-babel")
33 | //#doc:babel-camel-wiretap
34 |
35 | from("direct:babel-tap").processBody(_ => {
36 | Thread.sleep(1000);
37 | "tap"
38 | }).to("mock:output-babel").to("mock:babel-tap")
39 | }
40 |
41 | val nativeRoute = new CRouteBuilder() {
42 | def configure(): Unit = {
43 | from("direct:input-camel").wireTap("direct:camel-tap")
44 | .to("mock:output-camel")
45 |
46 | from("direct:camel-tap").delay(1000).setBody(constant("tap")).to("mock:output-camel").to("mock:camel-tap")
47 | }
48 | }
49 |
50 | routeDef.addRoutesToCamelContext(camelContext)
51 | camelContext.addRoutes(nativeRoute)
52 |
53 | camelContext.start()
54 |
55 | val mockEndpointB = camelContext.mockEndpoint("output-babel")
56 | val mockEndpointBT = camelContext.mockEndpoint("babel-tap")
57 | val mockEndpointC = camelContext.mockEndpoint("output-camel")
58 | val mockEndpointCT = camelContext.mockEndpoint("camel-tap")
59 |
60 | mockEndpointB.expectedBodiesReceived(testMessage, wireTapMessage)
61 | mockEndpointBT.expectedBodiesReceived(wireTapMessage)
62 | mockEndpointC.expectedBodiesReceived(testMessage, wireTapMessage)
63 | mockEndpointCT.expectedBodiesReceived(wireTapMessage)
64 |
65 | val producer = camelContext.createProducerTemplate()
66 |
67 | producer.sendBody("direct:input-camel", testMessage)
68 | producer.sendBody("direct:input-babel", testMessage)
69 |
70 | mockEndpointC.assertIsSatisfied()
71 | mockEndpointCT.assertIsSatisfied()
72 | mockEndpointB.assertIsSatisfied()
73 | mockEndpointBT.assertIsSatisfied()
74 |
75 | }
76 |
77 | "create a functionnal wire-tap" in new camel {
78 |
79 | val testMessage = "test"
80 | val wireTapMessage = "tap"
81 |
82 | import io.xtech.babel.camel.builder.RouteBuilder
83 |
84 | val routeDef = new RouteBuilder {
85 | //#doc:babel-camel-wiretap-functional
86 | from("direct:input-babel").
87 | //Incoming messages are sent to the direct endpoint
88 | // and to the next mock endpoint
89 | sideEffect(_.to("mock:in-wire").processBody(_ => wireTapMessage).to("mock:out-wire"))
90 | .to("mock:output")
91 | //#doc:babel-camel-wiretap-functional
92 |
93 | }
94 |
95 | routeDef.addRoutesToCamelContext(camelContext)
96 |
97 | camelContext.start()
98 |
99 | val mockEndpointBI = camelContext.mockEndpoint("in-wire")
100 | val mockEndpointBO = camelContext.mockEndpoint("out-wire")
101 | val mockEndpointBT = camelContext.mockEndpoint("output")
102 |
103 | mockEndpointBI.expectedBodiesReceived(testMessage)
104 | mockEndpointBO.expectedBodiesReceived(wireTapMessage)
105 | mockEndpointBT.expectedBodiesReceived(testMessage)
106 |
107 | val producer = camelContext.createProducerTemplate()
108 |
109 | producer.sendBody("direct:input-babel", testMessage)
110 |
111 | mockEndpointBI.assertIsSatisfied()
112 | mockEndpointBO.assertIsSatisfied()
113 | mockEndpointBT.assertIsSatisfied()
114 |
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/builder/RouteBuilderSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.builder
10 |
11 | import io.xtech.babel.camel.test.springContext
12 | import org.apache.camel.CamelContext
13 | import org.apache.camel.component.mock.MockEndpoint
14 | import org.specs2.mutable.SpecificationWithJUnit
15 |
16 | class RouteBuilderSpec extends SpecificationWithJUnit {
17 | sequential
18 |
19 | "Babel Camel route builder" should {
20 | "be defined by the packageScan" in new springContext("classpath:/META-INF/spring/context.xml") {
21 | val context: CamelContext = spring.getBean(classOf[CamelContext])
22 | val mock = context.getEndpoint("mock:babel-rb").asInstanceOf[MockEndpoint]
23 | mock.expectedBodiesReceived("Hello RB 1", "Hello RB 2")
24 | val producer = context.createProducerTemplate()
25 | producer.sendBody("direct:babel-rb-1", "Hello RB 1")
26 | producer.sendBody("direct:babel-rb-2", "Hello RB 2")
27 | mock.assertIsSatisfied should not(throwA[Exception])
28 | }
29 | /*
30 | "accept injection base on setter" in new springContext("classpath:/META-INF/spring/context-setter-injection.xml") {
31 | val context: CamelContext = spring.getBean(classOf[CamelContext])
32 |
33 | val mock = context.getEndpoint("mock:babel-rb-setter").asInstanceOf[MockEndpoint]
34 | mock.expectedBodiesReceived("Hello RB 1bla")
35 | val producer = context.createProducerTemplate()
36 | producer.sendBody("direct:babel-rb-setter", "Hello RB 1")
37 | mock.assertIsSatisfied should not(throwA[Exception])
38 | } //.pendingUntilFixed("refactor Babel Camel RouteBuilder to support setter injection")
39 |
40 | "accept injection base on constructor" in new springContext("classpath:/META-INF/spring/context-constructor-injection.xml") {
41 | val context: CamelContext = spring.getBean(classOf[CamelContext])
42 |
43 | val mock = context.getEndpoint("mock:babel-rb-setter").asInstanceOf[MockEndpoint]
44 | mock.expectedBodiesReceived("Hello RB 1bla")
45 | val producer = context.createProducerTemplate()
46 | producer.sendBody("direct:babel-rb-setter", "Hello RB 1")
47 | mock.assertIsSatisfied should not(throwA[Exception])
48 | } //.pendingUntilFixed("message about the issue")
49 | */
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/builder/spring/MyRouteBuilder.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | //#doc:babel-camel-spring
10 | package io.xtech.babel.camel.builder.spring
11 |
12 | import io.xtech.babel.camel.builder.RouteBuilder
13 |
14 | class MyRouteBuilder extends RouteBuilder {
15 | from("direct:babel-rb-1").routeId("route1").to("mock:babel-rb")
16 | from("direct:babel-rb-2").routeId("route2").to("mock:babel-rb")
17 | }
18 |
19 | //#doc:babel-camel-spring
20 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/builder/springinjection/SetterInjectionRouteBuilder.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.builder.springinjection
10 |
11 | import io.xtech.babel.camel.builder.{ RouteBuilder, SpringRouteBuilder }
12 | import org.springframework.stereotype.Component
13 |
14 | @Component
15 | class MyBeanProcessor {
16 | def doSomething(str: String): String = str + "bla"
17 | }
18 |
19 | //#doc:babel-camel-spring-setter
20 |
21 | import org.springframework.beans.factory.annotation.Autowired
22 |
23 | import scala.beans.BeanProperty
24 |
25 | class SetterInjectionRouteBuilder extends SpringRouteBuilder {
26 |
27 | @Autowired
28 | @BeanProperty
29 | var aBean: MyBeanProcessor = _
30 |
31 | def configure(): Unit = {
32 | from("direct:babel-rb-setter").as[String].
33 | processBody(aBean.doSomething).
34 | to("mock:babel-rb-setter")
35 | }
36 | }
37 |
38 | //#doc:babel-camel-spring-setter
39 |
40 | class ConstructorInjectionRouteBuilder @Autowired() (aBean: MyBeanProcessor) extends RouteBuilder {
41 |
42 | from("direct:babel-rb-setter").bean(aBean).to("mock:babel-rb-setter")
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/sample/SampleSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.sample
10 |
11 | import io.xtech.babel.camel.builder.{ RouteBuilder => BabelRouteBuilder }
12 | import io.xtech.babel.camel.mock._
13 | import io.xtech.babel.camel.test.camel
14 | import io.xtech.babel.fish.model.Message
15 | import org.specs2.mutable.SpecificationWithJUnit
16 |
17 | class SampleSpec extends SpecificationWithJUnit {
18 | sequential
19 |
20 | "Babel Camel Samples" should {
21 | "first typed and functional sample" in new camel {
22 |
23 | //#doc:babel-camel-sample-1
24 |
25 | val routeDef = new BabelRouteBuilder {
26 |
27 | val splitString = (body: String) => body.split(",").toList
28 |
29 | val isForSwitzerland = (msg: Message[String]) => msg.body.fold(false)(_ == "CH")
30 |
31 | val isForGermany = (msg: Message[String]) => msg.body.fold(false)(_ == "D")
32 |
33 | val filterGermanyErrors = (msg: Message[String]) => {
34 | !msg.headers.contains("GermanyCurrencyFailure")
35 | }
36 |
37 | val isForFrance = (msg: Message[String]) => msg.body.fold(false)(_ == "F")
38 |
39 | from("direct:input").as[String]
40 | .processBody(splitString)
41 | .splitBody(list => list.iterator)
42 | .processBody(string => string.toUpperCase)
43 | .choice {
44 | c =>
45 | c.when(isForSwitzerland).to("mock:switzerland")
46 | c.when(isForFrance).to("mock:france")
47 | c.when(isForGermany).filter(filterGermanyErrors).to("mock:germany")
48 | }
49 | .to("mock:output")
50 | }
51 |
52 | //#doc:babel-camel-sample-1
53 |
54 | routeDef.addRoutesToCamelContext(camelContext)
55 |
56 | camelContext.start()
57 |
58 | val mockEndpointF = camelContext.mockEndpoint("france")
59 | mockEndpointF.expectedBodiesReceived("F")
60 |
61 | val mockEndpointCH = camelContext.mockEndpoint("switzerland")
62 | mockEndpointCH.expectedBodiesReceived("CH")
63 |
64 | val producer = camelContext.createProducerTemplate()
65 | producer.sendBody("direct:input", "ch,f,d")
66 |
67 | mockEndpointF.assertIsSatisfied()
68 | mockEndpointCH.assertIsSatisfied()
69 | }
70 |
71 | }
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/test/SpecsContexts.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.test
10 |
11 | import org.apache.camel.Exchange
12 | import org.apache.camel.impl.{ DefaultCamelContext, DefaultExchange }
13 | import org.specs2.mutable.After
14 | import org.springframework.context.support.ClassPathXmlApplicationContext
15 |
16 | /**
17 | * Declare a CamelContext in the Context of a Specs2 example.
18 | */
19 | class camel extends After {
20 |
21 | lazy implicit val camelContext = new DefaultCamelContext()
22 |
23 | def createExchange(): Exchange = new DefaultExchange(camelContext)
24 |
25 | def after: Unit = {
26 | camelContext.shutdown()
27 | }
28 | }
29 |
30 | /**
31 | * Declare a Spring Application Context in the Context of a Specs2 example.
32 | * @param configLocation the location of a spring xml file.
33 | */
34 | class springContext(configLocation: String) extends After {
35 |
36 | lazy val spring = new ClassPathXmlApplicationContext(configLocation)
37 |
38 | def after: Unit = {
39 | spring.close()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/test/SpringSpecification.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel.test
10 |
11 | import org.apache.camel.ProducerTemplate
12 | import org.apache.camel.component.mock.MockEndpoint
13 | import org.apache.camel.model.ModelCamelContext
14 | import org.specs2.mutable.SpecificationWithJUnit
15 | import org.specs2.specification.{ AfterExample, BeforeExample, Fragments, Step }
16 | import org.springframework.context.ApplicationContext
17 | import org.springframework.context.support.AbstractApplicationContext
18 |
19 | import scala.reflect._
20 |
21 | trait SpringSpecification {
22 |
23 | type ContextType <: ApplicationContext
24 |
25 | def applicationContext: ContextType
26 |
27 | def bean[A: ClassTag]: A = applicationContext.getBean(classTag[A].runtimeClass.asInstanceOf[Class[A]])
28 | }
29 |
30 | trait CamelSpecification {
31 | self: SpringSpecification =>
32 |
33 | def camelContext: ModelCamelContext = applicationContext.getBean(classOf[ModelCamelContext])
34 |
35 | def mockEndpoint(uri: String): MockEndpoint = camelContext.getEndpoint(uri, classOf[MockEndpoint])
36 |
37 | def producerTemplate(): ProducerTemplate = camelContext.createProducerTemplate()
38 | }
39 |
40 | /**
41 | * Base class for Babel Camel tests. The same Application Context is used for the Specification.
42 | */
43 | trait CachedBabelSpringSpecification extends SpecificationWithJUnit with SpringSpecification with CamelSpecification {
44 |
45 | /**
46 | * Type of the Application Context
47 | */
48 | type ContextType <: AbstractApplicationContext
49 |
50 | /**
51 | * The Application Context used by all the tests of this Specification.
52 | */
53 | val applicationContext: ContextType
54 |
55 | private[this] def startContext(): Unit = {
56 | applicationContext.start()
57 | }
58 |
59 | private[this] def stopContext(): Unit = {
60 | applicationContext.close()
61 | }
62 |
63 | /** the map method allows to "post-process" the fragments after their creation */
64 | override def map(fs: => Fragments): Fragments = Step(startContext()) ^ fs ^ Step(stopContext())
65 | }
66 |
67 | /**
68 | * Base class for Babel Camel tests. An application context is created for each tests.
69 | */
70 | trait BabelSpringSpecification extends SpecificationWithJUnit with SpringSpecification with CamelSpecification with BeforeExample with AfterExample {
71 |
72 | private[this] var appContext: Option[ContextType] = _
73 |
74 | /**
75 | * Type of the Application Context
76 | */
77 | type ContextType <: AbstractApplicationContext
78 |
79 | def applicationContext: ContextType = appContext.get
80 |
81 | /**
82 | * A factory of Application Context used by each tests.
83 | */
84 | val applicationContextFactory: () => ContextType
85 |
86 | def before: Unit = {
87 | val context = applicationContextFactory()
88 | appContext = Some(context)
89 | context.start()
90 | }
91 |
92 | def after: Unit = {
93 | appContext.foreach(_.stop())
94 | appContext = None
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-mock/build.sbt:
--------------------------------------------------------------------------------
1 |
2 | organization := "io.xtech.babel"
3 |
4 | name := "babel-camel-mock"
5 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-mock/src/main/scala/io/xtech/babel/camel/mock/MockDSL.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | //#doc:babel-mock
10 |
11 | package io.xtech.babel.camel.mock
12 |
13 | import io.xtech.babel.fish.model.StepDefinition
14 | import io.xtech.babel.fish.parsing.{ Parsing, StepInformation }
15 | import io.xtech.babel.fish.{ BaseDSL, DSL2BaseDSL }
16 | import org.apache.camel.builder.RouteBuilder
17 | import org.apache.camel.model.ProcessorDefinition
18 |
19 | import scala.collection.immutable
20 | import scala.language.implicitConversions
21 | import scala.reflect.ClassTag
22 |
23 | case class MockDefinition(filePath: String) extends StepDefinition
24 |
25 | class MockDSL[I: ClassTag](protected val baseDsl: BaseDSL[I]) extends DSL2BaseDSL[I] {
26 |
27 | /**
28 | * The mock keyword. Stores received exchanges in order to assert properties in tests.
29 | * @param endpointUri target mock endpoint which translates to "mock:endpointUri"
30 | * @see io.xtech.babel.camel.mock
31 | * @return the possibility to add other steps to the current DSL
32 | */
33 | def mock(endpointUri: String): BaseDSL[I] = MockDefinition(endpointUri)
34 | }
35 |
36 | trait Mock extends Parsing[RouteBuilder] {
37 |
38 | val parse: Process = {
39 | case StepInformation(MockDefinition(uri), camelProcessor: ProcessorDefinition[_]) =>
40 | camelProcessor.to(s"mock:$uri")
41 |
42 | }
43 |
44 | abstract override protected def steps: immutable.Seq[Process] = super.steps :+ parse
45 |
46 | implicit protected def mockDSLExtension[I: ClassTag](baseDsl: BaseDSL[I]): MockDSL[I] = new MockDSL(baseDsl)
47 | }
48 |
49 | //#doc:babel-mock
50 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-mock/src/main/scala/io/xtech/babel/camel/mock/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import org.apache.camel.CamelContext
12 | import org.apache.camel.component.mock.MockEndpoint
13 |
14 | package object mock {
15 |
16 | implicit class CamelContextWithMock(val self: CamelContext) extends AnyVal {
17 |
18 | def getMockEndpoint(uri: String): MockEndpoint = mockEndpoint(uri)
19 |
20 | def mockEndpoint(uri: String): MockEndpoint = self.getEndpoint(s"mock:$uri").asInstanceOf[MockEndpoint]
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/babel-camel/babel-camel-mock/src/test/scala/io/xtech/babel/camel/MockSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.camel
10 |
11 | import org.apache.camel.builder.RouteBuilder
12 | import org.apache.camel.impl.DefaultCamelContext
13 | import org.apache.camel.{ Exchange, Processor }
14 | import org.specs2.mutable.SpecificationWithJUnit
15 |
16 | class MockSpec extends SpecificationWithJUnit {
17 | sequential
18 |
19 | "camel mock tools" in {
20 |
21 | val camelContext = new DefaultCamelContext()
22 |
23 | import io.xtech.babel.camel.mock._
24 |
25 | val routeDef = new RouteBuilder {
26 | from("direct:input").
27 | to("mock:output1").
28 | process(new Processor {
29 | override def process(exchange: Exchange): Unit = exchange.getIn.setBody(exchange.getIn.getBody(classOf[String]).toUpperCase)
30 | }).
31 | to("mock:output2")
32 |
33 | override def configure(): Unit = {}
34 | }
35 |
36 | routeDef.addRoutesToCamelContext(camelContext)
37 |
38 | camelContext.start()
39 |
40 | val mockEndpoint1 = camelContext.getMockEndpoint("output1")
41 | val mockEndpoint2 = camelContext.mockEndpoint("output2")
42 |
43 | mockEndpoint1.expectedBodiesReceived("test")
44 | mockEndpoint2.expectedBodiesReceived("TEST")
45 |
46 | val producer = camelContext.createProducerTemplate()
47 |
48 | producer.sendBody("direct:input", "test")
49 |
50 | mockEndpoint1.assertIsSatisfied()
51 | mockEndpoint2.assertIsSatisfied()
52 |
53 | camelContext.shutdown() must not(throwA[Exception])
54 |
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/babel-doc/documentation.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #How to use it: just call this script from the project root directory.
4 |
5 | # Setup if you want to use virtual python environment
6 | #virtualenv ENV
7 | #source ./ENV/bin/activate
8 |
9 | sudo pip install --upgrade sphinx sphinx_bootstrap_theme
10 |
11 | cd babel-doc
12 | make clean
13 |
14 | #generate the main documentation
15 | make html
16 |
17 | #generate the main documentation in pdf
18 | make latexpdf
19 | cp build/latex/Babel.pdf build/html/_static/
20 |
21 | #Clean the python virtual env
22 | cd ..
23 |
24 | #cleaning of the virtual python environment
25 | # deactivate
26 |
27 |
--------------------------------------------------------------------------------
/babel-doc/generate-pdf.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #generate the documentation in latex format
4 | make latex
5 |
6 | #generate grammar diagrams in png format
7 | for file in source/grammar-diagrams/*.svg
8 | do
9 | output=$(basename $file .svg).png
10 | convert $file $output
11 | mv $output build/latex/
12 | done
13 |
14 | #change tex images from svg to be png
15 | sed -e 's/svg/png/g' build/latex/Babel.tex > temp.tex
16 | mv temp.tex build/latex/Babel.tex
17 |
18 | #generate the pdf
19 | cd build/latex
20 | pdflatex *.tex
21 | pdflatex *.tex #done twice for table of content
22 |
--------------------------------------------------------------------------------
/babel-doc/images/architecture-camel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/images/architecture-camel.png
--------------------------------------------------------------------------------
/babel-doc/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/images/architecture.png
--------------------------------------------------------------------------------
/babel-doc/images/logo-without-pole.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/images/logo-without-pole.png
--------------------------------------------------------------------------------
/babel-doc/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/images/logo.png
--------------------------------------------------------------------------------
/babel-doc/images/vectorial/logo.idraw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/images/vectorial/logo.idraw
--------------------------------------------------------------------------------
/babel-doc/source/.gitignore:
--------------------------------------------------------------------------------
1 | *.py[cod]
2 |
--------------------------------------------------------------------------------
/babel-doc/source/.sphinx/exts/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/babel-doc/source/.static/default.css:
--------------------------------------------------------------------------------
1 | .left {
2 | float: left;
3 | width: 33%;
4 | padding-right: 20px;
5 | }
6 |
7 | .middle {
8 | display: block;
9 | overflow: hidden;
10 | width: 33%;
11 | }
12 |
13 | .right {
14 | padding-left: 20px;
15 | float: right;
16 | width: 33%;
17 | }
18 |
19 | .about {
20 | padding: 10px;
21 | padding-bottom: 30px;
22 | width: 100%;
23 | background-color: rgb(234, 241, 241);
24 | border-bottom-color: rgba(0, 0, 0, 0.1);
25 | border-bottom-width: 1px;
26 | border-bottom-style: solid;
27 | margin-bottom: 20px;
28 | margin-top: 20px;
29 | }
30 |
31 | .alert-info {
32 | background-color: #222222;
33 | }
34 |
35 | .alert-warning {
36 | background-color: #e74c3c;
37 | }
38 |
39 | #dLabelLocalToc {
40 | visibility: hidden;
41 | }
42 |
43 | .localtoc {
44 | visibility: hidden;
45 | }
46 |
47 | #pdf-link {
48 | float: right;
49 | vertical-align: middle;
50 | padding-top: 5px;
51 | padding-bottom: 5px;
52 | padding-left: 10px;
53 | }
54 |
55 | #pdf-link a:link {
56 | color: #FFFFFF;
57 | }
58 |
59 | #pdf-link a:visited {
60 | color: #FFFFFF;
61 | }
62 | .alert-info{
63 | background-color:#F5F5F5
64 | color: #333
65 | }
66 |
--------------------------------------------------------------------------------
/babel-doc/source/.static/eip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/.static/eip.png
--------------------------------------------------------------------------------
/babel-doc/source/.static/lambda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/.static/lambda.png
--------------------------------------------------------------------------------
/babel-doc/source/.static/language.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/.static/language.png
--------------------------------------------------------------------------------
/babel-doc/source/.static/modular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/.static/modular.png
--------------------------------------------------------------------------------
/babel-doc/source/.static/osgi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/.static/osgi.png
--------------------------------------------------------------------------------
/babel-doc/source/.static/type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/.static/type.png
--------------------------------------------------------------------------------
/babel-doc/source/.templates/layout.html:
--------------------------------------------------------------------------------
1 | {% extends "!layout.html" %}
2 |
3 | {# Custom CSS overrides #}
4 | {% set bootswatch_css_custom = ['_static/default.css'] %}
5 |
6 | {% block header %}
7 | {{ super() }}
8 |
14 |
15 |
28 |
37 | {% endblock %}
38 |
39 |
40 |
--------------------------------------------------------------------------------
/babel-doc/source/_themes/bootstrap:
--------------------------------------------------------------------------------
1 | ../../../bootstrap
--------------------------------------------------------------------------------
/babel-doc/source/architecture.rst:
--------------------------------------------------------------------------------
1 | .. _babel-architecture:
2 |
3 | Babel Architecture
4 | ==================
5 |
6 | Babel overview
7 | ++++++++++++++
8 |
9 | Babel is a Domain Specific Language (DSL). This means Babel helps you to specify what you want to achieve and not to make it directly.
10 |
11 | You may see Babel as one more DSL for Apache Camel, among well-known ones such as the Java, Scala and XML DSL:
12 |
13 | .. figure:: ../images/architecture-camel.png
14 | :align: center
15 | :scale: 75%
16 |
17 | Babel Camel is another way to write Apache Camel routes.
18 |
19 | Babel Modules
20 | +++++++++++++
21 |
22 | Babel is splitted into modules:
23 |
24 | * **babel-fish** is the core of Babel
25 | * **babel-camel** is a connector for Apache Camel
26 | * **babel-spring** is an experimental connector for Spring Integration (coming soon)
27 |
28 | .. figure:: ../images/architecture.png
29 | :align: center
30 | :scale: 75%
31 |
32 | Babel's modules : **babel-fish**, **babel-camel** and the experimental **babel-spring**
--------------------------------------------------------------------------------
/babel-doc/source/camel/mock.rst:
--------------------------------------------------------------------------------
1 |
2 | Mock Extension
3 | ===============
4 |
5 | Mock is the first extension of the Babel Camel DSL. It provides both a DSL and some helpers.
6 |
7 | Description
8 | +++++++++++
9 |
10 | An extension for Babel Camel declaring some helpers for testing.
11 |
12 | Requirement
13 | ~~~~~~~~~~~
14 |
15 | The ``babel-camel-mock`` module needs to in the classpath.
16 |
17 | Usage
18 | +++++
19 |
20 | Import the ``io.xtech.babel.camel.mock._`` package and extends the ``RouteBuilder`` with the ``Mock`` trait.
21 |
22 | mock component
23 | ~~~~~~~~~~~~~~
24 |
25 | For testing a mock endpoint can be declared with the mock endpoint.
26 |
27 | .. includecode:: ../../../babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/MockSpec.scala#doc:babel-camel-mock
28 |
29 | The mock keyword keeps the type of the payload as the mock component do not modify the received messages in most of the cases. For more complexe cases, such as when using ``returnReplyBody``, you may fallback to the legacy way to define mock endpoints.
30 |
31 |
--------------------------------------------------------------------------------
/babel-doc/source/camel/samples.rst:
--------------------------------------------------------------------------------
1 |
2 | Babel Camel Samples
3 | ===================
4 |
5 | Process - Split - Router Sample
6 | +++++++++++++++++++++++++++++++
7 |
8 | This snippet of code defines a Route which receives a list of country id and dispatch to the corresponding country.
9 |
10 | .. includecode:: ../../../babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/sample/SampleSpec.scala#doc:babel-camel-sample-1
--------------------------------------------------------------------------------
/babel-doc/source/camel/spring.rst:
--------------------------------------------------------------------------------
1 |
2 | Babel Camel using the Spring Application Context
3 | ================================================
4 |
5 | This page explains how to integrate a Babel Camel route with a Spring Application Context.
6 |
7 | A route defined with the Babel Camel DSL may be transparently loaded into a Spring Application Context, such as that:
8 |
9 | .. highlight:: xml
10 | .. includecode:: ../../../babel-camel/babel-camel-core/src/test/resources/META-INF/spring/context.xml
11 | .. highlight:: scala
12 |
13 | With the corresponding Babel Camel route:
14 |
15 | .. includecode:: ../../../babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/builder/spring/MyRouteBuilder.scala#doc:babel-camel-spring
16 |
17 | .. warning:: Unfortunately, the injection using setters may cause Babel initialization to fail because Babel may get intialized before every required Spring Bean. To handle this, please use the ``io.xtech.cf.babel.camel.builder.SpringRouteBuilder`` and define your route in the *configure* method body.
18 | You may also use the constructor injection if you prefer to rely on the basic ``io.xtech.babel.camel.builder.RouteBuilder``.
19 | .. includecode:: ../../../babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/builder/springinjection/SetterInjectionRouteBuilder.scala#doc:babel-camel-spring-setter
--------------------------------------------------------------------------------
/babel-doc/source/cameluserguide.rst:
--------------------------------------------------------------------------------
1 | .. _babel-camel-guide:
2 |
3 | Babel Camel User guide
4 | ======================
5 |
6 | .. todo : be able to create a pdf only for babel camel user guide
7 |
8 |
9 | In most examples, we are writing a `route` which represents the flow of your integration solution. Those `routes` are usually defined in a
10 | `RouteBuilder`.
11 | Most of the keywords are dealing with the Camel Message, unless specified as body specific (for example, **process** deals with a Camel Message and **processBody** deals with the body of the Camel Message).
12 |
13 | .. warning::
14 | In the Message interface, its body is represented as an Option[T] to handle the nullable case. Thus, the keywords, such as **process**, which handles a Message should be aware of this point. The keywords, such as **processBody**, which handles directly the Message body do not have to care about that.
15 |
16 | .. toctree::
17 | :maxdepth: 2
18 |
19 | camel/spring
20 | camel/samples
21 | camel/basics
22 | camel/transformation
23 | camel/routing
24 | camel/errormanagement
25 | camel/mock
26 |
27 |
--------------------------------------------------------------------------------
/babel-doc/source/dev/contribute.rst:
--------------------------------------------------------------------------------
1 |
2 | Contribute to Babel
3 | ===================
4 |
5 | First of all, thank you for wanting to improve the Babel project. These guidelines may help you in your trip to enrich Babel with your skills, whatever they are.
6 |
7 | How to contribute?
8 | ++++++++++++++++++
9 |
10 | Contribute with feedback
11 | ~~~~~~~~~~~~~~~~~~~~~~~~
12 |
13 | Maybe the first way to contribute to the Babel project is to test it and to provide us feedback about your experience.
14 |
15 | First, even if it may be obvious, have a look to the current documentation, the existing posts in the mailing list and the github issues. As computer scientists, we love when not repeating ourselves unnecessary.
16 |
17 | The best place to ask your questions (and potentially to get answer) is the `mailing list `_ .
18 | You may also (but not always) chat in our irc room (at irc.codehaus.net, channel #babel)
19 |
20 |
21 | Contribute with code
22 | ~~~~~~~~~~~~~~~~~~~~
23 |
24 | We will examine and hopefully accept your code contribution with pleasure. Please have a look to the following points which may help you to contribute:
25 |
26 | * Read and sign the `CLA `_ .
27 | * Make sure a github issue exists (to avoid other people to work on the same topic).
28 | * Ensure your using the Crossing-Tech `copyright `_, you are not addding dependencies incompatible with the licence Apache2.
29 | * Shape your contribution into a Github `Pull request `_ .
30 | * Please take the Pull request review as an opportunity to improve the quality of your contribution. Creating the Pull request is certainly not your the final goal.
31 | * Once the Pull requested is accepted, please clean your git branch (it should be more often a single commit).
32 |
33 | We would like to keep the contribution process as simple and effective as possible. This procedure may get improve with the time, do not hesitate if you have an opinion.
34 |
35 | .. toctree::
36 | :hidden:
37 |
38 | legal
--------------------------------------------------------------------------------
/babel-doc/source/dev/development.rst:
--------------------------------------------------------------------------------
1 |
2 | Babel development
3 | =================
4 |
5 | .. highlight:: bash
6 |
7 | We will define here some guide lines used during the development of Babel.
8 |
9 | Build
10 | +++++
11 |
12 | Babel is build using Apache Maven (even if a Sbt configuration is synchronized with).
13 |
14 | Source Code
15 | +++++++++++
16 |
17 | The Code is reformatted while compiling the sources using sbt (which uses `scalariform `_)
18 | To reformat the code:
19 | ::
20 |
21 | sbt test-compile
22 |
23 | Tests
24 | +++++
25 |
26 | In the Babel modules implemented using Scala, `Specs2 `_ is the used testing framework.
27 |
28 | Test coverage reports are generated using scoverage through the sbt build configuration following:
29 | ::
30 |
31 | sbt scoverage:test
32 | #browse test reports in modules target directory (target/classes/coverage-report)
33 |
34 | Deployment
35 | +++++++++++
36 |
37 | With Maven
38 | ~~~~~~~~~~
39 | Snapshots are deployed locally using the Maven build configuration as following:
40 | ::
41 |
42 | mvn install
43 |
44 | With Sbt
45 | ~~~~~~~~
46 | Snapshots are deployed using the Sbt build configuration as following:
47 | ::
48 |
49 | sbt publish-local
50 |
51 | Release
52 | +++++++
53 |
54 | Releases are done using the Sbt/Maven build configuration (coming soon)
55 |
56 |
57 | .. highlight:: scala
--------------------------------------------------------------------------------
/babel-doc/source/dev/extension.rst:
--------------------------------------------------------------------------------
1 |
2 | .. _babel-dev-extension:
3 |
4 | Babel Extension creation
5 | ========================
6 |
7 | This page will explains how you can extends the DSL from Babel Camel by adding new keywords and grammar parts to the existing DSL.
8 |
9 | .. warning::
10 | The extension of the DSL requires some knowledge of the Scala language.
11 |
12 | Existing Extensions
13 | +++++++++++++++++++
14 |
15 | .. toctree::
16 | :maxdepth: 1
17 |
18 | ../camel/mock
19 |
20 | Create an extension
21 | +++++++++++++++++++
22 |
23 | To create an extension, you need to create a new DSL, some definition objects and a Parser.
24 |
25 | Explanation
26 | ~~~~~~~~~~~
27 |
28 | #. Choose a package for your the new extension like ``io.xtech.babel.camel.mock``
29 | #. Create some definition objects that extends ``io.xtech.babel.fish.parsing.StepDefinition``.
30 | #. Create a DSL with your new keywords using the definition objects.
31 | The DSL will take a ``io.xtech.babel.fish.BaseDSL`` and extends a ``io.xtech.babel.fish.DSL2BaseDSL``
32 | #. Create a trait that extends ``io.xtech.babel.camel.parsing.CamelParsing``.
33 |
34 | a) Declare your parser by defining a parse method which returns a ``Process`` type and add it to the ``steps`` of the trait.
35 | b) Declare an implicit method using your new DSL.
36 |
37 | Example
38 | ~~~~~~~
39 | .. includecode:: ../../../babel-camel/babel-camel-core/src/test/scala/io/xtech/babel/camel/MockSpec.scala#doc:babel-camel-mock
40 |
41 |
--------------------------------------------------------------------------------
/babel-doc/source/dev/installation.rst:
--------------------------------------------------------------------------------
1 |
2 | Babel Installation Guide
3 | ========================
4 |
5 |
6 | Project Requirements
7 | ++++++++++++++++++++
8 |
9 | =========================== ========================================
10 | Operating System GNU/Linux, Mac OS X, MS Windows
11 | Java VM Oracle JDK 6
12 | Maven 3.0.5
13 | =========================== ========================================
14 |
15 | .. _MavenInstall:
16 |
17 | Build Babel with Maven
18 | ++++++++++++++++++++++
19 |
20 | .. highlight:: bash
21 |
22 | To build Babel from sources using `Apache Maven `_, in a regular shell::
23 |
24 | git clone https://github.com/babel-dsl/babel.git
25 | cd babel
26 | export MAVEN_OPTS="-XX:MaxPermSize=256m -Xmx1024m"
27 | mvn install
28 |
29 |
30 | Build Babel with Sbt
31 | ++++++++++++++++++++
32 | To build Babel from sources using `Sbt `_, in a regular shell::
33 |
34 | git clone https://github.com/babel-dsl/babel.git
35 | cd babel
36 | export SBT_OPTS="-XX:MaxPermSize=256m -Xmx1024m"
37 | sbt test publish-local
38 |
39 | .. highlight:: scala
40 |
41 | Generate the documentation
42 | ++++++++++++++++++++++++++
43 |
44 | to generate the documentation, first install the sphinx documentation generator and then, run:
45 | ::
46 |
47 | git clone https://github.com/babel-dsl/babel.git
48 | cd babel/babel-doc
49 | make html
50 | #browse build/html/index.html
51 |
52 | .. note::
53 | Akka provides some nice documentation on how to generate documentation with Sphinx: `Akka Sphinx Documentation `_
54 |
--------------------------------------------------------------------------------
/babel-doc/source/dev/legal.rst:
--------------------------------------------------------------------------------
1 |
2 | Babel copyright notice
3 | ======================
4 |
5 | The copyright notice should look like:
6 | ::
7 |
8 | /*
9 | *
10 | * Copyright STARTING_YEAR-CURRENT_YEAR Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
11 | * All rights reserved.
12 | *
13 | * ==================================================================================
14 | */
15 |
16 | Where the STARTING_YEAR states the creation of the file and the CURRENT_YEAR states the last modification of the file.
17 |
18 | Please avoid any mention of author information in the file. Instead of this, please make sure your name get mentioned with the first release of your contribution.
19 |
--------------------------------------------------------------------------------
/babel-doc/source/dev/structure.rst:
--------------------------------------------------------------------------------
1 |
2 | Babel Structure
3 | ===============
4 |
5 | Each of the presented Babel module is composed of the following objects:
6 |
7 | * Domain Specific Language (DSL)
8 | * Definition Objects (model)
9 | * Parser
10 |
11 | DSL
12 | ~~~
13 |
14 | - The DSL is used by the user when declaring the flow of a route.
15 | - The DSL exposes an API and creates definition object used by the parser.
16 |
17 | Definition Objects
18 | ~~~~~~~~~~~~~~~~~~
19 |
20 | - Each definition object defines the behaviour of an EIP in the route.
21 | - All the definitions define the model of the route.
22 |
23 | Parser
24 | ~~~~~~
25 |
26 | - A parser takes definition objects and use them to configure the runtime of the route (Apache Camel, Spring Integration).
27 | - A route is defined with all its definition objects.
28 |
29 |
30 |
--------------------------------------------------------------------------------
/babel-doc/source/devguide.rst:
--------------------------------------------------------------------------------
1 | Babel Development guide
2 | =======================
3 |
4 | This sections provides information if you want to develop or understand better Babel.
5 |
6 | .. toctree::
7 | :maxdepth: 1
8 |
9 | dev/structure
10 | dev/installation
11 | dev/development
12 | dev/contribute
13 | dev/extension
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/grammar-diagrams/handler-1.png
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/grammar-diagrams/handler-2.png
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/grammar-diagrams/handler-3.png
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crossing-Tech/babel/c2bfe0b76fe18cf95bdfdce75e0cf90f01fa146a/babel-doc/source/grammar-diagrams/handler-4.png
--------------------------------------------------------------------------------
/babel-doc/source/grammar-diagrams/handler-4.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/babel-doc/source/grammar.g:
--------------------------------------------------------------------------------
1 | route ::= 'from(' string ')' ( '.on[' Exception.Type ']' ( 'when' ( BODYPREDICATE | FUNCTION ) )? optionalConfiguration | '.onMessage[' Exception.Type ']' ( 'when' ( MESSAGEPREDICATE | FUNCTION ) )? optionalConfiguration )?
--------------------------------------------------------------------------------
/babel-doc/source/grammar/handler.grammar:
--------------------------------------------------------------------------------
1 | RouteBuilder = 'class RouteBuilder' '{' [handle] ('from' [ '.'handle])+ '}';
2 | handle = 'handle' '('('_.' 'error-handling' | 'route' '=>' '{' { 'route' '.' 'error-handling' } '}')')';
3 | exceptionClause = 'on' '[' Exception ']'['(' Predicate ')'] ('continued' '(' (Boolean | Predicate) ')' | 'handled' '(' (Boolean | Predicate) ')');
4 | errorHandler = (('defaultErrorHandler'|'deadletter(' String' )') ['.maximumRedeliveries(' Integer' )'] ['.maximumRedeliveries(' Long' )'] ['.maximumRedeliveryDelay(' Integer' )']) | 'loggingErrorHandler' '('[LoggingLevel] [Logger] ')'| 'noErrorHandler' )
--------------------------------------------------------------------------------
/babel-doc/source/opinion.rst:
--------------------------------------------------------------------------------
1 | .. _babel-opinion:
2 |
3 | Babel Opinion
4 | =============
5 |
6 | Babel opinion is that code which defines integration should be easy to write and to read. From the experience we have got using Apache Camel (Java DSL), we have raise the following points:
7 |
8 | - A DSL needs to be simple to make it easy to write
9 | - A DSL needs to be explicit to make it easy to read
10 |
11 | We have been influenced by the `Scala `_ language. In other words, we just want to have the same features we already had with Scala at the route layer. Let's take a look at those points:
12 |
13 | Simple DSL
14 | ++++++++++
15 |
16 | Simple means we would provide one way to do things. This means selection. Currently, the amount of possibilities does not facilitate the coding process.
17 |
18 | Actually, "simple" means composed by one thing, without duplicity nor ornamentation but plain. At this point, simple means also easy in the sense we have tried to restrict the possibilities to the most interesting. Babel adds as less as possible new Interfaces and tries as much as possible to rely on existing and basic tools such as Functions. As we will see latter, clear auto-completion provided by your IDE increase the coding process and adds confidence into what you are actually writing. Select the best way to achieve your task and then *transform a good practice into API* could be the main goal of the Babel project.
19 |
20 | Explicit DSL
21 | ++++++++++++
22 |
23 | As a first taste, explicit means to avoid some implicits. In Apache Camel, an implict we found really dangerous and not advantageous was the Implict type converters: Apache Camel implicitely add type conversion depending on your code expectations.
24 | In other words, with Apache Camel, if your code expects some type concerning its input which is not the output of the previous step, this will be fixed implicitely at runtime.
25 | On the contrary, with Babel, the input type is as explicit as possible. For convenience, it is simply computed from the previous step output. Even if you do not see it in your code, your IDE may compute it at compile time and this is used to validate your code before having actually run it.
26 |
27 | More important is the fact that adding information about the input type helps to read your code (and also to review it). Babel tends also to separate (explicit) type conversion from input transformation.
28 |
29 | Explicit and Simple DSL
30 | +++++++++++++++++++++++
31 |
32 | Now let's have a look to what does those two feature provide together to the coding process. Actually, we may also resume those two aspects as **typed** and **functional**.
33 |
34 | In other words, Babel lets you define processing in functional way and raise Scala type inference at the route level.
35 |
36 | Auto completion takes advantages from the typing as much as from the simplicity:
37 |
38 | - Having only the possible keywords in completion helps to find the good one
39 | - Type inference checks and provides inputs type to your functions
40 |
41 |
--------------------------------------------------------------------------------
/babel-doc/source/quickstartguide.rst:
--------------------------------------------------------------------------------
1 | .. _babel-quick-start:
2 |
3 | Quick start guide
4 | =================
5 |
6 | Babel depends mainly on the following artifacts:
7 |
8 | * org.scala-lang/scala-library/2.10.4
9 | * org.apache.camel/camel-core/2.12.4
10 |
11 | Using Maven
12 | +++++++++++
13 |
14 | .. highlight:: xml
15 |
16 | To add Babel Camel in a Maven project, just add the following dependencies to your pom.xml file:
17 |
18 | ::
19 |
20 |
21 | io.xtech.babel
22 | babel-camel-core
23 | BABEL_VERSION
24 |
25 |
26 | If you don't want to build the Babel project on your machine (otherwise, see :ref:`MavenInstall`), use the Sonatype Snapshot repository to your Maven configuration::
27 |
28 |
29 | oss-sonatype
30 | oss-sonatype
31 | https://oss.sonatype.org/content/repositories/snapshots/
32 |
33 | true
34 |
35 |
36 |
37 | If you also want to use the Babel Camel Mock extension for your tests, you may also add:
38 |
39 | ::
40 |
41 |
42 | io.xtech.babel
43 | babel-camel-mock
44 | BABEL_VERSION
45 | test
46 |
47 |
48 | Where BABEL_VERSION is replaced by the actual Babel version.
49 |
50 | Using Sbt
51 | +++++++++
52 |
53 | .. highlight:: scala
54 |
55 | To add Babel Camel in a Sbt project, you may just add the following dependencies and resolver to your build configuration:
56 |
57 | ::
58 |
59 | resolvers += "Sonatype OSS Snapshots" at
60 | "https://oss.sonatype.org/content/repositories/snapshots
61 |
62 | libraryDependencies += "io.xtech.babel" %% "babel-camel-core" % "BABEL_VERSION"
63 | //if you want to use the mock keyword to simplify your tests:
64 | libraryDependencies += "io.xtech.babel" %% "babel-camel-mock" % "BABEL_VERSION"
65 | % "test"
66 |
67 | Where BABEL_VERSION is replaced by the actual Babel version.
--------------------------------------------------------------------------------
/babel-fish/build.sbt:
--------------------------------------------------------------------------------
1 |
2 | organization := "io.xtech.babel"
3 |
4 | name := "babel-fish"
5 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/DSLHelper.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 |
13 | import scala.language.implicitConversions
14 | import scala.reflect.ClassTag
15 |
16 | trait DSLEnricher
17 |
18 | /**
19 | * Template DSL whose keywords are typing a BaseDSL
20 | */
21 | trait DSL2BaseDSL[I] extends DSLEnricher {
22 |
23 | protected def baseDsl: BaseDSL[I]
24 |
25 | protected implicit def addAStepToTheDSL[II: ClassTag](definition: StepDefinition): BaseDSL[II] = {
26 | baseDsl.step.next = Some(definition)
27 | new BaseDSL[II](definition)
28 | }
29 |
30 | }
31 |
32 | /**
33 | * Template DSL whose keywords are typing a FromDSL
34 | */
35 | trait BaseDSL2FromDSL[I] extends DSLEnricher {
36 |
37 | protected def baseDsl: BaseDSL[I]
38 |
39 | protected implicit def addAStepToTheDSL[II: ClassTag](definition: StepDefinition): FromDSL[II] = {
40 | baseDsl.step.next = Some(definition)
41 | new FromDSL[II](definition)
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/JVMLanguage.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish
10 |
11 | /**
12 | * extends a Java function be to read by Scala
13 | */
14 | trait JVMFunction[-I, +O] {
15 | def apply(input: I): O
16 | }
17 |
18 | /**
19 | * extends a Java predicate to be read by Scala
20 | */
21 | trait JVMPredicate[-I] {
22 | def apply(input: I): Boolean
23 | }
24 |
25 | /**
26 | * Facility tools for java 8 DSLs
27 | */
28 | object ScalaHelper {
29 |
30 | def scalaFunction[I, O](function: JVMFunction[I, O]): (I => O) = (i) => {
31 | function.apply(i)
32 | }
33 |
34 | def scalaPredicate[I](predicate: JVMPredicate[I]): (I => Boolean) = (i) => {
35 | predicate.apply(i)
36 | }
37 | }
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/NamingStrategy.scala:
--------------------------------------------------------------------------------
1 | package io.xtech.babel.fish
2 |
3 | import io.xtech.babel.fish.model.StepDefinition
4 |
5 | /**
6 | * The NamingStragegy trait lets define how pattern should be identified in the targeted framework.
7 | * It allows the definition of ids depending on the the squence of EIP currently parsed.
8 | */
9 | trait NamingStrategy {
10 |
11 | /**
12 | * Identifies the current sequence of EIP.
13 | */
14 | protected[babel] var routeId: Option[String] = None
15 |
16 | /**
17 | * Defines how Babel tanslates an EIP to its id, if this is the case.
18 | * @param stepDefinition the pattern for which an id is requested.
19 | * @return None if Babel should not provide an id for this pattern, Some id otherwise.
20 | */
21 | def name(stepDefinition: StepDefinition): Option[String]
22 |
23 | /**
24 | * Used when parsing a new sequence of EIP.
25 | * Helpful if your naming index the pattern with their position in the sequence.
26 | */
27 | protected[babel] def newRoute(): Unit
28 |
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/AggregationDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | /**
12 | * The base trait for all declaration of an aggregator.
13 | * Each DSL (Babel Camel, Babel Fish) need to create their own aggregation declaration with this trait.
14 | * @tparam I the message body type before the aggregation.
15 | * @tparam O the message body type after the aggregation.
16 | */
17 | trait AggregationConfiguration[I, O]
18 |
19 | /**
20 | * The definition a message filtering in a route.
21 | * @param configuration something the configure the aggregation.
22 | * @tparam I the body type of the input message.
23 | * @tparam O the body type after the aggregation.
24 | */
25 | case class AggregationDefinition[I, O](configuration: AggregationConfiguration[I, O]) extends StepDefinition
26 |
27 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/BaseDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | import scala.collection.immutable
12 |
13 | /*
14 | * The base classes for a route definition
15 | */
16 |
17 | /**
18 | * A RouteDefinition contains the definition of the DSL after it has been build.
19 | * @param from the beginning of the route.
20 | */
21 | case class RouteDefinition(from: FromDefinition)
22 |
23 | /*
24 | * The definitions of some basic blocks (EIP, etc ...)
25 | */
26 |
27 | /**
28 | * The definition of a sink in the route.
29 | * @param sink the sink itself.
30 | */
31 | case class EndpointDefinition[I, O](sink: Sink[I, O], requestReply: Option[Boolean] = None) extends StepDefinition
32 |
33 | /**
34 | * The definition of a multicast. A multicast routes the same message to multiple endpoints (sink).
35 | * @param sinks the endpoints.
36 | * @tparam I the body type of the input message.
37 | */
38 | case class MulticastDefinition[I](sinks: immutable.Seq[Sink[I, _]]) extends StepDefinition
39 |
40 | /**
41 | * The definition of a body message conversion.
42 | * @param outClass the new type of the body message.
43 | */
44 | case class BodyConvertorDefinition[I, O](inClass: Class[I], outClass: Class[O]) extends StepDefinition
45 |
46 | /**
47 | * The definition of a body type validation.
48 | * @param outClass the required type.
49 | */
50 | case class BodyTypeValidationDefinition[I, O](inClass: Class[I], outClass: Class[O]) extends StepDefinition
51 |
52 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/ChoiceDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | import scala.collection.immutable
12 |
13 | /*
14 | * Definitions objects that define the "choice" in the DSL
15 | */
16 |
17 | /**
18 | * The definition of the "choice" block in the DSL.
19 | */
20 | case class ChoiceDefinition[I]() extends ScopeDefinition[WhenDefinition[I]] {
21 |
22 | /**
23 | * @see WhenDefinition
24 | * @return a list of subroutes
25 | */
26 | var otherwise: Option[OtherwiseDefinition] = None
27 |
28 | /**
29 | * A helper method for non-scala language.
30 | * It adds a when definition to this choice definition.
31 | * @param when a When defintion.
32 | */
33 | def addWhen(when: WhenDefinition[I]): Unit = {
34 | this.scopedSteps = scopedSteps :+ when
35 | }
36 |
37 | override def validate(): immutable.Seq[ValidationError] = {
38 |
39 | // validate the subroutes
40 | val whenErrors = scopedSteps.map(_.validate()).flatten
41 | val otherwiseErrors = otherwise.map(_.validate()).getOrElse(immutable.Seq.empty)
42 |
43 | // validate the children definitions
44 | val errors = super.validate()
45 |
46 | // return all the errors
47 | whenErrors ++ otherwiseErrors ++ errors
48 | }
49 | }
50 |
51 | /**
52 | * This class defines a subroute with a predicate.
53 | * @param predicate an object that defined the predicate.
54 | * @tparam I body type of the message.
55 | */
56 | class WhenDefinition[I](val predicate: Predicate[I]) extends StepDefinition
57 |
58 | /**
59 | * This class defines a subroute if no other subroutes handle the message.
60 | */
61 | class OtherwiseDefinition extends StepDefinition
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/FilterDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | /**
12 | * The definition of filtering message in a route.
13 | * @param predicate the condition used for the filtering.
14 | * @tparam I the body type.
15 | */
16 | case class FilterDefinition[I](predicate: Predicate[I]) extends StepDefinition
17 |
18 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/FromDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | // TODO will be fixed in 2.12 https://issues.scala-lang.org/browse/SI-6541
12 |
13 | import scala.language.existentials
14 |
15 | /**
16 | * The FromDefinition define the start of the route.
17 | * @param outClass The type of object generated by the source.
18 | * @param source The source (endpoint) generating the message.
19 | */
20 | case class FromDefinition(outClass: Class[_], source: Source[_]) extends StepDefinition
21 |
22 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/Model.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | import scala.reflect.ClassTag
12 |
13 | /**
14 | * The source of a route.
15 | * @tparam O
16 | */
17 | trait Source[+O]
18 |
19 | /**
20 | * The destination of a route.
21 | * @tparam I
22 | * @tparam O
23 | */
24 | trait Sink[-I, +O]
25 |
26 | /**
27 | * The base case for babel predicate.
28 | * @tparam I the input type.
29 | */
30 | trait Predicate[-I] extends Expression[I, Boolean]
31 |
32 | /**
33 | * The base class for babel expression.
34 | * @tparam I the input type.
35 | * @tparam O the output type.
36 | */
37 | trait Expression[-I, +O]
38 |
39 | /**
40 | * A message passing through a route.
41 | * It is immutable and all changes create a new message.
42 | * @tparam T the type of the body.
43 | */
44 | trait Message[+T] {
45 |
46 | /**
47 | * Returns the body message.
48 | */
49 | def body: Option[T]
50 |
51 | /**
52 | * Returns the body converted to a new type.
53 | * @tparam A the new type.
54 | * @return the converted body.
55 | */
56 | def bodyAs[A: ClassTag]: Option[A]
57 |
58 | /**
59 | * Changes the body message with a function.
60 | * This method requires a body.
61 | * @param f the function that process the body.
62 | * @tparam O the type taken by the body after the change.
63 | * @return a new message with the new body.
64 | */
65 | //todo should we manage the potential NPE as body may be null, or let this problem to the user?
66 | def withBody[O: ClassTag](f: (T => O)): Message[O]
67 |
68 | /**
69 | * Changes the body message with a function.
70 | * This method let you handle the case when the body don't exist.
71 | * @param f the function that process the body.
72 | * @tparam O the type taken by the body after the change.
73 | * @return a new message with the new body.
74 | */
75 | def withOptionalBody[O: ClassTag](f: (Option[T] => Option[O])): Message[O]
76 |
77 | /**
78 | * Returns an immutable Map of all headers in this message.
79 | * @return an immutable Map with all the headers.
80 | */
81 | def headers: Map[String, Any]
82 |
83 | /**
84 | * Creates or updates a header in the message.
85 | * @param key the key.
86 | * @param value the value.
87 | * @return a new Message with the new header.
88 | */
89 | def withHeader(key: String, value: Any): Message[T]
90 |
91 | /**
92 | * Changes the message headers with a function.
93 | * @param f a function processing the headers of the message.
94 | * @return a new Message with modified headers.
95 | */
96 | def withHeaders(f: (Map[String, Any] => Map[String, Any])): Message[T]
97 | }
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/ScopeDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | import scala.collection.immutable
12 |
13 | /**
14 | * defines an EIP which may have several outputs
15 | */
16 | protected[babel] class ScopeDefinition[D <: StepDefinition] extends StepDefinition {
17 |
18 | /**
19 | * @return a list of subroutes
20 | */
21 | protected[babel] var scopedSteps: immutable.IndexedSeq[D] = immutable.IndexedSeq.empty
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/SplitterDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | /**
12 | * The definition of message splitter. It split a message in pieces.
13 | * @param expression how the messages are splitted.
14 | * @tparam I the message body type.
15 | * @tparam O the result type after the splitting.
16 | */
17 | case class SplitterDefinition[I, O](expression: Expression[I, O], stopOnException: Boolean, propagateException: Boolean) extends StepDefinition with SplitConfiguration
18 |
19 | case class SplitReduceDefinition[I, O, G](expression: Expression[I, O], reduce: (G, G) => G, stopOnException: Boolean, propagateException: Boolean) extends StepDefinition with SplitConfiguration {
20 | val internalRouteDefinition = new StepDefinition() {}
21 |
22 | }
23 |
24 | case class SplitFoldDefinition[I, O, G, H](expression: Expression[I, O], seed: H, fold: (H, G) => H, stopOnException: Boolean, propagateException: Boolean) extends StepDefinition with SplitConfiguration {
25 | val internalRouteDefinition = new StepDefinition() {}
26 | }
27 |
28 | trait SplitConfiguration {
29 | def stopOnException: Boolean
30 |
31 | def propagateException: Boolean
32 | }
33 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/StepDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | import scala.collection.immutable
12 |
13 | /**
14 | * A StepDefinition is the base for all Definition in the DSL.
15 | * It define only the next node in the DSL.
16 | */
17 | trait StepDefinition {
18 |
19 | /**
20 | * the next node in the fish.
21 | */
22 | protected[babel] var next: Option[StepDefinition] = None
23 |
24 | /**
25 | * meta information such as uuid, description.
26 | * potentially provided by other systems.
27 | */
28 | protected[babel] var metaInformation: immutable.Map[String, Any] = immutable.Map.empty[String, Any]
29 |
30 | /**
31 | * Validates the definition after the declaration in the fish.
32 | * @return a list of errors. Each error contains an error message and the invalid definition.
33 | */
34 | protected[babel] def validate(): immutable.Seq[ValidationError] = {
35 |
36 | var errors = immutable.Seq.empty[ValidationError]
37 |
38 | // commons validation
39 | val endpointError: immutable.Seq[ValidationError] = (this, next) match {
40 | // a from definition should not end a route
41 | case (FromDefinition(_, _), None) => immutable.Seq(ValidationError("a route or subroute may not end using a from statement", Some(this)))
42 | //a from definition should not follow another definition
43 | case (_, Some(from @ FromDefinition(_, _))) => immutable.Seq(ValidationError("a from may only start a route", Some(from)))
44 | // otherwise, everything is currently valid
45 | case (_, _) => immutable.Seq.empty
46 | }
47 |
48 | errors = endpointError ++ errors
49 |
50 | // children validation
51 | val childrenErrors = next.map(_.validate()).getOrElse(immutable.Seq.empty)
52 |
53 | errors = childrenErrors ++ errors
54 |
55 | errors
56 | }
57 | }
58 |
59 | /**
60 | * A ValidationError is an error found during the validation phase of the DSL.
61 | * @param errorMessage the error message
62 | * @param definition the definition with an error
63 | */
64 | case class ValidationError(errorMessage: String, definition: Option[StepDefinition] = None)
65 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/model/TransformerDefinition.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.model
10 |
11 | /**
12 | * The definition of some message transformation.
13 | * @param expression how the message is transformed.
14 | * @tparam I the type of the body.
15 | * @tparam O the type of the body after transformation.
16 | */
17 | case class TransformerDefinition[I, O](expression: Expression[I, O]) extends StepDefinition
18 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/parsing/Parser.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.parsing
10 |
11 | import io.xtech.babel.fish.model.StepDefinition
12 |
13 | import scala.annotation.tailrec
14 | import scala.collection.immutable
15 |
16 | case class StepInformation[B](step: StepDefinition, previousStepHelper: Any)(implicit val buildHelper: B)
17 |
18 | /**
19 | * base trait for Parsing objects.
20 | * Enforces parsing objects to define one sequence of each possible parsing definition.
21 | * @tparam T
22 | */
23 | trait Parsing[T] {
24 | type Process = PartialFunction[StepInformation[T], Any]
25 |
26 | //any for last reduced
27 | protected def steps: immutable.Seq[Process]
28 | }
29 |
30 | /**
31 | * base trait for DSL parsers (CamelDSL and SpringIntegrationDSL).
32 | * Provides a method which recursively parses an EIP definition and its children.
33 | * @tparam B
34 | */
35 |
36 | trait StepProcessor[B] extends Parsing[B] {
37 |
38 | private[this] lazy val parse: Function1[StepInformation[B], Option[Any]] = steps.reduce(_ orElse _).lift
39 |
40 | /**
41 | * Processes each step recursively (but the from, managed by the process method.
42 | * Uses the aggregated parsing method which, for each possible keyword, create the required Mediation engine instance.
43 | * @param info containing the informations of the current step.
44 | * @return the info updated with the next step if any, otherwise the info as processed, to get its RouteBuilder.
45 | * @see CamelDSL.process
46 | */
47 |
48 | @tailrec
49 | protected[babel] final def processSteps(info: StepInformation[B]): Unit = {
50 | val processed = parse(info).getOrElse(throw new ParsingException.UnknownStepException(info.step.toString)) //todo add step.toString for better comprehension)
51 | info.step.next match {
52 | case Some(next) => {
53 | processSteps(StepInformation(next, processed)(info.buildHelper))
54 | }
55 | case s =>
56 | }
57 | }
58 |
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/babel-fish/src/main/scala/io/xtech/babel/fish/parsing/ParsingException.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish.parsing
10 |
11 | object ParsingException {
12 |
13 | /**
14 | * An exception thrown when an unknown step (definition) is found in the Babel fish DSL.
15 | * @param step the unknown step
16 | */
17 | class UnknownStepException(step: String) extends Exception(s"The step '$step' has not been successfully parsed.")
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/babel-fish/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | #
3 | # Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | # All rights reserved.
5 | #
6 | # ==================================================================================
7 | #
8 |
9 | #
10 | # The logging properties used for eclipse testing, We want to see debug output on the console.
11 | #
12 | log4j.rootLogger=INFO, out
13 |
14 | # uncomment the following line to turn on Camel debugging
15 | #log4j.logger.org.apache.camel=DEBUG
16 |
17 | # uncomment the following line to turn on ActiveMQ debugging
18 | #log4j.logger.org.apache.activemq=DEBUG
19 |
20 | log4j.logger.org.springframework=WARN
21 |
22 |
23 | # CONSOLE appender not used by default
24 | log4j.appender.out=org.apache.log4j.ConsoleAppender
25 | log4j.appender.out.layout=org.apache.log4j.PatternLayout
26 | log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
27 | #log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
--------------------------------------------------------------------------------
/babel-fish/src/test/scala/io/xtech/babel/fish/AggregateDSLSpec.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish
10 |
11 | import io.xtech.babel.fish.model._
12 | import org.specs2.matcher.MatchResult
13 | import org.specs2.mutable.SpecificationWithJUnit
14 |
15 | class AggregateDSLSpec extends SpecificationWithJUnit {
16 | sequential
17 |
18 | "aggregate keyword" should {
19 | "create a route definition with a route containing an aggregation" in {
20 | import io.xtech.babel.fish.Test._
21 |
22 | case class AP[I, O](func: (I => O)) extends AggregationConfiguration[I, O]
23 |
24 | // create a route
25 | val definitions = new DSL() {
26 | from("direct:input").as[String].aggregate(AP((s: String) => "s")).to("mock:output")
27 | }.build()
28 |
29 | // tests the definition generated from the DSL
30 | definitions.headOption.map(_.from.source.uri) mustEqual Some("direct:input")
31 |
32 | val bodyConvStep = for {
33 | s <- definitions.headOption
34 | step <- s.from.next
35 | } yield step
36 |
37 | bodyConvStep must beSome.like[MatchResult[Any]] {
38 | case step: BodyConvertorDefinition[_, _] => {
39 | step.outClass mustEqual classOf[String]
40 | }
41 | }
42 |
43 | val aggregatorStep = for { previous <- bodyConvStep; step <- previous.next } yield step
44 | aggregatorStep must beSome.like[MatchResult[Any]] {
45 | case step: AggregationDefinition[_, _] =>
46 | step.configuration must haveClass[AP[String, String]]
47 | }
48 |
49 | val endpointStep = for { previous <- aggregatorStep; step <- previous.next } yield step
50 | endpointStep must beSome.like[MatchResult[Any]] {
51 | case step: EndpointDefinition[_, _] => {
52 | step.sink.uri mustEqual "mock:output"
53 | }
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/babel-fish/src/test/scala/io/xtech/babel/fish/Test.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | package io.xtech.babel.fish
10 |
11 | import io.xtech.babel.fish.model.{ Sink, Source }
12 |
13 | import scala.collection.immutable
14 | import scala.language.implicitConversions
15 |
16 | /**
17 | * This class defines what is a source
18 | * @param uri a uri
19 | * @tparam O The type of Object the source generates.
20 | */
21 | class TestSource[+O](val uri: String) extends Source[O]
22 |
23 | /**
24 | * This class defines what is a sink
25 | * @param uri a uri
26 | * @tparam I The type of Object the sink accepts.
27 | * @tparam O The type of Object the sink generates.
28 | */
29 | class TestSink[-I, +O](val uri: String) extends Sink[I, O]
30 |
31 | /**
32 | * It defines the implicits that make the fish works.
33 | */
34 | object Test {
35 |
36 | implicit def stringSource(uri: String) = new TestSource(uri)
37 |
38 | implicit def seqStringSink(uris: Seq[String]) = immutable.Seq(uris.map(new TestSink(_)): _*)
39 |
40 | implicit def stringSink(uri: String) = new TestSink(uri)
41 |
42 | implicit def testSource(source: Source[_]): TestSource[_] = {
43 |
44 | source match {
45 | case testSource: TestSource[_] => {
46 | testSource
47 | }
48 | }
49 | }
50 |
51 | implicit def testSink(sink: Sink[_, _]): TestSink[_, _] = {
52 |
53 | sink match {
54 | case testSink: TestSink[_, _] => {
55 | testSink
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 |
2 | organization := "io.xtech.babel"
3 |
4 | name := "babel"
5 |
6 | scalaVersion := "2.11.5"
7 |
8 | crossScalaVersions := Seq("2.10.5", "2.11.6")
9 |
--------------------------------------------------------------------------------
/notes/0.6.0.markdown:
--------------------------------------------------------------------------------
1 | First open source version
2 | =========================
3 |
4 | The initial open source release of Babel essentially presents a set of keyword to be used with Apache Camel. It also provides a core module (Babel fish) in order to implement other DSL.
5 |
6 |
7 | Keywords
8 | --------
9 |
10 | - Basics
11 | - sources and sinks (from, to, sub)
12 | - route hooks (routeId, onStart, onInit, ...)
13 | - exchange hooks (onExchangeDone, ...)
14 | - logging (log)
15 | - Typing (requireAs, marshal, ...)
16 | - Routing (choice, multicast, recipientList, filter, aggregate, split, vaidate)
17 | - Transformation (enrich, pollEnrich, process, resequence, sort, bean)
18 | - Error handling (handle, on[Throwable], continued, deadletter, loggingErrorHandler, defaultErrorHandler)
19 |
20 |
21 | Mock extension
22 | --------------
23 |
24 | - Define a subset DSL (Mock) for Babel Camel which may be mix in RouteBuilder to add functionnalities
25 |
26 |
27 | Feature
28 | -------
29 |
30 | - Integration with the legacy Apache Camel context (RouteBuilder)
31 | - Integration with the Camel Spring context (SpringRouteBuilder)
32 |
33 | Improvement
34 | -----------
35 |
36 | - Improve the support of scala types (scala.Int, scala.Byte, etc...)
37 |
38 | See the project [readme](https://github.com/crossing-tech/babel) for more information.
39 |
--------------------------------------------------------------------------------
/notes/0.7.0.markdown:
--------------------------------------------------------------------------------
1 | Second open source version
2 | ==========================
3 |
4 | Babel has now been used to address several use cases and got improved. Those projects should be put in production with the present released version of Babel.
5 |
6 | Additions
7 | ---------
8 |
9 | - the throttler keyword is added
10 | - Naming strategies may be set to define default ids
11 |
12 | Improvements
13 | ------------
14 |
15 | - the splitReduceBody and the splitFoldBody keywords let you define how to split, transform and aggregate with a leading API.
16 | - the enrich keyword may take an aggregation configuration argument.
17 | - noAutoStartup becomes autoStartup and takes a parameter.
18 | - Camel exchange may be reached through the CamelMessage (in process method argument).
19 |
20 |
21 | Bug fix
22 | -------
23 |
24 | - Error handling may be inherited, taking advantage of the elimination of the sub keyword.
25 |
26 |
27 | Deletion
28 | --------
29 |
30 | - the sub keyword is removed. Concerning error handling, it is replaced by the handlingRoute.
31 |
32 | See the project [readme](https://github.com/crossing-tech/babel) for more information.
33 |
--------------------------------------------------------------------------------
/notes/about.markdown:
--------------------------------------------------------------------------------
1 | [Babel](http://crossing-tech.github.io/babel) provides elegant DSL for integration. An implementation exists for Apache Camel.
2 |
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
11 |
12 | 4.0.0
13 |
14 | io.xtech.babel
15 | babel
16 | 0.7.0
17 |
18 |
21 |
22 | pom
23 |
24 | Babel :: Main
25 |
26 |
27 | babel-fish
28 | babel-camel
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/project/Build.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 |
10 | import com.typesafe.sbt.SbtScalariform
11 | import com.typesafe.sbt.SbtScalariform.ScalariformKeys
12 | import com.typesafe.sbt.osgi.SbtOsgi
13 | import com.typesafe.sbt.pgp.PgpKeys
14 | import org.scoverage.coveralls.CoverallsPlugin.coverallsSettings
15 | import sbt.Keys._
16 | import sbt._
17 | import sbtrelease.ReleasePlugin.{ReleaseKeys, releaseSettings}
18 | import sbtrelease.Version
19 |
20 | object Build extends Build {
21 |
22 | val artifactVersion = "0.8.0"
23 |
24 | lazy val basicSettings = Defaults.defaultSettings ++ Publish.settings ++ coverallsSettings ++ releaseSettings ++ Seq(
25 | version := artifactVersion,
26 | ReleaseKeys.crossBuild := true,
27 | ReleaseKeys.versionBump := Version.Bump.Minor,
28 | ReleaseKeys.publishArtifactsAction := PgpKeys.publishSigned.value
29 | )
30 |
31 | lazy val defaultSettings = basicSettings ++ formatSettings ++ SbtOsgi.osgiSettings ++ Seq(
32 | fork in test := true
33 | )
34 |
35 | lazy val root = Project(id = "babel",
36 | base = file("."),
37 | settings = basicSettings ++ Seq(
38 | publishArtifact in(Compile, packageBin) := false,
39 | publishArtifact in(Compile, packageSrc) := false,
40 | publishArtifact in(Compile, packageDoc) := false
41 | )
42 | ) aggregate(babelfish, babelcamelcore, babelcamelmock)
43 |
44 | lazy val babelfish = Project(id = "babel-fish",
45 | base = file("babel-fish"),
46 | settings = defaultSettings ++ Dependencies.babelFish
47 | )
48 |
49 | //allows you to define a camelVersion by prompting "set camelVersion=2.10.4" for example.
50 | lazy val camelVersion = SettingKey[String]("x-camel-version")
51 |
52 | lazy val babelcamelcore = Project(id = "babel-camel-core",
53 | base = file("babel-camel/babel-camel-core"),
54 | settings = defaultSettings ++ Dependencies.babelCamelCore++ Seq(
55 | publishArtifact in(Test, packageBin) := true
56 | )
57 | ).dependsOn(babelfish, babelcamelmock)
58 |
59 |
60 | lazy val babelcamelmock = Project(id = "babel-camel-mock",
61 | base = file("babel-camel/babel-camel-mock"),
62 | settings = defaultSettings ++ Dependencies.babelCamelMock
63 | ).dependsOn(babelfish)
64 |
65 |
66 |
67 | //reformatting enforced for compile phase
68 | lazy val formatSettings = SbtScalariform.scalariformSettings ++ Seq(
69 | ScalariformKeys.preferences in Compile := Formatting.formattingPreferences,
70 | ScalariformKeys.preferences in Test := Formatting.formattingPreferences
71 | )
72 |
73 |
74 | }
75 |
76 |
77 |
--------------------------------------------------------------------------------
/project/Dependencies.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | import com.typesafe.sbt.osgi.OsgiKeys
10 | import sbt._
11 | import sbt.Keys._
12 |
13 | object Dependencies {
14 |
15 |
16 | private val testScope = "test"
17 | private val optionalScope = "optional"
18 | private val camelModulePrefix = s"camel"
19 | private val camelGroupId = "org.apache.camel"
20 | private val snapshotSuffix = "-SNAPSHOT"
21 |
22 | lazy val babelFish = Seq(libraryDependencies ++= test, OsgiKeys.exportPackage := Seq("io.xtech.babel.fish.*"))
23 |
24 | lazy val babelCamelMock = Seq(
25 | libraryDependencies ++= Seq(camelCore(fixedCamelVersion)) ++ test,
26 | OsgiKeys.exportPackage := Seq("io.xtech.babel.camel.mock")
27 | )
28 |
29 | lazy val babelCamelCore = camelDependencies ++ camelTestsDependencies ++ Seq(
30 | OsgiKeys.exportPackage := Seq("io.xtech.babel.camel.*")
31 | )
32 |
33 | private[this] val fixedCamelVersion = "2.15.0"
34 |
35 | private[this] lazy val camelDependencies = Seq(
36 | Build.camelVersion := fixedCamelVersion,
37 | version <<= (version, Build.camelVersion) { parseCamelVersion },
38 | //libraryDependencies ++= Seq("com.novocode" % "junit-interface" % "0.8" % "test->default"),
39 | libraryDependencies <++= (Build.camelVersion) { (dv) =>
40 | test ++ camel(dv) ++ Seq(csvForTest, xomForTest)
41 | }
42 | )
43 |
44 | private[this] def parseCamelVersion(babel: String, camel: String): String = {
45 | val camelVersion = if (camel != fixedCamelVersion) {
46 | "-camel-" + camel.split("\\.").take(2).mkString(".")
47 | }else{
48 | ""
49 | }
50 | babel.replace(snapshotSuffix,"") + camelVersion + {if (babel.endsWith(snapshotSuffix)) {snapshotSuffix} else {""}}
51 | }
52 |
53 | private[this] lazy val camelTestsDependencies = Seq(
54 | libraryDependencies <++= (Build.camelVersion) { (dv) =>
55 | Seq(cglib, h2, slf4j) ++ Seq("io.xtech.babel" %% "babel-camel-mock" % Build.artifactVersion exclude("org.apache.camel", "camel-core"))
56 | }
57 | )
58 |
59 | private[this] val camelCore = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-core" % camelVersion
60 | private[this] val camelXmlJson = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-xmljson" % camelVersion % testScope
61 | private[this] val camelCsv = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-csv" % camelVersion % testScope
62 | private[this] val camelSql = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-sql" % camelVersion % testScope
63 | private[this] val camelSpring = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-spring" % camelVersion % optionalScope
64 | private[this] val camelScala = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-scala" % camelVersion % optionalScope
65 | private[this] val camelQuartz = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-quartz" % camelVersion % optionalScope
66 | private[this] val camelTest = (camelVersion: String) => camelGroupId% s"$camelModulePrefix-test" % camelVersion % testScope
67 | private[this] val csvForTest = "org.apache.commons" % "commons-csv" % "1.1" % testScope
68 | private[this] val xomForTest = "xom" % "xom" % "1.2.5" % testScope
69 |
70 | private[this] def camel(camelVersion: String) = Seq(camelCore, camelXmlJson, camelCsv, camelSql,
71 | camelSpring, camelScala, camelQuartz, camelTest).map(x => (x(camelVersion)))
72 |
73 | private[this] val commoncsv = "org.apache.servicemix.bundles" % "org.apache.servicemix.bundles.commons-csv" % "1.0-r706900_3" % testScope
74 |
75 |
76 |
77 | private[this] val cglib = "cglib" % "cglib-nodep" % "2.2" % testScope
78 | private[this] val h2 = "com.h2database" % "h2" % "1.3.174" % testScope
79 |
80 |
81 | private[this] val specs2 = "org.specs2" %% "specs2" % "2.4.1" % testScope
82 | private[this] val junit = "junit" % "junit" % "4.11" % testScope
83 |
84 | private[this] val test = Seq(junit, specs2)
85 |
86 | private[this] val slf4j = "org.slf4j" % "slf4j-log4j12" % "1.7.3"
87 |
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/project/Formatting.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | import scalariform.formatter.preferences._
10 |
11 | object Formatting{
12 |
13 | def formattingPreferences: FormattingPreferences = FormattingPreferences()
14 | .setPreference(AlignSingleLineCaseStatements, true)
15 | .setPreference(DoubleIndentClassDeclaration, true)
16 | .setPreference(PreserveDanglingCloseParenthesis, true)
17 | .setPreference(AlignParameters, true)
18 | .setPreference(AlignSingleLineCaseStatements, true)
19 | .setPreference(CompactControlReadability, true)
20 | .setPreference(CompactStringConcatenation, false)
21 | .setPreference(DoubleIndentClassDeclaration, true)
22 | .setPreference(FormatXml, true)
23 | .setPreference(IndentLocalDefs, false)
24 | .setPreference(IndentPackageBlocks, true)
25 | .setPreference(IndentSpaces, 2)
26 | .setPreference(IndentWithTabs, false)
27 | .setPreference(MultilineScaladocCommentsStartOnFirstLine, false)
28 | .setPreference(PreserveDanglingCloseParenthesis, true)
29 | .setPreference(PlaceScaladocAsterisksBeneathSecondAsterisk, true)
30 | .setPreference(PreserveSpaceBeforeArguments, false)
31 | .setPreference(RewriteArrowSymbols, false)
32 | .setPreference(SpaceBeforeColon, false)
33 | .setPreference(SpaceInsideBrackets, false)
34 | .setPreference(SpaceInsideParentheses, false)
35 | .setPreference(SpacesWithinPatternBinders, true)
36 | }
--------------------------------------------------------------------------------
/project/Publish.scala:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2010-2014 Crossing-Tech SA, EPFL QI-J, CH-1015 Lausanne, Switzerland.
4 | * All rights reserved.
5 | *
6 | * ==================================================================================
7 | */
8 |
9 | import sbt.Keys._
10 | import sbt._
11 |
12 | object Publish {
13 |
14 | lazy val settings = Seq(
15 | publishMavenStyle := true,
16 | publishArtifact in Test := false,
17 | pomIncludeRepository := { _ => false },
18 | publishTo := {
19 | val nexus = "https://oss.sonatype.org/"
20 | if (isSnapshot.value)
21 | Some("snapshots" at nexus + "content/repositories/snapshots")
22 | else
23 | Some("releases" at nexus + "service/local/staging/deploy/maven2")
24 | },
25 | pomExtra := (2014
26 | http://www.crossing-tech.com
27 |
28 |
29 | Apache 2
30 | http://www.apache.org/licenses/LICENSE-2.0.txt
31 | repo
32 |
33 |
34 |
35 | https://github.com/Crossing-Tech/babel.git
36 | scm:git:git@github.com:Crossing-Tech/babel.git
37 |
38 |
39 |
40 | chpache
41 | Christophe Pache
42 | https://twitter.com/chpache
43 |
44 |
45 | leifh
46 | Leif Hallgren
47 | https://twitter.com/lhallgren
48 |
49 | )
50 | )
51 | }
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 |
2 | resolvers += Classpaths.sbtPluginReleases
3 |
4 | resolvers += "Typesafe Repository" at "https://repo.typesafe.com/typesafe/releases/"
5 |
6 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.0.4")
7 |
8 | addSbtPlugin("org.scoverage" %% "sbt-coveralls" % "0.99.0")
9 |
10 | addSbtPlugin("com.codacy" % "sbt-codacy-coverage" % "1.0.3")
11 |
12 | addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
13 |
14 | addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.7.0")
15 |
16 | addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3")
17 |
18 | addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.8.5")
19 |
--------------------------------------------------------------------------------
/src/main/ls/0.6.json:
--------------------------------------------------------------------------------
1 | {
2 | "organization":"io.xtech.babel",
3 | "name":"babel",
4 | "version":"0.6",
5 | "description":"Babel is an efficient way to write your integration solution. It stands as a generic Domain Specific Language (DSL) especially maid for integration duties.",
6 | "site":"http://crossing-tech.github.io/babel",
7 | "tags":["scala", "camel" , "dsl", "mediation"],
8 | "docs":"http://crossing-tech.github.io/babel",
9 | "licenses": [{
10 | "name": "Apache 2",
11 | "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
12 | }],
13 | "resolvers": ["https://oss.sonatype.org/content/repositories/snapshots"],
14 | "dependencies": [{
15 | "organization":"org.apache.camel",
16 | "name": "camel-core",
17 | "version": "2.10.4"
18 | }],
19 | "scalas": ["2.10.3-4, 2.11.0-2"],
20 | "sbt": false
21 | }
--------------------------------------------------------------------------------
/src/main/ls/0.7.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "organization": "io.xtech.babel",
3 | "name": "babel",
4 | "version": "0.7.0",
5 | "description": "Babel is an efficient way to write your integration solution. It stands as a generic Domain Specific Language (DSL) especially maid for integration duties.",
6 | "site": "http://crossing-tech.github.io/babel",
7 | "tags": [
8 | "scala",
9 | "camel",
10 | "dsl",
11 | "mediation"
12 | ],
13 | "docs": "http://crossing-tech.github.io/babel",
14 | "licenses": [
15 | {
16 | "name": "Apache 2",
17 | "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
18 | }
19 | ],
20 | "resolvers": ["https://oss.sonatype.org/content/repositories/snapshots"],
21 | "dependencies": [{
22 | "organization": "org.apache.camel",
23 | "name": "camel-core",
24 | "versions": [
25 | "2.12.4",
26 | "2.13.3",
27 | "2.14.2",
28 | "2.15.0"
29 | ]
30 | }
31 | ],
32 | "scalas": [
33 | "2.10.3-5",
34 | "2.11.0-6"
35 | ],
36 | "sbt": false
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/ls/0.8.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "organization": "io.xtech.babel",
3 | "name": "babel",
4 | "version": "0.8.0",
5 | "description": "Babel is an efficient way to write your integration solution. It stands as a generic Domain Specific Language (DSL) especially maid for integration duties.",
6 | "site": "http://crossing-tech.github.io/babel",
7 | "tags": [
8 | "scala",
9 | "camel",
10 | "dsl",
11 | "mediation"
12 | ],
13 | "docs": "http://crossing-tech.github.io/babel",
14 | "licenses": [
15 | {
16 | "name": "Apache 2",
17 | "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
18 | }
19 | ],
20 | "resolvers": ["https://oss.sonatype.org/content/repositories/snapshots"],
21 | "dependencies": [{
22 | "organization": "org.apache.camel",
23 | "name": "camel-core",
24 | "versions": [
25 | "2.12.4",
26 | "2.13.3",
27 | "2.14.2",
28 | "2.15.0"
29 | ]
30 | }
31 | ],
32 | "scalas": [
33 | "2.10.3-5",
34 | "2.11.0-6"
35 | ],
36 | "sbt": false
37 | }
38 |
--------------------------------------------------------------------------------