Skip to content

Plugins

apryamostanov edited this page Apr 16, 2019 · 28 revisions

Pigeon Plugins

This page is about Pigeon Plugins - user-defined programmatical extensions of Pigeon.

For general information about Pigeon application please refer to Pigeon main wiki page.

❗ Refer to a collection of open source Pigeon Plugins for quick pick-up on SDK.

Contents

Table of contents generated with markdown-toc

Introduction

Pigeon itself defines a mechanism of HTTP message distribution.

However it does not define neither incoming nor outgoing message formats.

This is left to the end-users - to implement their own proprietary formats using a simple Pigeon Plugin SDK (Java/Groovy-based).

Furthermore - Pigeon behavior as a Web Application can also be extended using Plugins.

❇ You don't need IDE or any other special tools to develop or modify Pigeon Plugins. Even standard notepad.exe is enough. Once saved - the changes apply automatically - you don't even have to restart Pigeon.
The goal is to enable rapid development and deployment of the changes - if you want you can change Plugin code directly on Production system - and the changes will reflect immediately.
There are such situations... The Pigeon takes it with an understanding.

Pigeon Plugins SDK

Each Pigeon Plugin is nothing more than just a file with .groovy extension, containing a Groovy script or a Java code (compiled by Groovy Compiler).

By the SDK we mean a number of JAR modules already available to be used in Plugin code, as well as Plugin Variables Binding - the input data "variables" passed to the Plugin each time Pigeon runs it.

Available modules

Please refer to Pigeon Gradle Build Scan for convenient view on the list of available classpath modules (JARs):

Pigeon Build Scan dependency list

In short by default the following modules are available to be used in 'Pigeon Plugins' code:

  • Groovy
  • Spring Boot
  • Jackson Databind (JSON and YAML - via SnakeYaml)
  • BlackBox - logging code automation
  • Bobbin - SLF4J logger

Additionally JARs deployed by the user in the lib directory are also available on the Classpath (e.g. MySQLConnector or any other user-selected JARs).

Runtime data (variables) plugin binding

Pigeon passes several objects serving as variables to the plugin upon its execution.

Generally the binding objects are accessed as follows from within the plugin code:

Object pluginArgument = binding.getVariable("pluginArgumentName")

binding is pre-defined Groovy script global variable.

The available data binding variables are specific to individual Plugin Types and details can be found in the below sections.

Logging

The Pigeon takes amazing care about logging - including the User-defined Pigeon Plugins!
In practice the users writing or modifying Pigeon Plugins do not have to write any logging code - they just need to annotate their classes or methods with @BlackBox annotation - and the logging code will be added automatically using the Carburetor configuration.
That's it - the logs will start to output according to Bobbin configuration.

Plugin Types

Pigeon Plugins are placed on a file system according to the Pigeon Paths Configuration in application.properties:

pigeonOutPluginsDir=./conf/plugins/output/
pigeonInputPluginsRestDir=./conf/plugins/input/rest/
pigeonInputPluginsHttpDir=./conf/plugins/input/http/

The relative directory structure of Plugins normally is the following:

  • {Pigeon Home}
    • plugins
      • input
        • http
        • rest
      • output

Input Plugins

Input Plugins are used to extend the Pigeon functionality as a Web Application, i.e. acting as a Server.

As the primary use case of Pigeon is acting as a Client connecting to external endpoints - it is a safe assumption to say that Input Plugins server mainly the the supplementary internal role, not being critical for the Pigeon mission on Production.

The typical examples of such expansion are:

  • Self Test plugins
  • Mock Service plugins

Each input plugin becomes available as a URL resource (with a same name as Plugin except for the file extension) on the Pigeon URL context path:

<http(s)>://<pigeon ip>:<pigeon port>/<pigeon context path>/plugins/input/<input plugin type>/<plugin name excluding file extension>

The resource name in the end of URL corresponds to Plugin Name - and to its file name on the disk (however file name has .groovy extension which is removed from the resource name.

❗ Currently only POST and GET HTTP Methods are supported in all types of Input Plugins.

Input HTTP Plugins

Input HTTP Plugins are a generic form of Input Plugin and allow full manual control within the plugin over both HTTP Request and Response, including content type and response body.

However Input HTTP Plugins lack automatic content type negotiation feature of Input REST Plugins.

Use Input HTTP Plugins when you are exactly know the supported content types that are going to be used as well the expected response body format, for example SMS Gateway "HTTP API" mocking or forwarding:

Input HTTP Plugins become available as URL resources on the below path:

<http(s)>://<pigeon ip>:<pigeon port>/<pigeon context path>/plugins/input/http/<plugin name excluding file extension>

For example: http://localhost:8089/pigeon/plugins/input/http/MOCK_SMSGLOBAL_HTTP

Input HTTP Plugins Variables Binding
Variable name Class Description
httpServletRequest HttpServletRequest Actual HttpServletRequest with the HTTP Request data such as Headers, URL
httpServletResponse HttpServletResponse A modifiable response that will be returned to the Client calling this Input Plugin.
You can modify HTTP Response Headers and Body using this variable.
inputMessageRepository InputMessageRepository Using this variable you can save and query Pigeon Input Messages
requestBody String Use this variable to reliably access the complete HTTP Request Body as a String.
Note: "" - empty String for GET HTTP Requests.

❇ Input HTTP Plugin must return a String containing raw Response Body.

Input REST Plugins

Input REST Plugins are a more specific form of Input Plugin and act upon an existing REST support within Pigeon (Spring REST Controller).

This allows such features as automatic content type negotiation and Response Body serialization.

However the control over the Response is more limited (comparing to Input HTTP Plugins): the response must object correspond to CustomResponse class (which is just an enclosure of any other custom response Object without class constraints).

Furthermore - the HttpServletResponse is not available in the Input REST Plugin variable binding.

Use Input REST Plugins when there are no explicit requirements for Response Body format and you want to benefit from the above REST API features, e.g. mocking external Pigeon endpoints for automatic self testing and validations:

Input REST Plugins become available as URL resources on the below path:

<http(s)>://<pigeon ip>:<pigeon port>/<pigeon context path>/plugins/input/rest/<plugin name excluding file extension>

For example: http://localhost:8089/pigeon/plugins/input/rest/SelfTest

To specify desired response content type, pass the format URL Query String parameter with the supported value:

  • json
  • yaml

CustomResponse is automatically serialized using specified format, you don't have to worry about that in the REST Plugin code.

For example: http://localhost:8089/pigeon/plugins/input/rest/SelfTest?format=yaml

❇ Default format is json.

Input REST Plugins Variables Binding
Variable name Class Description
httpServletRequest HttpServletRequest Actual HttpServletRequest with the HTTP Request data such as Headers, URL
inputMessageRepository InputMessageRepository Using this variable you can save and query Pigeon Input Messages
requestBody String Use this variable to reliably access the complete HTTP Request Body as a String.

❇ Input REST Plugin must return a ResponseEntity<CustomResponse> (ref. ResponseEntity and CustomResponse).

Output Plugins

Output Plugins are the primary functionality of Pigeon.

They are used to create the actual HTTP Message that is being sent to external endpoints (URLs).

In Output Plugins you have control over:

  • URL
  • HTTP Method
  • Request Headers
  • Request Body

Each external URL (Output Queue) is assigned an Output Plugin, which will be called to create the HTTP Request:

{
  "name": "SELF_TEST_ECHO_HTTP",
  "url": "http://localhost:8089/pigeon/plugins/input/rest/EchoTest?format=yaml",
  "conversionModuleName": "PASSTHROUGH_POST.groovy",
  "senderClassName": "io.infinite.pigeon.http.SenderDefaultHttp"
}

This allows to send one Input Message to multiple URLs in different output formats.

The conversionModuleName variable contains the Output Plugin name including the file extension.

❗ It is Output Plugins the place where you will define the propriatory outgoing HTTP Message formats, which is specific to your business functionality or API.

Refer to basic examples of Output Plugins:

Output Plugins Variables Binding
Variable name Class Description
httpRequest HttpRequest This is the primary variable using which you can construct actual outgoing HTTP Request that will be sent to external endpoint, including the HTTP Request data such as Headers, URL and Request Body
outputQueue OutputQueue The Output Queue configuration object, which contains the configuration to where the message should be sent and how (URL, extensions, httpProperties). Recommended to be used as read-only variable.
inputMessage InputMessage The original source Input Message that triggerred sending process and applying this Output Plugin. Recommended to be used as read-only variable.
outputMessage OutputMessage This variable contains Output Message data such as attemptsCount which can affect the body of httpRequest. Recommended to be used as read-only variable.

Output Plugins are void; they do not return any object. Rather than that, they alter the input httpRequest variable.

Changing and adding Plugins

If you copy or change the Plugin files, the changes (or new plugins) will automatically reflect in the Pigeon configuration.

No restart is required.

However if you change Pigeon.json - it is needed to restart Pigeon.