// This module is included in the following assembly:
// as_develop-step-extensions.adoc

[id='example-camel-bean_{context}']
= Example of using a Camel bean

You can implement a custom step by developing an action as a Camel bean processor. 
To implement the example that creates a step that logs the body of a 
message with an optional prefix, you can write something like this: 

[source,java]
----
import org.apache.camel.Body;
import org.apache.camel.Handler;
import org.apache.camel.Header;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.syndesis.extension.api.annotations.Action;
import io.syndesis.extension.api.annotations.ConfigurationProperty;

@Action(
    id = "log-body-with-prefix",
    name = "Log body with prefix",
    description = "A simple body log with a prefix")
public class LogAction  {
    private static final Logger LOGGER = LoggerFactory.getLogger(LogAction.class);

    @ConfigurationProperty(
        name = "prefix",
        description = "The Log body prefix message",
        displayName = "Log Prefix",
        type = "string")
    private String prefix;

    @Handler // <1>
    public void process(@Header("prefix") String prefix, @Body Object body) {
        if (prefix == null) {
            LOGGER.info("Output {}", body);
        } else {
            LOGGER.info("{} {}", prefix, body);
        }
    }
}
----
<1> This is the function that implements the action.

This Java code uses Syndesis annotations, which means that the
`extension-maven-plugin` can automatically generate the action definition.
In the extension definition JSON file, the action definition will look 
like this: 

[source,json]
----
{
  "id": "log-body-with-prefix",
  "name": "Log body with prefix",
  "description": "A simple body log with a prefix",
  "descriptor": {
    "kind": "BEAN", <1>
    "entrypoint": "io.syndesis.extension.log.LogAction::process", <2>
    "inputDataShape": {
      "kind": "none"
    },
    "outputDataShape": {
      "kind": "none"
    },
    "propertyDefinitionSteps": [ {
      "description": "extension-properties",
      "name": "extension-properties",
      "properties": {
        "prefix": { <3>
          "componentProperty": false,
          "deprecated": false,
          "description": "The Log body prefix message",
          "displayName": "Log Prefix",
          "javaType": "java.lang.String",
          "kind": "parameter",
          "required": false,
          "secret": false,
          "type": "string",
          "raw": false
        }
      }
    } ]
  },
  "actionType": "step"
}
----
<1> The type of the action is `BEAN`. The runtime invokes a Camel bean processor 
to execute the action in this custom step. 
<2> This is the Camel bean to invoke. 
<3> These are the properties that the action defined in this custom step
exposes to the integrator who will be adding this step to an integration. In 
{prodname}, each value that the integrator specifies in the user interface
gets mapped to a message header that has the same name as the property. 
In this example, the integrator will see one input field, with the
*Log Prefix* display name. For more details, see 
link:{LinkSyndesisIntegrationGuide}#descriptions-of-user-interface-properties-in-extension-definitions_extensions[Descriptions of user interface properties].


When you use beans, you might find it convenient to  
inject user properties into the bean 
instead of retrieving them from the exchange header. To do this, implement 
getter and setter methods for the properties that you want to get injected. 
The action implementation would look like this:

[source,java]
----
import org.apache.camel.Body;
import org.apache.camel.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.syndesis.extension.api.annotations.Action;
import io.syndesis.extension.api.annotations.ConfigurationProperty;

@Action(
    id = "log-body-with-prefix",
    name = "Log body with prefix",
    description = "A simple body log with a prefix")
public class LogAction  {
    private static final Logger LOGGER = LoggerFactory.getLogger(LogAction.class);

    @ConfigurationProperty(
        name = "prefix",
        description = "The Log body prefix message",
        displayName = "Log Prefix",
        type = "string")
    private String prefix;

    public void setPrefix(String prefix) { // <1>
        this.prefix = prefix;
    }

    public String getPrefix() { // <2>
        return prefix;
    }

    @Handler
    public void process(@Body Object body) {
        if (this.prefix == null) {
            LOGGER.info("Output {}", body);
        } else {
            LOGGER.info("{} {}", this.prefix, body);
        }
    }
}
----
<1> This is the property setter method.
<2> This is the property getter method.
