SlideShare ist ein Scribd-Unternehmen logo
1 von 29
REDPILL LINPRO

SWAT

Competence Gathering #1            Apache Camel
April 2011                         introduction




PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Agenda

Background
EIP
Architecture from 10,000 ft
Endpoints & components
Programming model
Hiding the integration API from your code
Error handling
Type converters
Deployment




PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Background

Started as a subproject to ActiveMQ

   Now one of the top Apache projects


Implementation of the EIP patterns
Framework for declaring routing logic
NOT a fullblown runtime, such as an ESB.

   … but has the same characteristics


Reuses Spring concepts such as Templates, DI, registries,
  contexts etc..



     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Enterprise Integration Patterns
                      (EIP)




”Pipe and filter” stateless flows
The de facto bible when it comes to the messaging
  integration style
EIP is the basis for all types of flow-based integration
   frameworks (i.e. Camel, Spring Integration, Jboss ESB,
   Mule)

  PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
...EIP continued




PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
A Camel EIP example


                                                                   Queue
                                                                   Papers




                        Split on each      Route on body           Queue
    Queue
                        lineitem                                   Pencils
    purchaseOrder




                                                                   File dir
                                                                   /invalid


from("jms:queue:purchaseOrder?concurrentConsumers=5")
     .split().xpath("//lineItem")
     .choice()
          .when(body().contains("Pen")) .to("jms:queue:Pencils")
          .when(body().contains("Paper")).to("jms:queue:Papers")
          .otherwise().to("file:target/messages/invalid");

PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
10,000 ft architecture




CamelContext      -   Runtime "engine", similar to a SpringContext
Routes            -   Your DSL/XML declared flows
Components        -   Physical connectivity factories to Endpoints, i.e to()/from()
Processors        -   Implements the Processor interface (process() method)



  PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Components and endpoints

> 100 components                             jms:myQueue?concurrentConsumers=5&username=Billy

                                            Component   Path   Options
Separate JAR's
The usual suspects...

   File / JMS / RMI / WS / Http / DB
+ a lot more

   SEDA, Direct, MINA, XMPP,
     WebSockets, Twitter...
Components are bound to URI schemes
..which are then interpreted as Endpoints




       PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Message Exchanges

Context for messages
Exchange ID – Unique id
MEP – InOnly/InOut Enum
Exception – Contains eventual runtime
  exception
Properties – Meta-Data with a lifecycle
  of the complete exchange
Message – In/Out used in processors
  and request/reply




       PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Programming model


 Java "DSL"                            from("file:data/orders")
 (chained methods)                         .split.xpath("//order")
                                           .to("jms:queue:order");



 Declarative XML                       <route>
 (NS support)                           <from uri="file:data/orders"/>
                                         <split>
                                           <xpath>//order</xpath>
                                           <to uri="jms:queue:order"/>
                                         </split>
                                       </route>




       - Scala and Groovy alternatives...


PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Adding the routes, Java style


public class MyRoutes extends RouteBuilder{

    @Override
    public void configure() throws Exception {
      from("file:/orders").to("jms:/orders");
      from("file:/payments").to("jms/payments");
    }
}


camelContext.addRoutes(new MyRoutes());




     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Adding the routes, Spring /
             Blueprint style
   <camelContext xmlns="http://camel.apache.org/schema/spring">
     <route>
       <from uri="file:/orders"/>
       <to uri="jms:/orders"/>
     </route>
     <route>
       <from uri="file:/payments"/>
       <to uri="jms:/orders"/>
     </route>
   </camelContext>




Bootstraps the context as Spring starts

   Main, servlet listener, camel included Main class etc


       PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Loading Java Routes from XML

Mix'n match between XML/Java
Consistent concept throughout the framework


 <camelContext xmlns="http://camel.apache.org/schema/spring">
   <packageScan>
    <package>com.rl.routes</package>
    <excludes>**.*Excluded*</excludes>
    <includes>**.*</includes>
   </packageScan>
  </camelContext>



Irrespective of the language choice, the routes will be
   the same as it's only instructions to Camel
Means that cross-functionality such as visualization etc
  works across the languages
       PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Processors

Simple way to add custom logic in a route

Implements the Processor interface

Quick and dirty way, define your own anonymous impl inline




    from("file:/payments")
       .process(new Processor(){
           public void process(Exchange exchng) throws Exception {
              //business logic on exchange here
            }
          })
       .to("jms:payments");




      PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Service activator pattern
Instead of implementing the Processor intf
Reference service beans instead

   Flexible, less Camel API smell
   Camel can guess method based on message
     type/parameters, annotations or method-ref
   Can also reference by class type instead of registered
     beans

 from("file:/payments")
         .beanRef("paymentService")
         .to("jms/payments");

 @Service
 class PaymentService{
     public PaymentAck conductPayment(String payment){...

      PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
The Registry
public interface Registry {

    Object lookup(String name);

    <T> T lookup(String name, Class<T> type);

    <T> Map<String, T> lookupByType(Class<T> type);
}

    Strategy interface for bean lookups
    Used internally, i.e for finding a TransactionManager impl
    As well as from your flows, using beanRef(”myBean”)
    Impl delegates to SpringContext, CDI BeanManager, Guice,
      OSGi etc...
    camelContext.setRegistry(myRegistry)



         PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Payload type conversion


 from("file://inbox")
     .convertBodyTo(String.class, "UTF-8")
     .to("jms:inbox");




Camel often automatically tries to convert message payload to
  method param based on registered converters
If not, use .convertBodyTo(clazz) from flow to invoke type
   converter explicitly
Could be used where default type would not be the best fit

   I.e. explicitly wanting JMS TextMessage over ByteMessage



     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Writing type converters
 @Converter
 public final class IOConverter {

 @Converter
   public static InputStream toInputStream(URL url) throws IOException {
     return url.openStream();
   }
 }


META-INF/services/org/apache/camel/TypeConverter
 com.rl.common.typeconverters.IOConverter
 com.rl.<customer>.typeconverters.MyConverter
 ....



Or in runtime using..:
context.getTypeConverterRegistry().addTypeConverter(from, to, converter);




            PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
CamelProxy – Hiding Camel
                 from clients
Same concept as i.e. Spring Remoting
Camel automatically creates proxy implementations of a given
  interface
DI-wire your proxy to the client

<camelContext xmlns="http://camel.apache.org/schema/spring">
 <proxy id="paymentService" serviceInterface="se.rl.IPaymentService"
    serviceUrl="direct:payments"/>

 <route>
     <from uri="direct:payments"/>
     <to uri="...."/>
     ......
 </route>
</camelContext>

<b:bean id="paymentClient" class="se.rl.banking.PaymentClient">
    <b:property name="paymentSvc" ref="paymentService"/>
</b:bean>

         PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Error handling

Thrown exceptions → Exchange.exception

   Typically technical exceptions


Camel Error handling by default only kicks in when
  exchange.getException() != null



Error handling is declarative and very flexible

   But you should test your assumptions!




       PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Error handlers

  Default Error handling:
     No redelivery
     Exceptions are propagated back to the caller / incoming endpoint




DefaultErrorHandler                              Default if none specified
<retryable>
DeadLetterChannel                                Implements DLQ pattern. Redirect message.
<retryable>                                      Also supports rolling back to original message
TransactionErrorHandler                          Only used for transactions
<retryable>
NoErrorHandler                                   Dummy

LoggingErrorHandler                              Logging




         PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Error handler features
    errorHandler(defaultErrorHandler()
        .maximumRedeliveries(2)
        .redeliveryDelay(1000)
        .retryAttemptedLogLevel(LoggingLevel.WARN));

    from("seda:queue.inbox")
        .beanRef("orderService", "validate")
        .beanRef("orderService", "enrich")
        .log("Received order ${body}")
        .to("mock:queue.order");

Redelivery policies                               Specify retries, exponential backoff etc.
                                                  Redelivery will be on the exception origin,
                                                  NOT from the start of the route
Scope                                             Context or on a route basis

Exception policies (onException(E))               Specific policies for particular exceptions

onWhen                                            Even more fine-grained control. I.e check
                                                  status code on Http exceptions.

          PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Exception policies

 onException(JmsException.class)
    .handled(true)
    .beanRef("errorFormatter");

 from("jetty:http://0.0.0.0:80/orderservice")
     .beanRef("orderTransformer")
     .to("jms:queue:incomingOrders")
     .beanRef("orderAckTransformer");



onException lets you provide granularity to exception handling
handled(true) instructs the incoming endpoint to not throw
  exception back at caller
Basically an alternative route for i.e constructing an error reply
  message, without it the consumer would get the actual
  exception


     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Deployment options


Camel is only a framework, not a deployment server
WAR, Java standalone, JMS Provider, ServiceMix OSGI, in-
 application
Think about what Spring did for web app environment
  independence, Camel does the same for integration
  solutions


Does not impose restrictions on deployment
  environment!




     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
Proposed deployment path

Camel as stand-alone app or deployed into Jetty/Tomcat
Good for PoC and getting to know the framework
Another option is to bundle Jetty inside your application (as in
  demo)

         Tomcat/Jetty


                             OrderRoutes.war
                       camel-    camel-    camel-
                        core       file      cxf


                              P2pRoutes.war
                       camel-    camel-     camel-
                        core       file       cxf



     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
For transactional use-cases and messaging, consider deploying
  to your standard Java EE container (JBoss, Glassfish,
  Weblogic, Websphere)


          Java EE container


                             OrderRoutes.war
                       camel-    camel-    camel-
                        core       jms       jdbc


                              P2pRoutes.war
                       camel-    camel-     camel-
                        core       jms       jdbc
                JMS /                JPA /
                                                              JTA
             JCA adapters         DataSources



     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
To scale – go full OSGI, deploying to Fuse ESB/ServiceMix

   Removes need to bundle Camel in application
   Makes multi-versions at runtime possible
   Extra features for route management etc..

   Fuse ESB/ServiceMix
                                                                         camel-core
                                                                            1.0
                 OrderRoutes.jar
                                                                       camel-jms 1.0
                                                                         camel-jdbc
                                                                            1.0
                  P2pRoutes.jar
                                                                        camel-... x.x




     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
More info at


Camel Official site

   http://camel.apache.org/
FuseSource webinars

   http://fusesource.com/resources/video-archived-webinars/
Open Source SOA with Fuse

   http://www.parleys.com/#sl=2&st=5&id=1577



And of course, the Camel In Action book!




     PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
DEMO!




PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING

Weitere ähnliche Inhalte

Was ist angesagt?

MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)Daniel Bryant
 
Sling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak KhetawatSling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak KhetawatAEM HUB
 
Introduction to Spring
Introduction to SpringIntroduction to Spring
Introduction to SpringSujit Kumar
 
Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson AEM HUB
 
PROGRAMMING IN JAVA- unit 4-part II
PROGRAMMING IN JAVA- unit 4-part IIPROGRAMMING IN JAVA- unit 4-part II
PROGRAMMING IN JAVA- unit 4-part IISivaSankari36
 
Oracle ADF Architecture TV - Design - Task Flow Navigation Options
Oracle ADF Architecture TV - Design - Task Flow Navigation OptionsOracle ADF Architecture TV - Design - Task Flow Navigation Options
Oracle ADF Architecture TV - Design - Task Flow Navigation OptionsChris Muir
 
E-GEN/iCAN
E-GEN/iCANE-GEN/iCAN
E-GEN/iCANteddi22
 
PROGRAMMING IN JAVA-unit 3-part II
PROGRAMMING IN JAVA-unit 3-part IIPROGRAMMING IN JAVA-unit 3-part II
PROGRAMMING IN JAVA-unit 3-part IISivaSankari36
 

Was ist angesagt? (9)

MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
MSc Enterprise Systems Development Guest Lecture at UniS (2/12/09)
 
Sling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak KhetawatSling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak Khetawat
 
Introduction to Spring
Introduction to SpringIntroduction to Spring
Introduction to Spring
 
Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson
 
PROGRAMMING IN JAVA- unit 4-part II
PROGRAMMING IN JAVA- unit 4-part IIPROGRAMMING IN JAVA- unit 4-part II
PROGRAMMING IN JAVA- unit 4-part II
 
Oracle ADF Architecture TV - Design - Task Flow Navigation Options
Oracle ADF Architecture TV - Design - Task Flow Navigation OptionsOracle ADF Architecture TV - Design - Task Flow Navigation Options
Oracle ADF Architecture TV - Design - Task Flow Navigation Options
 
slingmodels
slingmodelsslingmodels
slingmodels
 
E-GEN/iCAN
E-GEN/iCANE-GEN/iCAN
E-GEN/iCAN
 
PROGRAMMING IN JAVA-unit 3-part II
PROGRAMMING IN JAVA-unit 3-part IIPROGRAMMING IN JAVA-unit 3-part II
PROGRAMMING IN JAVA-unit 3-part II
 

Ähnlich wie 01 apache camel-intro

TS 4839 - Enterprise Integration Patterns in Practice
TS 4839 - Enterprise Integration Patterns in PracticeTS 4839 - Enterprise Integration Patterns in Practice
TS 4839 - Enterprise Integration Patterns in Practiceaegloff
 
Real world #microservices with Apache Camel, Fabric8, and OpenShift
Real world #microservices with Apache Camel, Fabric8, and OpenShiftReal world #microservices with Apache Camel, Fabric8, and OpenShift
Real world #microservices with Apache Camel, Fabric8, and OpenShiftChristian Posta
 
Real-world #microservices with Apache Camel, Fabric8, and OpenShift
Real-world #microservices with Apache Camel, Fabric8, and OpenShiftReal-world #microservices with Apache Camel, Fabric8, and OpenShift
Real-world #microservices with Apache Camel, Fabric8, and OpenShiftChristian Posta
 
Alfresco Business Reporting - Tech Talk Live 20130501
Alfresco Business Reporting - Tech Talk Live 20130501Alfresco Business Reporting - Tech Talk Live 20130501
Alfresco Business Reporting - Tech Talk Live 20130501Tjarda Peelen
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_HourDilip Patel
 
Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"Fwdays
 
Integrating Microservices with Apache Camel
Integrating Microservices with Apache CamelIntegrating Microservices with Apache Camel
Integrating Microservices with Apache CamelChristian Posta
 
Building an ML Platform with Ray and MLflow
Building an ML Platform with Ray and MLflowBuilding an ML Platform with Ray and MLflow
Building an ML Platform with Ray and MLflowDatabricks
 
System Integration with Akka and Apache Camel
System Integration with Akka and Apache CamelSystem Integration with Akka and Apache Camel
System Integration with Akka and Apache Camelkrasserm
 
Microservices for java architects it-symposium-2015-09-15
Microservices for java architects it-symposium-2015-09-15Microservices for java architects it-symposium-2015-09-15
Microservices for java architects it-symposium-2015-09-15Derek Ashmore
 
Global Scale ESB with Mule
Global Scale ESB with MuleGlobal Scale ESB with Mule
Global Scale ESB with MuleAndrew Kennedy
 
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...Chester Chen
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextPrateek Maheshwari
 
Impact 2014 - IIB - selecting the right transformation option
Impact 2014 -  IIB - selecting the right transformation optionImpact 2014 -  IIB - selecting the right transformation option
Impact 2014 - IIB - selecting the right transformation optionAndrew Coleman
 
A machine learning and data science pipeline for real companies
A machine learning and data science pipeline for real companiesA machine learning and data science pipeline for real companies
A machine learning and data science pipeline for real companiesDataWorks Summit
 

Ähnlich wie 01 apache camel-intro (20)

EIP In Practice
EIP In PracticeEIP In Practice
EIP In Practice
 
TS 4839 - Enterprise Integration Patterns in Practice
TS 4839 - Enterprise Integration Patterns in PracticeTS 4839 - Enterprise Integration Patterns in Practice
TS 4839 - Enterprise Integration Patterns in Practice
 
Real world #microservices with Apache Camel, Fabric8, and OpenShift
Real world #microservices with Apache Camel, Fabric8, and OpenShiftReal world #microservices with Apache Camel, Fabric8, and OpenShift
Real world #microservices with Apache Camel, Fabric8, and OpenShift
 
Real-world #microservices with Apache Camel, Fabric8, and OpenShift
Real-world #microservices with Apache Camel, Fabric8, and OpenShiftReal-world #microservices with Apache Camel, Fabric8, and OpenShift
Real-world #microservices with Apache Camel, Fabric8, and OpenShift
 
Camel as a_glue
Camel as a_glueCamel as a_glue
Camel as a_glue
 
Alfresco Business Reporting - Tech Talk Live 20130501
Alfresco Business Reporting - Tech Talk Live 20130501Alfresco Business Reporting - Tech Talk Live 20130501
Alfresco Business Reporting - Tech Talk Live 20130501
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_Hour
 
Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"Julien Simon "Scaling ML from 0 to millions of users"
Julien Simon "Scaling ML from 0 to millions of users"
 
Integrating Microservices with Apache Camel
Integrating Microservices with Apache CamelIntegrating Microservices with Apache Camel
Integrating Microservices with Apache Camel
 
Building an ML Platform with Ray and MLflow
Building an ML Platform with Ray and MLflowBuilding an ML Platform with Ray and MLflow
Building an ML Platform with Ray and MLflow
 
AWS glue technical enablement training
AWS glue technical enablement trainingAWS glue technical enablement training
AWS glue technical enablement training
 
System Integration with Akka and Apache Camel
System Integration with Akka and Apache CamelSystem Integration with Akka and Apache Camel
System Integration with Akka and Apache Camel
 
Microservices for java architects it-symposium-2015-09-15
Microservices for java architects it-symposium-2015-09-15Microservices for java architects it-symposium-2015-09-15
Microservices for java architects it-symposium-2015-09-15
 
Global Scale ESB with Mule
Global Scale ESB with MuleGlobal Scale ESB with Mule
Global Scale ESB with Mule
 
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
Analytics Metrics delivery and ML Feature visualization: Evolution of Data Pl...
 
Eclipse e4
Eclipse e4Eclipse e4
Eclipse e4
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's Next
 
Impact 2014 - IIB - selecting the right transformation option
Impact 2014 -  IIB - selecting the right transformation optionImpact 2014 -  IIB - selecting the right transformation option
Impact 2014 - IIB - selecting the right transformation option
 
A machine learning and data science pipeline for real companies
A machine learning and data science pipeline for real companiesA machine learning and data science pipeline for real companies
A machine learning and data science pipeline for real companies
 

Mehr von RedpillLinpro

Myths, Open Source &
Myths, Open Source &Myths, Open Source &
Myths, Open Source &RedpillLinpro
 
11 information disaster risks
11 information disaster risks11 information disaster risks
11 information disaster risksRedpillLinpro
 
03 osgi and servicemix
03 osgi and servicemix03 osgi and servicemix
03 osgi and servicemixRedpillLinpro
 
00 intro & fuse offerings
00 intro & fuse offerings00 intro & fuse offerings
00 intro & fuse offeringsRedpillLinpro
 

Mehr von RedpillLinpro (6)

Version control:
Version control:Version control:
Version control:
 
Myths, Open Source &
Myths, Open Source &Myths, Open Source &
Myths, Open Source &
 
11 information disaster risks
11 information disaster risks11 information disaster risks
11 information disaster risks
 
03 osgi and servicemix
03 osgi and servicemix03 osgi and servicemix
03 osgi and servicemix
 
02 stock gwdemo
02 stock gwdemo02 stock gwdemo
02 stock gwdemo
 
00 intro & fuse offerings
00 intro & fuse offerings00 intro & fuse offerings
00 intro & fuse offerings
 

Kürzlich hochgeladen

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024SynarionITSolutions
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 

Kürzlich hochgeladen (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 

01 apache camel-intro

  • 1. REDPILL LINPRO SWAT Competence Gathering #1 Apache Camel April 2011 introduction PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 2. Agenda Background EIP Architecture from 10,000 ft Endpoints & components Programming model Hiding the integration API from your code Error handling Type converters Deployment PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 3. Background Started as a subproject to ActiveMQ Now one of the top Apache projects Implementation of the EIP patterns Framework for declaring routing logic NOT a fullblown runtime, such as an ESB. … but has the same characteristics Reuses Spring concepts such as Templates, DI, registries, contexts etc.. PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 4. Enterprise Integration Patterns (EIP) ”Pipe and filter” stateless flows The de facto bible when it comes to the messaging integration style EIP is the basis for all types of flow-based integration frameworks (i.e. Camel, Spring Integration, Jboss ESB, Mule) PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 5. ...EIP continued PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 6. A Camel EIP example Queue Papers Split on each Route on body Queue Queue lineitem Pencils purchaseOrder File dir /invalid from("jms:queue:purchaseOrder?concurrentConsumers=5") .split().xpath("//lineItem") .choice() .when(body().contains("Pen")) .to("jms:queue:Pencils") .when(body().contains("Paper")).to("jms:queue:Papers") .otherwise().to("file:target/messages/invalid"); PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 7. 10,000 ft architecture CamelContext - Runtime "engine", similar to a SpringContext Routes - Your DSL/XML declared flows Components - Physical connectivity factories to Endpoints, i.e to()/from() Processors - Implements the Processor interface (process() method) PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 8. Components and endpoints > 100 components jms:myQueue?concurrentConsumers=5&username=Billy Component Path Options Separate JAR's The usual suspects... File / JMS / RMI / WS / Http / DB + a lot more SEDA, Direct, MINA, XMPP, WebSockets, Twitter... Components are bound to URI schemes ..which are then interpreted as Endpoints PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 9. Message Exchanges Context for messages Exchange ID – Unique id MEP – InOnly/InOut Enum Exception – Contains eventual runtime exception Properties – Meta-Data with a lifecycle of the complete exchange Message – In/Out used in processors and request/reply PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 10. Programming model Java "DSL" from("file:data/orders") (chained methods) .split.xpath("//order") .to("jms:queue:order"); Declarative XML <route> (NS support) <from uri="file:data/orders"/> <split> <xpath>//order</xpath> <to uri="jms:queue:order"/> </split> </route> - Scala and Groovy alternatives... PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 11. Adding the routes, Java style public class MyRoutes extends RouteBuilder{ @Override public void configure() throws Exception { from("file:/orders").to("jms:/orders"); from("file:/payments").to("jms/payments"); } } camelContext.addRoutes(new MyRoutes()); PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 12. Adding the routes, Spring / Blueprint style <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file:/orders"/> <to uri="jms:/orders"/> </route> <route> <from uri="file:/payments"/> <to uri="jms:/orders"/> </route> </camelContext> Bootstraps the context as Spring starts Main, servlet listener, camel included Main class etc PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 13. Loading Java Routes from XML Mix'n match between XML/Java Consistent concept throughout the framework <camelContext xmlns="http://camel.apache.org/schema/spring"> <packageScan> <package>com.rl.routes</package> <excludes>**.*Excluded*</excludes> <includes>**.*</includes> </packageScan> </camelContext> Irrespective of the language choice, the routes will be the same as it's only instructions to Camel Means that cross-functionality such as visualization etc works across the languages PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 14. Processors Simple way to add custom logic in a route Implements the Processor interface Quick and dirty way, define your own anonymous impl inline from("file:/payments") .process(new Processor(){ public void process(Exchange exchng) throws Exception { //business logic on exchange here } }) .to("jms:payments"); PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 15. Service activator pattern Instead of implementing the Processor intf Reference service beans instead Flexible, less Camel API smell Camel can guess method based on message type/parameters, annotations or method-ref Can also reference by class type instead of registered beans from("file:/payments") .beanRef("paymentService") .to("jms/payments"); @Service class PaymentService{ public PaymentAck conductPayment(String payment){... PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 16. The Registry public interface Registry { Object lookup(String name); <T> T lookup(String name, Class<T> type); <T> Map<String, T> lookupByType(Class<T> type); } Strategy interface for bean lookups Used internally, i.e for finding a TransactionManager impl As well as from your flows, using beanRef(”myBean”) Impl delegates to SpringContext, CDI BeanManager, Guice, OSGi etc... camelContext.setRegistry(myRegistry) PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 17. Payload type conversion from("file://inbox") .convertBodyTo(String.class, "UTF-8") .to("jms:inbox"); Camel often automatically tries to convert message payload to method param based on registered converters If not, use .convertBodyTo(clazz) from flow to invoke type converter explicitly Could be used where default type would not be the best fit I.e. explicitly wanting JMS TextMessage over ByteMessage PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 18. Writing type converters @Converter public final class IOConverter { @Converter public static InputStream toInputStream(URL url) throws IOException { return url.openStream(); } } META-INF/services/org/apache/camel/TypeConverter com.rl.common.typeconverters.IOConverter com.rl.<customer>.typeconverters.MyConverter .... Or in runtime using..: context.getTypeConverterRegistry().addTypeConverter(from, to, converter); PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 19. CamelProxy – Hiding Camel from clients Same concept as i.e. Spring Remoting Camel automatically creates proxy implementations of a given interface DI-wire your proxy to the client <camelContext xmlns="http://camel.apache.org/schema/spring"> <proxy id="paymentService" serviceInterface="se.rl.IPaymentService" serviceUrl="direct:payments"/> <route> <from uri="direct:payments"/> <to uri="...."/> ...... </route> </camelContext> <b:bean id="paymentClient" class="se.rl.banking.PaymentClient"> <b:property name="paymentSvc" ref="paymentService"/> </b:bean> PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 20. Error handling Thrown exceptions → Exchange.exception Typically technical exceptions Camel Error handling by default only kicks in when exchange.getException() != null Error handling is declarative and very flexible But you should test your assumptions! PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 21. Error handlers Default Error handling: No redelivery Exceptions are propagated back to the caller / incoming endpoint DefaultErrorHandler Default if none specified <retryable> DeadLetterChannel Implements DLQ pattern. Redirect message. <retryable> Also supports rolling back to original message TransactionErrorHandler Only used for transactions <retryable> NoErrorHandler Dummy LoggingErrorHandler Logging PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 22. Error handler features errorHandler(defaultErrorHandler() .maximumRedeliveries(2) .redeliveryDelay(1000) .retryAttemptedLogLevel(LoggingLevel.WARN)); from("seda:queue.inbox") .beanRef("orderService", "validate") .beanRef("orderService", "enrich") .log("Received order ${body}") .to("mock:queue.order"); Redelivery policies Specify retries, exponential backoff etc. Redelivery will be on the exception origin, NOT from the start of the route Scope Context or on a route basis Exception policies (onException(E)) Specific policies for particular exceptions onWhen Even more fine-grained control. I.e check status code on Http exceptions. PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 23. Exception policies onException(JmsException.class) .handled(true) .beanRef("errorFormatter"); from("jetty:http://0.0.0.0:80/orderservice") .beanRef("orderTransformer") .to("jms:queue:incomingOrders") .beanRef("orderAckTransformer"); onException lets you provide granularity to exception handling handled(true) instructs the incoming endpoint to not throw exception back at caller Basically an alternative route for i.e constructing an error reply message, without it the consumer would get the actual exception PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 24. Deployment options Camel is only a framework, not a deployment server WAR, Java standalone, JMS Provider, ServiceMix OSGI, in- application Think about what Spring did for web app environment independence, Camel does the same for integration solutions Does not impose restrictions on deployment environment! PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 25. Proposed deployment path Camel as stand-alone app or deployed into Jetty/Tomcat Good for PoC and getting to know the framework Another option is to bundle Jetty inside your application (as in demo) Tomcat/Jetty OrderRoutes.war camel- camel- camel- core file cxf P2pRoutes.war camel- camel- camel- core file cxf PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 26. For transactional use-cases and messaging, consider deploying to your standard Java EE container (JBoss, Glassfish, Weblogic, Websphere) Java EE container OrderRoutes.war camel- camel- camel- core jms jdbc P2pRoutes.war camel- camel- camel- core jms jdbc JMS / JPA / JTA JCA adapters DataSources PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 27. To scale – go full OSGI, deploying to Fuse ESB/ServiceMix Removes need to bundle Camel in application Makes multi-versions at runtime possible Extra features for route management etc.. Fuse ESB/ServiceMix camel-core 1.0 OrderRoutes.jar camel-jms 1.0 camel-jdbc 1.0 P2pRoutes.jar camel-... x.x PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 28. More info at Camel Official site http://camel.apache.org/ FuseSource webinars http://fusesource.com/resources/video-archived-webinars/ Open Source SOA with Fuse http://www.parleys.com/#sl=2&st=5&id=1577 And of course, the Camel In Action book! PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
  • 29. DEMO! PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING