REpresentational State Transfer (REST) is a simple pattern for
producing Web Services. RESTful services use URI pattern matching to match
a particular web resource. Different HTTP verbs, for example
GET
and DELETE
, map to different operations on
that resource. Standard HTTP response codes are used to communicate the
result of an operation, potentially including a response body if the
operation returns a result.
The [1] Java API for RESTful Web Services Specification defines a set of
annotation mappings which allow Plain Old Java Objects (POJOs) to be
directly exposed as RESTful web resources; these resources can also be
grouped together using a JAX-RS Application
. Furthermore the
specification defines a plugable model for extending the behavior of the
application and the features of the JAX-RS container itself. For example
an extension may define specific error responses that should be sent when
particular exceptions occur, or an extension may add support for
serializing responses to a different format. The OSGi JAX-RS Whiteboard
Specification provides a light and convenient way of using these POJOs,
applications and extensions in an OSGi environment through the use of the
[3] Whiteboard Pattern.
The JAX-RS Whiteboard specification supports:
-
Registering Resources - Registering a JAX-RS annotated POJO in the Service Registry makes it available to be bound to an endpoint and to start responding to incoming requests.
-
Registering Applications - Registering a JAX-RS
Application
in the Service Registry makes it available to be bound to an endpoint and to start responding to incoming requests. -
Registering Extensions - The JAX-RS specification defines a variety of plugable extensions. JAX-RS extensions can be registered in the Service Registry to include them in the handling pipeline.
-
Requiring Extensions - Sometimes JAX-RS resources, or even JAX-RS extensions, depend upon the presence of another extension. For example a JAX-RS resource and a JAX-RS exception mapper may both depend on a JSON serializer. JAX-RS Whiteboard services may define preconditions that must be satisfied before they can be bound.
JAX-RS Whiteboard implementations must support at least version 2.1 of the JAX-RS API.
This specification defines the following entities:
-
JAX-RS Whiteboard service - An object registered in the Service Registry providing the necessary Whiteboard service properties defined by this specification. JAX-RS Whiteboard services may be resource, application or extension services
-
JAX-RS Whiteboard implementation - An implementation that provides one or more JAX-RS Whiteboards.
-
JAX-RS Whiteboard - A runtime instance that processes JAX-RS Whiteboard services. Each JAX-RS Whiteboard service may be processed by multiple JAX-RS Whiteboards. Different JAX-RS Whiteboards provided by the same JAX-RS Whiteboard implementation may configured differently, for example using different ports or root contexts.
-
JAX-RS Service Runtime service - A service providing runtime introspection into a JAX-RS Whiteboard instance.
-
JAX-RS Resource Service - A service that provides one or more RESTful resource methods which map to incoming HTTP requests.
-
JAX-RS Application Service - A service that provides a
javax.ws.rs.core.Application
to be hosted by a JAX-RS Whiteboard. -
JAX-RS Extension Service - A service that extends the functionality of a JAX-RS Whiteboard.
-
Static Resources - JAX-RS resources that are included programmatically in a JAX-RS Whiteboard application, rather than being added at runtime by the whiteboard.
The Figure 151.1 shows an OSGi framework running a JAX-RS Whiteboard Implementation bundle. This bundle has been configured to provide two JAX-RS whiteboards, each of which has a corresponding JAX-RS Service Runtime Service. The various JAX-RS Whiteboard services available in the framework are discovered and processed by both whiteboards.
An important principle of the JAX-RS Whiteboard specification is that an OSGi framework may contain many active JAX-RS Whiteboards at any time, even if there is only a single JAX-RS Whiteboard implementation present in the framework. In addition to providing a web endpoint with which to register Whiteboard services, a JAX-RS Whiteboard provides a holder for JAX-RS Applications.
All JAX-RS Whiteboards have a default
application which
is used to register resources that do not target an existing application.
In this respect a JAX-RS whiteboard application shares some similarities
with a Servlet Context in the Http Whiteboard Specification.
Resources registered with a JAX-RS Whiteboard are always
registered as part of an application. The generated name of the default
application is .default
, and it is mapped to the root context
of the JAX-RS Whiteboard.
A JAX-RS Whiteboard implementation must create a JAX-RS Whiteboard instance, however it is expected that most implementations will permit multiple JAX-RS whiteboards to be configured. These instances may differ significantly, or may simply offer the same capabilities on a different port.
For details on the association process between JAX-RS Whiteboard services and a JAX-RS Whiteboard see Common Whiteboard Properties.
The JaxrsServiceRuntime service represents the runtime state information of a JAX-RS Whiteboard instance. This information is provided through Data Transfer Objects (DTOs). The architecture of OSGi DTOs is described in OSGi Core Release 7.
Each JAX-RS Whiteboard implementation registers exactly one
JaxrsServiceRuntime
service per JAX-RS Whiteboard. The
service properties of the JAX-RS Service Runtime Service can be used to
target JAX-RS Whiteboard services at specific JAX-RS whiteboards, as
described by the osgi.jaxrs.whiteboard.target
property in
Common Whiteboard Properties.
The JaxrsServiceRuntime
provides service registration
properties to declare its underlying JAX-RS Whiteboard. These service
properties can include implementation-specific key-value pairs. They
also include the following:
Table 151.1 Service properties for the JaxrsServiceRuntime
service
Service Property Name | Type | Description |
---|---|---|
osgi.jaxrs.endpoint |
String+ |
Endpoint(s) where this JAX-RS Whiteboard is
listening. Registered Whiteboard services are made available
here. Values could be provided as URLs e.g.
|
service.changecount |
Long |
Whenever the DTOs available from the JAX-RS Service Runtime service change, the value of this property will increase. This allows interested parties to be
notified of changes to the DTOs by observing Service Events of
type |
The JAX-RS Service Runtime service provides information about registered Whiteboard services through the RuntimeDTO.
The Runtime DTO provides information about services that have been successfully registered as well as information about the JAX-RS Whiteboard services that were not successfully registered. JAX-RS Whiteboard services that have the required properties set but cannot be processed, are reflected in the failure DTOs. JAX-RS Whiteboard services of interfaces described in this specification that do not have the required properties set are ignored and not reflected in the failure DTOs.
The Runtime DTO can be obtained using the getRuntimeDTO() method. The Runtime DTO returned provides a snapshot of the state of the JAX-RS Runtime, including the JAX-RS Whiteboard resources, extensions and applications that are active in each registered application. The Runtime DTO also includes information about Whiteboard services which could not be activated.
When whiteboard services are registered with the whiteboard they
must be introspected and this information reflected in the DTO(s) for
that service. This introspection will include looking for annotations
such as @GET
and @Path
both at a class and
method level. The values associated with these annotations must then
be appropriately combined, for example when @Path
is
declared on a type and method level, and recorded in the DTO.
There are a variety of reasons that whiteboard services may not be able to be used by the whiteboard. For example, if the whiteboard service cannot be retrieved from the service registry, or if the whiteboard service provides an invalid service property value, such as a malformed filter.
In these cases the failed services are represented in the Runtime DTO under one of the failed DTO properties. Depending upon the failure reason one or more of the properties of the failed DTO may be unavailable. For example if the service cannot be retrieved from the service registry then it cannot be introspected for annotations. A failure DTO will always contain the service id for the failed service and the failure reason. The whiteboard implementation must then fill in other DTO properties on a best effort basis.
Implementations of this specification will often be backed by existing servlet containers, such as the OSGi Http Whiteboard, or a Java EE application server. There may also exist implementations which bridge into a servlet container into which the OSGi Framework has been deployed as a Web Application.
In bridged situations the JAX-RS Whiteboard implementation will have limited facilities for creating new JAX-RS whiteboards, and may also have limited information about its environment.
Information about the surrounding Servlet Container, including ServletContext information and HttpSession data, is available to JAX-RS Whiteboard resources using standard JAX-RS injection behavior.
@GET
@Path("{name}")
public String interrogateSession(@PathParam("name") String name,
@Context HttpServletRequest req) {
HttpSession s = req.getSession();
return String.valueOf(s.getAttribute(name));
}
A JAX-RS Whiteboard implementation needs to ensure that Http
Sessions are not shared amongst different JAX-RS Whiteboards, or amongst
different JAX-RS Whiteboard applications. That is,
HttpServletRequest.getSession()
calls must provide
different sessions for each whiteboard application with which a JAX-RS
whiteboard service is associated.
Even when they are created by the same JAX-RS Whiteboard implementation, each JAX-RS Whiteboard instance is separate, and isolated from other instances. Importantly, JAX-RS Whiteboard services targeted to one JAX-RS Whiteboard application must not be visible in any other Whiteboard or applications to which they are not targeted.
This isolation restriction is critical, as it ensures that different JAX-RS Whiteboard applications can be configured with different, potentially overlapping, incompatible extension features.
JAX-RS Whiteboard services support common service registration properties to associate them with a JAX-RS Whiteboard. These properties apply to whiteboard resources, extensions and applications except where explicitly stated otherwise. Each service property has an associated Component Property Type annotation that can be used to easily apply the property to a Declarative Services Component.
Table 151.2 Common properties
Service Property | Type | Description |
---|---|---|
|
optional |
A user defined name that can be used to identify a
JAX-RS whiteboard service. Names must follow OSGi symbolic name
rules, and also must not start with the prefixes If no name is defined for a
JAX-RS whiteboard service then one is generated for it. This
generated name will start with a If a JAX-RS service is registered with an illegal name then it is not bound and this is reflected in the failure DTOs. If two JAX-RS services are registered with the same name (even if they are advertised as different types) then only the higher ranked service is bound and the lower ranked service(s) are reflected in the failure DTOs. See JAX_RS_NAME. |
|
optional |
An LDAP-style filter to select the JAX-RS
Application(s) with which this Whiteboard service should be
associated. Any service property of the Application can be
filtered on. If this filter is not defined then the default
Application is used. The default application can also be
specifically targeted using the application name
For example, to select an
Application with name
To select all Applications in the whiteboard provide the following value:
If no matching application exists this is reflected in the failure DTOs. See JAX_RS_APPLICATION_SELECT. † Note that this property is not valid for JAX-RS Application services. |
|
optional |
A set of LDAP-style filters used to express dependencies on one or more extension services. If a filter is provided then the JAX-RS Whiteboard attempts to match that filter against the service properties of the Whiteboard runtime, the service properties of the whiteboard application, and each of the extension services currently active in the application. This search may occur in any order. If all of the supplied filters are matched then the whiteboard service is registered into the JAX-RS Whiteboard application. For example, to require an
extension which provides JSON serialization advertising property
name
A more detailed version of this example is available in A JAX-RS Whiteboard Extension Example If any filter(s) fail to match then this is reflected in the failure DTOs. See JAX_RS_EXTENSION_SELECT. |
|
optional |
The value of this service property is an LDAP-style
filter expression to select the JAX-RS Whiteboard(s) to handle
this Whiteboard service. The LDAP filter is used to match JaxrsServiceRuntime services. Each JAX-RS Whiteboard exposes
exactly one |
JAX-RS resources can be registered with the JAX-RS Whiteboard by
registering them as Whiteboard services. This means that the resource POJO
implementations are registered in the Service Registry. As JAX-RS
resources are POJOs they may be registered using any
valid service interface, including Object
. The JAX-RS
container will then use reflection to discover methods and annotations on
the resource object, just as it would outside of OSGi.
As JAX-RS resources have no common interface type they are instead
registered with the osgi.jaxrs.resource
service property with
a value of "true"
. This property serves as a marker to the
JAX-RS whiteboard runtime, indicating that this OSGi service should be
hosted as a JAX-RS Whiteboard resource.
JAX-RS resources use the Path
annotation to bind
themselves to particular URIs within the JAX-RS container. The path
annotation can be applied to the resource class, and to individual
resource methods. For example the following JAX-RS resource:
@Path("foo")
public class Foo {
private final List<String> entries =
Arrays.asList("fizz", "buzz", "fizzbuzz");
@GET
public List<String> getFoos() {
return Collections.unmodifiableList(entries);
}
@GET
@Path("{name}")
public String getFoo(@PathParam("name") String name) {
if(entries.contains(name)) {
return "A foo called " + name;
}
throw new IllegalArgumentException(“No foo called “ + name);
}
}
This JAX-RS resource defines two resource methods. The
Path
annotation applied to the class sets the base URI for
all methods in the resource. The getFoos()
method is
therefore bound to the URI foo
. The Path
annotation on the getFoo()
method makes this method a
sub-resource which captures the next token in the URI. This method is
therefore bound to URIs of the form foo/buzz
.
When used as an OSGi JAX-RS Whiteboard service a JAX-RS resource
follows the same mapping rules, but the base context(s) it uses are
determined by the Application(s) to which it is mapped. For example,
when mapped to the default application of a whiteboard with endpoint
http://127.0.0.1/
the getFoos()
method would
be available at http://127.0.0.1/foo
.
Resource services bound to a JAX-RS whiteboard application share a single URI namespace with other resources in the application (including any existing static resources). When JAX-RS services are bound it is possible that one or more methods on these services will map to the same URI. This situation is permitted by the JAX-RS specification which defines a detailed selection algorithm.
When clashes occur in the JAX-RS whiteboard then resources supplied using the service whiteboard must be preferred to static resources contained in the application. Otherwise resource method selection follows the normal rules defined in the JAX-RS specification.
A key tenet of JAX-RS is that all resource objects are stateless. In the JAX-RS specification resources therefore have one of two scopes, they are either singleton, or request-scoped. Singleton resources are created once, potentially outside the JAX-RS container, and request-scoped resources are created on-demand for each request, then discarded afterwards.
Typically JAX-RS developers are encouraged to write request-scoped
resources, as this makes it difficult to accidentally write stateful
components. In OSGi, however, it is more common to write singleton
services. On demand instances of OSGi services can be created, but only
if the service is registered as a prototype
scope.
The JAX-RS whiteboard implementation is responsible for managing the mismatch between the OSGi service lifecycle model and the JAX-RS resource lifecycle model. If the JAX-RS whiteboard resource is registered as prototype scope then the implementation must treat the resources as request-scoped, creating a new service instance for each request and releasing it when the request completes. Otherwise the JAX-RS whiteboard service must be registered as a singleton scope resource within the application. Singleton scope whiteboard resources must be released by the JAX-RS whiteboard when the application with which they have been registered is removed from the whiteboard, even if this is only a temporary situation.
If a failure occurs when getting the resource service this will prevent the service from being used, which is reflected using a failure DTO. In such a case the system treats the resource as unusable.
When multiple JAX-RS Whiteboard implementations are present all of
them can potentially process the whiteboard resources. In such
situations it can be useful to associate the servlet with a specific
whiteboard by specifying the osgi.http.whiteboard.target
property on the service.
JAX-RS resources may have objects injected into them by the
JAX-RS container. These objects may be related to an incoming request,
for example an HTTP header value, or part of the container runtime.
Injected resources are annotated with a JAX-RS annotation, for example
@Context
, and may be injected as method parameters, or as
fields in the object.
If the JAX-RS injected objects are passed as method parameters
then the resource object may be a singleton. If, however, the objects
are injected into fields by the JAX-RS container then the resource
should be declared as a prototype
scope. JAX-RS
Whiteboard implementations may support field injection for singleton
resources, however this behavior is non portable, and may lead to
errors at runtime when using other implementations.
Request-scoped resources are created on demand for a request and
then discarded afterwards. Critically for OSGi services the JAX-RS
whiteboard must not release a prototype scope
service until after the response has completed.
If the resource makes use of a JAX-RS AsyncResponse
,
SseEventSink
or a StreamingOutput
then this
may be some time after the return of resource method, and potentially
on a different thread.
JAX-RS whiteboard implementations must therefore take special care not to release request scoped instances until they are completely finished.
JAX-RS supports asynchronous responses either for single-valued results, or for streams of data.
Single valued results are provided by the
AsyncResponse
type which is injected into resource
methods using the @Suspended
annotation. If the resource
is request scoped then the resource must not be released until after
the AsyncResponse
has completed.
The following example demonstrates the use of the
AsyncResponse
:
@Component(service = MyResource.class,
scope = ServiceScope.PROTOTYPE)
@JaxrsResource
public class MyResource {
@Path(“foo”)
@GET
public void getFoo(@Suspended AsyncResponse async) {
Promise<String> p = doLongRunningTaskAsynchronously();
p.onSuccess(v -> async.resume(v))
.onFailure(t -> async.resume(t));
}
}
Multi-valued results in JAX-RS are handled using Server Sent
Events. To send Server Sent Events a JAX-RS resource must declare its
produced media type appropriately, and inject its resource method with
a SseEventSink
. The resource must also gain access to a
Sse
to use as a factory for Outbound Server Sent Events.
If the resource is request scoped then the resource must not be
released until after the SseEvent
has closed.
The following example demonstrates the use of the Server Sent Events:
@Component(service = MyResource.class,
scope = ServiceScope.PROTOTYPE)
@JaxrsResource
public class MyResource {
@Context
Sse sse;
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public void getFoo(@Context SseEventSink sink) {
PushStream<String> p = getStreamOfMessages();
p.map(sse::newEvent)
.forEach(e -> sink::send)
.onResolve(sink::close);
}
}
The following table describes the properties that can be used by JAX-RS resources registered as Whiteboard services. Additionally, the common properties listed in Table 151.2 on page are supported.
Table 151.3 Service properties for JAX-RS Whiteboard resource services.
Service Property | Type | Description |
---|---|---|
|
required |
Declares that this service must be processed by the
JAX-RS whiteboard when set to |
The following example code uses Declarative Services annotations to register a JAX-RS Whiteboard service.
@Component(service = MyResource.class,
scope = ServiceScope.PROTOTYPE)
@JaxrsResource
public class MyResource {
@GET
@Path("hello")
@Produces("text/plain")
public String sayHello(){
return "Hello World!";
}
}
This example registers the resource method at:
/hello
. Requests for http://www.acme.com/hello
map to the resource method, which is called to process the
request.
To associate the above example resource with another application add the following service property:
osgi.jaxrs.application.select=(osgi.jaxrs.name=myApp)
This can also be added using the property annotation:
@JaxrsApplicationSelect("(osgi.jaxrs.name=myApp)")
Setting this property requires a JAX-RS application named
myApp
to be registered:
@Component(service=Application.class)
@JaxrsName("myApp")
@JaxrsApplicationBase("foo")
public class MyApplication extends Application {}
Now the whiteboard resource will be available at
http://www.acme.com/foo/hello
as configured by the custom
JAX-RS application.
JAX-RS extensions can be registered with the JAX-RS Whiteboard by
registering them as Whiteboard services. This means that the extension
implementations are registered in the Service Registry. It is relatively
common for a single extension type to provide more than one extension
interface, for example MessageBodyReader
and
MessageBodyWriter
are often provided by a single
object.
Extension services must be registered with the JAX-RS application
that they target using only the interfaces that they advertise in the OSGi
service registry. If, for example, an extension service object implements
MessageBodyReader
and ContainerRequestFilter
but
only advertises MessageBodyReader
in its service registration
then it must only be used as a MessageBodyReader
The following JAX-RS extension interfaces are supported by this specification:
-
ContainerRequestFilter
andContainerResponseFilter
- these extensions are used to alter the HTTP request and response parameters. -
ReaderInterceptor
andWriterInterceptor
- these extensions are used to alter the incoming or outgoing objects for the call. -
MessageBodyReader
andMessageBodyWriter
- these extensions are used to deserialize/serialize objects to the wire for a given media type, for exampleapplication/json
. -
ContextResolver
extensions are used to provide objects for injection into other JAX-RS resources and extensions. -
ExceptionMapper
extensions are used to map exceptions thrown by JAX-RS resources into responses. -
ParamConverterProvider
extensions are used to map rich parameter types to and from String values. -
Feature
andDynamicFeature
- these extensions are used as a way to register multiple extension types with the JAX-RS container. Dynamic Features further allow the extensions to be targeted to specific resources within the JAX-RS container.
As JAX-RS extensions have many possible interface types, none of
which are defined by this specification, they must be registered with the
osgi.jaxrs.extension
service property with a value of
true
. This property serves as a marker to the JAX-RS
whiteboard runtime, indicating that this OSGi service should be used as a
JAX-RS Whiteboard extension.
If the osgi.jaxrs.extension
is added to a service which
does not advertise any of the JAX-RS extension types then this is an
error, and must result in a failure DTO being created.
By default JAX-RS extensions are applied to every request, however
sometimes they are only needed for a subset of resource methods. In this
case a NameBinding
annotation can be used to apply the
extension to a subset of resource methods. The following example
declares a binding annotation called FizzBuzz
and uses it
to bind an extension which replaces occurrences of "fizz" with
"fizzbuzz".
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@NameBinding
public @interface FizzBuzz{}
@Component
@JaxrsExtension
@FizzBuzz
public class FizzBuzzReplacer implements WriterInterceptor {
public void aroundWriteTo(WriterInterceptorContext ctx) {
Object entity = ctx.getEntity();
if(entity != null) {
ctx.setEntity(entity.toString()
.replace("fizz", "fizzbuzz"));
}
ctx.proceed();
}
}
@Component(service=FizzResource.class)
@JaxrsResource
@Path("fizzbuzz")
public class FizzResource {
@GET
@FizzBuzz
public String getFoos() {
return "fizz, buzz, fizzbuzz";
}
}
The result of an http request to the fizzbuzz
URI
will be fizzbuzz, buzz, fizzbuzzbuzz
The JAX-RS whiteboard implementation must support the use of
NameBinding
to limit the scope of applied whiteboard
extensions.
JAX-RS filters can be annotated with @PreMatching
to
indicate that they should be applied before the JAX-RS container works
out which resource should be called by the incoming request. These
filters can therefore change the request such that it maps to a
different resource than it would have before the filter’s operation.
Pre-matching filters cannot use NameBinding
as no
corresponding named resource is available to the runtime when they
operate.
When used in the OSGi JAX-RS Whiteboard JAX-RS extensions follow
the same ordering rules as defined by the JAX-RS specification. Where
more than one extension of a particular type is available then they are
ordered according to their javax.annotation.Priority
. If
two extensions of the same type have the same priority then the
whiteboard implementation must break the tie by ordering the extensions
according to the natural ordering of their service references, with
static extensions being ranked below all whiteboard services.
The extension processing flow is as follows:
-
Server receives a request
-
Pre-matching
ContainerRequestFilter
s are executed. Changes made here can affect which resource method is chosen -
The Server matches the request to a resource method
-
Post-matching ContainerRequestFilters are executed. This includes execution of all filters which match the incoming path and any name-bound filters.
-
ReaderInterceptors which match the incoming path are applied to the incoming request body. If the request has no body then the ReaderInterceptors are not called.
-
The list of
MessageBodyReader
s applicable to the path and incoming content type are tried according to the standard ordering rules. The firstMessageBodyReader
which states that it can deserialize the entity “wins” and is used to create the entity object. If the incoming request has no body then noMessageBodyReader
s are called. -
If the resource is request scoped then it is instantiated and injected with relevant types from any defined
ContextResolver
s. These are queried in order for each of the injectable fields. -
The resource method is executed, passing any injected parameters from the request, and from any
ContextResolver
s. These are queried in turn for each of the injectable parameters. -
ContainerResponseFilter
s are executed passing the method's response when it is complete. This includes execution of all filters, in order, which match the incoming path and any name-bound filters. Note that if anAsyncResponse
is used then the response may not complete on the same thread as the incoming request. -
WriterInterceptor
s which match the incoming path are applied to the outgoing response stream. If the response has no body then the WriterInterceptors are not called. -
The list of
MessageBodyWriter
s applicable to the path and outgoing content type are tried according to the standard ordering rules. The first writer which states that it can serialize the entity “wins” and is used to write out the entity object. If there is no response body then no writers are called. -
The Server response is flushed and committed. If the resource that created the response was request scoped then it must only be released once the response is complete. Note that this may be at some point in the future, and on a different thread if the resource is using an
AsyncResponse
The osgi.jaxrs.extension.select
property described in
Common Whiteboard Properties applies to extensions
as well as JAX-RS resources. This is because one extension may depend on
another.
The most common reason for an extension to have a dependency is
for a context injection dependency. Dependencies are often provided by a
ContextResolver
so that they can be injected into another
extension. The following example demonstrates a simple dependency on a
Jackson ObjectMapper.
@JaxrsExtension
@JaxrsName("configProvider")
@Component
public class ConfigProvider implements ContextResolver {
private ObjectMapper mapper = new ObjectMapper();
public <T> getContext(Class<T> clazz) {
if(ObjectMapper.class.equals(clazz)) {
return mapper;
}
return null;
}
}
@JaxrsExtension
@JaxrsExtensionSelect("(osgi.jaxrs.name=configProvider)")
@Component(scope=ServiceScope.PROTOTYPE)
public class ConfiguredExtension implements WriterInterceptor {
@Context
private Providers providers;
public void aroundWriteTo(WriterInterceptorContext ctx) {
Object entity = ctx.getEntity();
if(entity != null) {
ObjectMapper mapper = providers
.getContextResolver(ObjectMapper.class)
.getContext(ObjectMapper.class);
ctx.setEntity(mapper.writeValueAsString(entity));
}
ctx.proceed();
}
}
Depending on the capabilities of the JAX-RS whiteboard implementation, and any statically defined extensions that make up a JAX-RS Whiteboard application, there may be numerous non standard extensions available. These extensions must be represented using service properties on the JAX-RS Service Runtime, or the whiteboard application as appropriate. This is why the extension select filters must also be matched against the JAX-RS Service Runtime service and the whiteboard application being targeted.
JAX-RS extensions have a different lifecycle from JAX-RS resources, within a single application a JAX-RS extension always behaves as a singleton. If a JAX-RS whiteboard extension is registered as prototype scope then the whiteboard implementation must obtain a separate instance for every application to which the extension is applied. Whiteboard extension services must be released by the JAX-RS whiteboard when the application with which they have been registered is removed from the whiteboard, even if this is only a temporary situation.
JAX-RS extensions often require configuration, and need to be
configured differently for different applications. This configuration is
typically provided by a JAX-RS ContextResolver
and injected
into fields of the extension by the JAX-RS container. It is therefore
highly recommended that JAX-RS Whiteboard extensions are always
registered as prototype scope, so that separate instances can be created
for each whiteboard application.
If an extension is registered as a singleton service then it should not rely on any fields being injected by the JAX-RS Whiteboard implementation. JAX-RS Whiteboard implementations may support field injection for singleton extensions, however this behavior is non portable, and may lead to errors at runtime when using other implementations.
The following table describes the properties that can be used by JAX-RS extensions registered as Whiteboard services. Additionally, the common properties listed in Table 151.2 on page are supported.
Table 151.4 Service properties for JAX-RS Whiteboard extension services.
Service Property | Type | Description |
---|---|---|
|
required |
Declares that this service must be processed by the
JAX-RS whiteboard when set to |
The following example code uses Declarative Services annotations to register a require JAX-RS Whiteboard extension which provides JSON support, and requires the extension from a JAX-RS whiteboard resource.
@Component(property="serialize.to=JSON")
@JaxrsExtension
public class JsonProvider implements MessageBodyReader,
MessageBodyWriter {
...
}
@Component(service = Object.class,
scope = ServiceScope.PROTOTYPE)
@JaxrsResource
@JaxrsExtensionSelect("(serialize.to=JSON)")
public class MyResource {
@GET
@Path("hello")
@Produces(MediaType.APPLICATION_JSON)
public List<String> getList(){
return Arrays.asList("Hello", "World!");
}
}
The JAX-RS specification defines the concept of an
Application
. An application is an object which collects
together one or more JAX-RS resources and extensions, and provides them to
the JAX-RS container. These resources may be provided as pre-instantiated
singletons, or as Class
objects to be reflectively
instantiated.
The OSGi JAX-RS whiteboard supports direct registration of Applications for two reasons:
-
To support the use of legacy JAX-RS applications with the whiteboard
-
To provide simple scoping of JAX-RS resources and extensions within a whiteboard, in this scenario it can be desirable to register an otherwise empty Application. This application can then be targeted by whiteboard services using the
osgi.jaxrs.application.select
property.
Application
s can be registered with the JAX-RS
Whiteboard by registering them as Whiteboard services which advertise
themselves using the JAX-RS Application
type. In addition the
whiteboard services must provide a
osgi.jaxrs.application.base
property. The value of this
property is the URI path relative to the root whiteboard context at which
the application will be registered. Note that the value of any
ApplicationPath
annotation will be applied by the container
in addition to the osgi.jaxrs.application.base
.
Each registered Whiteboard Application service is provided as a separate application within the whiteboard, and is isolated from other applications, including the default application. Whiteboard applications may be empty, may include zero or more static resources, and may include zero or more static extensions.
The base URI for each application within the whiteboard must be
unique. If two or more applications targeting the same whiteboard are
registered with the same base URI then only the highest ranked service
will be made available. All other application services with that URI
will have a failure DTO created for them. The same rules also apply to
the osgi.jaxrs.name
property, with the highest ranked
service shadowing other applications with the same name.
The default application is implicitly created by the whiteboard
and has the name .default
. The default application has a
lower ranking than all registered services. Therefore an application
registered with a base of /
will shadow a default
application bound at /
.
A whiteboard application service may set an
osgi.jaxrs.name
of .default
to replace the
default application. This technique may be used to rebind the default
application to a base uri other than /
.
If a whiteboard application fails (for example if the service get
fails), or cannot be immediately deployed (for example if it has an
unsatisfied osgi.jaxrs.extension.select
) then any
applications that it shadows are still shadowed and relevant failure
DTOs are created for all of the applications.
It is possible for an application to require additional whiteboard
extensions before it is eligible to be hosted by the whiteboard. When
making this determination the Whiteboard implementation must perform a
dry-run validation of the osgi.jaxrs.extension.select
filter, applying all of the whiteboard extensions targeted to the
application before determining whether the application's requirements
are met.
The following table describes the properties that can be used by
JAX-RS applications registered as Whiteboard services. Additionally, the
common properties listed in Table 151.2 on page are supported, except for the
osgi.jaxrs.application.select
property.
Table 151.5 Service properties for JAX-RS Whiteboard application services.
Service Property | Type | Description |
---|---|---|
|
required |
Declares that this service must be processed by the JAX-RS whiteboard, and defines the URI, relative to the root context of the whiteboard, at which the Application should be registered. See JAX_RS_APPLICATION_BASE. |
In JAX-RS the @Context
annotation may be used to
inject the Application
instance into a resource or
extension. Application configuration properties can also be injected
using the Configuration
type.
When using the JAX-RS Whiteboard it can also be necessary to
access the service properties associated with the application hosting
the resource, for example to allow customization of the resource's
response. To this end, the JAX-RS whiteboard implementation must make
the Application service properties available as a Map
in
the configuration. The key used to store this map is
osgi.jaxrs.application.serviceProperties
, and it can be
found in any injected Configuration
instance.
Furthermore, for Feature
and
DynamicFeature
extensions the application service
properties must be visible in the FeatureContext
passed to
the extension when applying it to the application. The
FeatureContext
interface provides programmatic access to
the Configuration
for the application, so this visibility
is achieved in the same manner as for an injected Configuration
instance.
In the case where the hosting application is not an OSGi service,
for example a Whiteboard implementation may choose to provide its
default application as an internal detail, then the
osgi.jaxrs.application.serviceProperties
map must exist
containing the osgi.jaxrs.name
of the application and the
service properties associated with the JaxrsServiceRuntime
service.
The following example code uses Declarative Services annotations to register a JAX-RS Whiteboard application, and shows how to target an additional whiteboard resource to that application.
@Component(service=Application.class)
@JaxrsApplicationBase("example")
@JaxrsName("myApp")
public class MyApplication extends Application {
public Set<Class<?>> getClasses() {
return new HashSet<>(Arrays.asList(StaticResource.class));
}
}
@Component(service = MyResource.class,
scope = ServiceScope.PROTOTYPE)
@JaxrsResource
@JaxrsApplicationSelect("(osgi.jaxrs.name=myApp)")
public class MyResource {
@GET
@Path("hello")
@Produces("text/plain")
public List<String> getList(){
return Arrays.asList("Hello", "World!");
}
}
The MyResource
service will be available at
http://www.acme.com/example/hello
All JAX-RS Whiteboard services may be registered with an optional
osgi.jaxrs.name
property. For Whiteboard resources and
applications (but not extensions), if the registered service has set this
property then the JAX-RS container must register a JaxrsEndpoint service identifying the URI(s) that can be used to
access the service.
The endpoint service must declare the following properties:
Table 151.6 Service properties for JAX-RS Whiteboard application services.
Service Property Name | Type | Description |
---|---|---|
|
required |
The name of the JAX-RS bean or application that has been registered. |
|
required |
The URI(s) that can be used to access the JAX-RS resource or application |
|
required |
Set appropriately to export the Endpoint service using OSGi Remote Services. |
|
required |
Set to the symbolic name of the bundle that provided the JAX-RS whiteboard service. |
|
required |
Set to the id of the bundle that provided the JAX-RS service |
|
required |
Set to the version of the bundle that provided the JAX-RS service |
|
required |
Set to the service id of the JAX-RS service |
There are a number of error cases where the JAX-RS whiteboard may be unable to correctly register a resource. All of these cases must result in a failure DTO being created with the appropriate error code.
-
Failure to obtain a service instance - In the case where a published service is unable to obtained by the JAX-RS whiteboard then the service is blacklisted by the container. A failure DTO is made available from the JaxrsServiceRuntime representing the blacklisted service object.
-
Invalid service objects - JAX-RS extension and Application objects are required to advertise certain interfaces, or to extend certain types. If a service advertises itself using a JAX-RS whiteboard service property, but fails to advertise an appropriate JAX-RS type, or fails to provide any resource methods then this is an error and the service must be blacklisted by the container. A failure DTO is available from the JaxrsServiceRuntime representing the blacklisted service object.
-
Overlapping Application mappings - As with resources in a single application it is possible that two JAX-RS resources will register for the same path across applications. In this case the application with the longer base URI is shadowed, and a failure DTO is available from the JaxrsServiceRuntime representing the shadowed Application. Note that determining when two JAX-RS applications overlap requires an analysis of the resource paths and all of sub-resource paths. If any of these paths clash then the entirety of the shadowed application must be unregistered and marked as a failure. It is an implementation error for some application resource paths to be available while others are shadowed.
-
Class-Space Compatibility - Much of the JAX-RS mapping definition is handled using annotations with runtime visibility. As JAX-RS beans are POJOs there is no guarantee of class-space compatibility when the JAX-RS implementation searches for whiteboard services. The JAX-RS whiteboard must therefore confirm that the registered service shares the correct view of the JAX-RS packages. If the class space is not consistent then the JAX-RS whiteboard container must not register the services, but instead should create a failure DTO indicating that the JAX-RS object is unable to be registered due to an incompatible class-space.
-
Missing Required Extensions - If a JAX-RS resource or extension requires one or more extensions using a
osgi.jaxrs.extension.select
filter then at any given time it is possible that the JAX-RS container will not be able to host the resource. At this time a failure DTO must be created for the relevant resource or extension service.
The JAX-RS specification includes a client API for making REST
requests. The normal mechanism for obtaining a Client
is to
use a ClientBuilder
, which is instantiated using a static
factory method. Static factory methods require the reflective loading of
classes and suffer from significant lifecycle issues, as there is no way
to force indirectly wired objects to be discarded if the implementation
bundle is stopped or uninstalled.
JAX-RS implementations must therefore register their ClientBuilder implementations as OSGi services for bundles to use in making Client instances. The ClientBuilder must be registered as a prototype scoped service. This allows bundles to configure multiple separate Client instances, and ensures that separate bundles will never accidentally provide conflicting configuration to the same ClientBuilder instance.
While Container extensions can be made available using whiteboard services, the same is not true for Clients. There are two main reasons for this:
-
There is no simple way to scope the filters and interceptors that would be applied to a given client. In a multi-tenant environment this could lead to unexpected behaviors.
-
Clients are not, in general, expected to be extended by third parties. The Client model is designed to be used by a bundle when making requests from a REST API. If further requests need to be made by a different bundle then it should create and configure a separate client. This is different from the whiteboard server, where one container port may host several distinct sets of resources.
In order to add filters, interceptors, readers and writers to the
JAX-RS client users should use the ClientBuilder#register()
method when building their client.
The JAX-RS client API supports both synchronous and asynchronous
calls. In JAX-RS 2.1 the asynchronous behavior of the client was
extended using the RxInvoker
(reactive invoker) interface.
All clients are required to support a reactive invoker which returns
CompletionStage instances, however in OSGi the common representation of
an asynchronous return is the Promise
. This specification
therefore provides the PromiseRxInvoker interface which can be used to obtain Promises
from the JAX-RS client.
It is the responsibility of the JAX-RS whiteboard implementation
to create instances of PromiseRxInvoker
. The exact
mechanism by which instances are created is undefined, however it is
possible to register a portable factory to create
PromiseRxInvoker
instances by implementing the
RxInvokerProvider
interface and registering this type with
the JAX-RS client. This portable implementation, however, is forced to
use a blocking model by the underlying JAX-RS API, and so
implementations may choose to implement a more optimized non-blocking
model using internal types.
Clients of this specification may make use of the
PromiseRxInvoker
using normal JAX-RS idioms. For
example:
Client client = clientBuilder.build();
Promise<String> p = client.target(REST_SERVICE_URL)
.path("/foo")
.path("/{name}")
.resolveTemplate("name", buzz)
.request()
.rx(PromiseRxInvoker.class)
.get(String.class);
In JAX-RS 2.1 support was added for Server Sent Events. These
events are consumed by a REST client using the
SseEventSource
. The SseEventSource
is not
created by a JAX-RS client instance, but is normally created using a
static factory method, which does not work in a modular environment.
Therefore the JAX-RS whiteboard implementation must register a
SseEventSourceFactory
service in the service registry. This
object serves as a factory for the JAX-RS SSE types.
Note that the SseEventSource has no way to register filters or
message body processors. All of the filters and necessary processors
must be registered with the JAX-RS client that is used to create the
WebTarget
used when building the SseEventSource. A client
may therefore consume Server Sent Events in the following way:
Client client = clientBuilder.build();
WebTarget target = client.target(REST_SERVICE_URL)
.path("/foo")
.path("/{name}")
.resolveTemplate("name", buzz);
SseEventSource source = sseFactory.newSource(target);;
source.register(event -> doSomething(event));
source.open();
A SseEventSource
may easily be converted into a
PushEventSource
(and consequently a
PushStream
) as follows. Note that the implementation does
not respond to back-pressure requests and should typically be used with
a buffer.
SseEventSource source = sseBuilder.newSource(target);
PushEventSource<InboundSseEvent> pes = pec ->
source.register(e -> {
try {
if(pec.accept(PushEvent.data(e)) < 0) {
source.close();
}
} catch (Exception e) {
try {
pec.accept(PushEvent.error(e));
} finally {
source.close();
}
}
},
t -> pec.accept(PushEvent.error(t)),
() -> pec.accept(PushEvent.close()));
source.open();
return source;
};
The extensions defined by the JAX-RS specification make JAX-RS
runtimes highly plugable, and it is common to extend the behavior of an
application using this model. In many cases the custom behaviors are
specific to a particular use case, for example mapping a specific
exception into a Response
, and there is no need for
portability. In some common cases, however, there are extensions that can
be used across a great many applications.
In order to ensure that a JAX-RS whiteboard application can make use of a common extension service in a portable way this specification defines standard service property names that should be registered, as appropriate, by whiteboard extension services, whiteboard applications with static extensions, and JAX-RS whiteboard implementations that provide built-in extension capabilities.
A common use of the JAX-RS extension mechanism is to provide
support for additional media types, both for consuming incoming requests
and for producing responses. All JAX-RS whiteboards must implicitly
support text/plain
and application/xml
(using
JAXB), however commonly used media types, such as
application/json
must be provided as an extension.
To ensure that whiteboard resources can depend on support for a
particular media type in a portable way this specification defines the
osgi.jaxrs.media.type
property. This property key should be
registered with one or more media types that are supported, and may be
provided by:
-
A Whiteboard extension - if the extension provides general purpose support for reading from and writing to a media type then it should register this property.
-
A Whiteboard application - if the application provides general purpose support for reading from and writing to a media type using a static extension then it should register this property.
-
A JAX-RS Whiteboard implementation - if the implementation provides general purpose built-in support for reading from and writing to a media type then it should register this property. If the built-in extension is always available then it should also be advertised by the osgi.service Capability for the JaxrsServiceRuntime.
The term general purpose is used to indicate that the media type support must not require implementation specific mapping metadata (for example annotations) and should, at a minimum, work with the OSGi scalar types and DTOs. The property key is available as a constant in JAX_RS_MEDIA_TYPE.
Where possible the value(s) of the
osgi.jaxrs.media.type
property should use the IANA
registered names of the media type(s) supported, for example
application/json
. Officially registered media types are
available from [4] IANA Media Type Registrations. If
there is no officially registered media type then a vendor type should
be used. Personal types may also be used, however due to the lack of
portability afforded by personal types it is recommended that a
non-standard property key is used for personal types.
Wildcard types (containing a *
) are often used by
extensions to indicate that they can create a variety of different
media types. Rarely this is because the extension can serialize into
multiple different formats. More typically this is because the
extension can serialize into a format which has multiple names, or
multiple formats which use the same basic serialization. Suffixes can
further modify this behavior, for example VCards may be serialized as
XML using application/vcard+xml
or as JSON using
application/vcard+json
.
Wildcard types must not be used as values for the
osgi.jaxrs.media.type
property as these do not provide
sufficient information for whiteboard resources to reliably select a
media type provider. Where a provider wishes to advertise support for
a general suffix, for example +json
or +cbor
then the provider must advertise the primary media type associated
with the suffix; in the supplied example these would be
application/json
and application/cbor
.
Clients wishing to use suffixed types should therefore also depend on
the primary media type, not the suffixed type, if they wish to be
portable. Where greater specificity is required it is recommended that
the extension be selected based on additional custom properties. This
should also be used for suffixes that have no primary type, for
example +der
. Official media type registrations are
available from [5] IANA Media Type Suffix Registrations
The most commonly required media type for JAX-RS services is
application/json
. To this end this specification defines
a Component Property annotation JSONRequired which can be applied to a Declarative Services
component to express:
-
An extension requirement for runtime
application/json
media type support -
A requirement for the JAX-RS whiteboard
-
An optional active time requirement for
application/json
media type support, for use in application resolution/assembly.
Custom third-party annotations can easily be created to support additional media types as necessary, and are used as follows:
@Component(service = MyResource.class,
scope = ServiceScope.PROTOTYPE)
@JaxrsResource
@JSONRequired
@Produces(MediaType.APPLICATION_JSON)
public class MyResource {
@Path(“foo”)
@GET
public List<String> getFoos() {
return Arrays.asList("foo", "bar", "baz");
}
}
A corresponding component property type (JaxrsMediaType) exists for use on a JAX-RS whiteboard extension or application service which provides media type support. This can be used to declare that one or more media types are supported.
@Component(scope = ServiceScope.PROTOTYPE)
@JaxrsExtension
@JaxrsMediaType(MediaType.APPLICATION_JSON)
public class MyFeature implements Feature {
public boolean configure(FeatureContext context) {
context.register(MyJSONCodec.class);
return true;
}
}
The JAX-RS Whiteboard implementation bundle must provide the osgi.implementation
capability with name osgi.jaxrs
. This capability can be
used by provisioning tools and during resolution to ensure that a JAX-RS
Whiteboard implementation is present to process the Whiteboard services
defined in this specification. The capability must also declare a uses
constraint for the javax.ws.rs.*
specification packages,
and for the and OSGi JAX-RS Whiteboard package. The version of this
capability must match the version of this specification:
Provide-Capability: osgi.implementation;
osgi.implementation="osgi.jaxrs";
uses:="javax.ws.rs, javax.ws.rs.client, javax.ws.rs.container,
javax.ws.rs.core, javax.ws.rs.ext, javax.ws.rs.sse,
org.osgi.service.jaxrs.whiteboard";
version:Version="1.0"
This capability must follow the rules defined for the osgi.implementation Namespace.
The JAX-RS Whiteboard implementation must provide a capability in
the osgi.contract
namespace with name JavaJAXRS
if it exports the JAX-RS
specification packages. See [5] Portable Java Contract Definitions.
Providing the osgi.contract
capability enables
developer to build portable bundles for packages that are not versioned
under OSGi Semantic Versioning rules. For more details see osgi.contract Namespace.
If the JAX-RS API is provided by another bundle, the JAX-RS Whiteboard implementation must be a consumer of the API and require the contract.
The bundle providing the JaxrsServiceRuntime service must provide a capability in the osgi.service
namespace representing this service. This capability must also declare a
uses constraint for the org.osgi.service.jaxrs.runtime
and
org.osgi.service.jaxrs.runtime.dto
packages:
Provide-Capability: osgi.service;
objectClass:List<String>="org.osgi.service.jaxrs.runtime.JaxrsServiceRuntime";
uses:="org.osgi.service.jaxrs.runtime,org.osgi.service.jaxrs.runtime.dto"
The bundle providing the
javax.ws.rs.client.ClientBuilder
service must also provide
a capability in the osgi.service
namespace representing this service. This capability must declare that
the service is prototype scope, and that there is a uses constraint for
the javax.ws.rs.client
package:
Provide-Capability: osgi.service;
objectClass:List<String>="javax.ws.rs.client.ClientBuilder";
uses:="javax.ws.rs.client,org.osgi.service.jaxrs.client";
service.scope="prototype"
The bundle providing the
org.osgi.service.jaxrs.client.SseEventSourceFactory
service
must also provide a capability in the osgi.service
namespace representing this service. This capability must declare a uses
constraint for the org.osgi.service.jaxrs.client
package:
Provide-Capability: osgi.service;
objectClass:List<String>="org.osgi.service.jaxrs.client.SseEventSourceFactory";
uses:="org.osgi.service.jaxrs.client"
These capabilities must follow the rules defined for the osgi.service Namespace.
This section only applies when executing in an OSGi environment which is enforcing Java permissions.
Bundles that need to register JAX-RS Whiteboard services must be
granted ServicePermission[interfaceName, REGISTER]
where
interface name is the relevant JAX-RS Whiteboard service interface
name.
The Http Whiteboard implementation must be granted
ServicePermission[*, GET]
to retrieve the JAX-RS Whiteboard
services from the service registry.
Bundles that need to introspect the state of the JAX-RS runtime
will need
ServicePermission[org.osgi.service.jaxrs.runtime.JaxrsServiceRuntime,
GET]
to obtain the JAX-RS Service Runtime service and access the
DTO types.
This specification does not require that the JAX-RS Whiteboard
implementation is granted All Permission or wraps calls to the JAX-RS
Whiteboard services in a doPrivileged
block. Therefore, it
is the responsibility of the JAX-RS Whiteboard services to use a
doPrivileged
block when performing privileged
operations.
JAX-RS Client Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.jaxrs.client; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.jaxrs.client; version="[1.0,1.1)"
-
PromiseRxInvoker
- A specialization of the RxInvoker which creates Promise instances. -
SseEventSourceFactory
- A factory for SseEventSource instances.
A specialization of the RxInvoker which creates Promise instances.
Bundles may obtain an instance of a PromiseRxInvoker using a ClientBuilder obtained from the service registry and calling the javax.ws.rs.client.Invocation.Builder.rx(Class) method.
Consumers of this API must not implement this type
A factory for SseEventSource instances.
Bundles may obtain an instance of a SseEventSourceFactory using the service registry. This service may then be used to construct SseEventSource instances for the supplied WebTarget.
Consumers of this API must not implement this type
The web target to consume events from
Create a new javax.ws.rs.sse.SseEventSource.Builder
a builder which can be used to further configure the event source
JAX-RS Runtime Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.jaxrs.runtime; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.jaxrs.runtime; version="[1.0,1.1)"
-
JaxrsEndpoint
- A JaxrsEndpoint service represents a registered JAX-RS whiteboard resource or application. -
JaxrsServiceRuntime
- The JaxrsServiceRuntime service represents the runtime information of a JAX-RS Whiteboard implementation. -
JaxrsServiceRuntimeConstants
- Defines standard names for JAX-RS Runtime Service constants.
A JaxrsEndpoint service represents a registered JAX-RS whiteboard resource or application.
It provides access to service properties representing the service, and the URI at which it is available.
Consumers of this API must not implement this type
A service property providing the bundle id of the bundle which registered the whiteboard service.
A service property providing the symbolic name of the bundle which registered the whiteboard service.
A service property providing the bundle version of the bundle which registered the whiteboard service.
A service property providing the service id of the whiteboard service.
The JaxrsServiceRuntime service represents the runtime information of a JAX-RS Whiteboard implementation.
It provides access to DTOs representing the current state of the service.
The JaxrsServiceRuntime service must be registered with the JaxrsServiceRuntimeConstants.JAX_RS_SERVICE_ENDPOINT service property.
Thread-safe
Consumers of this API must not implement this type
Defines standard names for JAX-RS Runtime Service constants.
JAX-RS Runtime Service service property specifying the endpoints upon which the JAX-RS implementation is available.
An endpoint value is a URL or a relative path, to which the JAX-RS
Whiteboard implementation is listening. For example,
http://192.168.1.10:8080/
or /myapp/
. A relative path may
be used if the scheme and authority parts of the URL are not known, e.g.
if a bridged Http Whiteboard implementation is used. If the JAX-RS
Whiteboard implementation is serving the root context and neither scheme
nor authority is known, the value of the property is "/". Both, a URL and
a relative path, must end with a slash.
A JAX-RS Whiteboard implementation can be listening on multiple endpoints.
The value of this service property must be of type String
,
String[]
, or Collection<String>
.
JAX-RS Runtime DTO Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.jaxrs.runtime.dto; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.jaxrs.runtime.dto; version="[1.0,1.1)"
-
ApplicationDTO
- Represents a JAX-RS Application service. -
BaseApplicationDTO
- Represents common information about a JAX-RS application service. -
BaseDTO
- Represents common information about a JAX-RS service. -
BaseExtensionDTO
- Represents common information about a JAX-RS extension service. -
DTOConstants
- Defines standard constants for the DTOs. -
ExtensionDTO
- Represents a JAX-RS Filter service currently being hosted by the JaxrsServiceRuntime -
FailedApplicationDTO
- Represents a JAX-RS service which is currently not being used due to a problem. -
FailedExtensionDTO
- Represents a JAX-RS Extension service which is currently not being used due to a problem. -
FailedResourceDTO
- Represents a JAX-RS resource service which is currently not being used due to a problem. -
ResourceDTO
- Represents common information about a JAX-RS resource service. -
ResourceMethodInfoDTO
- Represents information about a JAX-RS resource method. -
RuntimeDTO
- Represents the state of a JAX-RS Service Runtime.
Represents a JAX-RS Application service.
Not Thread-safe
The RequestPaths handled by statically defined resources in this Application
Represents common information about a JAX-RS application service.
Not Thread-safe
The base URI of the resource defined by JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE.
Returns the representations of the dynamic JAX-RS extension services associated with this Application. The returned array may be empty if this application is currently not associated with any JAX-RS extension services.
Returns the representations of the dynamic JAX-RS resource services associated with this Application. The returned array may be empty if this application is currently not associated with any JAX-RS Resource services.
Represents common information about a JAX-RS service.
Not Thread-safe
The name of the service if it set one using JaxrsWhiteboardConstants.JAX_RS_NAME, otherwise this value will contain the generated name for this service
Represents common information about a JAX-RS extension service.
Not Thread-safe
Defines standard constants for the DTOs. The error codes are defined to take the same values as used by the Http Service Whiteboard
The service is registered in the service registry with the JaxrsWhiteboardConstants.JAX_RS_NAME property and a service with that name already exists in the runtime
The extension service is registered in the service registry but the service is not registered using a recognized extension type
The service is registered in the service registry with the JaxrsWhiteboardConstants.JAX_RS_APPLICATION_SELECT property and the filters is not matched by any running application.
The service is registered in the service registry with the JaxrsWhiteboardConstants.JAX_RS_EXTENSION_SELECT property and one or more of the filters is not matched.
The service is registered in the service registry but getting the service
fails as it returns null
.
Service is shadowed by another service.
For example, a service with the same service properties but a higher service ranking.
Represents a JAX-RS Filter service currently being hosted by the JaxrsServiceRuntime
Not Thread-safe
The media types consumed by this service, if provided in an Consumes annotation
The resourceDTOs that are mapped to this extension using a NameBinding annotation
The full names of the NameBinding annotations applied to this extension, if any
The media types produced by this service, if provided in an Produces annotation
Represents a JAX-RS service which is currently not being used due to a problem.
The service represented by this DTO is not used due to a failure, but the BaseApplicationDTO.extensionDTOs and BaseApplicationDTO.resourceDTOs may be non-empty if whiteboard services have been associated with this failed application.
Not Thread-safe
The reason why the resource represented by this DTO is not used.
DTOConstants.FAILURE_REASON_UNKNOWN, DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE, DTOConstants.FAILURE_REASON_VALIDATION_FAILED, DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, DTOConstants.FAILURE_REASON_REQUIRED_EXTENSIONS_UNAVAILABLE
Represents a JAX-RS Extension service which is currently not being used due to a problem.
Not Thread-safe
The reason why the extension represented by this DTO is not used.
DTOConstants.FAILURE_REASON_UNKNOWN, DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE, DTOConstants.FAILURE_REASON_VALIDATION_FAILED, DTOConstants.FAILURE_REASON_NOT_AN_EXTENSION_TYPE, DTOConstants.FAILURE_REASON_REQUIRED_EXTENSIONS_UNAVAILABLE
Represents a JAX-RS resource service which is currently not being used due to a problem.
Not Thread-safe
The reason why the resource represented by this DTO is not used.
DTOConstants.FAILURE_REASON_UNKNOWN, DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE, DTOConstants.FAILURE_REASON_VALIDATION_FAILED, DTOConstants.FAILURE_REASON_REQUIRED_EXTENSIONS_UNAVAILABLE
Represents common information about a JAX-RS resource service.
Not Thread-safe
The RequestPaths handled by this resource
Represents information about a JAX-RS resource method. All information is determined by reading the relevant annotations, from the JAX-RS type and not interpreted further. Dynamic information, or information provided in other ways may not be represented in this DTO.
Not Thread-safe
The mime-type(s) consumed by this resource method, null if Consumes is not defined
The HTTP verb being handled, for example GET, DELETE, PUT, POST, HEAD, OPTIONS, null if no HttpMethod is defined
The NameBinding annotations that apply to this resource method, if any
The path of this resource method. Placeholder information present in the URI pattern will not be interpreted and simply returned as defined.
The mime-type(s) produced by this resource method, null if Produces is not defined
Represents the state of a JAX-RS Service Runtime.
Not Thread-safe
Returns the representations of the JAX-RS Application services associated with this Runtime. The returned array may be empty if this whiteboard is currently not associated with any JAX-RS application services.
Returns the current state of the default application for this Runtime.
Returns the representations of the JAX-RS extension services targeted to this runtime but currently not used due to some problem. The returned array may be empty.
Returns the representations of the JAX-RS extension services targeted to this runtime but currently not used due to some problem. The returned array may be empty.
Returns the representations of the JAX-RS resource services targeted to this runtime but currently not used due to some problem. The returned array may be empty.
The DTO for the corresponding JaxrsServiceRuntime
. This value is
never null
.
JAX-RS Whiteboard Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.jaxrs.whiteboard; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.jaxrs.whiteboard; version="[1.0,1.1)"
-
JaxrsWhiteboardConstants
- Defines standard constants for the JAX-RS Whiteboard services.
Defines standard constants for the JAX-RS Whiteboard services.
Service property specifying the base URI mapping for a JAX-RS application service.
The specified uri is used to determine whether a request should be mapped to the resource. Services without this service property are ignored.
The value of this service property must be of type String
, and
will have a "/" prepended if no "/" exists.
If two applications are registered with the same base uri then the lower ranked service is failed with a cause of DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE
Service property specifying the target application for a JAX-RS resource or extension service.
The specified filter is used to determine whether a resource should be included in a particular application. Services without this service property are bound to the default Application.
If a filter property is registered and no application running in the whiteboard matches the filter then the service will be failed with a cause of DTOConstants.FAILURE_REASON_REQUIRED_APPLICATION_UNAVAILABLE
The value of this service property must be of type String
, and be
a valid OSGi filter.
The property key which can be used to find the application service properties inside an injected Configuration
The name of the default JAX-RS application in every Whiteboard instance.
Service property specifying that a JAX-RS resource should be processed by the whiteboard.
The value of this service property must be of type String
or
Boolean and set to "true" or true
.
A service providing this property must be registered as one or more of the following types:
-
MessageBodyReader
-
MessageBodyWriter
-
ContainerRequestFilter
-
ContainerResponseFilter
-
ReaderInterceptor
-
WriterInterceptor
-
ContextResolver
-
ExceptionMapper
-
ParamConverterProvider
-
Feature
-
DynamicFeature
If a service with this property does not match any of the defined types then it is registered as a failure DTO with the error code DTOConstants.FAILURE_REASON_NOT_AN_EXTENSION_TYPE,
A Service property specifying one or more target filters used to select the set of JAX-RS extension services required to support this whiteboard service.
A JAX-RS Whiteboard service may require one or more extensions to be
available so that it can function. For example a resource which declares
that it @Produces("text/json")
requires a
MessageBodyWriter which supports JSON to be available.
This service property provides a String+ set of LDAP filters which will be applied to the service properties of all extensions available in the JAX-RS container. If all of the filters are satisfied then this service is eligible to be hosted by the JAX-RS container.
This service property may be declared by any JAX-RS whiteboard service, whether it is a resource, or an extension.
If this service property is not specified, then no extensions are required.
If one or more filter properties are registered and no suitable extension(s) are available then the service will be failed with a cause of DTOConstants.FAILURE_REASON_REQUIRED_EXTENSIONS_UNAVAILABLE
The value of this service property must be of type String
and be
a valid filter string.
A service property specifying that a JAX-RS extension service, JAX-RS application service, or JAX-RS Whiteboard implementation provides support for reading from and writing to a specific media type.
The value of this property will be one or more media type identifiers,
and where possible IANA registered names, such as
application/json
should be used. The value must not be a
wildcard type. Support for multiple media types that use the same suffix
should be supported by registering the media type associated with the
suffix.
Service property specifying the name of a JAX-RS whiteboard service.
This name is provided as a property on the registered Endpoint service so that the URI for a particular JAX-RS service can be identified. If this service property is not specified, then no Endpoint information will be registered for this resource.
Resource names must be unique among all services associated with a single Whiteboard implementation. If a clashing name is registered then the lower ranked service will be failed with a cause of DTOConstants.FAILURE_REASON_DUPLICATE_NAME
The value of this service property must be of type String
.
Service property specifying that a JAX-RS resource should be processed by the whiteboard.
The value of this service property must be of type String
or
Boolean and set to "true" or true
.
The name of the implementation capability for the JAX-RS Whiteboard specification
The version of the implementation capability for the JAX-RS Whiteboard specification
Service property specifying the target filter to select the JAX-RS Whiteboard implementation to process the service.
A JAX-RS Whiteboard implementation can define any number of service properties which can be referenced by the target filter. The service properties should always include the osgi.jaxrs.endpoint service property if the endpoint information is known.
If this service property is not specified, then all JAX-RS Whiteboard implementations can process the service.
The value of this service property must be of type String
and be
a valid filter string.
JAX-RS Whiteboard Annotations Package Version 1.0.
This package contains annotations that can be used to require the JAX-RS Whiteboard implementation.
Bundles should not normally need to import this package as the annotations are only used at build-time.
-
RequireJaxrsWhiteboard
- This annotation can be used to require the JAX-RS Whiteboard implementation.
This annotation can be used to require the JAX-RS Whiteboard implementation. It can be used directly, or as a meta-annotation.
This annotation is applied to several of the JAX-RS Whiteboard component property annotations meaning that it does not normally need to be applied to Declarative Services components which use the JAX-RS Whiteboard.
CLASS
TYPE
, PACKAGE
JAX-RS Whiteboard Package Version 1.0.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.
Example import for consumers using the API in this package:
Import-Package: org.osgi.service.jaxrs.whiteboard; version="[1.0,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.service.jaxrs.whiteboard; version="[1.0,1.1)"
-
JaxrsApplicationBase
- Component Property Type for theosgi.jaxrs.application.base
service property. -
JaxrsApplicationSelect
- Component Property Type for theosgi.jaxrs.application.select
service property. -
JaxrsExtension
- Component Property Type for theosgi.jaxrs.extension
service property. -
JaxrsExtensionSelect
- Component Property Type for theosgi.jaxrs.extension.select
service property. -
JaxrsMediaType
- Component Property Type for theosgi.jaxrs.media.type
service property. -
JaxrsName
- Component Property Type for theosgi.jaxrs.name
service property. -
JaxrsResource
- Component Property Type for theosgi.jaxrs.resource
service property. -
JaxrsWhiteboardTarget
- Component Property Type for theosgi.jaxrs.whiteboard.target
service property. -
JSONRequired
- Component Property Type for requiring JSON media type support using the JaxrsWhiteboardConstants.JAX_RS_MEDIA_TYPE service property.
Component Property Type for the osgi.jaxrs.application.base
service
property.
This annotation can be used on a JAX-RS resource or extension to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE service property.
Component Property Types
CLASS
TYPE
Service property providing a base context URI for a JAX-RS whiteboard application.
The base URI for this application.
org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE
Component Property Type for the osgi.jaxrs.application.select
service
property.
This annotation can be used on a JAX-RS resource or extension to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_APPLICATION_SELECT service property.
Component Property Types
CLASS
TYPE
Service property providing an OSGi filter identifying the application(s) to which this service should be bound.
The filter for selecting the applications to bind to.
org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_APPLICATION_SELECT
Component Property Type for the osgi.jaxrs.extension
service
property.
This annotation can be used on a JAX-RS service to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_EXTENSION service property.
Component Property Types
CLASS
TYPE
Component Property Type for the osgi.jaxrs.extension.select
service
property.
This annotation can be used on a JAX-RS resource or extension to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_EXTENSION_SELECT service property.
Component Property Types
CLASS
TYPE
Service property providing one or more OSGi filters identifying the extension(s) or application features which this service requires to work.
The filters for selecting the extensions to require.
org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_EXTENSION_SELECT
Component Property Type for the osgi.jaxrs.media.type
service
property.
This annotation can be used on a JAX-RS extension or application to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_MEDIA_TYPE service property.
Component Property Types
CLASS
TYPE
Service property identifying the name(s) of media types supported by this service.
The JAX-RS media types supported.
org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_MEDIA_TYPE
Component Property Type for the osgi.jaxrs.name
service property.
This annotation can be used on a JAX-RS service to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_NAME service property.
Component Property Types
CLASS
TYPE
Service property identifying the name of a JAX-RS service for processing by the whiteboard.
The JAX-RS service name.
org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_NAME
Component Property Type for the osgi.jaxrs.resource
service property.
This annotation can be used on a JAX-RS resource to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_RESOURCE service property.
Component Property Types
CLASS
TYPE
Component Property Type for the osgi.jaxrs.whiteboard.target
service
property.
This annotation can be used on a JAX-RS resource or extension to declare the value of the org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_WHITEBOARD_TARGET service property.
Component Property Types
CLASS
TYPE
Service property providing an OSGi filter identifying the whiteboard(s) to which this service should be bound.
The filter for selecting the whiteboards to bind to.
org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants.JAX_RS_WHITEBOARD_TARGET
Component Property Type for requiring JSON media type support using the JaxrsWhiteboardConstants.JAX_RS_MEDIA_TYPE service property.
This annotation can be used on a JAX-RS resource to declare require that JSON support is available before the resource becomes active. It also adds an optional Requirement for a service providing this media type to aid with provisioning.
Component Property Types
CLASS
TYPE
Provides an extension selection filter for an extension supporting the JSON media type
A filter requiring an osgi.jaxrs.media.type
of
application/json
[1]Java API for RESTful Web Services Specificationhttps://jcp.org/en/jsr/detail?id=370
[2]Portable Java Contract Definitionshttps://docs.osgi.org/reference/portable-java-contracts.html
[3]Whiteboard Patternhttps://docs.osgi.org/whitepaper/whiteboard-pattern/
[4]IANA Media Type Registrationshttps://www.iana.org/assignments/media-types/media-types.xhtml
[5]IANA Media Type Suffix Registrationshttps://www.iana.org/assignments/media-type-structured-suffix/media-type-structured-suffix.xhtml