= Grape Component
:doctitle: Grape
:shortname: grape
:artifactid: camel-grape
:description: Fetch, load and manage additional jars dynamically after Camel Context was started.
:since: 2.16
:supportlevel: Stable
:component-header: Only producer is supported
//Manually maintained attributes
:camel-spring-boot-name: grape

*Since Camel {since}*

*{component-header}*

http://docs.groovy-lang.org/latest/html/documentation/grape.html[Grape]
component allows you to fetch, load and manage additional jars when
`CamelContext` is running. In practice with Camel Grape component you
can add new components, data formats and beans to your `CamelContext`
without the restart of the router.


== Grape options

// component-configure options: START

// component-configure options: END

// component options: START
include::partial$component-configure-options.adoc[]
include::partial$component-endpoint-options.adoc[]
// component options: END

// endpoint options: START

// endpoint options: END


== Setting up class loader

Grape requires using Groovy class loader with the `CamelContext`. You
can enable Groovy class loading on the existing Camel Context using the
`GrapeComponent#grapeCamelContext()` method:

[source,java]
--------------------------------------------------------------------------------
import static org.apache.camel.component.grape.GrapeComponent.grapeCamelContext;
...
CamelContext camelContext = grapeCamelContext(new DefaultCamelContext());
--------------------------------------------------------------------------------

You can also set up the Groovy class loader used be Camel context by
yourself:

[source,java]
------------------------------------------------------------------------------------
camelContext.setApplicationContextClassLoader(new GroovyClassLoader(myClassLoader));
------------------------------------------------------------------------------------

For example the following snippet loads Camel FTP component:

[source,java]
------------------------------------------------
from("direct:loadCamelFTP").
  to("grape:org.apache.camel/camel-ftp/2.15.2");
------------------------------------------------

You can also specify the Maven coordinates by sending them to the
endpoint as the exchange body:

[source,java]
----------------------------------------------------------
from("direct:loadCamelFTP").
  setBody().constant("org.apache.camel/camel-ftp/2.15.2").
  to("grape:defaultMavenCoordinates");
----------------------------------------------------------

== Adding the Grape component to the project

Maven users will need to add the following dependency to their `pom.xml`
for this component:

[source,xml]
------------------------------------------------------------
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-grape</artifactId>
    <version>x.y.z</version>
    <!-- use the same version as your Camel core version -->
</dependency>
------------------------------------------------------------

== Default payload type

By default Camel Grape component operates on the String payloads:

[source,java]
------------------------------------------------------------------------------------------------
producerTemplate.sendBody("grape:defaultMavenCoordinates", "org.apache.camel/camel-ftp/2.15.2");
------------------------------------------------------------------------------------------------

But of course Camel build-in xref:manual::type-converter.adoc[type conversion
API] can perform the automatic data type transformations for you. In the
example below Camel automatically converts binary payload into the
String:

[source,java]
-----------------------------------------------------------------------------------------------------------
producerTemplate.sendBody("grape:defaultMavenCoordinates", "org.apache.camel/camel-ftp/2.15.2".getBytes());
-----------------------------------------------------------------------------------------------------------

== Headers

The following headers are recognized by the Grape component:

[width="100%",cols="10%,10%,10%,10%,60%",options="header",]
|=======================================================================
|Header |Java constant |Endpoint type |Value type |Description

|`CamelGrapeCommand` |`GrapeConstants.GRAPE_COMMAND` |Producer |`org.apache.camel.component.grape.GrapeCommand` |The command to be performed by the Grape endpoint. Default to `grab`.
|=======================================================================

== Loading components at runtime

In order to load the new component at the router runtime, just grab the
jar containing the given component:

[source,java]
-------------------------------------------------------------------------
ProducerTemplate template = camelContext.createProducerTemplate();
template.sendBody("grape:grape", "org.apache.camel/camel-stream/2.15.2");
template.sendBody("stream:out", "msg");
-------------------------------------------------------------------------

== Loading processors bean at runtime

In order to load the new processor bean  with your custom business login
at the router runtime, just grab the jar containing the required bean:

[source,java]
-----------------------------------------------------------------------------------------------------------------
ProducerTemplate template = camelContext.createProducerTemplate();
template.sendBody("grape:grape", "com.example/my-business-processors/1.0");
int productId = 1;
int price = template.requestBody("bean:com.example.PricingBean?method=currentProductPrice", productId, int.class)
-----------------------------------------------------------------------------------------------------------------

 

== Loading deployed jars after Camel context restart

After you download new jar, you usually would like to have it loaded by
the Camel again after the restart of the `CamelContext`. It is certainly
possible, as Grape component keeps track of the jar files you have
installed. In order to load again the installed jars on the context
startup, use the `GrapeEndpoint.loadPatches()` method in your route: 

 
[source,java]
-------------------------------------------------------------------------
import static org.apache.camel.component.grape.GrapeEndpoint.loadPatches;

... 
camelContext.addRoutes(
  new RouteBuilder() { 
    @Override 
    public void configure() throws Exception { 
      loadPatches(camelContext);
 
      from("direct:loadCamelFTP").
        to("grape:org.apache.camel/camel-ftp/2.15.2"); 
    }
  });
-------------------------------------------------------------------------


== Managing the installed jars

If you would like to check what jars have been installed into the given
`CamelContext`, send message to the grape endpoint with
the `CamelGrapeCommand` header set to `GrapeCommand.listPatches`:

[source,java]
----------------------------------------------------------------------------------------
from("netty-http:http://0.0.0.0:80/patches").
    setHeader(GrapeConstats.GRAPE_COMMAND, constant(CamelGrapeCommand.listPatches)).
    to("grape:list");
----------------------------------------------------------------------------------------

Connecting the to the route defined above using the HTTP client returns
the list of the jars installed by Grape component:

[source,bash]
---------------------------------------
$ curl http://my-router.com/patches
grape:org.apache.camel/camel-ftp/2.15.2
grape:org.apache.camel/camel-jms/2.15.2
---------------------------------------

If you would like to remove the installed jars, so these won't be loaded
again after the context restart, use the `GrapeCommand.``clearPatches`
command:

[source,java]
-----------------------------------------------------------------------------------------
from("netty-http:http://0.0.0.0:80/patches").
    setHeader(GrapeConstats.GRAPE_COMMAND, constant(CamelGrapeCommand.clearPatches)).
    setBody().constant("Installed patches have been deleted.");
-----------------------------------------------------------------------------------------

include::spring-boot:partial$starter.adoc[]
