mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-03-09 14:33:32 +00:00
Refactor CLI to merge both CLI command frameworks
This commit is contained in:
parent
92dc0d42ee
commit
d85efbaa5b
@ -47,7 +47,12 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>classes</classifier>
|
<classifier>classes</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
<version>1.14</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||||
@ -232,7 +237,6 @@
|
|||||||
<artifactItem>
|
<artifactItem>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-cli-jpaserver</artifactId>
|
<artifactId>hapi-fhir-cli-jpaserver</artifactId>
|
||||||
<!--<version>1.5-SNAPSHOT</version>-->
|
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
<overWrite>true</overWrite>
|
<overWrite>true</overWrite>
|
||||||
<outputDirectory>target/classes</outputDirectory>
|
<outputDirectory>target/classes</outputDirectory>
|
||||||
@ -283,35 +287,6 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.eclipse.m2e</groupId>
|
|
||||||
<artifactId>lifecycle-mapping</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
<configuration>
|
|
||||||
<lifecycleMappingMetadata>
|
|
||||||
<pluginExecutions>
|
|
||||||
<pluginExecution>
|
|
||||||
<pluginExecutionFilter>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<versionRange>[2.10,)</versionRange>
|
|
||||||
<goals>
|
|
||||||
<goal>copy</goal>
|
|
||||||
</goals>
|
|
||||||
</pluginExecutionFilter>
|
|
||||||
<action>
|
|
||||||
<ignore></ignore>
|
|
||||||
</action>
|
|
||||||
</pluginExecution>
|
|
||||||
</pluginExecutions>
|
|
||||||
</lifecycleMappingMetadata>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,220 +1,25 @@
|
|||||||
package ca.uhn.fhir.cli;
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
import static org.fusesource.jansi.Ansi.ansi;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
|
||||||
import org.apache.commons.cli.DefaultParser;
|
|
||||||
import org.apache.commons.cli.HelpFormatter;
|
|
||||||
import org.apache.commons.cli.Options;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
|
||||||
import org.fusesource.jansi.Ansi;
|
|
||||||
import org.fusesource.jansi.Ansi.Color;
|
|
||||||
import org.fusesource.jansi.AnsiConsole;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.phloc.commons.io.file.FileUtils;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.util.VersionUtil;
|
import ca.uhn.fhir.util.VersionUtil;
|
||||||
import ch.qos.logback.classic.LoggerContext;
|
|
||||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
|
||||||
import ch.qos.logback.core.joran.spi.JoranException;
|
|
||||||
|
|
||||||
public class App {
|
public class App extends BaseApp {
|
||||||
private static List<BaseCommand> ourCommands;
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(App.class);
|
|
||||||
|
|
||||||
public static final String LINESEP = System.getProperty("line.separator");
|
@Override
|
||||||
|
protected String provideCommandName() {
|
||||||
static {
|
return "hapi-fhir-cli";
|
||||||
ourCommands = new ArrayList<BaseCommand>();
|
|
||||||
ourCommands.add(new RunServerCommand());
|
|
||||||
ourCommands.add(new ExampleDataUploader());
|
|
||||||
ourCommands.add(new ValidateCommand());
|
|
||||||
ourCommands.add(new ValidationDataUploader());
|
|
||||||
ourCommands.add(new WebsocketSubscribeCommand());
|
|
||||||
ourCommands.add(new UploadTerminologyCommand());
|
|
||||||
ourCommands.add(new IgPackUploader());
|
|
||||||
|
|
||||||
Collections.sort(ourCommands);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void logCommandUsage(BaseCommand theCommand) {
|
@Override
|
||||||
logAppHeader();
|
protected String provideProductName() {
|
||||||
|
return "HAPI FHIR";
|
||||||
logCommandUsageNoHeader(theCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void logCommandUsageNoHeader(BaseCommand theCommand) {
|
@Override
|
||||||
System.out.println("Usage:");
|
protected String provideProductVersion() {
|
||||||
System.out.println(" hapi-fhir-cli " + theCommand.getCommandName() + " [options]");
|
return VersionUtil.getVersion();
|
||||||
System.out.println();
|
|
||||||
System.out.println("Options:");
|
|
||||||
|
|
||||||
HelpFormatter fmt = new HelpFormatter();
|
|
||||||
PrintWriter pw = new PrintWriter(System.out);
|
|
||||||
fmt.printOptions(pw, 80, theCommand.getOptions(), 2, 2);
|
|
||||||
pw.flush();
|
|
||||||
pw.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loggingConfigOff() {
|
|
||||||
try {
|
|
||||||
JoranConfigurator configurator = new JoranConfigurator();
|
|
||||||
configurator.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
|
|
||||||
((LoggerContext) LoggerFactory.getILoggerFactory()).reset();
|
|
||||||
configurator.doConfigure(App.class.getResourceAsStream("/logback-cli-off.xml"));
|
|
||||||
} catch (JoranException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loggingConfigOn() {
|
|
||||||
try {
|
|
||||||
JoranConfigurator configurator = new JoranConfigurator();
|
|
||||||
configurator.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
|
|
||||||
((LoggerContext) LoggerFactory.getILoggerFactory()).reset();
|
|
||||||
configurator.doConfigure(App.class.getResourceAsStream("/logback-cli-on.xml"));
|
|
||||||
} catch (JoranException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void logUsage() {
|
|
||||||
logAppHeader();
|
|
||||||
System.out.println("Usage:");
|
|
||||||
System.out.println(" hapi-fhir-cli {command} [options]");
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("Commands:");
|
|
||||||
|
|
||||||
int longestCommandLength = 0;
|
|
||||||
for (BaseCommand next : ourCommands) {
|
|
||||||
longestCommandLength = Math.max(longestCommandLength, next.getCommandName().length());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (BaseCommand next : ourCommands) {
|
|
||||||
String left = " " + StringUtils.rightPad(next.getCommandName(), longestCommandLength);
|
|
||||||
String[] rightParts = WordUtils.wrap(next.getCommandDescription(), 80 - (left.length() + 3)).split("\\n");
|
|
||||||
for (int i = 1; i < rightParts.length; i++) {
|
|
||||||
rightParts[i] = StringUtils.leftPad("", left.length() + 3) + rightParts[i];
|
|
||||||
}
|
|
||||||
System.out.println(ansi().bold().fg(Color.GREEN) + left + ansi().boldOff().fg(Color.WHITE) + " - " + ansi().bold() + StringUtils.join(rightParts, LINESEP));
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
System.out.println(ansi().boldOff().fg(Color.WHITE) + "See what options are available:");
|
|
||||||
System.out.println(" hapi-fhir-cli help {command}");
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void logAppHeader() {
|
|
||||||
System.out.flush();
|
|
||||||
System.out.println("------------------------------------------------------------");
|
|
||||||
System.out.println("\ud83d\udd25 " + ansi().bold() + "HAPI FHIR" + ansi().boldOff() + " " + VersionUtil.getVersion() + " - Command Line Tool");
|
|
||||||
System.out.println("------------------------------------------------------------");
|
|
||||||
System.out.println("Max configured JVM memory (Xmx): " + FileUtils.getFileSizeDisplay(Runtime.getRuntime().maxMemory(), 1));
|
|
||||||
System.out.println("Detected Java version: " + System.getProperty("java.version"));
|
|
||||||
System.out.println("------------------------------------------------------------");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) {
|
public static void main(String[] theArgs) {
|
||||||
loggingConfigOff();
|
new App().run(theArgs);
|
||||||
AnsiConsole.systemInstall();
|
|
||||||
|
|
||||||
// log version while the logging is off
|
|
||||||
VersionUtil.getVersion();
|
|
||||||
|
|
||||||
if (theArgs.length == 0) {
|
|
||||||
logUsage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theArgs[0].equals("help")) {
|
|
||||||
if (theArgs.length < 2) {
|
|
||||||
logUsage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BaseCommand command = null;
|
|
||||||
for (BaseCommand nextCommand : ourCommands) {
|
|
||||||
if (nextCommand.getCommandName().equals(theArgs[1])) {
|
|
||||||
command = nextCommand;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (command == null) {
|
|
||||||
System.err.println("Unknown command: " + theArgs[1]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
logCommandUsage(command);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseCommand command = null;
|
|
||||||
for (BaseCommand nextCommand : ourCommands) {
|
|
||||||
if (nextCommand.getCommandName().equals(theArgs[0])) {
|
|
||||||
command = nextCommand;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command == null) {
|
|
||||||
System.out.println("Unrecognized command: " + ansi().bold().fg(Color.RED) + theArgs[0] + ansi().boldOff().fg(Ansi.Color.WHITE));
|
|
||||||
System.out.println();
|
|
||||||
logUsage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Options options = command.getOptions();
|
|
||||||
DefaultParser parser = new DefaultParser();
|
|
||||||
CommandLine parsedOptions;
|
|
||||||
|
|
||||||
logAppHeader();
|
|
||||||
validateJavaVersion();
|
|
||||||
loggingConfigOn();
|
|
||||||
|
|
||||||
try {
|
|
||||||
String[] args = Arrays.asList(theArgs).subList(1, theArgs.length).toArray(new String[theArgs.length - 1]);
|
|
||||||
parsedOptions = parser.parse(options, args, true);
|
|
||||||
if (parsedOptions.getArgList().isEmpty()==false) {
|
|
||||||
throw new ParseException("Unrecognized argument: " + parsedOptions.getArgList().get(0).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually execute the command
|
|
||||||
command.run(parsedOptions);
|
|
||||||
|
|
||||||
} catch (ParseException e) {
|
|
||||||
loggingConfigOff();
|
|
||||||
System.err.println("Invalid command options for command: " + command.getCommandName());
|
|
||||||
System.err.println(" " + ansi().fg(Color.RED).bold() + e.getMessage());
|
|
||||||
System.err.println("" + ansi().fg(Color.WHITE).boldOff());
|
|
||||||
logCommandUsageNoHeader(command);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (CommandFailureException e) {
|
|
||||||
ourLog.error(e.getMessage());
|
|
||||||
System.exit(1);
|
|
||||||
} catch (Exception e) {
|
|
||||||
ourLog.error("Error during execution: ", e);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateJavaVersion() {
|
|
||||||
String specVersion = System.getProperty("java.specification.version");
|
|
||||||
double version = Double.parseDouble(specVersion);
|
|
||||||
if (version < 1.8) {
|
|
||||||
System.err.flush();
|
|
||||||
System.err.println("HAPI-CLI requires Java 1.8+ to run (detected " + specVersion + ")");
|
|
||||||
System.err.println("Note that the HAPI library requires only Java 1.6, but you must install");
|
|
||||||
System.err.println("a newer JVM in order to use the HAPI CLI tool.");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,256 @@
|
|||||||
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.VersionUtil;
|
||||||
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
|
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||||
|
import ch.qos.logback.core.joran.spi.JoranException;
|
||||||
|
import com.phloc.commons.io.file.FileUtils;
|
||||||
|
import org.apache.commons.cli.*;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
|
import org.fusesource.jansi.Ansi;
|
||||||
|
import org.fusesource.jansi.AnsiConsole;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.fusesource.jansi.Ansi.ansi;
|
||||||
|
|
||||||
|
public abstract class BaseApp {
|
||||||
|
public static final String STACKFILTER_PATTERN = "%xEx{full, sun.reflect, org.junit, org.eclipse, java.lang.reflect.Method, org.springframework, org.hibernate, com.sun.proxy, org.attoparser, org.thymeleaf}";
|
||||||
|
public static final String STACKFILTER_PATTERN_PROP = "log.stackfilter.pattern";
|
||||||
|
public static final String LINESEP = System.getProperty("line.separator");
|
||||||
|
protected static final org.slf4j.Logger ourLog;
|
||||||
|
private static List<BaseCommand> ourCommands;
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.setProperty(STACKFILTER_PATTERN_PROP, STACKFILTER_PATTERN);
|
||||||
|
loggingConfigOff();
|
||||||
|
|
||||||
|
// We don't use qualified names for loggers in CLI
|
||||||
|
ourLog = LoggerFactory.getLogger(App.class.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logAppHeader() {
|
||||||
|
System.out.flush();
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println("\ud83d\udd25 " + ansi().bold() + " " + provideProductName() + ansi().boldOff() + " " + provideProductVersion() + " - Command Line Tool");
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println("Max configured JVM memory (Xmx): " + FileUtils.getFileSizeDisplay(Runtime.getRuntime().maxMemory(), 1));
|
||||||
|
System.out.println("Detected Java version: " + System.getProperty("java.version"));
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logCommandUsage(BaseCommand theCommand) {
|
||||||
|
logAppHeader();
|
||||||
|
|
||||||
|
logCommandUsageNoHeader(theCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logCommandUsageNoHeader(BaseCommand theCommand) {
|
||||||
|
System.out.println("Usage:");
|
||||||
|
System.out.println(" " + provideCommandName() + " " + theCommand.getCommandName() + " [options]");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("Options:");
|
||||||
|
|
||||||
|
// This is passed in from the launch script
|
||||||
|
String columnsString = System.getProperty("columns");
|
||||||
|
int columns;
|
||||||
|
try {
|
||||||
|
columns = Integer.parseInt(columnsString);
|
||||||
|
columns = Math.max(columns, 40);
|
||||||
|
columns = Math.min(columns, 180);
|
||||||
|
} catch (Exception e) {
|
||||||
|
columns = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpFormatter fmt = new HelpFormatter();
|
||||||
|
PrintWriter pw = new PrintWriter(System.out);
|
||||||
|
fmt.printOptions(pw, columns, theCommand.getOptions(), 2, 2);
|
||||||
|
pw.flush();
|
||||||
|
pw.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logUsage() {
|
||||||
|
logAppHeader();
|
||||||
|
System.out.println("Usage:");
|
||||||
|
System.out.println(" " + provideCommandName() + " {command} [options]");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("Commands:");
|
||||||
|
|
||||||
|
int longestCommandLength = 0;
|
||||||
|
for (BaseCommand next : ourCommands) {
|
||||||
|
longestCommandLength = Math.max(longestCommandLength, next.getCommandName().length());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BaseCommand next : ourCommands) {
|
||||||
|
String left = " " + StringUtils.rightPad(next.getCommandName(), longestCommandLength);
|
||||||
|
String[] rightParts = WordUtils.wrap(next.getCommandDescription(), 80 - (left.length() + 3)).split("\\n");
|
||||||
|
for (int i = 1; i < rightParts.length; i++) {
|
||||||
|
rightParts[i] = StringUtils.leftPad("", left.length() + 3) + rightParts[i];
|
||||||
|
}
|
||||||
|
System.out.println(ansi().bold().fg(Ansi.Color.GREEN) + left + ansi().boldOff().fg(Ansi.Color.WHITE) + " - " + ansi().bold() + StringUtils.join(rightParts, LINESEP));
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
System.out.println(ansi().boldOff().fg(Ansi.Color.WHITE) + "See what options are available:");
|
||||||
|
System.out.println(" " + provideCommandName() + " help {command}");
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String provideCommandName();
|
||||||
|
|
||||||
|
public List<BaseCommand> provideCommands() {
|
||||||
|
ArrayList<BaseCommand> commands = new ArrayList<>();
|
||||||
|
commands.add(new RunServerCommand());
|
||||||
|
commands.add(new ExampleDataUploader());
|
||||||
|
commands.add(new ValidateCommand());
|
||||||
|
commands.add(new ValidationDataUploader());
|
||||||
|
commands.add(new WebsocketSubscribeCommand());
|
||||||
|
commands.add(new UploadTerminologyCommand());
|
||||||
|
commands.add(new IgPackUploader());
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String provideProductName();
|
||||||
|
|
||||||
|
protected abstract String provideProductVersion();
|
||||||
|
|
||||||
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
public void run(String[] theArgs) {
|
||||||
|
loggingConfigOff();
|
||||||
|
validateJavaVersion();
|
||||||
|
|
||||||
|
AnsiConsole.systemInstall();
|
||||||
|
|
||||||
|
// log version while the logging is off
|
||||||
|
VersionUtil.getVersion();
|
||||||
|
|
||||||
|
// Set up command list
|
||||||
|
ourCommands = new ArrayList<>();
|
||||||
|
ourCommands.addAll(provideCommands());
|
||||||
|
Collections.sort(ourCommands);
|
||||||
|
|
||||||
|
|
||||||
|
if (theArgs.length == 0) {
|
||||||
|
logUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theArgs[0].equals("help")) {
|
||||||
|
if (theArgs.length < 2) {
|
||||||
|
logUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BaseCommand command = null;
|
||||||
|
for (BaseCommand nextCommand : ourCommands) {
|
||||||
|
if (nextCommand.getCommandName().equals(theArgs[1])) {
|
||||||
|
command = nextCommand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (command == null) {
|
||||||
|
System.err.println("Unknown command: " + theArgs[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logCommandUsage(command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseCommand command = null;
|
||||||
|
for (BaseCommand nextCommand : ourCommands) {
|
||||||
|
if (nextCommand.getCommandName().equals(theArgs[0])) {
|
||||||
|
command = nextCommand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == null) {
|
||||||
|
System.out.println("Unrecognized command: " + ansi().bold().fg(Ansi.Color.RED) + theArgs[0] + ansi().boldOff().fg(Ansi.Color.WHITE));
|
||||||
|
System.out.println();
|
||||||
|
logUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Options options = command.getOptions();
|
||||||
|
DefaultParser parser = new DefaultParser();
|
||||||
|
CommandLine parsedOptions;
|
||||||
|
|
||||||
|
logAppHeader();
|
||||||
|
validateJavaVersion();
|
||||||
|
loggingConfigOn();
|
||||||
|
|
||||||
|
try {
|
||||||
|
String[] args = Arrays.copyOfRange(theArgs, 1, theArgs.length);
|
||||||
|
parsedOptions = parser.parse(options, args, true);
|
||||||
|
if (!parsedOptions.getArgList().isEmpty()) {
|
||||||
|
throw new ParseException("Unrecognized argument: " + parsedOptions.getArgList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually execute the command
|
||||||
|
command.run(parsedOptions);
|
||||||
|
|
||||||
|
if (!"true".equals(System.getProperty("test"))) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ParseException e) {
|
||||||
|
loggingConfigOff();
|
||||||
|
System.err.println("Invalid command options for command: " + command.getCommandName());
|
||||||
|
System.err.println(" " + ansi().fg(Ansi.Color.RED).bold() + e.getMessage());
|
||||||
|
System.err.println("" + ansi().fg(Ansi.Color.WHITE).boldOff());
|
||||||
|
logCommandUsageNoHeader(command);
|
||||||
|
System.exit(1);
|
||||||
|
} catch (CommandFailureException e) {
|
||||||
|
ourLog.error(e.getMessage());
|
||||||
|
if ("true".equals(System.getProperty("test"))) {
|
||||||
|
throw e;
|
||||||
|
} else {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
ourLog.error("Error during execution: ", e);
|
||||||
|
if ("true".equals(System.getProperty("test"))) {
|
||||||
|
throw new CommandFailureException("Error: " + e.toString(), e);
|
||||||
|
} else {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateJavaVersion() {
|
||||||
|
String specVersion = System.getProperty("java.specification.version");
|
||||||
|
double version = Double.parseDouble(specVersion);
|
||||||
|
if (version < 1.8) {
|
||||||
|
System.err.flush();
|
||||||
|
System.err.println(provideProductName() + " requires Java 1.8+ to run (detected " + specVersion + ")");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loggingConfigOff() {
|
||||||
|
try {
|
||||||
|
JoranConfigurator configurator = new JoranConfigurator();
|
||||||
|
configurator.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
|
||||||
|
configurator.doConfigure(App.class.getResourceAsStream("/logback-cli-off.xml"));
|
||||||
|
} catch (JoranException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loggingConfigOn() {
|
||||||
|
try {
|
||||||
|
JoranConfigurator configurator = new JoranConfigurator();
|
||||||
|
configurator.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
|
||||||
|
((LoggerContext) LoggerFactory.getILoggerFactory()).reset();
|
||||||
|
configurator.doConfigure(App.class.getResourceAsStream("/logback-cli-on.xml"));
|
||||||
|
} catch (JoranException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -2,11 +2,15 @@ package ca.uhn.fhir.cli;
|
|||||||
|
|
||||||
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.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
|
import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor;
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.Option;
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@ -16,21 +20,28 @@ import org.apache.http.client.methods.HttpGet;
|
|||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.Base64Utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileOutputStream;
|
import java.util.Arrays;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
public abstract class BaseCommand implements Comparable<BaseCommand> {
|
public abstract class BaseCommand implements Comparable<BaseCommand> {
|
||||||
|
public static final String BASE_URL_PARAM = "t";
|
||||||
private static final String SPEC_DEFAULT_VERSION = "dstu3";
|
public static final String BASIC_AUTH_OPTION = "b";
|
||||||
|
public static final String BASIC_AUTH_LONGOPT = "basic-auth";
|
||||||
|
public static final String BEARER_TOKEN_LONGOPT = "bearer-token";
|
||||||
|
public static final String FHIR_VERSION_OPTION = "v";
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(BaseCommand.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(BaseCommand.class);
|
||||||
private FhirContext myFhirCtx;
|
private FhirContext myFhirCtx;
|
||||||
|
|
||||||
@ -38,10 +49,57 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void addBasicAuthOption(Options theOptions) {
|
||||||
|
addOptionalOption(theOptions, BASIC_AUTH_OPTION, BASIC_AUTH_LONGOPT, true, "If specified, this parameter supplies a username and password (in the format \"username:password\") to include in an HTTP Basic Auth header");
|
||||||
|
addOptionalOption(theOptions, null, BEARER_TOKEN_LONGOPT, true, "If specified, this parameter supplies a Bearer Token to supply with the request");
|
||||||
|
}
|
||||||
|
|
||||||
protected void addFhirVersionOption(Options theOptions) {
|
protected void addFhirVersionOption(Options theOptions) {
|
||||||
Option opt = new Option("f", "fhirversion", true, "Spec version to upload (default is '" + SPEC_DEFAULT_VERSION + "')");
|
String versions = Arrays.stream(FhirVersionEnum.values())
|
||||||
opt.setRequired(false);
|
.filter(t -> t != FhirVersionEnum.DSTU2_1 && t != FhirVersionEnum.DSTU2_HL7ORG)
|
||||||
theOptions.addOption(opt);
|
.map(t -> t.name().toLowerCase())
|
||||||
|
.sorted()
|
||||||
|
.collect(Collectors.joining(", "));
|
||||||
|
addRequiredOption(theOptions, FHIR_VERSION_OPTION, "fhir-version", "version", "The FHIR version being used. Valid values: " + versions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addOption(Options theOptions, boolean theRequired, String theOpt, String theLong, boolean theHasArgument, String theArgumentName, String theDescription) {
|
||||||
|
Option option = new Option(theOpt, theLong, theHasArgument, theDescription);
|
||||||
|
option.setRequired(theRequired);
|
||||||
|
if (theHasArgument && isNotBlank(theArgumentName)) {
|
||||||
|
option.setArgName(theArgumentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotBlank(theOpt)) {
|
||||||
|
if (theOptions.getOption(theOpt) != null) {
|
||||||
|
throw new IllegalStateException("Duplicate option: " + theOpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isNotBlank(theLong)) {
|
||||||
|
if (theOptions.getOption(theLong) != null) {
|
||||||
|
throw new IllegalStateException("Duplicate option: " + theLong);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
theOptions.addOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addOptionalOption(Options theOptions, String theOpt, String theLong, boolean theTakesArgument, String theDescription) {
|
||||||
|
addOption(theOptions, false, theOpt, theLong, theTakesArgument, null, theDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addOptionalOption(Options theOptions, String theOpt, String theLong, String theArgumentName, String theDescription) {
|
||||||
|
addOption(theOptions, false, theOpt, theLong, isNotBlank(theArgumentName), theArgumentName, theDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addRequiredOption(Options theOptions, String theOpt, String theLong, boolean theTakesArgument, String theDescription) {
|
||||||
|
addOption(theOptions, true, theOpt, theLong, theTakesArgument, null, theDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addRequiredOption(Options theOptions, String theOpt, String theLong, String theArgumentName, String theDescription) {
|
||||||
|
boolean hasArgument = isNotBlank(theArgumentName);
|
||||||
|
boolean required = true;
|
||||||
|
addOption(theOptions, required, theOpt, theLong, hasArgument, theArgumentName, theDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,6 +107,18 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||||||
return getCommandName().compareTo(theO.getCommandName());
|
return getCommandName().compareTo(theO.getCommandName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Reader createReader(File theInputFile) throws IOException {
|
||||||
|
InputStream inputStream = new FileInputStream(theInputFile);
|
||||||
|
if (theInputFile.getName().toLowerCase().endsWith(".gz")) {
|
||||||
|
inputStream = new GZIPInputStream(inputStream);
|
||||||
|
}
|
||||||
|
if (theInputFile.getName().toLowerCase().endsWith(".bz2")) {
|
||||||
|
inputStream = new BZip2CompressorInputStream(inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
private void downloadFileFromInternet(CloseableHttpResponse result, File localFile) throws IOException {
|
private void downloadFileFromInternet(CloseableHttpResponse result, File localFile) throws IOException {
|
||||||
FileOutputStream buffer = FileUtils.openOutputStream(localFile);
|
FileOutputStream buffer = FileUtils.openOutputStream(localFile);
|
||||||
try {
|
try {
|
||||||
@ -88,40 +158,73 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the complete authorization header value using the "-b" option
|
||||||
|
*/
|
||||||
|
protected String getAndParseOptionBasicAuthHeader(CommandLine theCommandLine) {
|
||||||
|
return getAndParseOptionBasicAuthHeader(theCommandLine, BASIC_AUTH_OPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the complete authorization header value using an arbitrary option
|
||||||
|
*/
|
||||||
|
protected String getAndParseOptionBasicAuthHeader(CommandLine theCommandLine, String theOptionName) {
|
||||||
|
String basicAuthHeaderValue = null;
|
||||||
|
if (theCommandLine.hasOption(theOptionName)) {
|
||||||
|
byte[] basicAuth = theCommandLine.getOptionValue(theOptionName).getBytes();
|
||||||
|
String base64EncodedBasicAuth = Base64Utils.encodeToString(basicAuth);
|
||||||
|
basicAuthHeaderValue = Constants.HEADER_AUTHORIZATION_VALPREFIX_BASIC + base64EncodedBasicAuth;
|
||||||
|
} else {
|
||||||
|
basicAuthHeaderValue = null;
|
||||||
|
}
|
||||||
|
return basicAuthHeaderValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Enum> T getAndParseOptionEnum(CommandLine theCommandLine, String theOption, Class<T> theEnumClass, T theDefault) throws ParseException {
|
||||||
|
String val = theCommandLine.getOptionValue(theOption);
|
||||||
|
if (isBlank(val)) {
|
||||||
|
return theDefault;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return (T) Enum.valueOf(theEnumClass, val);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ParseException("Invalid option \"" + val + "\" for option -" + theOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAndParsePositiveIntegerParam(CommandLine theCommandLine, String theName) throws ParseException {
|
||||||
|
String value = theCommandLine.getOptionValue(theName);
|
||||||
|
value = trim(value);
|
||||||
|
if (isBlank(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int valueInt = Integer.parseInt(value);
|
||||||
|
if (valueInt < 1) {
|
||||||
|
throw new ParseException("Value for argument " + theName + " must be a positive integer, got: " + value);
|
||||||
|
}
|
||||||
|
return valueInt;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ParseException("Value for argument " + theName + " must be a positive integer, got: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends IBaseBundle> getBundleTypeForFhirVersion() {
|
||||||
|
return getFhirContext().getResourceDefinition("Bundle").getImplementingClass(IBaseBundle.class);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String getCommandDescription();
|
public abstract String getCommandDescription();
|
||||||
|
|
||||||
public abstract String getCommandName();
|
public abstract String getCommandName();
|
||||||
|
|
||||||
public abstract Options getOptions();
|
protected FhirContext getFhirContext() {
|
||||||
|
|
||||||
protected FhirContext getSpecVersionContext(CommandLine theCommandLine) throws ParseException {
|
|
||||||
if (myFhirCtx == null) {
|
|
||||||
String specVersion = theCommandLine.getOptionValue("f", SPEC_DEFAULT_VERSION);
|
|
||||||
specVersion = specVersion.toLowerCase();
|
|
||||||
FhirVersionEnum version;
|
|
||||||
if ("dstu2".equals(specVersion)) {
|
|
||||||
version = FhirVersionEnum.DSTU2;
|
|
||||||
} else if ("dstu3".equals(specVersion)) {
|
|
||||||
version = FhirVersionEnum.DSTU3;
|
|
||||||
} else if ("r4".equals(specVersion)) {
|
|
||||||
version = FhirVersionEnum.R4;
|
|
||||||
} else {
|
|
||||||
throw new ParseException("Unknown spec version: " + specVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
myFhirCtx = new FhirContext(version);
|
|
||||||
}
|
|
||||||
return myFhirCtx;
|
return myFhirCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public FhirContext getFhirCtx() {
|
public abstract Options getOptions();
|
||||||
// if (myFhirCtx == null) {
|
|
||||||
// myFhirCtx = FhirContext.forDstu2();
|
|
||||||
// }
|
|
||||||
// return myFhirCtx;
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected Collection<File> loadFile(FhirContext theCtx, String theSpecUrl, String theFilepath, boolean theCacheFile) throws IOException {
|
protected Collection<File> loadFile(String theSpecUrl, String theFilepath, boolean theCacheFile) throws IOException {
|
||||||
String userHomeDir = System.getProperty("user.home");
|
String userHomeDir = System.getProperty("user.home");
|
||||||
|
|
||||||
File applicationDir = new File(userHomeDir + File.separator + "." + "hapi-fhir-cli");
|
File applicationDir = new File(userHomeDir + File.separator + "." + "hapi-fhir-cli");
|
||||||
@ -138,7 +241,7 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||||||
File suppliedFile = new File(FilenameUtils.normalize(theFilepath));
|
File suppliedFile = new File(FilenameUtils.normalize(theFilepath));
|
||||||
|
|
||||||
if (suppliedFile.isDirectory()) {
|
if (suppliedFile.isDirectory()) {
|
||||||
inputFiles = FileUtils.listFiles(suppliedFile, new String[]{"zip"}, false);
|
inputFiles = FileUtils.listFiles(suppliedFile, new String[] {"zip"}, false);
|
||||||
} else {
|
} else {
|
||||||
inputFiles = Collections.singletonList(suppliedFile);
|
inputFiles = Collections.singletonList(suppliedFile);
|
||||||
}
|
}
|
||||||
@ -148,13 +251,13 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||||||
File cacheDir = new File(applicationDir, "cache");
|
File cacheDir = new File(applicationDir, "cache");
|
||||||
FileUtils.forceMkdir(cacheDir);
|
FileUtils.forceMkdir(cacheDir);
|
||||||
|
|
||||||
File inputFile = new File(cacheDir, "examples-json-" + theCtx.getVersion().getVersion() + ".zip");
|
File inputFile = new File(cacheDir, "examples-json-" + getFhirContext().getVersion().getVersion() + ".zip");
|
||||||
|
|
||||||
Date cacheExpiryDate = DateUtils.addHours(new Date(), -12);
|
Date cacheExpiryDate = DateUtils.addHours(new Date(), -12);
|
||||||
|
|
||||||
if (!inputFile.exists() | (theCacheFile && FileUtils.isFileOlder(inputFile, cacheExpiryDate))) {
|
if (!inputFile.exists() | (theCacheFile && FileUtils.isFileOlder(inputFile, cacheExpiryDate))) {
|
||||||
|
|
||||||
File exampleFileDownloading = new File(cacheDir, "examples-json-" + theCtx.getVersion().getVersion() + ".zip.partial");
|
File exampleFileDownloading = new File(cacheDir, "examples-json-" + getFhirContext().getVersion().getVersion() + ".zip.partial");
|
||||||
|
|
||||||
HttpGet get = new HttpGet(theSpecUrl);
|
HttpGet get = new HttpGet(theSpecUrl);
|
||||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||||
@ -184,12 +287,46 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||||||
return inputFiles;
|
return inputFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IGenericClient newClient(FhirContext ctx, String theBaseUrl) {
|
protected IGenericClient newClient(CommandLine theCommandLine) {
|
||||||
ctx.getRestfulClientFactory().setSocketTimeout(10 * 60 * 1000);
|
return newClient(theCommandLine, BASE_URL_PARAM, BASIC_AUTH_OPTION, BEARER_TOKEN_LONGOPT);
|
||||||
IGenericClient fhirClient = ctx.newRestfulGenericClient(theBaseUrl);
|
|
||||||
return fhirClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void run(CommandLine theCommandLine) throws ParseException, Exception;
|
protected IGenericClient newClient(CommandLine theCommandLine, String theBaseUrlParamName, String theBasicAuthOptionName, String theBearerTokenOptionName) {
|
||||||
|
String baseUrl = theCommandLine.getOptionValue(theBaseUrlParamName);
|
||||||
|
|
||||||
|
myFhirCtx.getRestfulClientFactory().setSocketTimeout(10 * 60 * 1000);
|
||||||
|
IGenericClient retVal = myFhirCtx.newRestfulGenericClient(baseUrl);
|
||||||
|
|
||||||
|
String basicAuthHeaderValue = getAndParseOptionBasicAuthHeader(theCommandLine, theBasicAuthOptionName);
|
||||||
|
if (isNotBlank(basicAuthHeaderValue)) {
|
||||||
|
retVal.registerInterceptor(new SimpleRequestHeaderInterceptor(Constants.HEADER_AUTHORIZATION, basicAuthHeaderValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotBlank(theBearerTokenOptionName)) {
|
||||||
|
String bearerToken = theCommandLine.getOptionValue(theBearerTokenOptionName);
|
||||||
|
if (isNotBlank(bearerToken)) {
|
||||||
|
retVal.registerInterceptor(new SimpleRequestHeaderInterceptor(Constants.HEADER_AUTHORIZATION, Constants.HEADER_AUTHORIZATION_VALPREFIX_BEARER + bearerToken));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void parseFhirContext(CommandLine theCommandLine) throws ParseException {
|
||||||
|
String version = theCommandLine.getOptionValue(FHIR_VERSION_OPTION);
|
||||||
|
if (isBlank(version)) {
|
||||||
|
throw new ParseException("Missing required option: -" + FHIR_VERSION_OPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
FhirVersionEnum versionEnum = FhirVersionEnum.valueOf(version.toUpperCase());
|
||||||
|
myFhirCtx = versionEnum.newContext();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ParseException("Invalid FHIR version string: " + version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract void run(CommandLine theCommandLine) throws ParseException, ExecutionException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@ package ca.uhn.fhir.cli;
|
|||||||
|
|
||||||
public class CommandFailureException extends Error {
|
public class CommandFailureException extends Error {
|
||||||
|
|
||||||
|
public CommandFailureException(Throwable theCause) {
|
||||||
|
super(theCause.getMessage(), theCause);
|
||||||
|
}
|
||||||
|
|
||||||
public CommandFailureException(String theMessage) {
|
public CommandFailureException(String theMessage) {
|
||||||
super(theMessage);
|
super(theMessage);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ import org.hl7.fhir.dstu3.model.Resource;
|
|||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
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 java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -327,6 +326,8 @@ public class ExampleDataUploader extends BaseCommand {
|
|||||||
opt.setRequired(false);
|
opt.setRequired(false);
|
||||||
options.addOption(opt);
|
options.addOption(opt);
|
||||||
|
|
||||||
|
addBasicAuthOption(options);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,8 +574,9 @@ public class ExampleDataUploader extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws Exception {
|
public void run(CommandLine theCommandLine) throws ParseException {
|
||||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
parseFhirContext(theCommandLine);
|
||||||
|
FhirContext ctx = getFhirContext();
|
||||||
|
|
||||||
String targetServer = theCommandLine.getOptionValue("t");
|
String targetServer = theCommandLine.getOptionValue("t");
|
||||||
if (isBlank(targetServer)) {
|
if (isBlank(targetServer)) {
|
||||||
@ -613,17 +615,22 @@ public class ExampleDataUploader extends BaseCommand {
|
|||||||
|
|
||||||
boolean cacheFile = theCommandLine.hasOption('c');
|
boolean cacheFile = theCommandLine.hasOption('c');
|
||||||
|
|
||||||
Collection<File> inputFiles = loadFile(ctx, specUrl, filepath, cacheFile);
|
Collection<File> inputFiles = null;
|
||||||
|
try {
|
||||||
for (File inputFile : inputFiles) {
|
inputFiles = loadFile(specUrl, filepath, cacheFile);
|
||||||
IBaseBundle bundle = getBundleFromFile(limit, inputFile, ctx);
|
for (File inputFile : inputFiles) {
|
||||||
processBundle(ctx, bundle);
|
IBaseBundle bundle = getBundleFromFile(limit, inputFile, ctx);
|
||||||
sendBundleToTarget(targetServer, ctx, bundle);
|
processBundle(ctx, bundle);
|
||||||
|
sendBundleToTarget(targetServer, ctx, bundle, theCommandLine);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CommandFailureException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendBundleToTarget(String targetServer, FhirContext ctx, IBaseBundle bundle) throws Exception {
|
private void sendBundleToTarget(String targetServer, FhirContext ctx, IBaseBundle bundle, CommandLine theCommandLine) throws Exception {
|
||||||
List<IBaseResource> resources = BundleUtil.toListOfResources(ctx, bundle);
|
List<IBaseResource> resources = BundleUtil.toListOfResources(ctx, bundle);
|
||||||
|
|
||||||
for (Iterator<IBaseResource> iter = resources.iterator(); iter.hasNext(); ) {
|
for (Iterator<IBaseResource> iter = resources.iterator(); iter.hasNext(); ) {
|
||||||
@ -707,7 +714,7 @@ public class ExampleDataUploader extends BaseCommand {
|
|||||||
} else {
|
} else {
|
||||||
ourLog.info("Uploading bundle to server: " + targetServer);
|
ourLog.info("Uploading bundle to server: " + targetServer);
|
||||||
|
|
||||||
IGenericClient fhirClient = newClient(ctx, targetServer);
|
IGenericClient fhirClient = newClient(theCommandLine);
|
||||||
fhirClient.registerInterceptor(new GZipContentInterceptor());
|
fhirClient.registerInterceptor(new GZipContentInterceptor());
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.cli;
|
|||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
|
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
|
||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
|
import net.sf.ehcache.transaction.xa.commands.Command;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.Option;
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
@ -16,6 +17,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class IgPackUploader extends BaseCommand {
|
public class IgPackUploader extends BaseCommand {
|
||||||
@ -48,20 +51,31 @@ public class IgPackUploader extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws ParseException, Exception {
|
public void run(CommandLine theCommandLine) throws ParseException{
|
||||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
parseFhirContext(theCommandLine);
|
||||||
|
|
||||||
String targetServer = theCommandLine.getOptionValue("t");
|
IGenericClient client = newClient(theCommandLine);
|
||||||
IGenericClient client = ctx.newRestfulGenericClient(targetServer);
|
|
||||||
|
|
||||||
String url = theCommandLine.getOptionValue("u");
|
String url = theCommandLine.getOptionValue("u");
|
||||||
|
|
||||||
Collection<File> files = loadFile(ctx, url, null, false);
|
Collection<File> files = null;
|
||||||
|
try {
|
||||||
|
files = loadFile(url, null, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new CommandFailureException(e);
|
||||||
|
}
|
||||||
|
|
||||||
for (File nextFile : files) {
|
for (File nextFile : files) {
|
||||||
|
FhirContext ctx = getFhirContext();
|
||||||
switch (ctx.getVersion().getVersion()) {
|
switch (ctx.getVersion().getVersion()) {
|
||||||
case DSTU3:
|
case DSTU3:
|
||||||
IgPackParserDstu3 packParser = new IgPackParserDstu3(ctx);
|
IgPackParserDstu3 packParser = new IgPackParserDstu3(ctx);
|
||||||
IValidationSupport ig = packParser.parseIg(new FileInputStream(nextFile), nextFile.getName());
|
IValidationSupport ig = null;
|
||||||
|
try {
|
||||||
|
ig = packParser.parseIg(new FileInputStream(nextFile), nextFile.getName());
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new CommandFailureException(e);
|
||||||
|
}
|
||||||
Iterable<IBaseResource> conformanceResources = ig.fetchAllConformanceResources(ctx);
|
Iterable<IBaseResource> conformanceResources = ig.fetchAllConformanceResources(ctx);
|
||||||
for (IBaseResource nextResource : conformanceResources) {
|
for (IBaseResource nextResource : conformanceResources) {
|
||||||
String nextResourceUrl = ((IPrimitiveType<?>)ctx.newTerser().getSingleValueOrNull(nextResource, "url")).getValueAsString();
|
String nextResourceUrl = ((IPrimitiveType<?>)ctx.newTerser().getSingleValueOrNull(nextResource, "url")).getValueAsString();
|
||||||
|
@ -34,13 +34,14 @@ public class RunServerCommand extends BaseCommand {
|
|||||||
private static final String OPTION_P = "p";
|
private static final String OPTION_P = "p";
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RunServerCommand.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RunServerCommand.class);
|
||||||
|
public static final String RUN_SERVER_COMMAND = "run-server";
|
||||||
private int myPort;
|
private int myPort;
|
||||||
|
|
||||||
private Server myServer;
|
private Server myServer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCommandName() {
|
public String getCommandName() {
|
||||||
return "run-server";
|
return RUN_SERVER_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -68,6 +69,8 @@ public class RunServerCommand extends BaseCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws ParseException {
|
public void run(CommandLine theCommandLine) throws ParseException {
|
||||||
|
parseFhirContext(theCommandLine);
|
||||||
|
|
||||||
myPort = parseOptionInteger(theCommandLine, OPTION_P, DEFAULT_PORT);
|
myPort = parseOptionInteger(theCommandLine, OPTION_P, DEFAULT_PORT);
|
||||||
|
|
||||||
if (theCommandLine.hasOption(OPTION_LOWMEM)) {
|
if (theCommandLine.hasOption(OPTION_LOWMEM)) {
|
||||||
@ -104,7 +107,7 @@ public class RunServerCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextHolder.setCtx(getSpecVersionContext(theCommandLine));
|
ContextHolder.setCtx(getFhirContext());
|
||||||
|
|
||||||
ourLog.info("Preparing HAPI FHIR JPA server on port {}", myPort);
|
ourLog.info("Preparing HAPI FHIR JPA server on port {}", myPort);
|
||||||
File tempWarFile;
|
File tempWarFile;
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
package ca.uhn.fhir.cli;
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import org.apache.commons.cli.*;
|
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
|
||||||
|
|
||||||
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.jpa.term.IHapiTerminologyLoaderSvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.BearerTokenAuthInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.BearerTokenAuthInterceptor;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.commons.cli.Option;
|
||||||
|
import org.apache.commons.cli.Options;
|
||||||
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.hl7.fhir.dstu3.model.Parameters;
|
||||||
|
import org.hl7.fhir.dstu3.model.StringType;
|
||||||
|
import org.hl7.fhir.dstu3.model.UriType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public class UploadTerminologyCommand extends BaseCommand {
|
public class UploadTerminologyCommand extends BaseCommand {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(UploadTerminologyCommand.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(UploadTerminologyCommand.class);
|
||||||
|
private static final String BASE_URL_PARAM = "t";
|
||||||
|
private static final String UPLOAD_EXTERNAL_CODE_SYSTEM = "upload-external-code-system";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCommandDescription() {
|
public String getCommandDescription() {
|
||||||
return "Uploads a terminology package (e.g. a SNOMED CT ZIP file) to a HAPI JPA server. "
|
return "Uploads a terminology package (e.g. a SNOMED CT ZIP file) to a server, using the $" + UPLOAD_EXTERNAL_CODE_SYSTEM + " operation.";
|
||||||
+ "Note that this command uses a custom operation that is only implemented on HAPI "
|
|
||||||
+ "JPA servers that have been configured to accept it.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -45,28 +49,27 @@ public class UploadTerminologyCommand extends BaseCommand {
|
|||||||
opt.setRequired(false);
|
opt.setRequired(false);
|
||||||
options.addOption(opt);
|
options.addOption(opt);
|
||||||
|
|
||||||
opt = new Option("d", "data", true, "Local *.zip containing file to use to upload");
|
opt = new Option("d", "data", true, "Local file to use to upload (can be a raw file or a ZIP containing the raw file)");
|
||||||
opt.setRequired(false);
|
opt.setRequired(false);
|
||||||
options.addOption(opt);
|
options.addOption(opt);
|
||||||
|
|
||||||
opt = new Option("b", "bearer-token", true, "Bearer token to add to the request");
|
addBasicAuthOption(options);
|
||||||
opt.setRequired(false);
|
|
||||||
options.addOption(opt);
|
|
||||||
|
|
||||||
opt = new Option("v", "verbose", false, "Verbose output");
|
opt = new Option("v", "verbose", false, "Verbose output");
|
||||||
opt.setRequired(false);
|
opt.setRequired(false);
|
||||||
options.addOption(opt);
|
options.addOption(opt);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws Exception {
|
public void run(CommandLine theCommandLine) throws ParseException {
|
||||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
parseFhirContext(theCommandLine);
|
||||||
|
FhirContext ctx = getFhirContext();
|
||||||
|
|
||||||
String targetServer = theCommandLine.getOptionValue("t");
|
String targetServer = theCommandLine.getOptionValue(BASE_URL_PARAM);
|
||||||
if (isBlank(targetServer)) {
|
if (isBlank(targetServer)) {
|
||||||
throw new ParseException("No target server (-t) specified");
|
throw new ParseException("No target server (-" + BASE_URL_PARAM + ") specified");
|
||||||
} else if (targetServer.startsWith("http") == false && targetServer.startsWith("file") == false) {
|
} else if (targetServer.startsWith("http") == false && targetServer.startsWith("file") == false) {
|
||||||
throw new ParseException("Invalid target server specified, must begin with 'http' or 'file'");
|
throw new ParseException("Invalid target server specified, must begin with 'http' or 'file'");
|
||||||
}
|
}
|
||||||
@ -75,15 +78,15 @@ public class UploadTerminologyCommand extends BaseCommand {
|
|||||||
if (isBlank(termUrl)) {
|
if (isBlank(termUrl)) {
|
||||||
throw new ParseException("No URL provided");
|
throw new ParseException("No URL provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] datafile = theCommandLine.getOptionValues("d");
|
String[] datafile = theCommandLine.getOptionValues("d");
|
||||||
if (datafile == null || datafile.length == 0) {
|
if (datafile == null || datafile.length == 0) {
|
||||||
throw new ParseException("No data file provided");
|
throw new ParseException("No data file provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
String bearerToken = theCommandLine.getOptionValue("b");
|
String bearerToken = theCommandLine.getOptionValue("b");
|
||||||
|
|
||||||
IGenericClient client = super.newClient(ctx, targetServer);
|
IGenericClient client = super.newClient(theCommandLine);
|
||||||
IBaseParameters inputParameters;
|
IBaseParameters inputParameters;
|
||||||
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||||
Parameters p = new Parameters();
|
Parameters p = new Parameters();
|
||||||
@ -103,12 +106,12 @@ public class UploadTerminologyCommand extends BaseCommand {
|
|||||||
if (theCommandLine.hasOption('v')) {
|
if (theCommandLine.hasOption('v')) {
|
||||||
client.registerInterceptor(new LoggingInterceptor(true));
|
client.registerInterceptor(new LoggingInterceptor(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Beginning upload - This may take a while...");
|
ourLog.info("Beginning upload - This may take a while...");
|
||||||
IBaseParameters response = client
|
IBaseParameters response = client
|
||||||
.operation()
|
.operation()
|
||||||
.onServer()
|
.onServer()
|
||||||
.named("upload-external-code-system")
|
.named(UPLOAD_EXTERNAL_CODE_SYSTEM)
|
||||||
.withParameters(inputParameters)
|
.withParameters(inputParameters)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
package ca.uhn.fhir.cli;
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import static org.fusesource.jansi.Ansi.ansi;
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
|
import ca.uhn.fhir.validation.SingleValidationMessage;
|
||||||
import java.io.*;
|
import ca.uhn.fhir.validation.ValidationResult;
|
||||||
|
import com.phloc.commons.io.file.FileUtils;
|
||||||
import org.apache.commons.cli.*;
|
import org.apache.commons.cli.*;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
import org.fusesource.jansi.Ansi.Color;
|
import org.fusesource.jansi.Ansi.Color;
|
||||||
import org.hl7.fhir.dstu3.hapi.validation.*;
|
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
|
||||||
|
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||||
|
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
|
||||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import com.phloc.commons.io.file.FileUtils;
|
import java.io.*;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import ca.uhn.fhir.validation.*;
|
import static org.fusesource.jansi.Ansi.ansi;
|
||||||
|
|
||||||
public class ValidateCommand extends BaseCommand {
|
public class ValidateCommand extends BaseCommand {
|
||||||
|
|
||||||
@ -54,7 +56,9 @@ public class ValidateCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws ParseException, Exception {
|
public void run(CommandLine theCommandLine) throws ParseException {
|
||||||
|
parseFhirContext(theCommandLine);
|
||||||
|
|
||||||
String fileName = theCommandLine.getOptionValue("n");
|
String fileName = theCommandLine.getOptionValue("n");
|
||||||
String contents = theCommandLine.getOptionValue("c");
|
String contents = theCommandLine.getOptionValue("c");
|
||||||
if (isNotBlank(fileName) && isNotBlank(contents)) {
|
if (isNotBlank(fileName) && isNotBlank(contents)) {
|
||||||
@ -68,7 +72,11 @@ public class ValidateCommand extends BaseCommand {
|
|||||||
String encoding = theCommandLine.getOptionValue("e", "UTF-8");
|
String encoding = theCommandLine.getOptionValue("e", "UTF-8");
|
||||||
ourLog.info("Reading file '{}' using encoding {}", fileName, encoding);
|
ourLog.info("Reading file '{}' using encoding {}", fileName, encoding);
|
||||||
|
|
||||||
contents = IOUtils.toString(new InputStreamReader(new FileInputStream(fileName), encoding));
|
try {
|
||||||
|
contents = IOUtils.toString(new InputStreamReader(new FileInputStream(fileName), encoding));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new CommandFailureException(e);
|
||||||
|
}
|
||||||
ourLog.info("Fully read - Size is {}", FileUtils.getFileSizeDisplay(contents.length()));
|
ourLog.info("Fully read - Size is {}", FileUtils.getFileSizeDisplay(contents.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +85,7 @@ public class ValidateCommand extends BaseCommand {
|
|||||||
throw new ParseException("Could not detect encoding (json/xml) of contents");
|
throw new ParseException("Could not detect encoding (json/xml) of contents");
|
||||||
}
|
}
|
||||||
|
|
||||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
FhirContext ctx = getFhirContext();
|
||||||
FhirValidator val = ctx.newValidator();
|
FhirValidator val = ctx.newValidator();
|
||||||
|
|
||||||
IBaseResource localProfileResource = null;
|
IBaseResource localProfileResource = null;
|
||||||
|
@ -100,10 +100,12 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
|
|
||||||
addFhirVersionOption(options);
|
addFhirVersionOption(options);
|
||||||
|
|
||||||
opt = new Option("t", "target", true, "Base URL for the target server (e.g. \"http://example.com/fhir\")");
|
opt = new Option(BASE_URL_PARAM, "target", true, "Base URL for the target server (e.g. \"http://example.com/fhir\")");
|
||||||
opt.setRequired(true);
|
opt.setRequired(true);
|
||||||
options.addOption(opt);
|
options.addOption(opt);
|
||||||
|
|
||||||
|
addBasicAuthOption(options);
|
||||||
|
|
||||||
opt = new Option("e", "exclude", true, "Exclude uploading the given resources, e.g. \"-e dicom-dcim,foo\"");
|
opt = new Option("e", "exclude", true, "Exclude uploading the given resources, e.g. \"-e dicom-dcim,foo\"");
|
||||||
opt.setRequired(false);
|
opt.setRequired(false);
|
||||||
options.addOption(opt);
|
options.addOption(opt);
|
||||||
@ -113,6 +115,8 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws ParseException {
|
public void run(CommandLine theCommandLine) throws ParseException {
|
||||||
|
parseFhirContext(theCommandLine);
|
||||||
|
|
||||||
String targetServer = theCommandLine.getOptionValue("t");
|
String targetServer = theCommandLine.getOptionValue("t");
|
||||||
if (isBlank(targetServer)) {
|
if (isBlank(targetServer)) {
|
||||||
throw new ParseException("No target server (-t) specified");
|
throw new ParseException("No target server (-t) specified");
|
||||||
@ -120,7 +124,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
throw new ParseException("Invalid target server specified, must begin with 'http'");
|
throw new ParseException("Invalid target server specified, must begin with 'http'");
|
||||||
}
|
}
|
||||||
|
|
||||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
FhirContext ctx = getFhirContext();
|
||||||
String exclude = theCommandLine.getOptionValue("e");
|
String exclude = theCommandLine.getOptionValue("e");
|
||||||
|
|
||||||
if (isNotBlank(exclude)) {
|
if (isNotBlank(exclude)) {
|
||||||
@ -134,18 +138,19 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU2) {
|
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU2) {
|
||||||
uploadDefinitionsDstu2(targetServer, ctx);
|
uploadDefinitionsDstu2(theCommandLine, ctx);
|
||||||
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||||
uploadDefinitionsDstu3(targetServer, ctx);
|
uploadDefinitionsDstu3(theCommandLine, ctx);
|
||||||
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.R4) {
|
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||||
uploadDefinitionsR4(targetServer, ctx);
|
uploadDefinitionsR4(theCommandLine, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadDefinitionsDstu2(String targetServer, FhirContext ctx) throws CommandFailureException {
|
private void uploadDefinitionsDstu2(CommandLine theCommandLine, FhirContext ctx) throws CommandFailureException {
|
||||||
IGenericClient client = newClient(ctx, targetServer);
|
IGenericClient client = newClient(theCommandLine);
|
||||||
ourLog.info("Uploading definitions to server: " + targetServer);
|
|
||||||
|
ourLog.info("Uploading definitions to server");
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
@ -242,9 +247,9 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadDefinitionsDstu3(String targetServer, FhirContext ctx) throws CommandFailureException {
|
private void uploadDefinitionsDstu3(CommandLine theCommandLine, FhirContext theCtx) throws CommandFailureException {
|
||||||
IGenericClient client = newClient(ctx, targetServer);
|
IGenericClient client = newClient(theCommandLine);
|
||||||
ourLog.info("Uploading definitions to server: " + targetServer);
|
ourLog.info("Uploading definitions to server");
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
int total = 0;
|
int total = 0;
|
||||||
@ -253,12 +258,12 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
String vsContents;
|
String vsContents;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ctx.getVersion().getPathToSchemaDefinitions();
|
theCtx.getVersion().getPathToSchemaDefinitions();
|
||||||
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/" + "valuesets.xml"), "UTF-8");
|
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/" + "valuesets.xml"), "UTF-8");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new CommandFailureException(e.toString());
|
throw new CommandFailureException(e.toString());
|
||||||
}
|
}
|
||||||
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
|
bundle = theCtx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
|
||||||
filterBundle(bundle);
|
filterBundle(bundle);
|
||||||
|
|
||||||
total = bundle.getEntry().size();
|
total = bundle.getEntry().size();
|
||||||
@ -267,7 +272,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
|
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
|
||||||
next.setId(next.getIdElement().toUnqualifiedVersionless());
|
next.setId(next.getIdElement().toUnqualifiedVersionless());
|
||||||
|
|
||||||
int bytes = ctx.newXmlParser().encodeResourceToString(next).length();
|
int bytes = theCtx.newXmlParser().encodeResourceToString(next).length();
|
||||||
|
|
||||||
ourLog.info("Uploading ValueSet {}/{} : {} ({} bytes}", new Object[] {count, total, next.getIdElement().getValue(), bytes});
|
ourLog.info("Uploading ValueSet {}/{} : {} ({} bytes}", new Object[] {count, total, next.getIdElement().getValue(), bytes});
|
||||||
try {
|
try {
|
||||||
@ -287,7 +292,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
throw new CommandFailureException(e.toString());
|
throw new CommandFailureException(e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
|
bundle = theCtx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
|
||||||
filterBundle(bundle);
|
filterBundle(bundle);
|
||||||
|
|
||||||
total = bundle.getEntry().size();
|
total = bundle.getEntry().size();
|
||||||
@ -310,7 +315,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new CommandFailureException(e.toString());
|
throw new CommandFailureException(e.toString());
|
||||||
}
|
}
|
||||||
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
|
bundle = theCtx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
|
||||||
filterBundle(bundle);
|
filterBundle(bundle);
|
||||||
total = bundle.getEntry().size();
|
total = bundle.getEntry().size();
|
||||||
count = 1;
|
count = 1;
|
||||||
@ -329,9 +334,9 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
ourLog.info("Finished uploading ValueSets");
|
ourLog.info("Finished uploading ValueSets");
|
||||||
|
|
||||||
|
|
||||||
uploadDstu3Profiles(ctx, client, "profiles-resources");
|
uploadDstu3Profiles(theCtx, client, "profiles-resources");
|
||||||
uploadDstu3Profiles(ctx, client, "profiles-types");
|
uploadDstu3Profiles(theCtx, client, "profiles-types");
|
||||||
uploadDstu3Profiles(ctx, client, "profiles-others");
|
uploadDstu3Profiles(theCtx, client, "profiles-others");
|
||||||
|
|
||||||
ourLog.info("Finished uploading ValueSets");
|
ourLog.info("Finished uploading ValueSets");
|
||||||
|
|
||||||
@ -340,9 +345,9 @@ public class ValidationDataUploader extends BaseCommand {
|
|||||||
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadDefinitionsR4(String theTargetServer, FhirContext theCtx) throws CommandFailureException {
|
private void uploadDefinitionsR4(CommandLine theCommandLine, FhirContext theCtx) throws CommandFailureException {
|
||||||
IGenericClient client = newClient(theCtx, theTargetServer);
|
IGenericClient client = newClient(theCommandLine);
|
||||||
ourLog.info("Uploading definitions to server: " + theTargetServer);
|
ourLog.info("Uploading definitions to server");
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
@ -1,30 +1,22 @@
|
|||||||
package ca.uhn.fhir.cli;
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
import org.eclipse.jetty.websocket.api.annotations.*;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
|
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
|
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
|
||||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
public class WebsocketSubscribeCommand extends BaseCommand {
|
public class WebsocketSubscribeCommand extends BaseCommand {
|
||||||
private static final org.slf4j.Logger LOG_RECV = org.slf4j.LoggerFactory.getLogger("websocket.RECV");
|
private static final org.slf4j.Logger LOG_RECV = org.slf4j.LoggerFactory.getLogger("websocket.RECV");
|
||||||
|
|
||||||
private static final org.slf4j.Logger LOG_SEND = org.slf4j.LoggerFactory.getLogger("websocket.SEND");
|
private static final org.slf4j.Logger LOG_SEND = org.slf4j.LoggerFactory.getLogger("websocket.SEND");
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(WebsocketSubscribeCommand.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(WebsocketSubscribeCommand.class);
|
||||||
|
|
||||||
private boolean myQuit;
|
private boolean myQuit;
|
||||||
@ -38,6 +30,7 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
public String getCommandName() {
|
public String getCommandName() {
|
||||||
return "subscription-client";
|
return "subscription-client";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Options getOptions() {
|
public Options getOptions() {
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
@ -45,15 +38,16 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
options.addOption("i", "subscriptionid", true, "Subscription ID, e.g. \"5235\"");
|
options.addOption("i", "subscriptionid", true, "Subscription ID, e.g. \"5235\"");
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandLine theCommandLine) throws ParseException, Exception {
|
public void run(CommandLine theCommandLine) throws ParseException {
|
||||||
String target = theCommandLine.getOptionValue("t");
|
String target = theCommandLine.getOptionValue("t");
|
||||||
if (isBlank(target) || (!target.startsWith("ws://") && !target.startsWith("wss://"))) {
|
if (isBlank(target) || (!target.startsWith("ws://") && !target.startsWith("wss://"))) {
|
||||||
throw new ParseException("Target (-t) needs to be in the form \"ws://foo\" or \"wss://foo\"");
|
throw new ParseException("Target (-t) needs to be in the form \"ws://foo\" or \"wss://foo\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
IdDt subsId = new IdDt(theCommandLine.getOptionValue("i"));
|
IdDt subsId = new IdDt(theCommandLine.getOptionValue("i"));
|
||||||
|
|
||||||
WebSocketClient client = new WebSocketClient();
|
WebSocketClient client = new WebSocketClient();
|
||||||
SimpleEchoSocket socket = new SimpleEchoSocket(subsId.getIdPart());
|
SimpleEchoSocket socket = new SimpleEchoSocket(subsId.getIdPart());
|
||||||
try {
|
try {
|
||||||
@ -68,6 +62,8 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Shutting down websocket client");
|
ourLog.info("Shutting down websocket client");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CommandFailureException(e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
client.stop();
|
client.stop();
|
||||||
@ -76,7 +72,7 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Echo Client Socket
|
* Basic Echo Client Socket
|
||||||
*/
|
*/
|
||||||
@ -84,7 +80,7 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
public class SimpleEchoSocket {
|
public class SimpleEchoSocket {
|
||||||
|
|
||||||
private String mySubsId;
|
private String mySubsId;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private Session session;
|
private Session session;
|
||||||
|
|
||||||
@ -93,17 +89,6 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
mySubsId = theSubsId;
|
mySubsId = theSubsId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnWebSocketError
|
|
||||||
public void onError(Throwable theError) {
|
|
||||||
ourLog.error("Websocket error: ", theError);
|
|
||||||
myQuit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnWebSocketFrame
|
|
||||||
public void onFrame(Frame theFrame) {
|
|
||||||
ourLog.debug("Websocket frame: {}", theFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnWebSocketClose
|
@OnWebSocketClose
|
||||||
public void onClose(int statusCode, String reason) {
|
public void onClose(int statusCode, String reason) {
|
||||||
ourLog.info("Received CLOSE status={} reason={}", statusCode, reason);
|
ourLog.info("Received CLOSE status={} reason={}", statusCode, reason);
|
||||||
@ -123,10 +108,21 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnWebSocketError
|
||||||
|
public void onError(Throwable theError) {
|
||||||
|
ourLog.error("Websocket error: ", theError);
|
||||||
|
myQuit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnWebSocketFrame
|
||||||
|
public void onFrame(Frame theFrame) {
|
||||||
|
ourLog.debug("Websocket frame: {}", theFrame);
|
||||||
|
}
|
||||||
|
|
||||||
@OnWebSocketMessage
|
@OnWebSocketMessage
|
||||||
public void onMessage(String theMsg) {
|
public void onMessage(String theMsg) {
|
||||||
LOG_RECV.info("{}", theMsg);
|
LOG_RECV.info("{}", theMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<useJansi>true</useJansi>
|
<useJansi>true</useJansi>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%boldGreen(%d{HH:mm:ss}) %white(%-5level) %logger{36} - %boldWhite(%msg%n)
|
<pattern>%green(%d{yyyy-MM-dd}) %boldGreen(%d{HH:mm:ss}) %white([%thread]) %white(%-5level) %boldBlue(%logger{20}) %boldWhite(%msg%n)
|
||||||
</pattern>
|
</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<logger name="ca.uhn.fhir" additivity="false" level="info">
|
<logger name="ca.uhn.fhir.cli" additivity="false" level="info">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
<logger name="ca.cdr.cli" additivity="false" level="info">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
@ -20,6 +23,15 @@
|
|||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
<!-- These two are used by SynchronizeFhirServersCommand -->
|
||||||
|
<logger name="sync.SOURCE" additivity="false" level="info">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
<logger name="sync.TARGET" additivity="false" level="info">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
|
||||||
<root level="warn">
|
<root level="warn">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</root>
|
</root>
|
||||||
|
@ -127,6 +127,9 @@ fi
|
|||||||
|
|
||||||
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
|
||||||
|
COLUMNS=$(tput cols)
|
||||||
|
|
||||||
exec "$JAVACMD" \
|
exec "$JAVACMD" \
|
||||||
|
-Dcolumns=$COLUMNS \
|
||||||
$CLI_OPTS \
|
$CLI_OPTS \
|
||||||
-jar $SCRIPTDIR/hapi-fhir-cli.jar "$@"
|
-jar $SCRIPTDIR/hapi-fhir-cli.jar "$@"
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class InstallIgPackTest {
|
public class InstallIgPackTest {
|
@ -0,0 +1,15 @@
|
|||||||
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class OptionsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOptions() {
|
||||||
|
App app = new App();
|
||||||
|
for (BaseCommand next : app.provideCommands()) {
|
||||||
|
next.getOptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.cli.App;
|
|
||||||
|
|
||||||
public class ValidateTest {
|
public class ValidateTest {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidateTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidateTest.class);
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ public class ValidateTest {
|
|||||||
String resourcePath = ValidateTest.class.getResource("/patient-uslab-example1.xml").getFile();
|
String resourcePath = ValidateTest.class.getResource("/patient-uslab-example1.xml").getFile();
|
||||||
ourLog.info(resourcePath);
|
ourLog.info(resourcePath);
|
||||||
|
|
||||||
App.main(new String[] {"validate", "-p", "-n", resourcePath});
|
App.main(new String[] {"validate", "-v", "dstu3", "-p", "-n", resourcePath});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
pom.xml
5
pom.xml
@ -593,6 +593,11 @@
|
|||||||
<artifactId>commons-codec</artifactId>
|
<artifactId>commons-codec</artifactId>
|
||||||
<version>${commons_codec_version}</version>
|
<version>${commons_codec_version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
<version>1.14</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user