Merge branch 'oauth2'

Conflicts:
This commit is contained in:
James Agnew 2014-09-11 16:29:08 -04:00
commit 0b6c985f3a
70 changed files with 798 additions and 761 deletions

View File

@ -3,6 +3,7 @@ package example;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import ca.uhn.fhir.rest.server.IResourceProvider;
@ -20,19 +21,25 @@ public class ExampleRestfulServlet extends RestfulServer {
private static final long serialVersionUID = 1L;
/**
* Constructor
* The initialize method is automatically called when the servlet is starting up, so it can
* be used to configure the servlet to define resource providers, or set up
* configuration, interceptors, etc.
*/
public ExampleRestfulServlet() {
/*
* The servlet defines any number of resource providers, and
* configures itself to use them by calling
* setResourceProviders()
*/
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
resourceProviders.add(new RestfulPatientResourceProvider());
resourceProviders.add(new RestfulObservationResourceProvider());
setResourceProviders(resourceProviders);
}
@Override
protected void initialize() throws ServletException {
/*
* The servlet defines any number of resource providers, and
* configures itself to use them by calling
* setResourceProviders()
*/
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
resourceProviders.add(new RestfulPatientResourceProvider());
resourceProviders.add(new RestfulObservationResourceProvider());
setResourceProviders(resourceProviders);
}
}
//END SNIPPET: servlet

View File

@ -7,6 +7,7 @@ import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.composite.PeriodDt;
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
@ -16,88 +17,103 @@ import ca.uhn.fhir.model.primitive.StringDt;
public class FhirDataModel {
public static void datatypes() {
// START SNIPPET: datatypes
Observation obs = new Observation();
public static void datatypes() {
// START SNIPPET: datatypes
Observation obs = new Observation();
// These are all equivalent
obs.setIssued(new InstantDt(new Date()));
obs.setIssued(new Date(), TemporalPrecisionEnum.MILLI);
obs.setIssuedWithMillisPrecision(new Date());
// These are all equivalent
obs.setIssued(new InstantDt(new Date()));
obs.setIssued(new Date(), TemporalPrecisionEnum.MILLI);
obs.setIssuedWithMillisPrecision(new Date());
// The InstantDt also lets you work with the instant as a Java Date
// object or as a FHIR String.
Date date = obs.getIssued().getValue(); // A date object
String dateString = obs.getIssued().getValueAsString(); // "2014-03-08T12:59:58.068-05:00"
// END SNIPPET: datatypes
// The InstantDt also lets you work with the instant as a Java Date
// object or as a FHIR String.
Date date = obs.getIssued().getValue(); // A date object
String dateString = obs.getIssued().getValueAsString(); // "2014-03-08T12:59:58.068-05:00"
// END SNIPPET: datatypes
System.out.println(date);
System.out.println(dateString);
System.out.println(date);
System.out.println(dateString);
}
@SuppressWarnings("unused")
public void nonNull() {
// START SNIPPET: nonNull
Observation observation = new Observation();
}
// None of these calls will return null, but instead create their respective
// child elements.
IdentifierDt identifierDt = observation.getIdentifier();
PeriodDt periodDt = observation.getIdentifier().getPeriod();
DateTimeDt activeDt = observation.getIdentifier().getPeriod().getStart();
@SuppressWarnings("unused")
public void nonNull() {
// START SNIPPET: nonNull
Observation observation = new Observation();
// DateTimeDt is a FHIR primitive however, so the following will return null
// unless a value has been placed there.
Date active = observation.getIdentifier().getPeriod().getStart().getValue();
// END SNIPPET: nonNull
// None of these calls will return null, but instead create their
// respective
// child elements.
IdentifierDt identifierDt = observation.getIdentifier();
PeriodDt periodDt = observation.getIdentifier().getPeriod();
DateTimeDt activeDt = observation.getIdentifier().getPeriod().getStart();
// DateTimeDt is a FHIR primitive however, so the following will return
// null
// unless a value has been placed there.
Date active = observation.getIdentifier().getPeriod().getStart().getValue();
// END SNIPPET: nonNull
}
public static void codes() {
// START SNIPPET: codes
Patient patient = new Patient();
}
// Coded types can naturally be set using plain Strings
CodingDt genderCoding = patient.getGender().addCoding();
genderCoding.setSystem("http://hl7.org/fhir/v3/AdministrativeGender");
genderCoding.setCode("M");
public static void codes() {
// START SNIPPET: codes
Patient patient = new Patient();
// This is equivalent to the three statements above
patient.setGender(AdministrativeGenderCodesEnum.M);
// END SNIPPET: codes
// Coded types can naturally be set using plain Strings
CodingDt genderCoding = patient.getGender().addCoding();
genderCoding.setSystem("http://hl7.org/fhir/v3/AdministrativeGender");
genderCoding.setCode("M");
// This is equivalent to the three statements above
patient.setGender(AdministrativeGenderCodesEnum.M);
// END SNIPPET: codes
}
public static void main(String[] args) {
datatypes();
// START SNIPPET: observation
Observation observation = new Observation();
// Create a quantity datatype
QuantityDt q = new QuantityDt();
q.setValue(185);
q.setSystem("http://unitsofmeasure.org");
q.setCode("lbs");
// Put the datatype in the observation
observation.setValue(q);
// Set the reference range
observation.getReferenceRangeFirstRep().setLow(100);
observation.getReferenceRangeFirstRep().setHigh(200);
// END SNIPPET: observation
}
public void namesHard() {
// START SNIPPET: namesHard
Patient patient = new Patient();
HumanNameDt name = patient.addName();
StringDt family = name.addFamily();
family.setValue("Smith");
StringDt firstName = name.addGiven();
firstName.setValue("Rob");
StringDt secondName = name.addGiven();
secondName.setValue("Bruce");
// END SNIPPET: namesHard
}
public void namesEasy() {
// START SNIPPET: namesEasy
Patient patient = new Patient();
patient.addName().addFamily("Smith").addGiven("Rob").addGiven("Bruce");
// END SNIPPET: namesEasy
}
}
public static void main(String[] args) {
datatypes();
}
public void namesHard() {
// START SNIPPET: namesHard
Patient patient = new Patient();
HumanNameDt name = patient.addName();
StringDt family = name.addFamily();
family.setValue("Smith");
StringDt firstName = name.addGiven();
firstName.setValue("Rob");
StringDt secondName = name.addGiven();
secondName.setValue("Bruce");
//END SNIPPET: namesHard
}
public void namesEasy() {
// START SNIPPET: namesEasy
Patient patient = new Patient();
patient.addName().addFamily("Smith").addGiven("Rob").addGiven("Bruce");
//END SNIPPET: namesEasy
}
}

View File

@ -0,0 +1,37 @@
package example;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
@SuppressWarnings("serial")
public class ServletExamples {
// START SNIPPET: loggingInterceptor
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
public class RestfulServerWithLogging extends RestfulServer {
@Override
protected void initialize() throws ServletException {
// ... define your resource providers here ...
// Now register the logging interceptor
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
registerInterceptor(loggingInterceptor);
// The SLF4j logger "test.accesslog" will receive the logging events
loggingInterceptor.setLoggerName("test.accesslog");
// This is the format for each line. A number of substitution variables may
// be used here. See the JavaDoc for LoggingInterceptor for information on
// what is available.
loggingInterceptor.setMessageFormat("Source[${remoteAddr}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
}
}
// END SNIPPET: loggingInterceptor
}

View File

@ -1,8 +1,15 @@
package example;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
import ca.uhn.fhir.parser.DataFormatException;
@ -11,8 +18,7 @@ import ca.uhn.fhir.validation.ValidationFailureException;
public class ValidatorExamples {
public static void main(String[] args) throws DataFormatException, IOException {
public void validateResource() {
//START SNIPPET: basicValidation
// As always, you need a context
FhirContext ctx = new FhirContext();
@ -35,10 +41,45 @@ public class ValidatorExamples {
System.out.println("Validation failed");
// The ValidationFailureException which gets thrown by the validator
// will contain an OperationOutcome resource describing the failure
String results = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome());
System.out.println(results);
}
//END SNIPPET: basicValidation
}
public static void main(String[] args) throws DataFormatException, IOException {
validateFiles();
}
private static void validateFiles() throws IOException, FileNotFoundException {
//START SNIPPET: validateFiles
FhirContext ctx = new FhirContext();
// Create a validator and configure it
FhirValidator validator = ctx.newValidator();
validator.setValidateAgainstStandardSchema(true);
validator.setValidateAgainstStandardSchematron(true);
// Get a list of files in a given directory
String[] fileList = new File("/home/some/dir").list(new WildcardFileFilter("*.txt"));
for (String nextFile : fileList) {
// For each file, load the contents into a string
String nextFileContents = IOUtils.toString(new FileReader(nextFile));
// Parse that string (this example assumes JSON encoding)
IResource resource = ctx.newJsonParser().parseResource(nextFileContents);
// Apply the validation. This will throw an exception on the first validation failure
validator.validate(resource);
}
// If we make it here with no exception, all the files validated!
//START SNIPPET: validateFiles
}
}

View File

@ -521,7 +521,6 @@
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>${maven_site_plugin_version}</version>
<executions>
<execution>
<id>stage-for-scm-publish</id>

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.testutil;
package ca.uhn.fhir.util;
import java.io.IOException;
import java.net.ServerSocket;
@ -8,10 +8,13 @@ import java.util.List;
/**
* Provides server ports
*/
public class RandomServerPortProvider {
public class PortUtil {
private static List<Integer> ourPorts = new ArrayList<Integer>();
/**
* This is really only used for unit tests but is included in the library so it can be reused across modules. Use with caution.
*/
public static int findFreePort() {
ServerSocket server;
try {

View File

@ -86,12 +86,12 @@
}
tt {
margin-left: 10px;
white-space: pre;
color: #448;
padding: 4px;
margin-bottom: 5px;
margin-top: 10px;
padding: 2px;
border: 1px solid #AAA;
}
h1,h2,h3,h4,h5 {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -4,18 +4,18 @@
<bannerLeft>
<name>HAPI</name>
<src>images/hapi_fhir_banner.png</src>
<href>http://hl7api.sourceforge.net/hapi-fhir/</href>
<href>http://jamesagnew.github.io/hapi-fhir/</href>
</bannerLeft>
<bannerRight>
<name>FHIR</name>
<src>images/hapi_fhir_banner_right.png</src>
<href>http://hl7api.sourceforge.net/hapi-fhir/</href>
<href>http://jamesagnew.github.io/hapi-fhir/</href>
</bannerRight>
<poweredBy>
<logo name="Hosted on SourceForge.net" href="https://sourceforge.net/projects/hl7api/" img="http://sflogo.sourceforge.net/sflogo.php?group_id=38899&amp;type=2" />
<logo name="Built with Maven 2" href="http://maven.apache.org" img="images/logos/maven-feather.png" />
<logo name="Hosted on GitHub" href="https://github.com/jamesagnew/hapi-fhir" img="./images/github-logo-mini.png"/>
<logo name="Built with Maven 3" href="http://maven.apache.org" img="./images/maven-logo-mini.png" />
</poweredBy>
<version position="left" />

View File

@ -103,7 +103,24 @@
</subsection>
</section>
<section name="Examples">
<subsection name="Populating an Observation Resource">
<p>
The following example shows how to create an observation resource containing
a numeric datatype.
</p>
<macro name="snippet">
<param name="id" value="observation" />
<param name="file" value="examples/src/main/java/example/FhirDataModel.java" />
</macro>
</subsection>
</section>
</body>
</document>

View File

@ -108,6 +108,16 @@
</p>
</section>
<section name="Server Request Logging">
<p>
To enable detailed logging of server requests and responses,
an interceptor may be added to the server which logs each transaction. See
<a href="./doc_rest_server_interceptor.html#Logging">Logging Server Requests</a> for more information.
</p>
</section>
</body>

View File

@ -110,6 +110,21 @@
of detail about each incoming request.
</p>
<p>
The following example shows how to register a logging interceptor within
a FHIR RESTful server.
</p>
<macro name="snippet">
<param name="id" value="loggingInterceptor" />
<param name="file" value="examples/src/main/java/example/ServletExamples.java" />
</macro>
<p>
This interceptor will then produce output similar to the following:
</p>
<source><![CDATA[2014-09-04 02:37:30.030 Source[127.0.0.1] Operation[vread Patient/1667/_history/1] UA[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36] Params[?_format=json]
2014-09-04 03:30:00.443 Source[127.0.0.1] Operation[search-type Organization] UA[Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)] Params[]]]></source>
</subsection>
</section>

View File

@ -17,13 +17,13 @@
<p>
HAPI provides a built-in and configurable mechanism for validating resources.
This mechanism is called the <i>Resource Validator</i>.
This mechanism is called the <i>FHIR Validator</i>.
</p>
<subsection name="Background">
<p>
FHIR resource definitions are distributed with a set of XML schema files (XDS)
FHIR resource definitions are distributed with a set of XML schema files (XSD)
as well as a set of XML Schematron (SCH) files. These two sets of files are
complimentary to each other, meaning that in order to claim compliance to the
FHIR specification, your resources must validate against both sets.
@ -60,6 +60,19 @@
</subsection>
<subsection name="Validating a Set of Files">
<p>
The following example shows how to load a set of resources from files
on disk and validate each one.
</p>
<macro name="snippet">
<param name="id" value="validateFiles" />
<param name="file" value="examples/src/main/java/example/ValidatorExamples.java" />
</macro>
</subsection>
</section>
</body>

View File

@ -27,7 +27,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
public class ClientIntegrationTest {
@ -37,7 +37,7 @@ public class ClientIntegrationTest {
@Before
public void before() {
myPort = RandomServerPortProvider.findFreePort();
myPort = PortUtil.findFreePort();
myServer = new Server(myPort);
myPatientProvider = new MyPatientResourceProvider();

View File

@ -25,7 +25,7 @@ import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.ResourceBinding;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
@ -80,7 +80,7 @@ public class InterceptorTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyProvider patientProvider = new DummyProvider();

View File

@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -122,7 +122,7 @@ public class BinaryTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
ResourceProvider patientProvider = new ResourceProvider();

View File

@ -32,7 +32,7 @@ import ca.uhn.fhir.rest.param.CompositeOrListParam;
import ca.uhn.fhir.rest.param.CompositeParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -100,7 +100,7 @@ public class CompositeParameterTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyObservationResourceProvider patientProvider = new DummyObservationResourceProvider();

View File

@ -30,7 +30,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -101,7 +101,7 @@ public class CompressionTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyProvider patientProvider = new DummyProvider();

View File

@ -30,7 +30,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.server.ResfulServerSelfReferenceTest.DummyPatientResourceProvider;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -42,7 +42,7 @@ public class CorsTest {
@Test
public void testContextWithSpace() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
Server server = new Server(port);
RestfulServer restServer = new RestfulServer();

View File

@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -146,7 +146,7 @@ public class CreateTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
PatientProvider patientProvider = new PatientProvider();

View File

@ -30,7 +30,7 @@ import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -134,7 +134,7 @@ public class CustomTypeTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -33,7 +33,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -131,7 +131,7 @@ public class ExceptionTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -29,7 +29,7 @@ import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -119,7 +119,7 @@ public class HistoryTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPlainProvider plainProvider = new DummyPlainProvider();

View File

@ -36,8 +36,8 @@ import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -225,7 +225,7 @@ public class IncludeTest {
public static void beforeClass() throws Exception {
ourCtx = new FhirContext();
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -40,7 +40,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -95,7 +95,7 @@ public class InterceptorTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -68,7 +68,7 @@ public class MethodPriorityTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
ServletHandler proxyHandler = new ServletHandler();

View File

@ -27,7 +27,7 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -167,7 +167,7 @@ public class PagingTest {
public static void beforeClass() throws Exception {
ourContext = new FhirContext();
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -43,7 +43,7 @@ import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
public class PlainProviderTest {
@ -56,7 +56,7 @@ public class PlainProviderTest {
@Before
public void before() throws Exception {
myPort = RandomServerPortProvider.findFreePort();
myPort = PortUtil.findFreePort();
myServer = new Server(myPort);
myCtx = new FhirContext(Patient.class);

View File

@ -26,7 +26,7 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -116,7 +116,7 @@ public class ReadTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyProvider patientProvider = new DummyProvider();

View File

@ -37,7 +37,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -229,7 +229,7 @@ public class ReferenceParameterTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -72,7 +72,7 @@ import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -1001,7 +1001,7 @@ public class ResfulServerMethodTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
ourCtx = new FhirContext(Patient.class);

View File

@ -36,7 +36,7 @@ import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -59,7 +59,7 @@ public class ResfulServerSelfReferenceTest {
@Test
public void testContextWithSpace() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
Server server = new Server(port);
RestfulServer restServer = new RestfulServer();
@ -102,7 +102,7 @@ public class ResfulServerSelfReferenceTest {
@Test
public void testSearchByParamIdentifier() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
Server hServer = new Server(port);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -15,7 +15,7 @@ import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
public class ResourceProviderWithNoMethodsTest {
@ -28,7 +28,7 @@ public class ResourceProviderWithNoMethodsTest {
@Test
public void testNoAnnotatedMethods() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
ourServer = new Server(port);
ResourceProvider patientProvider = new ResourceProvider();
@ -50,7 +50,7 @@ public class ResourceProviderWithNoMethodsTest {
@Test
public void testNonPublicMethod() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
ourServer = new Server(port);
NonPublicMethodProvider patientProvider = new NonPublicMethodProvider();

View File

@ -41,7 +41,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -199,7 +199,7 @@ public class SearchTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -25,7 +25,7 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -51,7 +51,7 @@ public class ServerBaseTest {
@Test
public void testWithContextPath() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
myServer = new Server(port);
DummyProvider patientProvider = new DummyProvider();
@ -85,7 +85,7 @@ public class ServerBaseTest {
@Test
public void testWithContextAndServletPath() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
myServer = new Server(port);
DummyProvider patientProvider = new DummyProvider();
@ -118,7 +118,7 @@ public class ServerBaseTest {
@Test
public void testWithNoPath() throws Exception {
int port = RandomServerPortProvider.findFreePort();
int port = PortUtil.findFreePort();
myServer = new Server(port);
DummyProvider patientProvider = new DummyProvider();

View File

@ -27,7 +27,7 @@ import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
public class ServerExtraParametersTest {
@ -37,7 +37,7 @@ public class ServerExtraParametersTest {
@Before
public void before() {
myPort = RandomServerPortProvider.findFreePort();
myPort = PortUtil.findFreePort();
myServer = new Server(myPort);
ServletHandler proxyHandler = new ServletHandler();

View File

@ -36,7 +36,7 @@ import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -251,7 +251,7 @@ public class ServerFeaturesTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -130,7 +130,7 @@ public class SortTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -26,7 +26,7 @@ import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -148,7 +148,7 @@ public class StringParameterTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -34,7 +34,7 @@ import ca.uhn.fhir.rest.annotation.GetTags;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.TagListParam;
import ca.uhn.fhir.rest.annotation.VersionIdParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -238,7 +238,7 @@ public class TagsServerTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
ourCtx = new FhirContext(Patient.class);

View File

@ -32,7 +32,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -224,7 +224,7 @@ public class TransactionTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyProvider patientProvider = new DummyProvider();

View File

@ -32,7 +32,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -173,7 +173,7 @@ public class TransactionWithBundleParamTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyProvider patientProvider = new DummyProvider();

View File

@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -286,7 +286,7 @@ public class UpdateTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
PatientProvider patientProvider = new PatientProvider();

View File

@ -38,7 +38,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
@ -124,7 +124,7 @@ public class LoggingInterceptorTest {
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();

View File

@ -9,6 +9,7 @@ import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.util.FhirTerser;
@ -18,6 +19,7 @@ public class FhirTerserTest {
public void testGetAllPopulatedChildElementsOfType() {
Patient p = new Patient();
p.setGender(AdministrativeGenderCodesEnum.M);
p.addIdentifier().setSystem("urn:foo");
p.addAddress().addLine("Line1");
p.addAddress().addLine("Line2");

View File

@ -10,6 +10,9 @@
<logger name="org.eclipse" additivity="false" level="info">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.apache" additivity="false" level="info">
<appender-ref ref="STDOUT" />
</logger>
<!--
<logger name="ca.uhn.fhir.rest.client" additivity="false" level="trace">

View File

@ -268,7 +268,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>17.0</version>
<version>${guava_version}</version>
</dependency>
</dependencies>

View File

@ -81,7 +81,7 @@ public class TestRestfulServer extends RestfulServer {
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
loggingInterceptor.setLoggerName("fhirtest.access");
loggingInterceptor.setMessageFormat("Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
registerInterceptor(loggingInterceptor);
this.registerInterceptor(loggingInterceptor);
}

View File

@ -1 +0,0 @@
/target/

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hapi-fhir-mitreid-integration</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -1,528 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-mitreid-integration</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - MitreID Integration Module</name>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.6-SNAPSHOT</version>
</dependency>
<!-- Only required for OpenID Connect Support -->
<dependency>
<groupId>org.mitre</groupId>
<artifactId>openid-connect-client</artifactId>
<version>${mitreid-connect-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<!-- Server -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<version>1.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<!-- UNIT TEST DEPENDENCIES -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest_version}</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring_security_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring_security_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.2.RELEASE</version>
<scope>test</scope>
</dependency>
-->
</dependencies>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changes-plugin</artifactId>
<version>2.10</version>
<inherited>false</inherited>
<reportSets>
<reportSet>
<reports>
<report>changes-report</report>
</reports>
</reportSet>
</reportSets>
<configuration>
<feedType>atom_1.0</feedType>
<issueLinkTemplatePerSystem>
<default>http://sourceforge.net/support/tracker.php?aid=%ISSUE%</default>
<newbugs>https://sourceforge.net/p/hl7api/bugs/%ISSUE%/</newbugs>
<newfeatures>https://sourceforge.net/p/hl7api/feature-requests/%ISSUE%/</newfeatures>
</issueLinkTemplatePerSystem>
<escapeHTML>false</escapeHTML>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.4</version>
<reportSets>
<reportSet>
<id>normal</id>
<reports>
<report>jxr</report>
</reports>
</reportSet>
<reportSet>
<id>restful-server-example</id>
<reports>
<report>jxr</report>
</reports>
<configuration>
<sourcePath>../restful-server-example/src/main/java</sourcePath>
<destDir>${project.reporting.outputDirectory}/rse-xref</destDir>
<outputDirectory>tmp</outputDirectory>
<reportOutputDirectory>rse-xref</reportOutputDirectory>
</configuration>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
<reportSets>
<reportSet>
<reports>
<report>project-team</report>
<report>issue-tracking</report>
<report>license</report>
<report>scm</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-linkcheck-plugin</artifactId> <version>1.1</version> </plugin> -->
</plugins>
</reporting>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<siteMainDirectory>${user.home}/sites/hapi-fhir</siteMainDirectory>
<scmPubCheckoutDirectory>${user.home}/sites/scm/hapi-fhir</scmPubCheckoutDirectory>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>false</skip>
<skipDeploy>true</skipDeploy>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-scm</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-api</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>addSyntaxHighlighter</id>
<phase>site</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>Adding Syntax Highlighter</echo>
<replace dir="target/site" summary="true">
<include name="*.html"></include>
<replacetoken><![CDATA[</body>]]></replacetoken>
<replacevalue><![CDATA[
<script type="text/javascript">
var elements = document.getElementsByClassName("source");
for (var i=0; i < elements.length; i++) {
var pres = elements[i].getElementsByTagName("pre");
for (var j = 0; j < pres.length; j++) {
var pre = pres[j];
if (pre.innerHTML.match(/\/\*/)) {
pre.className = 'brush: java';
} else if (pre.innerHTML.match(/^\/\//)) {
pre.className = 'brush: java';
} else if (pre.innerHTML.match(/^\{/)) {
pre.className = 'brush: jscript';
} else if (pre.innerHTML.match(/^\#/)) {
pre.className = 'brush: bash';
} else if (pre.innerHTML.match(/\&lt\;\//)) {
pre.className = 'brush: xml';
} else {
pre.className = 'brush: java';
}
}
}
SyntaxHighlighter.all();
</script>
</body>
]]></replacevalue>
</replace>
</target>
</configuration>
</execution>
<execution>
<id>addAnalytics</id>
<phase>post-site</phase>
<configuration>
<target>
<echo>Adding Google analytics in target/site for &lt;body&gt;</echo>
<replace dir="target/site" summary="true">
<include name="**/*.html"></include>
<replacefilter token="#build#" value="${label}" />
<replacefilter token="#version#" value="${project.version}" />
<replacetoken><![CDATA[</body>]]></replacetoken>
<replacevalue><![CDATA[
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-1395874-5', 'auto');
ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
</script>
</body >
]]></replacevalue>
</replace>
<echo>Adding Google analytics in target/site for &lt;BODY&gt;</echo>
<replace dir="target/site" summary="true">
<include name="**/*.html"></include>
<replacetoken><![CDATA[</BODY>]]></replacetoken>
<replacevalue><![CDATA[
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-1395874-5', 'auto');
ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
</script>
</BODY >
]]></replacevalue>
</replace>
<echo>Adding social plugins for HAPI</echo>
<replace dir="target/site/" summary="true">
<include name="**/*.html"></include>
<replacetoken><![CDATA[SOCIALPLUGINSHEREFHIR]]></replacetoken>
<replacevalue><![CDATA[
<table cellpadding="0" cellspacing="0" border="0"><tr>
<td><div class="g-plusone" data-annotation="inline" data-width="300" data-href="http://hl7api.sourceforge.net/"></div></td>
<td><div class="fb-like" data-href="http://hl7api.sourceforge.net/" data-send="false" data-layout="button_count" data-width="450" data-show-faces="true"></div></td>
</tr></table>
</p><p>
<!-- Place this tag after the last +1 button tag. -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
]]></replacevalue>
</replace>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<executions>
<execution>
<id>stage-for-scm-publish</id>
<phase>post-site</phase>
<goals>
<goal>stage</goal>
</goals>
<configuration>
<stagingDirectory>${siteMainDirectory}</stagingDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-publish-plugin</artifactId>
<version>1.1</version>
<configuration>
<checkoutDirectory>${scmPubCheckoutDirectory}</checkoutDirectory>
<content>\${siteMainDirectory}</content>
<tryUpdate>true</tryUpdate>
<scmBranch>gh-pages</scmBranch>
<pubScmUrl>scm:git:git@github.com:jamesagnew/hapi-fhir.git</pubScmUrl>
</configuration>
<executions>
<execution>
<id>scm-publish</id>
<phase>site-deploy</phase>
<goals>
<goal>publish-scm</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<!-- <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-scm</artifactId> <version>2.6</version> </extension> <extension> <groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId> <version>1.9</version> </extension> <extension> <groupId>org.apache.maven.scm</groupId> <artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9</version> </extension> </extensions> -->
</build>
<profiles>
<profile>
<id>DIST</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<minmemory>128m</minmemory>
<maxmemory>1g</maxmemory>
<linksource>true</linksource>
<verbose>false</verbose>
<debug>false</debug>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<attach>false</attach>
<descriptors>
<descriptor>${project.basedir}/src/assembly/hapi-fhir-all.xml</descriptor>
<!-- <descriptor>src/assembly/hapi-jdk14.xml</descriptor> -->
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<executions>
<execution>
<id>first</id>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
<configuration>
<licenseName>apache_v2</licenseName>
<canUpdateDescription>true</canUpdateDescription>
<canUpdateCopyright>true</canUpdateCopyright>
<roots>
<root>src/main/java</root>
</roots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -12,6 +12,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>

View File

@ -1,2 +1,2 @@
target/
bin/
/target/
/bin/

151
hapi-fhir-oauth2/pom.xml Normal file
View File

@ -0,0 +1,151 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-oauth2</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - OAUTH2 Support</name>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.6-SNAPSHOT</version>
</dependency>
<!-- Only required for OpenID Connect Support -->
<dependency>
<groupId>org.mitre</groupId>
<artifactId>openid-connect-client</artifactId>
<version>${mitreid-connect-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<!-- Server -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet_api_version}</version>
<scope>provided</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<version>1.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>${jetty_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${jetty_version}</version>
<scope>test</scope>
</dependency>
<!-- UNIT TEST DEPENDENCIES -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest_version}</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring_security_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring_security_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.2.RELEASE</version>
<scope>test</scope>
</dependency>
-->
</dependencies>
<build>
<pluginManagement>
<plugins>
</plugins>
</pluginManagement>
<plugins>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

View File

@ -24,6 +24,7 @@ import java.text.ParseException;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.mitre.jwt.signer.service.impl.JWKSetCacheService;
@ -34,18 +35,22 @@ import org.mitre.openid.connect.client.service.ServerConfigurationService;
import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import ca.uhn.fhir.rest.method.OtherOperationTypeEnum;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class OpenIdConnectBearerTokenSecurityManager implements IResourceSecurity {
public class OpenIdConnectBearerTokenServerInterceptor extends InterceptorAdapter {
private static final String BEARER_PREFIX = "Bearer ";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(OpenIdConnectBearerTokenSecurityManager.class);
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(OpenIdConnectBearerTokenServerInterceptor.class);
@Autowired
private ClientConfigurationService myClientConfigurationService;
@ -54,16 +59,32 @@ public class OpenIdConnectBearerTokenSecurityManager implements IResourceSecurit
private int myTimeSkewAllowance = 300;
private SymmetricCacheService symmetricCacheService;
private JWKSetCacheService validationServices;
private SymmetricCacheService mySymmetricCacheService;
private JWKSetCacheService myValidationServices;
public OpenIdConnectBearerTokenSecurityManager() {
symmetricCacheService = new SymmetricCacheService();
validationServices = new JWKSetCacheService();
public OpenIdConnectBearerTokenServerInterceptor() {
mySymmetricCacheService = new SymmetricCacheService();
myValidationServices = new JWKSetCacheService();
}
@Override
public ISecurityOutcome authenticate(HttpServletRequest theRequest) throws AuthenticationException {
public boolean incomingRequestPostProcessed(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException {
if (theRequestDetails.getOtherOperationType() == OtherOperationTypeEnum.METADATA) {
return true;
}
authenticate(theRequest);
return true;
}
public void authenticate(HttpServletRequest theRequest) throws AuthenticationException {
String token = theRequest.getHeader(Constants.HEADER_AUTHORIZATION);
if (token == null) {
throw new AuthenticationException("Not authorized (no authorization header found in request)");
@ -110,10 +131,10 @@ public class OpenIdConnectBearerTokenSecurityManager implements IResourceSecurit
if (alg.equals(JWSAlgorithm.HS256) || alg.equals(JWSAlgorithm.HS384) || alg.equals(JWSAlgorithm.HS512)) {
// generate one based on client secret
jwtValidator = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient());
jwtValidator = mySymmetricCacheService.getSymmetricValidtor(clientConfig.getClient());
} else {
// otherwise load from the server's public key
jwtValidator = validationServices.getValidator(serverConfig.getJwksUri());
jwtValidator = myValidationServices.getValidator(serverConfig.getJwksUri());
}
if (jwtValidator != null) {
@ -130,8 +151,9 @@ public class OpenIdConnectBearerTokenSecurityManager implements IResourceSecurit
throw new AuthenticationException("Id Token does not have required expiration claim");
} else {
// it's not null, see if it's expired
Date now = new Date(System.currentTimeMillis() - (myTimeSkewAllowance * 1000));
if (now.after(idClaims.getExpirationTime())) {
Date minAllowableExpirationTime = new Date(System.currentTimeMillis() - (myTimeSkewAllowance * 1000L));
Date expirationTime = idClaims.getExpirationTime();
if (!expirationTime.after(minAllowableExpirationTime)) {
throw new AuthenticationException("Id Token is expired: " + idClaims.getExpirationTime());
}
}
@ -155,8 +177,6 @@ public class OpenIdConnectBearerTokenSecurityManager implements IResourceSecurit
}
}
return new ISecurityOutcome() {
};
}
public int getTimeSkewAllowance() {
@ -176,7 +196,7 @@ public class OpenIdConnectBearerTokenSecurityManager implements IResourceSecurit
}
public void setValidationServices(JWKSetCacheService theValidationServices) {
validationServices = theValidationServices;
myValidationServices = theValidationServices;
}
}

View File

@ -0,0 +1,34 @@
package ca.uhn.fhir.rest.server.security;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
public class DummyOpenIdServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DummyOpenIdServlet.class);
@Override
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
ourLog.info("Request: {}", theReq.getRequestURI());
if (theReq.getRequestURI().equals("/openid/jwk")) {
theResp.setStatus(200);
InputStream is = DummyOpenIdServlet.class.getResourceAsStream("/svr_keystore.jwks");
IOUtils.copy(is, theResp.getOutputStream());
IOUtils.closeQuietly(theResp.getOutputStream());
return;
}
super.doGet(theReq, theResp);
}
}

View File

@ -0,0 +1,159 @@
package ca.uhn.fhir.rest.server.security;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mitre.oauth2.model.RegisteredClient;
import org.mitre.openid.connect.client.service.impl.StaticClientConfigurationService;
import org.mitre.openid.connect.client.service.impl.StaticServerConfigurationService;
import org.mitre.openid.connect.config.ServerConfiguration;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class OpenIdConnectBearerTokenServerInterceptorIntegrationTest {
private static CloseableHttpClient ourClient;
private static FhirContext ourCtx = new FhirContext();
private static int ourPort;
private static Server ourServer;
private static OpenIdConnectBearerTokenServerInterceptor myInterceptor;
@Test
public void testSearchWithoutToken() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?");
HttpResponse status = ourClient.execute(httpGet);
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(401, status.getStatusLine().getStatusCode());
}
@Test
public void testSearchWithExpiredToken() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?");
httpGet.addHeader(
"Authorization",
"Bearer "
+ "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MDY4NDE4NTgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0Ojg4ODhcL3Vobi1vcGVuaWQtY29ubmVjdFwvIiwianRpIjoiOTNiMzRjOTUtNTNiMC00YzZmLTkwYjEtYWVjODRjZTc3OGFhIiwiaWF0IjoxNDA2ODM4MjU4fQ.fYtwehPUulUYnDG_10bN6TNf7uw2FNUh_E40YagpITrVfXsV06pjU2YpNgy8nbSFmxY9IBH44UXTmMH9PLFiRn88WsPMSrUQbFCcvGIYwhqkRjGm_J1Y6oWIafUzCwZBCvk4Ne44p3DJRR6FSZRnnC850p55901DGQmNLe-rZJk3t0MHl6wySduqT3K1-Vbuq-7H6xLE10hKpLhSqBTghpQNKNjm48jm0sHcFa3ENWzyWPOmpNfzDKmJAYK2UnBtqNSJP6AJzVrJXqSu-uzasq0VOVcRU4n8b39vU1olbho1eKF0cfQlQwbrtvWipBJJSsRp_tmB9SV9BXhENxOFTw");
HttpResponse status = ourClient.execute(httpGet);
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(401, status.getStatusLine().getStatusCode());
}
@Test
public void testSearchWithValidToken() throws Exception {
myInterceptor.setTimeSkewAllowance(10 * 365 * 24 * 60 * 60);
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?");
httpGet.addHeader(
"Authorization",
"Bearer "
+ "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MDY4NDE4NTgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0Ojg4ODhcL3Vobi1vcGVuaWQtY29ubmVjdFwvIiwianRpIjoiOTNiMzRjOTUtNTNiMC00YzZmLTkwYjEtYWVjODRjZTc3OGFhIiwiaWF0IjoxNDA2ODM4MjU4fQ.fYtwehPUulUYnDG_10bN6TNf7uw2FNUh_E40YagpITrVfXsV06pjU2YpNgy8nbSFmxY9IBH44UXTmMH9PLFiRn88WsPMSrUQbFCcvGIYwhqkRjGm_J1Y6oWIafUzCwZBCvk4Ne44p3DJRR6FSZRnnC850p55901DGQmNLe-rZJk3t0MHl6wySduqT3K1-Vbuq-7H6xLE10hKpLhSqBTghpQNKNjm48jm0sHcFa3ENWzyWPOmpNfzDKmJAYK2UnBtqNSJP6AJzVrJXqSu-uzasq0VOVcRU4n8b39vU1olbho1eKF0cfQlQwbrtvWipBJJSsRp_tmB9SV9BXhENxOFTw");
HttpResponse status = ourClient.execute(httpGet);
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
}
@Before
public void before() {
myInterceptor.setTimeSkewAllowance(10 * 60);
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
ServletHandler proxyHandler = new ServletHandler();
DummyOpenIdServlet openIdServlet = new DummyOpenIdServlet();
ServletHolder proxyHolder = new ServletHolder(openIdServlet);
proxyHandler.addServletWithMapping(proxyHolder, "/openid/*");
RestfulServer servlet = new RestfulServer();
servlet.setResourceProviders(new DummyObservationResourceProvider());
ServletHolder servletHolder = new ServletHolder(servlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");
// DynamicServerConfigurationService s = new DynamicServerConfigurationService();
// s.setWhitelist(new HashSet<String>());
// s.getWhitelist().add("http://localhost:8888/uhn-openid-connect/");
StaticServerConfigurationService srv = new StaticServerConfigurationService();
srv.setServers(new HashMap<String, ServerConfiguration>());
ServerConfiguration srvCfg = new ServerConfiguration();
srvCfg.setJwksUri("http://localhost:" + ourPort + "/openid/jwk");
srvCfg.setIssuer("http://localhost:8888/uhn-openid-connect/");
srv.getServers().put("http://localhost:8888/uhn-openid-connect/", srvCfg);
srv.afterPropertiesSet();
StaticClientConfigurationService cli = new StaticClientConfigurationService();
cli.setClients(new HashMap<String, RegisteredClient>());
cli.getClients().put("http://localhost:8888/uhn-openid-connect/", new RegisteredClient());
myInterceptor = new OpenIdConnectBearerTokenServerInterceptor();
myInterceptor.setClientConfigurationService(cli);
myInterceptor.setServerConfigurationService(srv);
servlet.registerInterceptor(myInterceptor);
ourServer.setHandler(proxyHandler);
ourServer.start();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
}
public static class DummyObservationResourceProvider implements IResourceProvider {
@Override
public Class<? extends IResource> getResourceType() {
return Observation.class;
}
@Search
public Observation search() {
Observation o = new Observation();
o.setId("1");
o.getName().setText("This is an observation");
return o;
}
}
}

View File

@ -20,14 +20,22 @@ import org.mitre.openid.connect.client.service.impl.StaticServerConfigurationSer
import org.mitre.openid.connect.config.ServerConfiguration;
import org.springframework.core.io.ClassPathResource;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
public class OpenIdConnectBearerTokenSecurityManagerTest {
public class OpenIdConnectBearerTokenServerInterceptorTest {
@Test
public void testValidateToken() throws Exception {
StaticServerConfigurationService srv = new StaticServerConfigurationService();
srv.setServers(new HashMap<String, ServerConfiguration>());
ServerConfiguration srvCfg = new ServerConfiguration();
@ -35,38 +43,41 @@ public class OpenIdConnectBearerTokenSecurityManagerTest {
srvCfg.setIssuer("http://localhost:8888/uhn-openid-connect/");
srv.getServers().put("http://localhost:8888/uhn-openid-connect/", srvCfg);
srv.afterPropertiesSet();
StaticClientConfigurationService cli = new StaticClientConfigurationService();
cli.setClients(new HashMap<String, RegisteredClient>());
cli.getClients().put("http://localhost:8888/uhn-openid-connect/", new RegisteredClient());
OpenIdConnectBearerTokenSecurityManager mgr = new OpenIdConnectBearerTokenSecurityManager();
OpenIdConnectBearerTokenServerInterceptor mgr = new OpenIdConnectBearerTokenServerInterceptor();
mgr.setClientConfigurationService(cli);
mgr.setServerConfigurationService(srv);
HttpServletRequest req = mock(HttpServletRequest.class);
when(req.getHeader(Constants.HEADER_AUTHORIZATION)).thenReturn("Bearer " + "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MDY4NDE4NTgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0Ojg4ODhcL3Vobi1vcGVuaWQtY29ubmVjdFwvIiwianRpIjoiOTNiMzRjOTUtNTNiMC00YzZmLTkwYjEtYWVjODRjZTc3OGFhIiwiaWF0IjoxNDA2ODM4MjU4fQ.fYtwehPUulUYnDG_10bN6TNf7uw2FNUh_E40YagpITrVfXsV06pjU2YpNgy8nbSFmxY9IBH44UXTmMH9PLFiRn88WsPMSrUQbFCcvGIYwhqkRjGm_J1Y6oWIafUzCwZBCvk4Ne44p3DJRR6FSZRnnC850p55901DGQmNLe-rZJk3t0MHl6wySduqT3K1-Vbuq-7H6xLE10hKpLhSqBTghpQNKNjm48jm0sHcFa3ENWzyWPOmpNfzDKmJAYK2UnBtqNSJP6AJzVrJXqSu-uzasq0VOVcRU4n8b39vU1olbho1eKF0cfQlQwbrtvWipBJJSsRp_tmB9SV9BXhENxOFTw");
when(req.getHeader(Constants.HEADER_AUTHORIZATION))
.thenReturn(
"Bearer "
+ "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MDY4NDE4NTgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0Ojg4ODhcL3Vobi1vcGVuaWQtY29ubmVjdFwvIiwianRpIjoiOTNiMzRjOTUtNTNiMC00YzZmLTkwYjEtYWVjODRjZTc3OGFhIiwiaWF0IjoxNDA2ODM4MjU4fQ.fYtwehPUulUYnDG_10bN6TNf7uw2FNUh_E40YagpITrVfXsV06pjU2YpNgy8nbSFmxY9IBH44UXTmMH9PLFiRn88WsPMSrUQbFCcvGIYwhqkRjGm_J1Y6oWIafUzCwZBCvk4Ne44p3DJRR6FSZRnnC850p55901DGQmNLe-rZJk3t0MHl6wySduqT3K1-Vbuq-7H6xLE10hKpLhSqBTghpQNKNjm48jm0sHcFa3ENWzyWPOmpNfzDKmJAYK2UnBtqNSJP6AJzVrJXqSu-uzasq0VOVcRU4n8b39vU1olbho1eKF0cfQlQwbrtvWipBJJSsRp_tmB9SV9BXhENxOFTw");
JWKSetCacheService val = mock(JWKSetCacheService.class);
JWKSetKeyStore keyStore = new JWKSetKeyStore();
keyStore.setLocation(new ClassPathResource("/svr_keystore.jwks"));
DefaultJwtSigningAndValidationService valSvc = new DefaultJwtSigningAndValidationService(keyStore);
when(val.getValidator("AAAAAA")).thenReturn(valSvc);
mgr.setValidationServices(val);
try {
mgr.authenticate(req);
fail();
mgr.authenticate(req);
fail();
} catch (AuthenticationException e) {
assertThat(e.getMessage(), StringContains.containsString("expired"));
}
mgr.setTimeSkewAllowance(10 * 365 * 24 * 60);
mgr.setTimeSkewAllowance(10 * 365 * 24 * 60 * 60);
mgr.authenticate(req);
}
}

View File

@ -0,0 +1,24 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.eclipse" additivity="false" level="info">
<appender-ref ref="STDOUT" />
</logger>
<!--
<logger name="ca.uhn.fhir.rest.client" additivity="false" level="trace">
<appender-ref ref="STDOUT" />
</logger>
-->
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -1,15 +1,20 @@
package ca.uhn.fhir.to;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Required;
public class TesterConfig {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TesterConfig.class);
public static final String SYSPROP_FORCE_SERVERS = "ca.uhn.fhir.to.TesterConfig_SYSPROP_FORCE_SERVERS";
private LinkedHashMap<String, String> myIdToServerName = new LinkedHashMap<String, String>();
public LinkedHashMap<String, String> getIdToServerName() {
return myIdToServerName;
}
@ -22,7 +27,17 @@ public class TesterConfig {
@Required
public void setServers(List<String> theServers) {
for (String nextRaw : theServers) {
List<String> servers = theServers;
// This is mostly for unit tests
String force = System.getProperty(SYSPROP_FORCE_SERVERS);
if (StringUtils.isNotBlank(force)) {
ourLog.warn("Forcing server confirguration because of system property: {}", force);
servers = Collections.singletonList(force);
}
for (String nextRaw : servers) {
String[] nextSplit = nextRaw.split(",");
Validate.notBlank(nextSplit[0], "theId can not be blank");
Validate.notBlank(nextSplit[1], "theDisplayName can not be blank");

10
pom.xml
View File

@ -73,6 +73,7 @@
<modules>
<module>hapi-fhir-base</module>
<module>hapi-fhir-oauth2</module>
<module>hapi-fhir-base/examples</module>
<module>hapi-tinder-plugin</module>
<module>hapi-tinder-test</module>
@ -80,13 +81,14 @@
<module>hapi-fhir-jpaserver-base</module>
<module>hapi-fhir-jpaserver-test</module>
<module>restful-server-example</module>
<module>restful-server-example-test</module>
<module>hapi-fhir-testpage-overlay</module>
<module>hapi-fhir-jpaserver-uhnfhirtest</module>
</modules>
<properties>
<commons_lang_version>3.3.2</commons_lang_version>
<derby_version>10.10.2.0</derby_version>
<derby_version>10.11.1.1</derby_version>
<guava_version>18.0</guava_version>
<hamcrest_version>1.3</hamcrest_version>
<hibernate_version>4.2.12.Final</hibernate_version>
@ -94,7 +96,7 @@
<jetty_version>9.2.2.v20140723</jetty_version>
<jscience_version>4.3.1</jscience_version>
<junit_version>4.11</junit_version>
<logback_version>1.1.1</logback_version>
<logback_version>1.1.2</logback_version>
<maven_assembly_plugin_version>2.4.1</maven_assembly_plugin_version>
<maven_javadoc_plugin_version>2.9.1</maven_javadoc_plugin_version>
<maven_license_plugin_version>1.7</maven_license_plugin_version>
@ -105,8 +107,9 @@
<mockito_version>1.9.5</mockito_version>
<phloc_schematron_version>2.7.1</phloc_schematron_version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<servlet_api_version>3.1.0</servlet_api_version>
<slf4j_version>1.7.7</slf4j_version>
<spring_version>4.0.6.RELEASE</spring_version>
<spring_version>4.1.0.RELEASE</spring_version>
<spring_security_version>3.2.4.RELEASE</spring_security_version>
<thymeleaf-version>2.1.3.RELEASE</thymeleaf-version>
<ebay_cors_filter_version>1.0.1</ebay_cors_filter_version>
@ -131,6 +134,7 @@
<version>${maven_surefire_plugin_version}</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>random</runOrder>
</configuration>
</plugin>
<plugin>

View File

@ -11,7 +11,7 @@
<artifactId>restful-server-example-test</artifactId>
<packaging>jar</packaging>
<name>HAPI Tinder Plugin - Test Project</name>
<name>HAPI FHIR Sample RESTful Server - Tests</name>
<dependencies>
<dependency>

View File

@ -23,6 +23,9 @@ public class ExampleTest {
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
System.clearProperty("ca.uhn.fhir.to.TesterConfig_SYSPROP_FORCE_SERVERS");
}
@Test
@ -40,6 +43,9 @@ public class ExampleTest {
ourPort = RandomServerPortProvider.findFreePort();
ourServer = new Server(ourPort);
String base = "http://localhost:" + ourPort+"/fhir";
System.setProperty("ca.uhn.fhir.to.TesterConfig_SYSPROP_FORCE_SERVERS", "example , Restful Server Example , " + base);
WebAppContext root = new WebAppContext();
root.setWar("file:../restful-server-example/target/restful-server-example.war");
@ -54,8 +60,9 @@ public class ExampleTest {
ourServer.start();
ourCtx = new FhirContext();
ourClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort+"/fhir");
ourClient = ourCtx.newRestfulGenericClient(base);
}
}

View File

@ -16,7 +16,7 @@
<version>0.6</version>
<packaging>war</packaging>
<name>Sample RESTful Server (HAPI-FHIR)</name>
<name>HAPI FHIR Sample RESTful Server</name>
<repositories>
<repository>
@ -51,7 +51,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.1</version>
<version>1.1.2</version>
</dependency>
<!-- Needed for JEE/Servlet support -->