Fix build

This commit is contained in:
James Agnew 2015-09-24 15:12:06 -04:00
parent 4ff7452c9b
commit 291fd21836
15 changed files with 722 additions and 580 deletions

View File

@ -191,6 +191,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
String[] nextPathsSplit = nextPathsUnsplit.split("\\|");
for (String nextPath : nextPathsSplit) {
nextPath = nextPath.trim();
List<Class<? extends IBaseResource>> allowedTypesInField = null;
for (Object nextObject : extractValues(nextPath, theResource)) {
if (nextObject == null) {

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.util.ArrayList;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.Set;
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao.data;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.springframework.data.repository.CrudRepository;
import ca.uhn.fhir.jpa.entity.SubscriptionFlaggedResource;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.entity;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@ -15,7 +35,7 @@ import javax.persistence.Table;
public class SubscriptionFlaggedResource {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@GeneratedValue(strategy = GenerationType.AUTO)
@SequenceGenerator(name = "SEQ_SUBSCRIPTION_FLAG_ID", sequenceName = "SEQ_SUBSCRIPTION_FLAG_ID")
@Column(name = "PID", insertable = false, updatable = false)
private Long myId;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.entity;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.Collection;
import java.util.Date;
@ -43,7 +63,7 @@ public class SubscriptionTable {
private long myCheckInterval;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@GeneratedValue(strategy = GenerationType.AUTO)
@SequenceGenerator(name = "SEQ_SUBSCRIPTION_ID", sequenceName = "SEQ_SUBSCRIPTION_ID")
@Column(name = "PID", insertable = false, updatable = false)
private Long myId;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.util;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.hibernate.dialect.DerbyTenSevenDialect;
/**

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.util;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

View File

@ -198,7 +198,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
myPatientDao.create(p);
fail();
} catch (UnprocessableEntityException e) {
assertEquals("Resource contains reference to Organization/1 but resource with ID 1 is actually of type Observation", e.getMessage());
assertEquals("Resource contains reference to Organization/" + id1.getIdPart() + " but resource with ID "+ id1.getIdPart()+" is actually of type Observation", e.getMessage());
}
// Now with a forced ID

View File

@ -20,31 +20,31 @@ package ca.uhn.fhir.osgi;
* #L%
*/
/**
* Exception thrown from the Spring-DM/OSGi wiring. These
* exceptions are thrown when an error was encountered
* that was caused by incorrect wiring.
*
* @author Akana, Inc. Professional Services
*
*/
public class FhirConfigurationException extends Exception {
public FhirConfigurationException() {
super();
}
public FhirConfigurationException(String message) {
super(message);
}
public FhirConfigurationException(Throwable cause) {
super(cause);
}
public FhirConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* Exception thrown from the Spring-DM/OSGi wiring. These
* exceptions are thrown when an error was encountered
* that was caused by incorrect wiring.
*
* @author Akana, Inc. Professional Services
*
*/
public class FhirConfigurationException extends Exception {
public FhirConfigurationException() {
super();
}
public FhirConfigurationException(String message) {
super(message);
}
public FhirConfigurationException(Throwable cause) {
super(cause);
}
public FhirConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -20,37 +20,37 @@ package ca.uhn.fhir.osgi;
* #L%
*/
import java.util.Collection;
/**
* This is an abstraction for adding one or more Providers
* ("plain" providers as well as Resource Providers)
* to the configuration of a Fhir Server. This approach
* is needed versus direct publication of providers as
* OSGi services because references to OSGi services are
* really proxies that only implement the methods of the
* service's interfaces. This means that the introspection
* and annotation processing needed for HAPI FHIR provider
* processing is not possible on those proxy references..
*
* To get around this restriction, instances of this interface
* will be published as OSGi services and the real providers
* will typically be Spring wired into the underlying bean.
*
* Beans that are decorated with this interface can be
* published as OSGi services and will be registered in
* the specified FHIR Server. The OSGi service definition
* should have the following <service-property> entry:
*
* <entry key="fhir.server.name" value="a-name"/>
*
* where the value matches the same <service-property>
* assigned to a FhirServer OSGi service.
*
* @author Akana, Inc. Professional Services
*
*/
public interface FhirProviderBundle {
public Collection<Object> getProviders();
}
import java.util.Collection;
/**
* This is an abstraction for adding one or more Providers
* ("plain" providers as well as Resource Providers)
* to the configuration of a Fhir Server. This approach
* is needed versus direct publication of providers as
* OSGi services because references to OSGi services are
* really proxies that only implement the methods of the
* service's interfaces. This means that the introspection
* and annotation processing needed for HAPI FHIR provider
* processing is not possible on those proxy references..
*
* To get around this restriction, instances of this interface
* will be published as OSGi services and the real providers
* will typically be Spring wired into the underlying bean.
*
* Beans that are decorated with this interface can be
* published as OSGi services and will be registered in
* the specified FHIR Server. The OSGi service definition
* should have the following <service-property> entry:
*
* <entry key="fhir.server.name" value="a-name"/>
*
* where the value matches the same <service-property>
* assigned to a FhirServer OSGi service.
*
* @author Akana, Inc. Professional Services
*
*/
public interface FhirProviderBundle {
public Collection<Object> getProviders();
}

View File

@ -20,68 +20,68 @@ package ca.uhn.fhir.osgi;
* #L%
*/
import java.util.Collection;
/**
* Instances of the FHIR Server must implement this interface
* in order to be registered as OSGi services capable of dynamic
* provider registration. It expected that implementations of this
* interface will also extend RestfulService.
*
* The OSGi service definition for instances of the FHIR SERver
* should have the following <service-property> entry:
*
* <entry key="fhir.server.name" value="a-name"/>
*
* where the value matches the same <service-property> specified
* on the published "provider" OSGi services that are to be
* dynamically registered in the FHIR Server instance.
*
* @author Akana, Inc. Professional Services
*
*/
public interface FhirServer {
public static final String SVCPROP_SERVICE_NAME = "fhir.server.name";
/**
* Dynamically registers a single provider with the RestfulServer
*
* @param provider the provider to be registered
* @throws FhirConfigurationException
*/
public void registerOsgiProvider(Object provider) throws FhirConfigurationException;
/**
* Dynamically unregisters a single provider with the RestfulServer
*
* @param provider the provider to be unregistered
* @throws FhirConfigurationException
*/
public void unregisterOsgiProvider(Object provider) throws FhirConfigurationException;
/**
* Dynamically registers a list of providers with the RestfulServer
*
* @param provider the providers to be registered
* @throws FhirConfigurationException
*/
public void registerOsgiProviders(Collection<Object> provider) throws FhirConfigurationException;
/**
* Dynamically unregisters a list of providers with the RestfulServer
*
* @param provider the providers to be unregistered
* @throws FhirConfigurationException
*/
public void unregisterOsgiProviders(Collection<Object> provider) throws FhirConfigurationException;
/**
* Dynamically unregisters all of providers currently registered
*
* @throws FhirConfigurationException
*/
public void unregisterOsgiProviders() throws FhirConfigurationException;
}
import java.util.Collection;
/**
* Instances of the FHIR Server must implement this interface
* in order to be registered as OSGi services capable of dynamic
* provider registration. It expected that implementations of this
* interface will also extend RestfulService.
*
* The OSGi service definition for instances of the FHIR SERver
* should have the following <service-property> entry:
*
* <entry key="fhir.server.name" value="a-name"/>
*
* where the value matches the same <service-property> specified
* on the published "provider" OSGi services that are to be
* dynamically registered in the FHIR Server instance.
*
* @author Akana, Inc. Professional Services
*
*/
public interface FhirServer {
public static final String SVCPROP_SERVICE_NAME = "fhir.server.name";
/**
* Dynamically registers a single provider with the RestfulServer
*
* @param provider the provider to be registered
* @throws FhirConfigurationException
*/
public void registerOsgiProvider(Object provider) throws FhirConfigurationException;
/**
* Dynamically unregisters a single provider with the RestfulServer
*
* @param provider the provider to be unregistered
* @throws FhirConfigurationException
*/
public void unregisterOsgiProvider(Object provider) throws FhirConfigurationException;
/**
* Dynamically registers a list of providers with the RestfulServer
*
* @param provider the providers to be registered
* @throws FhirConfigurationException
*/
public void registerOsgiProviders(Collection<Object> provider) throws FhirConfigurationException;
/**
* Dynamically unregisters a list of providers with the RestfulServer
*
* @param provider the providers to be unregistered
* @throws FhirConfigurationException
*/
public void unregisterOsgiProviders(Collection<Object> provider) throws FhirConfigurationException;
/**
* Dynamically unregisters all of providers currently registered
*
* @throws FhirConfigurationException
*/
public void unregisterOsgiProviders() throws FhirConfigurationException;
}

View File

@ -20,138 +20,138 @@ package ca.uhn.fhir.osgi.impl;
* #L%
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.osgi.FhirConfigurationException;
import ca.uhn.fhir.osgi.FhirServer;
import ca.uhn.fhir.rest.server.RestfulServer;
/**
*
* @author Akana, Inc. Professional Services
*
*/
public class FhirServerImpl extends RestfulServer implements FhirServer {
private static Logger log = LoggerFactory.getLogger(FhirServerImpl.class);
private Collection<Object> serverProviders = Collections.synchronizedCollection(new ArrayList<Object>());
public FhirServerImpl() {
super();
}
public FhirServerImpl(FhirContext theCtx) {
super(theCtx);
}
/**
* Dynamically registers a single provider with the RestfulServer
*
* @param provider the provider to be registered
* @throws FhirConfigurationException
*/
@Override
public void registerOsgiProvider (Object provider) throws FhirConfigurationException {
if (null == provider) {
throw new NullPointerException("FHIR Provider cannot be null");
}
try {
super.registerProvider(provider);
log.trace("registered provider. class ["+provider.getClass().getName()+"]");
this.serverProviders.add(provider);
} catch (Exception e) {
log.error("Error registering FHIR Provider", e);
throw new FhirConfigurationException("Error registering FHIR Provider", e);
}
}
/**
* Dynamically unregisters a single provider with the RestfulServer
*
* @param provider the provider to be unregistered
* @throws FhirConfigurationException
*/
@Override
public void unregisterOsgiProvider (Object provider) throws FhirConfigurationException {
if (null == provider) {
throw new NullPointerException("FHIR Provider cannot be null");
}
try {
this.serverProviders.remove(provider);
log.trace("unregistered provider. class ["+provider.getClass().getName()+"]");
super.unregisterProvider(provider);
} catch (Exception e) {
log.error("Error unregistering FHIR Provider", e);
throw new FhirConfigurationException("Error unregistering FHIR Provider", e);
}
}
/**
* Dynamically registers a list of providers with the RestfulServer
*
* @param provider the providers to be registered
* @throws FhirConfigurationException
*/
@Override
public void registerOsgiProviders (Collection<Object> providers) throws FhirConfigurationException {
if (null == providers) {
throw new NullPointerException("FHIR Provider list cannot be null");
}
try {
super.registerProviders(providers);
for (Object provider : providers) {
log.trace("registered provider. class ["+provider.getClass().getName()+"]");
this.serverProviders.add(provider);
}
} catch (Exception e) {
log.error("Error registering FHIR Providers", e);
throw new FhirConfigurationException("Error registering FHIR Providers", e);
}
}
/**
* Dynamically unregisters a list of providers with the RestfulServer
*
* @param provider the providers to be unregistered
* @throws FhirConfigurationException
*/
@Override
public void unregisterOsgiProviders (Collection<Object> providers) throws FhirConfigurationException {
if (null == providers) {
throw new NullPointerException("FHIR Provider list cannot be null");
}
try {
for (Object provider : providers) {
log.trace("unregistered provider. class ["+provider.getClass().getName()+"]");
this.serverProviders.remove(provider);
}
super.unregisterProvider(providers);
} catch (Exception e) {
log.error("Error unregistering FHIR Providers", e);
throw new FhirConfigurationException("Error unregistering FHIR Providers", e);
}
}
/**
* Dynamically unregisters all of providers currently registered
*
* @throws FhirConfigurationException
*/
@Override
public void unregisterOsgiProviders () throws FhirConfigurationException {
// need to make a copy to be able to remove items
Collection<Object> providers = new ArrayList<Object>();
providers.addAll(this.serverProviders);
this.unregisterOsgiProviders(providers);
}
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.osgi.FhirConfigurationException;
import ca.uhn.fhir.osgi.FhirServer;
import ca.uhn.fhir.rest.server.RestfulServer;
/**
*
* @author Akana, Inc. Professional Services
*
*/
public class FhirServerImpl extends RestfulServer implements FhirServer {
private static Logger log = LoggerFactory.getLogger(FhirServerImpl.class);
private Collection<Object> serverProviders = Collections.synchronizedCollection(new ArrayList<Object>());
public FhirServerImpl() {
super();
}
public FhirServerImpl(FhirContext theCtx) {
super(theCtx);
}
/**
* Dynamically registers a single provider with the RestfulServer
*
* @param provider the provider to be registered
* @throws FhirConfigurationException
*/
@Override
public void registerOsgiProvider (Object provider) throws FhirConfigurationException {
if (null == provider) {
throw new NullPointerException("FHIR Provider cannot be null");
}
try {
super.registerProvider(provider);
log.trace("registered provider. class ["+provider.getClass().getName()+"]");
this.serverProviders.add(provider);
} catch (Exception e) {
log.error("Error registering FHIR Provider", e);
throw new FhirConfigurationException("Error registering FHIR Provider", e);
}
}
/**
* Dynamically unregisters a single provider with the RestfulServer
*
* @param provider the provider to be unregistered
* @throws FhirConfigurationException
*/
@Override
public void unregisterOsgiProvider (Object provider) throws FhirConfigurationException {
if (null == provider) {
throw new NullPointerException("FHIR Provider cannot be null");
}
try {
this.serverProviders.remove(provider);
log.trace("unregistered provider. class ["+provider.getClass().getName()+"]");
super.unregisterProvider(provider);
} catch (Exception e) {
log.error("Error unregistering FHIR Provider", e);
throw new FhirConfigurationException("Error unregistering FHIR Provider", e);
}
}
/**
* Dynamically registers a list of providers with the RestfulServer
*
* @param provider the providers to be registered
* @throws FhirConfigurationException
*/
@Override
public void registerOsgiProviders (Collection<Object> providers) throws FhirConfigurationException {
if (null == providers) {
throw new NullPointerException("FHIR Provider list cannot be null");
}
try {
super.registerProviders(providers);
for (Object provider : providers) {
log.trace("registered provider. class ["+provider.getClass().getName()+"]");
this.serverProviders.add(provider);
}
} catch (Exception e) {
log.error("Error registering FHIR Providers", e);
throw new FhirConfigurationException("Error registering FHIR Providers", e);
}
}
/**
* Dynamically unregisters a list of providers with the RestfulServer
*
* @param provider the providers to be unregistered
* @throws FhirConfigurationException
*/
@Override
public void unregisterOsgiProviders (Collection<Object> providers) throws FhirConfigurationException {
if (null == providers) {
throw new NullPointerException("FHIR Provider list cannot be null");
}
try {
for (Object provider : providers) {
log.trace("unregistered provider. class ["+provider.getClass().getName()+"]");
this.serverProviders.remove(provider);
}
super.unregisterProvider(providers);
} catch (Exception e) {
log.error("Error unregistering FHIR Providers", e);
throw new FhirConfigurationException("Error unregistering FHIR Providers", e);
}
}
/**
* Dynamically unregisters all of providers currently registered
*
* @throws FhirConfigurationException
*/
@Override
public void unregisterOsgiProviders () throws FhirConfigurationException {
// need to make a copy to be able to remove items
Collection<Object> providers = new ArrayList<Object>();
providers.addAll(this.serverProviders);
this.unregisterOsgiProviders(providers);
}
}

View File

@ -20,282 +20,282 @@ package ca.uhn.fhir.osgi.impl;
* #L%
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.fhir.osgi.FhirConfigurationException;
import ca.uhn.fhir.osgi.FhirProviderBundle;
import ca.uhn.fhir.osgi.FhirServer;
/**
* Manage the dynamic registration of FHIR Servers and FHIR Providers.
* Methods on this Spring Bean will be invoked from OSGi Reference
* Listeners when OSGi services are published for these interfaces.
*
* @author Akana, Inc. Professional Services
*
*/
public class FhirServerManager {
private static Logger log = LoggerFactory.getLogger(FhirServerManager.class);
private static final String FIRST_SERVER = "#first";
private Map<String,FhirServer> registeredServers = new ConcurrentHashMap<String,FhirServer>();
private Map<String,Collection<Collection<Object>>> serverProviders = new ConcurrentHashMap<String,Collection<Collection<Object>>>();
private Collection<Collection<Object>> registeredProviders = Collections.synchronizedList(new ArrayList<Collection<Object>>());
private Map<String,Collection<Collection<Object>>> pendingProviders = new ConcurrentHashMap<String,Collection<Collection<Object>>>();
private boolean haveDefaultProviders = false;
/**
* Register a new FHIR Server OSGi service.
* We need to track these services so we can find the correct
* server to use when registering/unregistering providers.
* <p>
* The OSGi service definition of a FHIR Server should look like:
* <code><pre>
* &lt;osgi:service ref="<b><i>some.bean</i></b>" interface="ca.uhn.fhir.osgi.FhirServer">
* &lt;osgi:service-properties>
* &lt;entry key="name" value="<b><i>osgi-service-name</i></b>"/>
* &lt;entry key="fhir.server.name" value="<b><i>fhir-server-name</i></b>"/>
* &lt;/osgi:service-properties>
* &lt;/osgi:service>
* </pre></code>
* The <b><i>fhir-server-name</i></b> parameter is also specified for all
* of the FHIR Providers that are to be dynamically registered with the
* named FHIR Server.
*
* @param server OSGi service implementing the FhirService interface
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void registerFhirServer (FhirServer server, Map<String,Object> props) throws FhirConfigurationException {
if (server != null) {
String serviceName = (String)props.get("name");
if (null == serviceName) {
serviceName = "<default>";
}
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
if (serverName != null) {
if (registeredServers.containsKey(serverName)) {
throw new FhirConfigurationException("FHIR Server named ["+serverName+"] is already registered. These names must be unique.");
}
log.trace("Registering FHIR Server ["+serverName+"]. (OSGi service named ["+serviceName+"])");
registeredServers.put(serverName, server);
if (haveDefaultProviders && registeredServers.size() > 1) {
throw new FhirConfigurationException("FHIR Providers are registered without a server name. Only one FHIR Server is allowed.");
}
Collection<Collection<Object>> providers = pendingProviders.get(serverName);
if (providers != null) {
log.trace("Registering FHIR providers waiting for this server to be registered.");
pendingProviders.remove(serverName);
for (Collection<Object> list : providers) {
this.registerProviders(list, server, serverName);
}
}
if (registeredServers.size() == 1) {
providers = pendingProviders.get(FIRST_SERVER);
if (providers != null) {
log.trace("Registering FHIR providers waiting for the first/only server to be registered.");
pendingProviders.remove(FIRST_SERVER);
for (Collection<Object> list : providers) {
this.registerProviders(list, server, serverName);
}
}
}
} else {
throw new FhirConfigurationException("FHIR Server registered in OSGi is missing the required ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
/**
* This method will be called when a FHIR Server OSGi service
* is being removed from the container. This normally will only
* occur when its bundle is stopped because it is being removed
* or updated.
*
* @param server OSGi service implementing the FhirService interface
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void unregisterFhirServer (FhirServer server, Map<String,Object> props) throws FhirConfigurationException {
if (server != null) {
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
if (serverName != null) {
FhirServer service = registeredServers.get(serverName);
if (service != null) {
log.trace("Unregistering FHIR Server ["+serverName+"]");
service.unregisterOsgiProviders();
registeredServers.remove(serverName);
log.trace("Dequeue any FHIR providers waiting for this server");
pendingProviders.remove(serverName);
if (registeredServers.size() == 0) {
log.trace("Dequeue any FHIR providers waiting for the first/only server");
pendingProviders.remove(FIRST_SERVER);
}
Collection<Collection<Object>> providers = serverProviders.get(serverName);
if (providers != null) {
serverProviders.remove(serverName);
registeredProviders.removeAll(providers);
}
}
} else {
throw new FhirConfigurationException("FHIR Server registered in OSGi is missing the required ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
/**
* Register a new FHIR Provider-Bundle OSGi service.
*
* This could be a "plain" provider that is published with the
* FhirProvider interface or it could be a resource provider that
* is published with either that same interface or the IResourceProvider
* interface.
*
* (That check is not made here but is included as usage documentation)
*
* <p>
* The OSGi service definition of a FHIR Provider would look like:
* <code><pre>
* &lt;osgi:service ref="<b><i>some.bean</i></b>" interface="ca.uhn.fhir.osgi.IResourceProvider">
* &lt;osgi:service-properties>
* &lt;entry key="name" value="<b><i>osgi-service-name</i></b>"/>
* &lt;entry key="fhir.server.name" value="<b><i>fhir-server-name</i></b>"/>
* &lt;/osgi:service-properties>
* &lt;/osgi:service>
* </pre></code>
* The <b><i>fhir-server-name</i></b> parameter is the value assigned to the
* <code>fhir.server.name</code> service-property of one of the OSGi-published
* FHIR Servers.
*
* @param server OSGi service implementing a FHIR provider interface
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void registerFhirProviders (FhirProviderBundle bundle, Map<String,Object> props) throws FhirConfigurationException {
if (bundle != null) {
Collection<Object> providers = bundle.getProviders();
if (providers != null && !providers.isEmpty()) {
try {
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
String ourServerName = getServerName(serverName);
String bundleName = (String)props.get("name");
if (null == bundleName) {
bundleName = "<default>";
}
log.trace("Register FHIR Provider Bundle ["+bundleName+"] on FHIR Server ["+ourServerName+"]");
FhirServer server = registeredServers.get(ourServerName);
if (server != null) {
registerProviders(providers, server, serverName);
} else {
log.trace("Queue the Provider Bundle waiting for FHIR Server to be registered");
Collection<Collection<Object>> pending;
synchronized(pendingProviders) {
pending = pendingProviders.get(serverName);
if (null == pending) {
pending = Collections.synchronizedCollection(new ArrayList<Collection<Object>>());
pendingProviders.put(serverName, pending);
}
}
pending.add(providers);
}
} catch (BadServerException e) {
throw new FhirConfigurationException("Unable to register the OSGi FHIR Provider. Multiple Restful Servers exist. Specify the ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
}
protected void registerProviders (Collection<Object> providers, FhirServer server, String serverName) throws FhirConfigurationException {
server.registerOsgiProviders(providers);
Collection<Collection<Object>> active;
synchronized(serverProviders) {
active = serverProviders.get(serverName);
if (null == active) {
active = Collections.synchronizedCollection(new ArrayList<Collection<Object>>());
serverProviders.put(serverName, active);
}
}
active.add(providers);
registeredProviders.add(providers);
}
/**
* This method will be called when a FHIR Provider OSGi service
* is being removed from the container. This normally will only
* occur when its bundle is stopped because it is being removed
* or updated.
*
* @param server OSGi service implementing one of the provider
* interfaces
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void unregisterFhirProviders (FhirProviderBundle bundle, Map<String,Object> props) throws FhirConfigurationException {
if (bundle != null) {
Collection<Object> providers = bundle.getProviders();
if (providers != null && !providers.isEmpty()) {
try {
registeredProviders.remove(providers);
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
String ourServerName = getServerName(serverName);
FhirServer server = registeredServers.get(ourServerName);
if (server != null) {
server.unregisterOsgiProviders(providers);
Collection<Collection<Object>> active = serverProviders.get(serverName);
if (active != null) {
active.remove(providers);
}
}
} catch (BadServerException e) {
throw new FhirConfigurationException("Unable to register the OSGi FHIR Provider. Multiple Restful Servers exist. Specify the ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
}
/*
* Adjust the FHIR Server name allowing for null which would
* indicate that the Provider should be registered with the
* only FHIR Server defined.
*/
private String getServerName (String osgiName) throws BadServerException {
String result = osgiName;
if (null == result) {
if (registeredServers.isEmpty()) { // wait for the first one
haveDefaultProviders = true; // only allow one server
result = FIRST_SERVER;
} else
if (registeredServers.size() == 1) { // use the only one
haveDefaultProviders = true; // only allow one server
result = registeredServers.keySet().iterator().next();
} else {
throw new BadServerException();
}
}
return result;
}
class BadServerException extends Exception {
BadServerException() {
super();
}
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.fhir.osgi.FhirConfigurationException;
import ca.uhn.fhir.osgi.FhirProviderBundle;
import ca.uhn.fhir.osgi.FhirServer;
/**
* Manage the dynamic registration of FHIR Servers and FHIR Providers.
* Methods on this Spring Bean will be invoked from OSGi Reference
* Listeners when OSGi services are published for these interfaces.
*
* @author Akana, Inc. Professional Services
*
*/
public class FhirServerManager {
private static Logger log = LoggerFactory.getLogger(FhirServerManager.class);
private static final String FIRST_SERVER = "#first";
private Map<String,FhirServer> registeredServers = new ConcurrentHashMap<String,FhirServer>();
private Map<String,Collection<Collection<Object>>> serverProviders = new ConcurrentHashMap<String,Collection<Collection<Object>>>();
private Collection<Collection<Object>> registeredProviders = Collections.synchronizedList(new ArrayList<Collection<Object>>());
private Map<String,Collection<Collection<Object>>> pendingProviders = new ConcurrentHashMap<String,Collection<Collection<Object>>>();
private boolean haveDefaultProviders = false;
/**
* Register a new FHIR Server OSGi service.
* We need to track these services so we can find the correct
* server to use when registering/unregistering providers.
* <p>
* The OSGi service definition of a FHIR Server should look like:
* <code><pre>
* &lt;osgi:service ref="<b><i>some.bean</i></b>" interface="ca.uhn.fhir.osgi.FhirServer">
* &lt;osgi:service-properties>
* &lt;entry key="name" value="<b><i>osgi-service-name</i></b>"/>
* &lt;entry key="fhir.server.name" value="<b><i>fhir-server-name</i></b>"/>
* &lt;/osgi:service-properties>
* &lt;/osgi:service>
* </pre></code>
* The <b><i>fhir-server-name</i></b> parameter is also specified for all
* of the FHIR Providers that are to be dynamically registered with the
* named FHIR Server.
*
* @param server OSGi service implementing the FhirService interface
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void registerFhirServer (FhirServer server, Map<String,Object> props) throws FhirConfigurationException {
if (server != null) {
String serviceName = (String)props.get("name");
if (null == serviceName) {
serviceName = "<default>";
}
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
if (serverName != null) {
if (registeredServers.containsKey(serverName)) {
throw new FhirConfigurationException("FHIR Server named ["+serverName+"] is already registered. These names must be unique.");
}
log.trace("Registering FHIR Server ["+serverName+"]. (OSGi service named ["+serviceName+"])");
registeredServers.put(serverName, server);
if (haveDefaultProviders && registeredServers.size() > 1) {
throw new FhirConfigurationException("FHIR Providers are registered without a server name. Only one FHIR Server is allowed.");
}
Collection<Collection<Object>> providers = pendingProviders.get(serverName);
if (providers != null) {
log.trace("Registering FHIR providers waiting for this server to be registered.");
pendingProviders.remove(serverName);
for (Collection<Object> list : providers) {
this.registerProviders(list, server, serverName);
}
}
if (registeredServers.size() == 1) {
providers = pendingProviders.get(FIRST_SERVER);
if (providers != null) {
log.trace("Registering FHIR providers waiting for the first/only server to be registered.");
pendingProviders.remove(FIRST_SERVER);
for (Collection<Object> list : providers) {
this.registerProviders(list, server, serverName);
}
}
}
} else {
throw new FhirConfigurationException("FHIR Server registered in OSGi is missing the required ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
/**
* This method will be called when a FHIR Server OSGi service
* is being removed from the container. This normally will only
* occur when its bundle is stopped because it is being removed
* or updated.
*
* @param server OSGi service implementing the FhirService interface
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void unregisterFhirServer (FhirServer server, Map<String,Object> props) throws FhirConfigurationException {
if (server != null) {
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
if (serverName != null) {
FhirServer service = registeredServers.get(serverName);
if (service != null) {
log.trace("Unregistering FHIR Server ["+serverName+"]");
service.unregisterOsgiProviders();
registeredServers.remove(serverName);
log.trace("Dequeue any FHIR providers waiting for this server");
pendingProviders.remove(serverName);
if (registeredServers.size() == 0) {
log.trace("Dequeue any FHIR providers waiting for the first/only server");
pendingProviders.remove(FIRST_SERVER);
}
Collection<Collection<Object>> providers = serverProviders.get(serverName);
if (providers != null) {
serverProviders.remove(serverName);
registeredProviders.removeAll(providers);
}
}
} else {
throw new FhirConfigurationException("FHIR Server registered in OSGi is missing the required ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
/**
* Register a new FHIR Provider-Bundle OSGi service.
*
* This could be a "plain" provider that is published with the
* FhirProvider interface or it could be a resource provider that
* is published with either that same interface or the IResourceProvider
* interface.
*
* (That check is not made here but is included as usage documentation)
*
* <p>
* The OSGi service definition of a FHIR Provider would look like:
* <code><pre>
* &lt;osgi:service ref="<b><i>some.bean</i></b>" interface="ca.uhn.fhir.osgi.IResourceProvider">
* &lt;osgi:service-properties>
* &lt;entry key="name" value="<b><i>osgi-service-name</i></b>"/>
* &lt;entry key="fhir.server.name" value="<b><i>fhir-server-name</i></b>"/>
* &lt;/osgi:service-properties>
* &lt;/osgi:service>
* </pre></code>
* The <b><i>fhir-server-name</i></b> parameter is the value assigned to the
* <code>fhir.server.name</code> service-property of one of the OSGi-published
* FHIR Servers.
*
* @param server OSGi service implementing a FHIR provider interface
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void registerFhirProviders (FhirProviderBundle bundle, Map<String,Object> props) throws FhirConfigurationException {
if (bundle != null) {
Collection<Object> providers = bundle.getProviders();
if (providers != null && !providers.isEmpty()) {
try {
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
String ourServerName = getServerName(serverName);
String bundleName = (String)props.get("name");
if (null == bundleName) {
bundleName = "<default>";
}
log.trace("Register FHIR Provider Bundle ["+bundleName+"] on FHIR Server ["+ourServerName+"]");
FhirServer server = registeredServers.get(ourServerName);
if (server != null) {
registerProviders(providers, server, serverName);
} else {
log.trace("Queue the Provider Bundle waiting for FHIR Server to be registered");
Collection<Collection<Object>> pending;
synchronized(pendingProviders) {
pending = pendingProviders.get(serverName);
if (null == pending) {
pending = Collections.synchronizedCollection(new ArrayList<Collection<Object>>());
pendingProviders.put(serverName, pending);
}
}
pending.add(providers);
}
} catch (BadServerException e) {
throw new FhirConfigurationException("Unable to register the OSGi FHIR Provider. Multiple Restful Servers exist. Specify the ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
}
protected void registerProviders (Collection<Object> providers, FhirServer server, String serverName) throws FhirConfigurationException {
server.registerOsgiProviders(providers);
Collection<Collection<Object>> active;
synchronized(serverProviders) {
active = serverProviders.get(serverName);
if (null == active) {
active = Collections.synchronizedCollection(new ArrayList<Collection<Object>>());
serverProviders.put(serverName, active);
}
}
active.add(providers);
registeredProviders.add(providers);
}
/**
* This method will be called when a FHIR Provider OSGi service
* is being removed from the container. This normally will only
* occur when its bundle is stopped because it is being removed
* or updated.
*
* @param server OSGi service implementing one of the provider
* interfaces
* @param props the <service-properties> for that service
*
* @throws FhirConfigurationException
*/
public void unregisterFhirProviders (FhirProviderBundle bundle, Map<String,Object> props) throws FhirConfigurationException {
if (bundle != null) {
Collection<Object> providers = bundle.getProviders();
if (providers != null && !providers.isEmpty()) {
try {
registeredProviders.remove(providers);
String serverName = (String)props.get(FhirServer.SVCPROP_SERVICE_NAME);
String ourServerName = getServerName(serverName);
FhirServer server = registeredServers.get(ourServerName);
if (server != null) {
server.unregisterOsgiProviders(providers);
Collection<Collection<Object>> active = serverProviders.get(serverName);
if (active != null) {
active.remove(providers);
}
}
} catch (BadServerException e) {
throw new FhirConfigurationException("Unable to register the OSGi FHIR Provider. Multiple Restful Servers exist. Specify the ["+FhirServer.SVCPROP_SERVICE_NAME+"] service-property");
}
}
}
}
/*
* Adjust the FHIR Server name allowing for null which would
* indicate that the Provider should be registered with the
* only FHIR Server defined.
*/
private String getServerName (String osgiName) throws BadServerException {
String result = osgiName;
if (null == result) {
if (registeredServers.isEmpty()) { // wait for the first one
haveDefaultProviders = true; // only allow one server
result = FIRST_SERVER;
} else
if (registeredServers.size() == 1) { // use the only one
haveDefaultProviders = true; // only allow one server
result = registeredServers.keySet().iterator().next();
} else {
throw new BadServerException();
}
}
return result;
}
class BadServerException extends Exception {
BadServerException() {
super();
}
}
}

View File

@ -20,39 +20,39 @@ package ca.uhn.fhir.osgi.impl;
* #L%
*/
import java.util.Collection;
import ca.uhn.fhir.osgi.FhirProviderBundle;
/**
*
* @author Akana, Inc. Professional Services
*
*/
public class SimpleFhirProviderBundle implements FhirProviderBundle {
// /////////////////////////////////////
// //////// Spring Wiring ////////
// /////////////////////////////////////
private Collection<Object> providers;
public void setProviders (Collection<Object> providers) {
this.providers = providers;
}
// /////////////////////////////////////
// /////////////////////////////////////
// /////////////////////////////////////
public SimpleFhirProviderBundle () {
super();
}
@Override
public Collection<Object> getProviders () {
return this.providers;
}
}
import java.util.Collection;
import ca.uhn.fhir.osgi.FhirProviderBundle;
/**
*
* @author Akana, Inc. Professional Services
*
*/
public class SimpleFhirProviderBundle implements FhirProviderBundle {
// /////////////////////////////////////
// //////// Spring Wiring ////////
// /////////////////////////////////////
private Collection<Object> providers;
public void setProviders (Collection<Object> providers) {
this.providers = providers;
}
// /////////////////////////////////////
// /////////////////////////////////////
// /////////////////////////////////////
public SimpleFhirProviderBundle () {
super();
}
@Override
public Collection<Object> getProviders () {
return this.providers;
}
}