Initial implementation (#2381)
This commit is contained in:
parent
fdd0b67188
commit
9c3f9f84d5
|
@ -91,10 +91,13 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
|
@ -106,7 +109,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the central class for the HAPI FHIR Plain Server framework.
|
* This class is the central class for the HAPI FHIR Plain Server framework.
|
||||||
*
|
* <p>
|
||||||
* See <a href="https://hapifhir.io/hapi-fhir/docs/server_plain/">HAPI FHIR Plain Server</a>
|
* See <a href="https://hapifhir.io/hapi-fhir/docs/server_plain/">HAPI FHIR Plain Server</a>
|
||||||
* for information on how to use this framework.
|
* for information on how to use this framework.
|
||||||
*/
|
*/
|
||||||
|
@ -769,6 +772,19 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
return myResourceNameToBinding.values();
|
return myResourceNameToBinding.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<BaseMethodBinding<?>> getProviderMethodBindings(Object theProvider) {
|
||||||
|
Set<BaseMethodBinding<?>> retVal = new HashSet<>();
|
||||||
|
for (ResourceBinding resourceBinding : getResourceBindings()) {
|
||||||
|
for (BaseMethodBinding<?> methodBinding : resourceBinding.getMethodBindings()) {
|
||||||
|
if (theProvider.equals(methodBinding.getProvider())) {
|
||||||
|
retVal.add(methodBinding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the resource providers for this server
|
* Provides the resource providers for this server
|
||||||
*/
|
*/
|
||||||
|
@ -1684,10 +1700,29 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
removeResourceMethods(theProvider, clazz, resourceNames);
|
removeResourceMethods(theProvider, clazz, resourceNames);
|
||||||
removeResourceMethodsOnInterfaces(theProvider, clazz.getInterfaces(), resourceNames);
|
removeResourceMethodsOnInterfaces(theProvider, clazz.getInterfaces(), resourceNames);
|
||||||
|
removeResourceNameBindings(resourceNames, theProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeResourceNameBindings(Collection<String> resourceNames, Object theProvider) {
|
||||||
for (String resourceName : resourceNames) {
|
for (String resourceName : resourceNames) {
|
||||||
|
ResourceBinding resourceBinding = myResourceNameToBinding.get(resourceName);
|
||||||
|
if (resourceBinding == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Iterator<BaseMethodBinding<?>> it = resourceBinding.getMethodBindings().iterator(); it.hasNext(); ) {
|
||||||
|
BaseMethodBinding<?> binding = it.next();
|
||||||
|
if (theProvider.equals(binding.getProvider())) {
|
||||||
|
it.remove();
|
||||||
|
ourLog.info("{} binding of {} was removed", resourceName, binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceBinding.getMethodBindings().isEmpty()) {
|
||||||
myResourceNameToBinding.remove(resourceName);
|
myResourceNameToBinding.remove(resourceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void removeResourceMethodsOnInterfaces(Object theProvider, Class<?>[] interfaces, Collection<String> resourceNames) {
|
private void removeResourceMethodsOnInterfaces(Object theProvider, Class<?>[] interfaces, Collection<String> resourceNames) {
|
||||||
for (Class<?> anInterface : interfaces) {
|
for (Class<?> anInterface : interfaces) {
|
||||||
|
|
|
@ -3,14 +3,19 @@ package ca.uhn.fhir.rest.server;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.rest.annotation.Create;
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.api.server.IFhirVersionServer;
|
import ca.uhn.fhir.rest.api.server.IFhirVersionServer;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
@ -21,12 +26,10 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.mockito.Mockito.*;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class RestfulServerTest {
|
public class RestfulServerTest {
|
||||||
|
@ -43,6 +46,32 @@ public class RestfulServerTest {
|
||||||
restfulServer.init();
|
restfulServer.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mockResource(Class theClass) {
|
||||||
|
RuntimeResourceDefinition resourceDefinitionMock = mock(RuntimeResourceDefinition.class);
|
||||||
|
String className = theClass.getSimpleName();
|
||||||
|
lenient().when(resourceDefinitionMock.getName()).thenReturn(className);
|
||||||
|
lenient().when(myCtx.getResourceDefinition(className)).thenReturn(resourceDefinitionMock);
|
||||||
|
lenient().when(myCtx.getResourceType(theClass)).thenReturn(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegisterProvidersWithMethodBindings() {
|
||||||
|
mockResource(MyResource.class);
|
||||||
|
mockResource(MyResource2.class);
|
||||||
|
|
||||||
|
MyProvider provider = new MyProvider();
|
||||||
|
restfulServer.registerProvider(provider);
|
||||||
|
MyProvider2 provider2 = new MyProvider2();
|
||||||
|
restfulServer.registerProvider(provider2);
|
||||||
|
|
||||||
|
assertFalse(restfulServer.getProviderMethodBindings(provider).isEmpty());
|
||||||
|
assertFalse(restfulServer.getProviderMethodBindings(provider2).isEmpty());
|
||||||
|
|
||||||
|
restfulServer.unregisterProvider(provider);
|
||||||
|
assertTrue(restfulServer.getProviderMethodBindings(provider).isEmpty());
|
||||||
|
assertFalse(restfulServer.getProviderMethodBindings(provider2).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterProviders() {
|
public void testRegisterProviders() {
|
||||||
//test register Plain Provider
|
//test register Plain Provider
|
||||||
|
@ -123,4 +152,89 @@ public class RestfulServerTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class MyProvider implements IResourceProvider {
|
||||||
|
@Operation(name = "SHOW_ME_THE_MONEY", typeName = "MyResource")
|
||||||
|
public IBaseBundle match() {
|
||||||
|
return mock(IBaseBundle.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
|
return MyResource.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyProvider2 implements IResourceProvider {
|
||||||
|
@Operation(name = "SHOW_ME_MORE_MONEY", typeName = "MyResource2")
|
||||||
|
public IBaseBundle match() {
|
||||||
|
return mock(IBaseBundle.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
|
return MyResource2.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyResource implements IBaseResource {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFormatComment() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getFormatCommentsPre() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getFormatCommentsPost() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getUserData(String theName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserData(String theName, Object theValue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBaseMetaType getMeta() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIdType getIdElement() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBaseResource setId(String theId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBaseResource setId(IIdType theId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FhirVersionEnum getStructureFhirVersionEnum() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyResource2 extends MyResource {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue