This document describes how to develop and deploy plugins that integrate with the Oracle REST Data Services (ORDS) runtime.
For a more a more detailed reference, consult the developer guide.
Below are some examples that give a flavour of the programming model.
The Hello World example below demonstrates the basics of creating a request handler plugin:
@Dispatches(@PathTemplate("/hello")) @Provides public class HelloWorld extends HttpServlet { public doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain"); response.getWriter().println("Hello World"); } }
A plugin can express it’s dependencies on external APIs using the @Inject annotation on its constructor.
@Dispatches(@PathTemplate("/uses-logging")) @Provides public class UsesLogging extends HttpServlet { @Inject public UsesLogging(Logger log) { this.log = log; } public doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { log.fine("received request:\n" + request.toString()); response.setContentType("text/plain"); response.getWriter().println("Hello World"); log.fine("processed request"); } private final Logger log; }
All of the files referenced in this tutorial are included in the product distribution under the examples/plugins folder:
${ORDS_HOME} |-- examples |-- plugins |-- lib |-- plugin-demo |-- src
where ${ORDS_HOME} is the location where the product distribution was unzipped.
Consult the instructions in the Oracle REST Services Documentation to install and configure ORDS.
To make a database schema accessible to ORDS, it must be explicitly enabled. To demonstrate this we will create a new schema and enable it:
$ sqlplus /nolog SQL> CONNECT SYS as SYSDBA Enter password: SYS_password SQL> create user TEST_SCHEMA identified by TEST_SCHEMA_password; SQL> grant connect, resource to TEST_SCHEMA; SQL> DISCONNECT SQL> CONNECT TEST_SCHEMA Enter password: TEST_SCHEMA_password SQL> execute ords.enable_schema; SQL> commit;
Note: Replace TEST_SCHEMA_password with your own choice of password.
In this guide we will walk through building and deploying the plugin-demo plugin that queries the database to determine the current database user and echo that information in the response. This example uses Apache ANT to manage the build process.
The plugin-demo source files are located within the ${ORDS_HOME} folder at:
${ORDS_HOME}/examples/plugins/plugin-demo
The folder contains the following:
Located in the parent folder is a lib/ folder which holds the .jar files required to compile plugins.
To compile a plugin the following libraries must be in the classpath:
Each of the required jars is included in the product distribution in the ${ORDS_HOME}/examples/plugins/lib folder.
This library provides the glue code - such as @Dispatches - to weave the plugin into the runtime.
This library provides the annotation processor that makes classes annotated with @Provides discoverable.
This library provides the JSR-330 API types such as @Inject.
This library provides the Java Servlet 3.1.0 API types, such as HttpServlet.
This library is optional and is only required if the plugin needs to access the Oracle JDBC Extension APIs such as OracleConnection.
The source code of the plugin is reproduced below, following that is a point by point explanation of the source code.
package example; import java.io.IOException; import java.sql.*; import jakarta.inject.Inject; import javax.servlet.ServletException; import javax.servlet.http.*; import oracle.dbtools.plugin.api.di.annotations.Provides; import oracle.dbtools.plugin.api.http.annotations.*; import oracle.dbtools.plugin.api.routes.*; /** * This example plugin {@link HttpServlet} demonstrates: * <ul> * <li>Using the injected {@link Connection} to query the database.</li> * <li>Using the injected {@link PathTemplates} service to decode the parameters * of the servlet's {@link PathTemplateMatch}.</li> * </ul> * * <h4>Testing the Servlet</h4> Invoke the servlet with the following URL: * * <pre> * http://<i>server</i>/ords/<i>schema</i>/demos/plugin?who=<i>somebody</i> * </pre> * * where: * <ul> * <li><i>server</i> is the hostname and port of the server.</li> * <li><i>schema</i> is the name of the REST enabled database schema.</li> * <li><i>somebody</i> is any value you wish, e.g. a person's name.</li> * <ul> * For example: * * <pre> * http://localhost:8080/ords/test_schema/demos/plugin?who=Scott * </pre> * * @author cdivilly * */ @Provides @Dispatches(@PathTemplate("/demos/plugin")) class PluginDemo extends HttpServlet { @Inject PluginDemo(Connection conn, PathTemplates pathTemplates) { this.conn = conn; this.pathTemplates = pathTemplates; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PathTemplateMatch match = pathTemplates .matchedTemplate(request); try { /* retrieve 'who' query parameter */ String who = match.parameters().get("who"); who = null == who ? "anonymous" : who; /* execute database query */ PreparedStatement ps = conn .prepareStatement("select sys_context('USERENV','CURRENT_USER') from dual"); ResultSet rs = ps.executeQuery(); rs.next(); /* determine the database user */ String user = rs.getString(1); /* Print the greeting */ response.getWriter().println(user + " says hello to: " + who); rs.close(); ps.close(); } catch (SQLException e) { throw new ServletException(e); } } private final Connection conn; private final PathTemplates pathTemplates; }
The plugin we have built needs a database connection to function. Therefore ORDS must be able to figure out what database and schema to connect to. ORDS does this by examine the Request URL and mapping the URL to the appropriate database pool and database schema.
If ORDS cannot determine a mapping, then it will report a 404 Not Found status for the request URL.
To map a database schema to a URL, you must enable the schema to be accessed by ORDS, as we did in the section titled ‘Enable Database Schema’.
With ORDS running in standalone mode on localhost, try the following URL:
http://localhost:8080/ords/test_schema/demos/plugin?who=Scott
The browser should display the following text:
TEST_SCHEMA says hello to: Scott