Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "Tutorial: JaxRS Remote Services on Karaf"
(→Install Jersey Distribution Provider via Karaf Console) |
|||
Line 32: | Line 32: | ||
'''NOTE: These and other parts of the dynamically-constructed remote service URL can be set via system properties OR service-instance-specific service properties. For the [[https://github.com/ECF/JaxRSProviders JaxRSProviders] the system or service properties are described [https://github.com/ECF/JaxRSProviders/wiki/JaxRS-Distribution-Provider-Configuration-Properties here].''' | '''NOTE: These and other parts of the dynamically-constructed remote service URL can be set via system properties OR service-instance-specific service properties. For the [[https://github.com/ECF/JaxRSProviders JaxRSProviders] the system or service properties are described [https://github.com/ECF/JaxRSProviders/wiki/JaxRS-Distribution-Provider-Configuration-Properties here].''' | ||
− | Shutdown and restart Karaf so that the org.osgi.service.http.port system property set can take effect on startup. | + | '''Shutdown and restart Karaf so that the org.osgi.service.http.port system property set can take effect on startup'''. |
===JaxRS Student Example=== | ===JaxRS Student Example=== | ||
Line 111: | Line 111: | ||
http://localhost:8181/rservices/studentservice/students | http://localhost:8181/rservices/studentservice/students | ||
− | This is because the ecf.endpoint.id=http://localhost:8181/rservices, the StudentService path is set to '''studentservice''' (via JaxRS annotation of StudentService), and the StudentService.getStudents() method path is set to 'students' (again via JaxRS annotation). | + | This is because the ecf.endpoint.id=http://localhost:8181/rservices, the [https://github.com/ECF/JaxRSProviders/blob/master/examples/com.mycorp.examples.student/src/com/mycorp/examples/student/StudentService.java StudentService] path is set to '''studentservice''' (via [https://github.com/ECF/JaxRSProviders/blob/master/examples/com.mycorp.examples.student/src/com/mycorp/examples/student/StudentService.java#L24 JaxRS Path annotation of StudentService]), and the StudentService.getStudents() method path is set to 'students' (again via [https://github.com/ECF/JaxRSProviders/blob/master/examples/com.mycorp.examples.student/src/com/mycorp/examples/student/StudentService.java#L29 JaxRS Path method annotation]). |
For example: | For example: |
Revision as of 14:13, 30 July 2019
Contents
Introduction
Jersey and CXF can be run on Karaf as an ECF distribution provider for JaxRS-defined remote services.
This tutorial describes installing and running an example JaxRS remote service on Karaf. Developers can create and deploy arbitrary remote services by reusing the ECF RSA impl and the Jersey or CXF distribution provider.
Requirements: Karaf 4.2.1+ running on Java 8+
Install Jersey Distribution Provider via Karaf Console
Add the ECF Remote Services features repo:
karaf@root()>feature:repo-add ecf
Install the Jersey Distribution Provider and dependencies
karaf@root()>feature:install ecf-rs-distribution-jersey
To properly run in Karaf the org.osgi.service.http.port system property must be set to the desired port:
karaf@root()> system:property -p org.osgi.service.http.port 8181
and since Karaf typically uses the root path (/) of the HttpService, it's necessary to set an explicit pathPrefix to something other than the default of '/'
karaf@root()> system:property -p ecf.jaxrs.jersey.server.pathPrefix /rservices
NOTE: These and other parts of the dynamically-constructed remote service URL can be set via system properties OR service-instance-specific service properties. For the [JaxRSProviders the system or service properties are described here.
Shutdown and restart Karaf so that the org.osgi.service.http.port system property set can take effect on startup.
JaxRS Student Example
In this tutorial an example REST service is presented. The completed example bundles with source are available in the ECF JaxRSProviders repository. To run this example you may wish to clone this repo, and import into Eclipse these three projects: examples/com.mycorp.examples.student, examples/com.mycorp.examples.remoteservice.host, and examples/com.mycorp.examples.client.
Install JaxRS Student Example Service Client and Host
karaf@root()> feature:install ecf-rs-examples-jaxrs-student-client karaf@root()> feature:install ecf-rs-examples-jaxrs-student-host
This should produce output indicating the StudentService was exported
karaf@root()> feature:install ecf-rs-examples-jaxrs-student-host 16:17:04.904;EXPORT_REGISTRATION;exportedSR=[com.mycorp.examples.student.Student Service];cID=URIID [uri=http://localhost:8181/1];rsId=1 --Endpoint Description--- <endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0"> <endpoint-description> <property name="ecf.endpoint.id" value-type="String" value="http://localhost:8181/rservices"/> <property name="ecf.endpoint.id.ns" value-type="String" value="ecf.namespace.jaxrs"/> <property name="ecf.endpoint.ts" value-type="Long" value="1530573424662"/> <property name="ecf.rsvc.id" value-type="Long" value="1"/> <property name="endpoint.framework.uuid" value-type="String" value="7473f8a1-f0ac-4146-8087-0558ed8e46aa"/> <property name="endpoint.id" value-type="String" value="c9e3bb65-f157-40fe-b4bb-6c98c926ca03"/> <property name="endpoint.package.version.com.mycorp.examples.student" value-type="String" value="1.0.0"/> <property name="endpoint.service.id" value-type="Long" value="162"/> <property name="objectClass" value-type="String"> <array> <value>com.mycorp.examples.student.StudentService</value> </array> </property> <property name="osgi.basic.timeout" value-type="String" value="50000"/> <property name="remote.configs.supported" value-type="String"> <array> <value>ecf.jaxrs.cxf.server</value> </array> </property> <property name="remote.intents.supported" value-type="String"> <array> <value>passByValue</value> <value>exactlyOnce</value> <value>ordered</value> <value>osgi.async</value> <value>osgi.private</value> <value>osgi.confidential</value> <value>jaxrs</value> </array> </property> <property name="service.imported" value-type="String" value="true"/> <property name="service.imported.configs" value-type="String"> <array> <value>ecf.jaxrs.cxf.server</value> </array> </property> <property name="service.intents" value-type="String" value="osgi.async"/> </endpoint-description> </endpoint-descriptions> ---End Endpoint Description Discovered student service=com.mycorp.examples.student.remoteservice.host.StudentServiceImpl@51154196 Student0=Student [id=06f375e2-859d-4077-9bf4-edf8a1128439, name=Joe Senior, grade=First, address=Address [street=111 Park Ave, city=New York, state=NY, postalCode=11111]] Updated Student0=Student [id=06f375e2-859d-4077-9bf4-edf8a1128439, name=Joe Senior, grade=Eighth, address=Address [street=111 Park Ave, city=New York, state=NY, postalCode=11111]] Student=0=Student [id=06f375e2-859d-4077-9bf4-edf8a1128439, name=Joe Senior, grade=Eighth, address=Address [street=111 Park Ave, city=New York, state=NY, postalCode=11111]] Created student=Student [id=ba408587-9546-45f2-b311-9b2d65c5761c, name=April Snow, grade=null, address=null] Updated student=Student [id=ba408587-9546-45f2-b311-9b2d65c5761c, name=April Snow, grade=First, address=Address [street=111 NE 1st, city=Austin, state=Oregon, postalCode=97200]] Deleted student=Student [id=ba408587-9546-45f2-b311-9b2d65c5761c, name=April Snow, grade=First, address=Address [street=111 NE 1st, city=Austin, state=Oregon, postalCode=97200]]
The output in between the --Start Endpoint Description-- and ---End Endpoint Description--- is debug output from the ECF RSA Console for the remote service export.
The output that begins Discovered student service... is output from the StudentService consumer when the remote service is discovered and injected into the client component so that it can be called. This output shows the invocation of the JaxRS remote service methods by the client component.
Note that once exported via a Jax-RS supporting provider (currently Jersey and CXF), the getStudents() service method can be accessed directly via an http get call via the following url:
http://localhost:8181/rservices/studentservice/students
This is because the ecf.endpoint.id=http://localhost:8181/rservices, the StudentService path is set to studentservice (via JaxRS Path annotation of StudentService), and the StudentService.getStudents() method path is set to 'students' (again via JaxRS Path method annotation).
For example:
$ curl http://localhost:8181/rservices/studentservice/students {"students":[{"id":"24e7dfdb-b9e1-4540-a450-b0c19bf43ec9","name":"Joe Senior","grade":"Eighth","address":{"street":"111 Park Ave","city":"New York","state":"NY","postalCode":"11111"}}]}
Note: It's also possible to run the test client on another system, e.g. from within Eclipse workspace using the StudentClient.jersey.product configuration located here in the com.mycorp.examples.student.client example project.
The client/remote service consumer source code is here.
Using CXF impl of JaxRS Rather than Jersey
To use CXF rather than Jersey, all that's necessary is to install the CXF server and client distribution providers rather than Jersey providers.
Add the ECF Remote Services features repo:
karaf@root()>feature:repo-add ecf
Install the CXF Distribution Provider
karaf@root()>feature:install ecf-rs-distribution-cxf
Set the org.osgi.service.http.port system property to the desired server port (8181):
karaf@root()> system:property -p org.osgi.service.http.port 8181
Shutdown and restart Karaf so that the org.osgi.service.http.port system property set can take effect on startup.
Once the CXF provider is installed, the StudentService example may be installed and run in the same way as shown above, but now the CXF implementation will be used as the distribution system for exporting and importing the StudentService.
Note: Similar to the Jersey example above, there is a StudentExample.cxf.product configuration file that allows one to run the example client from an Eclipse workspace.
Creating a Custom Distribution Provider By Configuring and/or Extending Jersey or CXF
It's possible to reuse the existing ECF JaxRSProvider code to create your own new Remote Service Distribution provider, with custom security, serialization, filters, or interceptors. Here are the existing/default Jersey and CXF providers:
org.eclipse.ecf.provider.jersey.server
org.eclipse.ecf.provider.jersey.client
and
org.eclipse.ecf.provider.cxf.server
org.eclipse.ecf.providerjersey.client
There is now an example of extending the Jersey distribution provider in this example proect.
The general process is:
1) Create and register as an OSGi service (usually upon bundle start) an impl of IRemoteServiceDistributionProvider. The distribution provider provides a unique name/config type. For example,here is the distribution provider with new unique config name of 'ecf.jaxrs.jersey.server.ext'.
2) Override methods implemented in JaxRSServerContainer to configure your distribution provider at runtime. For example, the the ExtJerseyServerContainer overrides the JaxRSServerContainer.getServletAlias method, which is responsible for getting the servlet alias for the remote service...e.g. /rservices (value of pathPrefix property) in JaxRSServerContainer.getServletAlias. You may extend any JaxRSServerContainer or JerseyServerContainer methods to configure your remote service distribution provider in terms of filtering requests, serialization, invocation or any of the JaxRS-standard or Jersey-specific extensions. See the protected and public methods in JaxRSServerContainer for details.
Remote Service Implementation Details
See the Exposing a Jax REST service as a Remote Service tutorial.