Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Commit

Permalink
Fix #88: Jersey server configuration properties are ignored
Browse files Browse the repository at this point in the history
A new type was introduced called ApplicationConfiguration. Clients can
register an implementation as an OSGi service. The connector tracks all
ApplicationConfigurations and uses its properties to configure the
JAX-RS Application.

The connector is aware of dynamic ApplicationConfigurations. So it's
possible to register them anytime.
  • Loading branch information
hstaudacher committed Mar 18, 2015
1 parent 3ef18c4 commit c03759e
Show file tree
Hide file tree
Showing 14 changed files with 569 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Holger Staudacher - initial API and implementation, ongoing development
******************************************************************************/
package com.eclipsesource.jaxrs.publisher;

import java.util.Map;

import javax.ws.rs.core.Application;

/**
* <p>
* Service that allows configuration of the JAX-RS {@link Application}. Multiple registrations will be tracked.
* </p>
*
* @since 4.3
*/
public interface ApplicationConfiguration {

/**
* <p>
* Will be called before the JAX-RS {@link Application} is registered. Please note that
* one {@link ApplicationConfiguration} can overwrite the values of other {@link ApplicationConfiguration}s. It
* depends on the order they are available in the OSGi container.
* </p>
*
* @see Application#getProperties()
*/
Map<String, Object> getProperties();

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class Activator implements BundleActivator {
private HttpTracker httpTracker;
private ResourceTracker allTracker;
private ServletConfigurationTracker servletConfigurationTracker;
private ApplicationConfigurationTracker applicationConfigurationTracker;
private ServiceRegistration configRegistration;

@Override
Expand All @@ -50,6 +51,7 @@ public void start( BundleContext context ) throws Exception {
connectorRegistration = context.registerService( JAXRSConnector.class.getName(), jaxRsConnector, null );
openHttpServiceTracker( context );
openServletConfigurationTracker( context );
openApplicationConfigurationTracker( context );
openAllServiceTracker( context );
}

Expand Down Expand Up @@ -78,6 +80,11 @@ private void openServletConfigurationTracker( BundleContext context ) {
servletConfigurationTracker.open();
}

private void openApplicationConfigurationTracker( BundleContext context ) {
applicationConfigurationTracker = new ApplicationConfigurationTracker( context, jaxRsConnector );
applicationConfigurationTracker.open();
}

private void openAllServiceTracker( BundleContext context ) throws InvalidSyntaxException {
ResourceFilter allResourceFilter = getResourceFilter( context );
allTracker = new ResourceTracker( context, allResourceFilter.getFilter(), jaxRsConnector );
Expand All @@ -96,6 +103,7 @@ private ResourceFilter getResourceFilter( BundleContext context ) {
public void stop( BundleContext context ) throws Exception {
httpTracker.close();
servletConfigurationTracker.close();
applicationConfigurationTracker.close();
allTracker.close();
connectorRegistration.unregister();
configRegistration.unregister();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2015 Holger Staudacher and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Holger Staudacher - initial API and implementation
******************************************************************************/
package com.eclipsesource.jaxrs.publisher.internal;

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;

import com.eclipsesource.jaxrs.publisher.ApplicationConfiguration;

/**
* <p>
* Tracker for OSGi Services implementing the {@link ApplicationConfiguration} interface.
* </p>
*/
public class ApplicationConfigurationTracker extends ServiceTracker {

private final JAXRSConnector connector;

ApplicationConfigurationTracker( BundleContext context, JAXRSConnector connector ) {
super( context, ApplicationConfiguration.class.getName(), null );
this.connector = connector;
}

@Override
public Object addingService( ServiceReference reference ) {
return connector.addApplicationConfiguration( reference );
}

@Override
public void removedService( ServiceReference reference, Object service ) {
if( service instanceof ApplicationConfiguration ) {
connector.removeApplicationConfiguration( reference, ( ApplicationConfiguration )service );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,31 @@
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;

import com.eclipsesource.jaxrs.publisher.ApplicationConfiguration;


@SuppressWarnings( "rawtypes" )
public class Configuration implements ManagedService {

static final String CONFIG_SERVICE_PID = "com.eclipsesource.jaxrs.connector";
static final String PROPERTY_ROOT = "root";
static final String PROPERTY_WADL_DISABLE = "disableWadl";
static final String PROPERTY_PUBLISH_DELAY = "publishDelay";
static final long DEFAULT_PUBLISH_DELAY = 150;

/**
* Will be remove in favor of {@link ApplicationConfiguration}
*/
@Deprecated
static final String PROPERTY_WADL_DISABLE = "disableWadl";

private final JAXRSConnector connector;
private boolean isWadlDisabled;
private long publishDelay;
private String rootPath;

public Configuration( JAXRSConnector jaxRsConnector ) {
this.connector = jaxRsConnector;
this.publishDelay = DEFAULT_PUBLISH_DELAY;
}

@Override
Expand All @@ -39,7 +50,10 @@ public void updated( Dictionary properties ) throws ConfigurationException {
ensureRootIsPresent( root );
String rootPath = ( String )root;
ensureRootIsValid( rootPath );
connector.updateConfiguration( rootPath, isWadlDisabled( properties ), getPublishDelay( properties ) );
this.rootPath = rootPath;
this.isWadlDisabled = isWadlDisabled( properties );
this.publishDelay = getPublishDelay( properties );
connector.updateConfiguration( this );
}
}

Expand Down Expand Up @@ -70,4 +84,21 @@ private long getPublishDelay( Dictionary properties ) {
}
return ( ( Long )interval );
}

/**
* Will be remove in favor of {@link ApplicationConfiguration}
*/
@Deprecated
public boolean isWadlDisabled() {
return isWadlDisabled;
}

public long getPublishDelay() {
return publishDelay;
}

public String getRoothPath() {
return rootPath == null ? "/services" : rootPath;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Holger Staudacher - initial API and implementation, ongoing development
******************************************************************************/
package com.eclipsesource.jaxrs.publisher.internal;

import java.util.HashMap;
import java.util.Map;

import org.glassfish.jersey.server.ServerProperties;

import com.eclipsesource.jaxrs.publisher.ApplicationConfiguration;


public class DefaultApplicationConfiguration implements ApplicationConfiguration {

private final Configuration configuration;

public DefaultApplicationConfiguration( Configuration configuration ) {
this.configuration = configuration;
}

@Override
public Map<String, Object> getProperties() {
Map<String, Object> properties = new HashMap<>();
// don't look for implementations described by META-INF/services/*
properties.put( ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, false );
// disable auto discovery on server, as it's handled via OSGI
properties.put( ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true );
diableWadlToConfiguration( properties );
return properties;
}

/**
* WADL generation is enabled in Jersey by default. This means that OPTIONS methods are added by
* default to each resource and an auto-generated /application.wadl resource is deployed too. In
* case you want to disable that you can set this property to true.
*
* @param disableWadl <code>true</code> to disable WADL feature
*/
@SuppressWarnings( "deprecation" )
private void diableWadlToConfiguration( Map<String, Object> properties ) {
properties.put( ServerProperties.WADL_FEATURE_DISABLE, configuration.isWadlDisabled() );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;

import com.eclipsesource.jaxrs.publisher.ApplicationConfiguration;
import com.eclipsesource.jaxrs.publisher.ServletConfiguration;
import com.eclipsesource.jaxrs.publisher.internal.ServiceContainer.ServiceHolder;

Expand All @@ -37,37 +38,23 @@ public class JAXRSConnector {
private final BundleContext bundleContext;
private final List<ServiceHolder> resourceCache;
private ServletConfiguration servletConfiguration;
private String rootPath;
private boolean isWadlDisabled;
private long publishDelay;
private final ServiceContainer applicationConfigurations;
private Configuration configuration;

JAXRSConnector( BundleContext bundleContext ) {
this.bundleContext = bundleContext;
this.configuration = new Configuration( this );
this.httpServices = new ServiceContainer( bundleContext );
this.resources = new ServiceContainer( bundleContext );
this.contextMap = new HashMap<HttpService, JerseyContext>();
this.resourceCache = new ArrayList<ServiceHolder>();
this.publishDelay = Configuration.DEFAULT_PUBLISH_DELAY;
this.applicationConfigurations = new ServiceContainer( bundleContext );
}

void updateConfiguration( String rootPath, boolean isWadlDisabled, long publishDelay ) {
void updateConfiguration( Configuration configuration ) {
synchronized( lock ) {
doUpdateConfiguration( rootPath, isWadlDisabled, publishDelay );
}
}

private void doUpdateConfiguration( String rootPath, boolean isWadlDisabled, long publishDelay ) {
this.rootPath = rootPath;
this.isWadlDisabled = isWadlDisabled;
this.publishDelay = publishDelay;
doUpdateHttpServices();
}

private void doUpdateHttpServices() {
ServiceHolder[] services = httpServices.getServices();
for( ServiceHolder serviceHolder : services ) {
doRemoveHttpService( ( HttpService )serviceHolder.getService() );
doAddHttpService( serviceHolder.getReference() );
this.configuration = configuration;
doUpdateHttpServices();
}
}

Expand All @@ -94,11 +81,33 @@ void unsetServletConfiguration(ServiceReference reference, ServletConfiguration
}
}

ApplicationConfiguration addApplicationConfiguration( ServiceReference reference ) {
synchronized( lock ) {
ApplicationConfiguration service = ( ApplicationConfiguration )applicationConfigurations.add( reference ).getService();
doUpdateHttpServices();
return service;
}
}

void removeApplicationConfiguration( ServiceReference reference, ApplicationConfiguration service ) {
synchronized( lock ) {
applicationConfigurations.remove( service );
doUpdateHttpServices();
}
}

private void doUpdateHttpServices() {
ServiceHolder[] services = httpServices.getServices();
for( ServiceHolder serviceHolder : services ) {
doRemoveHttpService( ( HttpService )serviceHolder.getService() );
doAddHttpService( serviceHolder.getReference() );
}
}

HttpService doAddHttpService( ServiceReference reference ) {
ServiceHolder serviceHolder = httpServices.add( reference );
HttpService service = ( HttpService )serviceHolder.getService();
contextMap.put( service,
createJerseyContext( service, rootPath, isWadlDisabled, publishDelay, servletConfiguration ) );
contextMap.put( service, createJerseyContext( service, configuration, servletConfiguration ) );
clearCache();
return service;
}
Expand Down Expand Up @@ -209,11 +218,9 @@ private void removeResourcesFromContext( Object resource, HttpService httpServic

// For testing purpose
JerseyContext createJerseyContext( HttpService service,
String rootPath,
boolean disableWadl,
long publishDelay,
Configuration configuration,
ServletConfiguration servletConfiguration )
{
return new JerseyContext( service, rootPath, disableWadl, publishDelay, servletConfiguration );
return new JerseyContext( service, configuration, servletConfiguration, applicationConfigurations );
}
}
Loading

0 comments on commit c03759e

Please sign in to comment.