Some cleanup and tests before first commit.

This commit is contained in:
markiantorno 2020-04-17 20:17:12 -04:00
parent 9a9de764b4
commit 89250de244
14 changed files with 212 additions and 34 deletions

View File

@ -197,5 +197,4 @@
</plugin>
</plugins>
</build>
</project>

View File

@ -135,7 +135,7 @@ public class Validator {
String v = Common.getVersion(args);
String definitions = VersionUtilities.packageForVersion(v) + "#" + v;
ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog());
ValidatorGui.start(cliContext, validationEngine);
ValidatorGui.start(cliContext, validationEngine, true);
} else if (Params.hasParam(args, Params.TEST)) {
Common.runValidationEngineTests();
} else if (args.length == 0 || Params.hasParam(args, Params.HELP) || Params.hasParam(args, "?") || Params.hasParam(args, "-?") || Params.hasParam(args, "/?")) {

View File

@ -1,6 +1,5 @@
package org.hl7.fhir.validation.cli;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.Javalin;
import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.cli.controller.CliContextController;
@ -22,8 +21,8 @@ public class RestEndpoints {
app.get("/home", myUIController.renderLandingPage);
app.get("/context", myCliContextController.getCurrentCliContext);
app.post("/context", myCliContextController.setCurrentCliContext);
app.get("/context", myCliContextController::handleGetCurrentCliContext);
app.post("/context", myCliContextController::handleSetCurrentCliContext);
app.post("/validate", myValidationController.handleValidationRequest);
}

View File

@ -18,6 +18,8 @@ public class ValidatorGui {
private static final String WEB_APP_FILE_LOCATION = "/public";
private static Javalin app;
private ValidatorGui(){}
/**
* N.B. this entry point, is only for testing. Please start from command line using the argument {@code -gui} for
* actual use.
@ -27,16 +29,18 @@ public class ValidatorGui {
String v = Common.getVersion(args);
String definitions = VersionUtilities.packageForVersion(v) + "#" + v;
ValidationEngine validationEngine = Common.getValidationEngine(v, definitions, cliContext.getTxLog());
start(new CliContext(), validationEngine);
start(new CliContext(), validationEngine, false);
}
public static void start(CliContext currentContext, ValidationEngine validationEngine) {
public static void start(CliContext currentContext, ValidationEngine validationEngine, boolean bootBrowser) {
app = Javalin.create();
new RestEndpoints().initRestEndpoints(app, currentContext, validationEngine);
app.config.addStaticFiles(WEB_APP_FILE_LOCATION);
app.start(GUI_FRONTEND_PORT);
if (bootBrowser) {
openBrowser();
}
}
public static void openBrowser() {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {

View File

@ -1,27 +1,30 @@
package org.hl7.fhir.validation.cli.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.http.Handler;
import io.javalin.http.Context;
import org.apache.http.HttpStatus;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.jetbrains.annotations.NotNull;
public class CliContextController {
private final String JSON_MIME_TYPE = "application/json";
private CliContext myCliContext;
public CliContextController(CliContext cliContext) {
this.myCliContext = cliContext;
}
public Handler getCurrentCliContext = ctx -> {
public void handleGetCurrentCliContext(@NotNull Context ctx) throws JsonProcessingException {
ObjectMapper Obj = new ObjectMapper();
String jsonStr = Obj.writeValueAsString(myCliContext);
ctx.result(jsonStr);
};
ctx.result(jsonStr).contentType(JSON_MIME_TYPE).status(HttpStatus.SC_OK);
}
public Handler setCurrentCliContext = ctx -> {
public void handleSetCurrentCliContext(@NotNull Context ctx) {
myCliContext = ctx.bodyAsClass(CliContext.class);
ctx.status(HttpStatus.SC_CREATED);
};
ctx.status(HttpStatus.SC_OK);
}
}

View File

@ -1,7 +1,9 @@
package org.hl7.fhir.validation.cli.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.http.Context;
import io.javalin.http.Handler;
import org.apache.http.HttpStatus;
import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.cli.model.ValidationRequest;
import org.hl7.fhir.validation.cli.model.ValidationResponse;
@ -15,6 +17,25 @@ public class ValidationController {
this.myValidationEngine = validationEngine;
}
public void handleValidationRequest(Context ctx) {
ValidationRequest request = ctx.bodyAsClass(ValidationRequest.class);
ValidationResponse response = null;
try {
response = ValidationService.validateSources(request, myValidationEngine);
ObjectMapper Obj = new ObjectMapper();
/*
* TODO
* Write file contents to temp files to pass to validator instead of creating our own endpoint.
* Create File => new temp file
* Use Option => DeleteOnShutdown
*/
String jsonStr = Obj.writeValueAsString(response);
ctx.status(200).json(jsonStr);
} catch (Exception e) {
ctx.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).result(e.getLocalizedMessage());
}
}
public Handler handleValidationRequest = ctx -> {
ValidationRequest request = ctx.bodyAsClass(ValidationRequest.class);
ValidationResponse response = ValidationService.validateSources(request, myValidationEngine);

View File

@ -60,7 +60,7 @@ public class CliContext {
private Validator.EngineMode mode = Validator.EngineMode.VALIDATION;
@JsonProperty("locale")
private Locale locale = null;
private String locale = Locale.ENGLISH.getDisplayLanguage();
@JsonProperty("locations")
private Map<String, String> locations = new HashMap<String, String>();
@ -172,21 +172,21 @@ public class CliContext {
@JsonProperty("locale")
public String getLanguageCode() {
return this.locale.getDisplayLanguage();
return locale;
}
public Locale getLocale() {
return locale;
return Locale.forLanguageTag(this.locale);
}
@JsonProperty("locale")
public CliContext setLocale(String languageString) {
this.locale = new Locale(languageString);
this.locale = languageString;
return this;
}
public CliContext setLocale(Locale locale) {
this.locale = locale;
this.locale = locale.getDisplayLanguage();
return this;
}
@ -332,14 +332,18 @@ public class CliContext {
return this;
}
public SnomedVersion getSnomedCT() {
return SnomedVersion.getFromCode(snomedCT);
}
@JsonProperty("snomedCT")
public String getSnomedCT() {
public String getSnomedCTCode() {
return snomedCT;
}
@JsonProperty("snomedCT")
public CliContext setSnomedCT(String snomedCT) {
this.snomedCT = SnomedVersion.resolveSnomedCTCode(snomedCT);
this.snomedCT = snomedCT;
return this;
}
@ -405,4 +409,40 @@ public class CliContext {
", assumeValidRestReferences=" + assumeValidRestReferences +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CliContext that = (CliContext) o;
return doNative == that.doNative &&
anyExtensionsAllowed == that.anyExtensionsAllowed &&
hintAboutNonMustSupport == that.hintAboutNonMustSupport &&
recursive == that.recursive &&
doDebug == that.doDebug &&
assumeValidRestReferences == that.assumeValidRestReferences &&
canDoNative == that.canDoNative &&
Objects.equals(map, that.map) &&
Objects.equals(output, that.output) &&
Objects.equals(txServer, that.txServer) &&
Objects.equals(sv, that.sv) &&
Objects.equals(txLog, that.txLog) &&
Objects.equals(mapLog, that.mapLog) &&
Objects.equals(lang, that.lang) &&
Objects.equals(fhirpath, that.fhirpath) &&
Objects.equals(snomedCT, that.snomedCT) &&
Objects.equals(targetVer, that.targetVer) &&
Objects.equals(igs, that.igs) &&
Objects.equals(questionnaires, that.questionnaires) &&
Objects.equals(profiles, that.profiles) &&
Objects.equals(sources, that.sources) &&
mode == that.mode &&
Objects.equals(locale, that.locale) &&
Objects.equals(locations, that.locations);
}
@Override
public int hashCode() {
return Objects.hash(doNative, anyExtensionsAllowed, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, map, output, txServer, sv, txLog, mapLog, lang, fhirpath, snomedCT, targetVer, igs, questionnaires, profiles, sources, mode, locale, locations);
}
}

View File

@ -178,7 +178,7 @@ public class ValidationService {
validator.setAnyExtensionsAllowed(cliContext.isAnyExtensionsAllowed());
validator.setLanguage(cliContext.getLang());
validator.setLocale(cliContext.getLocale());
validator.setSnomedExtension(cliContext.getSnomedCT());
validator.setSnomedExtension(cliContext.getSnomedCTCode());
validator.setAssumeValidRestReferences(cliContext.isAssumeValidRestReferences());
return validator;
}

View File

@ -1,6 +1,8 @@
package org.hl7.fhir.validation.cli.utils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public enum SnomedVersion {
@ -32,15 +34,15 @@ public enum SnomedVersion {
return code;
}
public static String resolveSnomedCTCode(String s) {
String foundCode;
Optional<SnomedVersion> opt = Arrays.stream(values())
.filter(v -> v.lang.equals(s))
.findFirst();
if (opt.isPresent()) {
return opt.get().code;
} else {
throw new Error("Snomed edition '" + s + "' not known");
public static SnomedVersion getFromCode(String code) {
return lookup.get(code);
}
private static final Map<String, SnomedVersion> lookup = new HashMap<>();
static {
for (SnomedVersion s : SnomedVersion.values()) {
lookup.put(s.getCode(), s);
}
}
}

View File

@ -0,0 +1,36 @@
package org.hl7.fhir.validation.cli;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import java.io.IOException;
public abstract class BaseRestTest {
protected final String JSON_MIME_TYPE = "application/json";
@BeforeAll
public static void startServer() {
ValidatorGui.start(new CliContext(), null, false);
}
@AfterAll
public static void stopServer() {
ValidatorGui.stop();
}
public static <T> T retrieveResourceFromResponse(HttpResponse response, Class<T> clazz)
throws IOException {
String jsonFromResponse = EntityUtils.toString(response.getEntity());
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.readValue(jsonFromResponse, clazz);
}
}

View File

@ -3,6 +3,7 @@ package org.hl7.fhir.validation.cli;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
@ -15,8 +16,9 @@ class ValidatorGuiTest {
private final String HTML_TITLE_TAG = "<title>FHIR HL7 Resrouce Validator GUI</title>";
@Test
@DisplayName("Page boots correctly, and displays index.html")
public void UI_contains_correct_heading() throws IOException {
ValidatorGui.start(new CliContext(), null);
ValidatorGui.start(new CliContext(), null, false);
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");

View File

@ -0,0 +1,47 @@
package org.hl7.fhir.validation.cli.controller;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClientBuilder;
import org.hl7.fhir.validation.cli.BaseRestTest;
import org.hl7.fhir.validation.cli.model.CliContext;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.io.IOException;
class HttpGetContextTest extends BaseRestTest {
private final String GET_CONTEXT_URL = "http://localhost:8080/context";
@Test
@DisplayName("Testing status code on get context endpoint.")
public void testStatus() throws IOException {
HttpUriRequest request = new HttpGet(GET_CONTEXT_URL);
HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
Assertions.assertEquals(httpResponse.getStatusLine().getStatusCode(), HttpStatus.SC_OK);
}
@Test
@DisplayName("Testing media type on get context endpoint.")
public void testMediaType() throws IOException {
HttpUriRequest request = new HttpGet(GET_CONTEXT_URL);
HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
String mimeType = ContentType.getOrDefault(httpResponse.getEntity()).getMimeType();
Assertions.assertEquals(JSON_MIME_TYPE, mimeType );
}
@Test
@DisplayName("Testing status code on get context endpoint.")
public void testJSONPayload() throws IOException {
HttpUriRequest request = new HttpGet(GET_CONTEXT_URL);
HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
CliContext resource = retrieveResourceFromResponse(httpResponse, CliContext.class);
Assertions.assertEquals(new CliContext(), resource);
}
}

View File

@ -0,0 +1,24 @@
package org.hl7.fhir.validation.cli.controller;
import io.javalin.http.Context;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
class HttpPutContextTest {
public CliContextController myCliContextController;
public HttpPutContextTest() {
this.myCliContextController = new CliContextController(null);
}
@Test
void handleSetCurrentCliContext() {
Context context = mock(Context.class);
this.myCliContextController.handleSetCurrentCliContext(context);
verify(context).status(200);
}
}