This article provides a step-by-step guide to setting up an Oracle REST Data Services (ORDS) plugin using Maven. It covers the installation of two ORDS jars into the local Maven repository, the creation of the project structure, the configuration of the plugin, and the building and deployment of the plugin. This guide will help developers get started quickly with ORDS plugin development where Maven is already used in their software development infrastructure.
- Introduction
- Step 1: Install ORDS Jars Into the Local Maven Repository
- Step 2: Set Up the Project Structure
- Step 3: Create Configuration Files and Source
- Step 4: Build and Deploy the Plugin
- Step 5: Verify the Plugin
- Conclusion
Introduction
ORDS provides a plugin framework which makes it possible to extend the functionality and introduce custom behaviour. Creating a plugin can be a daunting task, especially if you’re not familiar with ORDS or the underlying technologies. Fortunately, there are some great examples out there to get you started, including the ORDS YAML plugin example. However, the plugin example projects are Ant-based, so if you’re looking to use Maven for your plugin project, you’ll need to take a few extra steps.
These steps have Maven as a prerequisite and it is assumed your familiarity with Maven is the reason you’re here, reading this article. If you need more information on Maven then start with What is Maven?
Step 1: Install ORDS Jars Into the Local Maven Repository
An ORDS plugin has a dependency on two jars that are distributed with ORDS. The ords-plugin-api jar provides all the interfaces, annotations and base classes described in the ORDS Java API which are the building blocks for your plugin implementation. The ords-plugin-apt jar provides the annotation processing support required when building your plugin. These two jar files can be found in the examples/plugins/lib/
directory of ORDS distribution.
First, you’ll need to install the two ORDS jars into your local Maven repository. To install the jars, you’ll need to use the command line. Navigate to the directory where the ORDS was extracted to, and then run the following two commands:
> mvn install:install-file \ -DgroupId=oracle.dbtools.ords \ -DartifactId=ords-plugin-api \ -Dversion=22.4.4 \ -Dpackaging=jar \ -Dfile=examples/plugins/lib/ords-plugin-api-22.4.4.041.1526.jar \ -DgeneratePom=true > mvn install:install-file \ -DgroupId=oracle.dbtools.ords \ -DartifactId=ords-plugin-apt \ -Dversion=22.4.4 \ -Dpackaging=jar \ -Dfile=examples/plugins/lib/ords-plugin-apt-22.4.4.041.1526.jar \ -DgeneratePom=true
That will put two artefacts in your local maven repository both as version 22.4.4. That is the version of ORDS that this article refers to but you can change the version number to be reflect the version of ORDS you are using.
Step 2: Set Up the Project Structure
This guide is based on the ORDS YAML plugin example and will use the source PluginYaml.java from that article. The plugin can modify the application/json
response which would normally be returned by ORDS and that response in text/yaml
format instead.
For simplicity we’ll use maven-archetype-quickstart as outlined in Maven in 5 Minutes to create the project structure. The focus here is on creating an example, so that term makes sense as the group identifier. You should use your existing Maven artefact nomenclature for identifiers. In the directory where you typically have your Maven projects run the following command:
> mvn archetype:generate \ -DgroupId=example \ -DartifactId=ords-yaml-plugin \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DarchetypeVersion=1.4 \ -DinteractiveMode=false [INFO] Scanning for projects... [INFO] [INFO] ---------< org.apache.maven:standalone-pom >---------- [INFO] Building Maven Stub Project (No POM) 1 [INFO] -----------------------[ pom ]------------------------ [INFO] ... [INFO] ------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------ [INFO] Total time: 4.779 s [INFO] Finished at: 2023-03-27T23:18:25+01:00 [INFO] ------------------------------------------------------
You should now have an ords-yaml-plugin
directory which looks like this:
ords-yaml-plugin |-- pom.xml `-- src |-- main | `-- java | `-- example | `-- App.java `-- test `-- java `-- example `-- AppTest.java
The generated App.java
and AppTest.java
files can be removed or ignored. They serve no purpose but to provide placeholders in the source directory. Change directory into ords-yaml-plugin
and verify the project builds.
> cd ords-yaml-plugin > mvn clean package [INFO] Scanning for projects... [INFO] [INFO] -------------< example:ords-yaml-plugin >------------- [INFO] Building ords-yaml-plugin 1.0-SNAPSHOT [INFO] -----------------------[ jar ]------------------------ ... [INFO] ------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------ [INFO] Total time: 2.755 s [INFO] Finished at: 2023-03-27T23:39:42+01:00 [INFO] ------------------------------------------------------
Once that completes you should see target/ords-yaml-plugin-1.0-SNAPSHOT.jar
file has been produced. Let’s make it interesting by adding the PluginYaml.java
to the project.
Step 3: Create Configuration Files and Source
To compile the ORDS plugin there are classpath dependencies that must be met. Modify the ords-yaml-plug project pom.xml and put these dependencies just after the <dependencies> element at line #21.
<dependency>
<groupId>oracle.dbtools.ords</groupId>
<artifactId>ords-plugin-api</artifactId>
<version>22.4.4</version>
</dependency>
<dependency>
<groupId>oracle.dbtools.ords</groupId>
<artifactId>ords-plugin-apt</artifactId>
<version>22.4.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.14.2</version>
</dependency>
Most of those dependencies will be satisfied by the artefacts already available in the central Maven repository and you have addressed the remaining two dependencies by putting the ORDS plugin api and apt jars in your local repository earlier.
Download the source for the plugin class into the source package directory created when the Maven project was created.
> curl --output src/main/java/example/PluginYaml.java \ https://raw.githubusercontent.com/pobalopalous/pobalopalous/main/example/PluginYaml.java
That PluginYaml.java
example was written for an earlier version of ORDS which used the javax.inject
library. ORDS 22.4.4 uses the jakarta.inject
library. So edit the java source and replace the import statement at line #15
import javax.inject.Inject;
with
import jakarta.inject.Inject;
With that minor change in place you are now ready for the next step: build and deploy the plugin.
Step 4: Build and Deploy the Plugin
It’s as simple as running this on the command line:
> mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< example:ords-yaml-plugin >----------------------
[INFO] Building ords-yaml-plugin 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ ords-yaml-plugin ---
[INFO] Deleting /development/github/ords-yaml-plugin/target
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ ords-yaml-plugin ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /development/github/ords-yaml-plugin/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ ords-yaml-plugin ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /development/github/ords-yaml-plugin/target/classes
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ ords-yaml-plugin ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /development/github/ords-yaml-plugin/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ ords-yaml-plugin ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /development/github/ords-yaml-plugin/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ ords-yaml-plugin ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running example.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.041 s - in example.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ ords-yaml-plugin ---
[INFO] Building jar: /development/github/ords-yaml-plugin/target/ords-yaml-plugin-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.580 s
[INFO] Finished at: 2023-03-28T00:34:29+01:00
[INFO] ------------------------------------------------------------------------
Now your target/ords-yaml-plugin-1.0-SNAPSHOT.jar
file really does have the capability of doing something interesting but it must be put in the lib/ext/
directory of your ORDS installation directory first. Many of the runtime dependencies will be met by the jars distributed with ORDS. However, this particular plugin requires certain YAML related jars to also be in the runtime classpath: snakeyaml
and jackson-dataformat-yaml
. These jars will also have to be copied to the lib/ext/
directory.
The jackson-dataformat-yaml
artefact will be in your local Maven repository because it was pulled in for this ords-yaml-plugin project and that can just be copied over. However, for snakeyaml
you may have to download that file.
Let’s assume the directory that ORDS was extracted to can be referred to by the environment variable $ORDS_HOME.
To download the snakeyaml
jar so that it is included in the ORDS runtime classpath run this command:
> curl -o $ORDS_HOME/lib/ext/snakeyaml-1.33.jar \
https://repo1.maven.org/maven2/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar
To copy the jackson-dataformat-yaml
jar so that it is included in the ORDS runtime classpath run this command:
> cp ~/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.14.2/jackson-dataformat-yaml-2.14.2.jar \
$ORDS_HOME/lib/ext/
Unless you want to change the versions of these jars used, you only need to do this once. Every time you build a new ords-yaml-plugin
jar you will have to copy it to the ORDS library extension directory. To copy the jar file you built, run this command while in your ords-yaml-plugin
project directory:
> cp target/ords-yaml-plugin-1.0-SNAPSHOT.jar \
$ORDS_HOME/lib/ext/
Your ORDS directory should look like this:
ords-dist-22.4.4.041.1526 |-- FUTC.txt |-- bin |-- doc |-- examples |-- icons |-- index.html `-- lib |-- ext | `-- README | `-- jackson-dataformat-yaml-2.14.2.jar | `-- ords-yaml-plugin-1.0-SNAPSHOT.jar | `-- snakeyaml-1.33.jar |-- license.txt |-- linux-support |-- ords.war |-- scripts
Now just start ORDS in standalone mode with a configuration directory setup to use your preferred database.
> $ORDS_HOME/bin/ords --config /path/to/config serve
ORDS: Release 22.4 Production on Tue Mar 28 00:14:06 2023
Copyright (c) 2010, 2023, Oracle.
Configuration:
/path/to/config/
2023-03-28T00:14:06.522Z INFO HTTP and HTTP/2 cleartext listening on host: 0.0.0.0 port: 8080
...
2023-03-28T00:14:23.618Z INFO
Mapped local pools from /path/to/config/databases:
/ords/ => default => VALID
2023-03-28T00:14:23.662Z INFO Oracle REST Data Services initialized
Oracle REST Data Services version : 22.4.4.r0411526
Oracle REST Data Services server info: jetty/10.0.12
Oracle REST Data Services java info: Java HotSpot(TM) 64-Bit Server VM 11.0.13+10-LTS-370
ORDS started up without issue so you plugin is effectively deployed and ready to work.
Step 5: Verify the Plugin
It’s time to confirm that the PluginYaml
class does in fact transform the application/json
response to text/yaml
when the client requests that format. Send a request to ORDS that would normally return application/json
but indicate that text/yaml
is preferred. In my database I have the HR schema, and it’s EMPLOYEES table, REST Enabled and accessible at http://localhost:8080/ords/hr/employees/
. The plugin is looking for Accepts
header in the request to see if it should transform the response.
> curl -i -H "Accepts: text/yaml" 'http://localhost:8080/ords/hr/employees/?limit=2'
HTTP/1.1 200 OK
Content-Type: text/yaml
ETag: "PJjqS1hHizmvT8/WpBBub/3wIZ3HcdY6w/hNFD279DyLK4Prvk+q7BlnmHeKEfnQu7Ek7gGqeT86ltVBQcky6Q=="
Transfer-Encoding: chunked
---
items:
- employee_id: 100
first_name: "Steven"
last_name: "King"
email: "SKING"
phone_number: "515.123.4567"
hire_date: "1987-06-17T00:00:00Z"
job_id: "AD_PRES"
salary: 24000
commission_pct: null
manager_id: null
department_id: 90
links:
- rel: "self"
href: "http://localhost:8080/ords/hr/employees/100"
- employee_id: 101
first_name: "Neena"
last_name: "Kochhar"
email: "NKOCHHAR"
phone_number: "515.123.4568"
hire_date: "1989-09-21T00:00:00Z"
job_id: "AD_VP"
salary: 17000
commission_pct: null
manager_id: 100
department_id: 90
links:
- rel: "self"
href: "http://localhost:8080/ords/hr/employees/101"
hasMore: true
limit: 2
offset: 0
count: 2
links:
- rel: "self"
href: "http://localhost:8080/ords/hr/employees/"
- rel: "edit"
href: "http://localhost:8080/ords/hr/employees/"
- rel: "describedby"
href: "http://localhost:8080/ords/hr/metadata-catalog/employees/"
- rel: "first"
href: "http://localhost:8080/ords/hr/employees/?limit=2"
- rel: "next"
href: "http://localhost:8080/ords/hr/employees/?offset=2&limit=2"
Conclusion
By following the steps in this article you have used Maven to compile and package an ORDS plugin. There were a few once of steps to get dependencies addressed but you now have a Maven project structure for developing more extensions to the existing ORDS behaviour.
If you’re looking to build an ORDS plugin, Apache Maven is a great choice because it provides a uniform build system and there is a huge range of Integrated Development Environments and Source Control Systems that work with Maven. Give it a try today and see how it can help you take your development efforts to the next level.