Chapter 47. Configuring the API Component Maven Plug-In
Abstract
This chapter provides a reference for all of the configuration options available on the API component Maven plug-in.
47.1. Overview of the Plug-In Configuration
Overview
The main purpose of the API component Maven plug-in, camel-api-component-maven-plugin
, is to generate the API mapping classes, which implement the mapping between endpoint URIs and API method invocations. By editing the configuration of the API component Maven plug-in, you can customize various aspects of the API mapping.
Location of the generated code
The API mapping classes generated by the API component Maven plug-in are placed in the following location, by default:
ProjectName-component/target/generated-sources/camel-component
Prerequisites
The main inputs to the API component Maven plug-in are the Java API classes and the Javadoc metadata. These are made available to the plug-in by declaring them as regular Maven dependencies (where the Javadoc Maven dependencies should be declared with provided
scope).
Setting up the plug-in
The recommended way to set up the API component Maven plug-in is to generate starting point code using the API component archetype. This generates the default plug-in configuration in the ProjectName-component/pom.xml
file, which you can then customize for your project. The main aspects of the plug-in set-up are, as follows:
- Maven dependencies must be declared for the requisite Java API and for the Javadoc metadata.
-
The plug-in’s base configuration is declared in the
pluginManagement
scope (which also defines the version of the plug-in to use). - The plug-in instance itself is declared and configured.
-
The
build-helper-maven
plug-in is configured to pick up the generated sources from thetarget/generated-sources/camel-component
directory and include them in the Maven build.
Example base configuration
The following POM file extract shows the base configuration of the API component Maven plug-in, as defined in the Maven pluginManagement
scope when the code has been generated using the API component archetype:
<?xml version="1.0" encoding="UTF-8"?> <project ...> ... <build> ... <pluginManagement> <plugins> <plugin> <groupId>org.apache.camel</groupId> <artifactId>camel-api-component-maven-plugin</artifactId> <version>2.21.0.fuse-000077-redhat-1</version> <configuration> <scheme>${schemeName}</scheme> <componentName>${componentName}</componentName> <componentPackage>${componentPackage}</componentPackage> <outPackage>${outPackage}</outPackage> </configuration> </plugin> </plugins> </pluginManagement> ... </build> ... </project
The configuration specified in the pluginManagement
scope provides default settings for the plug-in. It does not actually create an instance of a plug-in, but its default settings will be used by any API component plug-in instance.
Base configuration
In addition to specifying the plug-in version (in the version
element), the preceding base configuration specifies the following configuration properties:
scheme
- The URI scheme for this API component.
componentName
- The name of this API component (which is also used as a prefix for generated class names).
componentPackage
-
Specifies the Java package containing the classes generated by the API component Maven archetype. This package is also exported by the default
maven-bundle-plugin
configuration. Hence, if you want a class to be publicly visible, you should place it in this Java package. outPackage
-
Specifies the Java package where the generated API mapping classes are placed (when they are generated by the API component Maven plug-in). By default, this has the value of the
componentName
property, with the addition of the.internal
suffix. This package is declared as private by the defaultmaven-bundle-plugin
configuration. Hence, if you want a class to be private, you should place it in this Java package.
Example instance configuration
The following POM file extract shows a sample instance of the API component Maven plug-in, which is configured to generate an API mapping during the Maven build:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ... <build> <defaultGoal>install</defaultGoal> <plugins> ... <!-- generate Component source and test source --> <plugin> <groupId>org.apache.camel</groupId> <artifactId>camel-api-component-maven-plugin</artifactId> <executions> <execution> <id>generate-test-component-classes</id> <goals> <goal>fromApis</goal> </goals> <configuration> <apis> <api> <apiName>hello-file</apiName> <proxyClass>org.jboss.fuse.example.api.ExampleFileHello</proxyClass> <fromSignatureFile>signatures/file-sig-api.txt</fromSignatureFile> </api> <api> <apiName>hello-javadoc</apiName> <proxyClass>org.jboss.fuse.example.api.ExampleJavadocHello</proxyClass> <fromJavadoc/> </api> </apis> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
Basic mapping configuration
The plug-in is configured by the configuration
element, which contains a single apis
child element to configure the classes of the Java API. Each API class is configured by an api
element, as follows:
apiName
The API name is a short name for the API class and is used as the
endpoint-prefix
part of an endpoint URI.NoteIf the API consists of just a single Java class, you can leave the
apiName
element empty, so that theendpoint-prefix
becomes redundant, and you can then specify the endpoint URI using the format shown in the section called “URI format for a single API class”.proxyClass
- This element specifies the fully-qualified name of the API class.
fromJavadoc
-
If the API class is accompanied by Javadoc metadata, you must indicate this by including the
fromJavadoc
element and the Javadoc itself must also be specified in the Maven file, as aprovided
dependency. fromSignatureFile
If the API class is accompanied by signature file metadata, you must indicate this by including the
fromSignatureFile
element, where the content of this element specifies the location of the signature file.NoteThe signature files do not get included in the final package built by Maven, because these files are needed only at build time, not at run time.
Customizing the API mapping
The following aspects of the API mapping can be customized by configuring the plug-in:
-
Method aliases — you can define additional names (aliases) for an API method using the
aliases
configuration element. For details, see Section 47.3, “Method Aliases”. -
Nullable options — you can use the
nullableOptions
configuration element to declare method arguments that default tonull
. For details, see Section 47.4, “Nullable Options”. -
Argument name substitution — due to the way the API mapping is implemented, the arguments from all of the methods in a particular API class belong to the same namespace. If two arguments with the same name are declared to be of different type, this leads to a clash. To avoid such name clashes, you can use the
substitutions
configuration element to rename method arguments (as they would appear in a URI). For details, see Section 47.5, “Argument Name Substitution”. -
Excluding arguments — when it comes to mapping Java arguments to URI options, you might sometimes want to exclude certain arguments from the mapping. You can filter out unwanted arguments by specifying either the
excludeConfigNames
element or theexcludeConfigTypes
element. For details, see Section 47.6, “Excluded Arguments”. -
Extra options — sometimes you might want to define extra options, which are not part of the Java API. You can do this using the
extraOptions
configuration element.
Configuring Javadoc metadata
It is possible to filter the Javadoc metadata to ignore or explicitly include certain content. For details of how to do this, see Section 47.2, “Javadoc Options”.
Configuring signature file metadata
In cases where no Javadoc is available, you can resort to signature files to supply the needed mapping metadata. The fromSignatureFile
is used to specify the location of the corresponding signature file. It has no special options.
47.2. Javadoc Options
Overview
If the metadata for your Java API is provided by Javadoc, it is generally sufficient to specify the fromJavadoc
element with no options. But in cases where you do not want to include the entire Java API in your API mapping, you can filter the Javadoc metadata to customize the content. In other words, because the API component Maven plug-in generates the API mapping by iterating over the Javadoc metadata, it is possible to customize the scope of the generated API mapping by filtering out unwanted parts of the Javadoc metadata.
Syntax
The fromJavadoc
element can be configured with optional child elements, as follows:
<fromJavadoc> <excludePackages>PackageNamePattern</excludePackages> <excludeClasses>ClassNamePattern</excludeClasses> <excludeMethods>MethodNamePattern</excludeMethods> <includeMethods>MethodNamePattern</includeMethods> <includeStaticMethods>[true|false]<includeStaticMethods> </fromJavadoc>
Scope
As shown in the following extract, the fromJavadoc
element can optionally appear as a child of the apis
element and/or as a child of api
elements:
<configuration> <apis> <api> <apiName>...</apiName> ... <fromJavadoc>...</fromJavadoc> </api> <fromJavadoc>...</fromJavadoc> ... </apis> </configuration>
You can define the fromJavadoc
element at the following scopes:
-
As a child of an
api
element — thefromJavadoc
options apply only to the API class specified by theapi
element. -
As a child of the
apis
element — thefromJavadoc
options apply to all API classes by default, but can be overridden at theapi
level.
Options
The following options can be defined as child elements of fromJavadoc
:
excludePackages
-
Specifies a regular expression (
java.util.regex
syntax) for excluding Java packages from the API mapping model. All package names that match the regular expression are excluded; and all classes derived from the excluded classes are also ignored. Default value isjavax?\.lang.\*
. excludeClasses
-
Specifies a regular expression (
java.util.regex
syntax) for excluding API base classes from the API mapping. All class names that match the regular expression are excluded; and all classes derived from the excluded classes are also ignored. excludeMethods
-
Specifies a regular expression (
java.util.regex
syntax) for excluding methods from the API mapping model. includeMethods
-
Specifies a regular expression (
java.util.regex
syntax) for including methods from the API mapping model. includeStaticMethods
-
If
true
, static methods will also be included in the API mapping model. Default isfalse
.
47.3. Method Aliases
Overview
Often it can be useful to define additional names (aliases) for a given method, in addition to the standard method name that appears in the Java API. A particularly common case is where you allow a property name (such as widget
) to be used as an alias for an accessor method (such as getWidget
or setWidget
).
Syntax
The aliases
element can be defined with one or more alias
child elements, as follows:
<aliases> <alias> <methodPattern>MethodPattern</methodPattern> <methodAlias>Alias</methodAlias> </alias> ... </aliases>
Where MethodPattern
is a regular expression (java.util.regex
syntax) for matching method names from the Java API, and the pattern typically includes capturing groups. The Alias
is the replacement expression (for use in a URI), which can use the text from the preceding capturing groups (for example, specified as $1
, $2
, or $3
for the text from the first, second, or third capturing group).
Scope
As shown in the following extract, the aliases
element can optionally appear as a child of the apis
element and/or as a child of api
elements:
<configuration> <apis> <api> <apiName>...</apiName> ... <aliases>...</aliases> </api> <aliases>...</aliases> ... </apis> </configuration>
You can define the aliases
element at the following scopes:
-
As a child of an
api
element — thealiases
mappings apply only to the API class specified by theapi
element. -
As a child of the
apis
element — thealiases
mappings apply to all API classes by default, but can be overridden at theapi
level.
Example
The following example shows how to generate aliases for the common get/set bean method pattern:
<aliases> <alias> <methodPattern>[gs]et(.+)</methodPattern> <methodAlias>$1</methodAlias> </alias> </aliases>
With the preceding alias definition, you could use widget
as an alias for either of the methods getWidget
or setWidget
. Note the use of a capturing group, (.+)
, to capture the latter part of the method name (for example, Widget
).
47.4. Nullable Options
Overview
In some cases, it can make sense to let method arguments default to null
. But this is not allowed by default. If you want to allow some of your method arguments from the Java API to take null
values, you must declare this explicitly using the nullableOptions
element.
Syntax
The nullableOptions
element can be defined with one or more nullableOption
child elements, as follows:
<nullableOptions>
<nullableOption>ArgumentName</nullableOption>
...
</nullableOptions>
Where ArgumentName
is the name of a method argument from the Java API.
Scope
As shown in the following extract, the nullableOptions
element can optionally appear as a child of the apis
element and/or as a child of api
elements:
<configuration> <apis> <api> <apiName>...</apiName> ... <nullableOptions>...</nullableOptions> </api> ... <nullableOptions>...</nullableOptions> </apis> </configuration>
You can define the nullableOptions
element at the following scopes:
-
As a child of an
api
element — thenullableOptions
mappings apply only to the API class specified by theapi
element. -
As a child of the
apis
element — thenullableOptions
mappings apply to all API classes by default, but can be overridden at theapi
level.
Example
The following example shows the nullable options declared for the CompaniesResource
proxy class from the Apache Camel LinkedIn component:
<nullableOptions> <nullableOption>companySizes</nullableOption> <nullableOption>count</nullableOption> <nullableOption>email_domain</nullableOption> <nullableOption>end_timestamp</nullableOption> <nullableOption>event_type</nullableOption> <nullableOption>geos</nullableOption> <nullableOption>industries</nullableOption> <nullableOption>is_company_admin</nullableOption> <nullableOption>jobFunc</nullableOption> <nullableOption>secure_urls</nullableOption> <nullableOption>seniorities</nullableOption> <nullableOption>start</nullableOption> <nullableOption>start_timestamp</nullableOption> <nullableOption>statistics_update_key</nullableOption> <nullableOption>time_granularity</nullableOption> </nullableOptions>
47.5. Argument Name Substitution
Overview
The API component framework requires that URI option names are unique within each proxy class (Java API class). This is not always the case for method argument names, however. For example, consider the following Java methods in an API class:
public void doSomething(int id, String name); public void doSomethingElse(int id, String name);
When you build your Maven project, the camel-api-component-maven-plugin
generates the configuration class, ProxyClassEndpointConfiguration
, which contains getter and setter methods for all of the arguments in the ProxyClass
class. For example, given the preceding methods, the plug-in would generate the following getter and setter methods in the configuration class:
public int getId(); public void setId(int id); public String getName(); public void setName(String name);
But what happens, if the id
argument appears multiple times as different types, as in the following example:
public void doSomething(int id, String name); public void doSomethingElse(int id, String name); public String lookupByID(String id);
In this case, the code generation would fail, because you cannot define a getId
method that returns int
and a getId
method that returns String
in the same scope. The solution to this problem is to use argument name substitution to customize the mapping of argument names to URI option names.
Syntax
The substitutions
element can be defined with one or more substitution
child elements, as follows:
<substitutions> <substitution> <method>MethodPattern</method> <argName>ArgumentNamePattern</argName> <argType>TypeNamePattern</argType> <replacement>SubstituteArgName</replacement> <replaceWithType>[true|false]</replaceWithType> </substitution> ... </substitutions>
Where the argType
element and the replaceWithType
element are optional and can be omitted.
Scope
As shown in the following extract, the substitutions
element can optionally appear as a child of the apis
element and/or as a child of api
elements:
<configuration> <apis> <api> <apiName>...</apiName> ... <substitutions>...</substitutions> </api> <substitutions>...</substitutions> ... </apis> </configuration>
You can define the substitutions
element at the following scopes:
-
As a child of an
api
element — thesubstitutions
apply only to the API class specified by theapi
element. -
As a child of the
apis
element — thesubstitutions
apply to all API classes by default, but can be overridden at theapi
level.
Child elements
Each substitution
element can be defined with the following child elements:
method
-
Specifies a regular expression (
java.util.regex
syntax) to match a method name from the Java API. argName
-
Specifies a regular expression (
java.util.regex
syntax) to match an argument name from the matched method, where the pattern typically includes capturing groups. argType
-
(Optional) Specifies a regular expression (
java.util.regex
syntax) to match the type of the argument. If you set thereplaceWithType
option totrue
, you would typically use capturing groups in this regular expression. replacement
-
Given a particular match of the
method
pattern,argName
pattern, and (optionally)argType
pattern, thereplacement
element defines the substitute argument name (for use in a URI). The replacement text can be constructed using strings captured from theargName
regular expression pattern (using the syntax,$1
,$2
,$3
to insert the first, second, or third capturing group, respectively). Alternatively, the replacement text can be constructed using strings captured from theargType
regular expression pattern, if you set thereplaceWithType
option totrue
. replaceWithType
-
When
true
, specifies that the replacement text is constructed using strings captured from theargType
regular expression. Defaults tofalse
.
Example
The following substitution example modifies every argument of java.lang.String
type, by adding the suffix, Param
to the argument name:
<substitutions> <substitution> <method>^.+$</method> <argName>^.+$</argName> <argType>java.lang.String</argType> <replacement>$1Param</replacement> <replaceWithType>false</replaceWithType> </substitution> </substitutions>
For example, given the following method signature:
public String greetUs(String name1, String name2);
The arguments of this method would be specified through the options, name1Param
and name2Param
, in the endpoint URI.
47.6. Excluded Arguments
Overview
Sometimes, you might need to exclude certain arguments, when it comes to mapping Java arguments to URI options. You can filter out unwanted arguments by specifying either the excludeConfigNames
element or the excludeConfigTypes
element in the camel-api-component-maven-plugin
plug-in configuration.
Syntax
The excludeConfigNames
element and the excludeConfigTypes
element are specified as follows:
<excludeConfigNames>ArgumentNamePattern</excludeConfigNames> <excludeConfigTypes>TypeNamePattern</excludeConfigTypes>
Where ArgumentNamePattern
and TypeNamePattern
are regular expressions that match the argument name and the argument type, respectively.
Scope
As shown in the following extract, the excludeConfigNames
element and the excludeConfigTypes
element can optionally appear as children of the apis
element and/or as children of api
elements:
<configuration> <apis> <api> <apiName>...</apiName> ... <excludeConfigNames>...</excludeConfigNames> <excludeConfigTypes>...</excludeConfigTypes> </api> <excludeConfigNames>...</excludeConfigNames> <excludeConfigTypes>...</excludeConfigTypes> ... </apis> </configuration>
You can define the excludeConfigNames
element and the excludeConfigTypes
element at the following scopes:
-
As a child of an
api
element — the exclusions apply only to the API class specified by theapi
element. -
As a child of the
apis
element — the exclusions apply to all API classes by default, but can be overridden at theapi
level.
Elements
The following elements can be used to exclude arguments from the API mapping (so that they are unavailable as URI options):
excludeConfigNames
-
Specifies a regular expression (
java.util.regex
syntax) for excluding arguments, based on matching the argument name. excludeConfigTypes
-
Specifies a regular expression (
java.util.regex
syntax) for excluding arguments, based on matching the argument type.
47.7. Extra Options
Overview
The extraOptions
options are usually used to either compute or hide complex API parameters by providing simpler options instead. For example, the API method might take a POJO option, that could be provided more easily as parts of the POJO in the URI. The component could do this by adding the parts as extra options, and creating the POJO parameter internally. To complete the implementation of these extra options, you also need to override the interceptProperties
method in the EndpointConsumer
and/or EndpointProducer
classes (see Section 46.4, “Programming Model”).
Syntax
The extraOptions
element can be defined with one or more extraOption
child elements, as follows:
<extraOptions> <extraOption> <type>TypeName</type> <name>OptionName</name> </extraOption> </extraOptions>
Where TypeName
is the fully-qualified type name of the extra option and OptionName
is the name of the extra URI option.
Scope
As shown in the following extract, the extraOptions
element can optionally appear as a child of the apis
element and/or as a child of api
elements:
<configuration> <apis> <api> <apiName>...</apiName> ... <extraOptions>...</extraOptions> </api> <extraOptions>...</extraOptions> ... </apis> </configuration>
You can define the extraOptions
element at the following scopes:
-
As a child of an
api
element — theextraOptions
apply only to the API class specified by theapi
element. -
As a child of the
apis
element — theextraOptions
apply to all API classes by default, but can be overridden at theapi
level.
Child elements
Each extraOptions
element can be defined with the following child elements:
type
- Specifies the fully-qualified type name of the extra option.
name
- Specifies the option name, as it would appear in an endpoint URI.
Example
The following example defines an extra URI option, customOption
, which is of java.util.list<String>
type:
<extraOptions> <extraOption> <type>java.util.List<String></type> <name>customOption</name> </extraOption> </extraOptions>