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>
|
||||
<classifier>classes</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.14</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
|
@ -232,7 +237,6 @@
|
|||
<artifactItem>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-cli-jpaserver</artifactId>
|
||||
<!--<version>1.5-SNAPSHOT</version>-->
|
||||
<type>war</type>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>target/classes</outputDirectory>
|
||||
|
@ -283,35 +287,6 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
</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>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -1,220 +1,25 @@
|
|||
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 ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||
import ch.qos.logback.core.joran.spi.JoranException;
|
||||
|
||||
public class App {
|
||||
private static List<BaseCommand> ourCommands;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(App.class);
|
||||
public class App extends BaseApp {
|
||||
|
||||
public static final String LINESEP = System.getProperty("line.separator");
|
||||
|
||||
static {
|
||||
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);
|
||||
@Override
|
||||
protected String provideCommandName() {
|
||||
return "hapi-fhir-cli";
|
||||
}
|
||||
|
||||
private static void logCommandUsage(BaseCommand theCommand) {
|
||||
logAppHeader();
|
||||
|
||||
logCommandUsageNoHeader(theCommand);
|
||||
@Override
|
||||
protected String provideProductName() {
|
||||
return "HAPI FHIR";
|
||||
}
|
||||
|
||||
private static void logCommandUsageNoHeader(BaseCommand theCommand) {
|
||||
System.out.println("Usage:");
|
||||
System.out.println(" hapi-fhir-cli " + theCommand.getCommandName() + " [options]");
|
||||
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("------------------------------------------------------------");
|
||||
@Override
|
||||
protected String provideProductVersion() {
|
||||
return VersionUtil.getVersion();
|
||||
}
|
||||
|
||||
public static void main(String[] theArgs) {
|
||||
loggingConfigOff();
|
||||
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);
|
||||
}
|
||||
|
||||
new App().run(theArgs);
|
||||
}
|
||||
|
||||
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.FhirVersionEnum;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
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.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
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.FilenameUtils;
|
||||
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.HttpClientBuilder;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
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> {
|
||||
|
||||
private static final String SPEC_DEFAULT_VERSION = "dstu3";
|
||||
public static final String BASE_URL_PARAM = "t";
|
||||
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 FhirContext myFhirCtx;
|
||||
|
||||
|
@ -38,10 +49,57 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
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) {
|
||||
Option opt = new Option("f", "fhirversion", true, "Spec version to upload (default is '" + SPEC_DEFAULT_VERSION + "')");
|
||||
opt.setRequired(false);
|
||||
theOptions.addOption(opt);
|
||||
String versions = Arrays.stream(FhirVersionEnum.values())
|
||||
.filter(t -> t != FhirVersionEnum.DSTU2_1 && t != FhirVersionEnum.DSTU2_HL7ORG)
|
||||
.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
|
||||
|
@ -49,6 +107,18 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
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 {
|
||||
FileOutputStream buffer = FileUtils.openOutputStream(localFile);
|
||||
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 getCommandName();
|
||||
|
||||
public abstract Options getOptions();
|
||||
|
||||
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);
|
||||
}
|
||||
protected FhirContext getFhirContext() {
|
||||
return myFhirCtx;
|
||||
}
|
||||
|
||||
// public FhirContext getFhirCtx() {
|
||||
// if (myFhirCtx == null) {
|
||||
// myFhirCtx = FhirContext.forDstu2();
|
||||
// }
|
||||
// return myFhirCtx;
|
||||
// }
|
||||
public abstract Options getOptions();
|
||||
|
||||
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");
|
||||
|
||||
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));
|
||||
|
||||
if (suppliedFile.isDirectory()) {
|
||||
inputFiles = FileUtils.listFiles(suppliedFile, new String[]{"zip"}, false);
|
||||
inputFiles = FileUtils.listFiles(suppliedFile, new String[] {"zip"}, false);
|
||||
} else {
|
||||
inputFiles = Collections.singletonList(suppliedFile);
|
||||
}
|
||||
|
@ -148,13 +251,13 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
File cacheDir = new File(applicationDir, "cache");
|
||||
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);
|
||||
|
||||
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);
|
||||
CloseableHttpClient client = HttpClientBuilder.create().build();
|
||||
|
@ -184,12 +287,46 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
return inputFiles;
|
||||
}
|
||||
|
||||
protected IGenericClient newClient(FhirContext ctx, String theBaseUrl) {
|
||||
ctx.getRestfulClientFactory().setSocketTimeout(10 * 60 * 1000);
|
||||
IGenericClient fhirClient = ctx.newRestfulGenericClient(theBaseUrl);
|
||||
return fhirClient;
|
||||
protected IGenericClient newClient(CommandLine theCommandLine) {
|
||||
return newClient(theCommandLine, BASE_URL_PARAM, BASIC_AUTH_OPTION, BEARER_TOKEN_LONGOPT);
|
||||
}
|
||||
|
||||
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 CommandFailureException(Throwable theCause) {
|
||||
super(theCause.getMessage(), theCause);
|
||||
}
|
||||
|
||||
public CommandFailureException(String 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.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
@ -327,6 +326,8 @@ public class ExampleDataUploader extends BaseCommand {
|
|||
opt.setRequired(false);
|
||||
options.addOption(opt);
|
||||
|
||||
addBasicAuthOption(options);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
@ -573,8 +574,9 @@ public class ExampleDataUploader extends BaseCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws Exception {
|
||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
parseFhirContext(theCommandLine);
|
||||
FhirContext ctx = getFhirContext();
|
||||
|
||||
String targetServer = theCommandLine.getOptionValue("t");
|
||||
if (isBlank(targetServer)) {
|
||||
|
@ -613,17 +615,22 @@ public class ExampleDataUploader extends BaseCommand {
|
|||
|
||||
boolean cacheFile = theCommandLine.hasOption('c');
|
||||
|
||||
Collection<File> inputFiles = loadFile(ctx, specUrl, filepath, cacheFile);
|
||||
|
||||
for (File inputFile : inputFiles) {
|
||||
IBaseBundle bundle = getBundleFromFile(limit, inputFile, ctx);
|
||||
processBundle(ctx, bundle);
|
||||
sendBundleToTarget(targetServer, ctx, bundle);
|
||||
Collection<File> inputFiles = null;
|
||||
try {
|
||||
inputFiles = loadFile(specUrl, filepath, cacheFile);
|
||||
for (File inputFile : inputFiles) {
|
||||
IBaseBundle bundle = getBundleFromFile(limit, inputFile, ctx);
|
||||
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);
|
||||
|
||||
for (Iterator<IBaseResource> iter = resources.iterator(); iter.hasNext(); ) {
|
||||
|
@ -707,7 +714,7 @@ public class ExampleDataUploader extends BaseCommand {
|
|||
} else {
|
||||
ourLog.info("Uploading bundle to server: " + targetServer);
|
||||
|
||||
IGenericClient fhirClient = newClient(ctx, targetServer);
|
||||
IGenericClient fhirClient = newClient(theCommandLine);
|
||||
fhirClient.registerInterceptor(new GZipContentInterceptor());
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.cli;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
|
||||
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.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
|
@ -16,6 +17,8 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
public class IgPackUploader extends BaseCommand {
|
||||
|
@ -48,20 +51,31 @@ public class IgPackUploader extends BaseCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws ParseException, Exception {
|
||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
||||
public void run(CommandLine theCommandLine) throws ParseException{
|
||||
parseFhirContext(theCommandLine);
|
||||
|
||||
String targetServer = theCommandLine.getOptionValue("t");
|
||||
IGenericClient client = ctx.newRestfulGenericClient(targetServer);
|
||||
IGenericClient client = newClient(theCommandLine);
|
||||
|
||||
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) {
|
||||
FhirContext ctx = getFhirContext();
|
||||
switch (ctx.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
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);
|
||||
for (IBaseResource nextResource : conformanceResources) {
|
||||
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 org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RunServerCommand.class);
|
||||
public static final String RUN_SERVER_COMMAND = "run-server";
|
||||
private int myPort;
|
||||
|
||||
private Server myServer;
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "run-server";
|
||||
return RUN_SERVER_COMMAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,6 +69,8 @@ public class RunServerCommand extends BaseCommand {
|
|||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
parseFhirContext(theCommandLine);
|
||||
|
||||
myPort = parseOptionInteger(theCommandLine, OPTION_P, DEFAULT_PORT);
|
||||
|
||||
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);
|
||||
File tempWarFile;
|
||||
|
|
|
@ -1,28 +1,32 @@
|
|||
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.FhirVersionEnum;
|
||||
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.interceptor.BearerTokenAuthInterceptor;
|
||||
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 {
|
||||
|
||||
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
|
||||
public String getCommandDescription() {
|
||||
return "Uploads a terminology package (e.g. a SNOMED CT ZIP file) to a HAPI JPA server. "
|
||||
+ "Note that this command uses a custom operation that is only implemented on HAPI "
|
||||
+ "JPA servers that have been configured to accept it.";
|
||||
return "Uploads a terminology package (e.g. a SNOMED CT ZIP file) to a server, using the $" + UPLOAD_EXTERNAL_CODE_SYSTEM + " operation.";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,28 +49,27 @@ public class UploadTerminologyCommand extends BaseCommand {
|
|||
opt.setRequired(false);
|
||||
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);
|
||||
options.addOption(opt);
|
||||
|
||||
opt = new Option("b", "bearer-token", true, "Bearer token to add to the request");
|
||||
opt.setRequired(false);
|
||||
options.addOption(opt);
|
||||
addBasicAuthOption(options);
|
||||
|
||||
opt = new Option("v", "verbose", false, "Verbose output");
|
||||
opt.setRequired(false);
|
||||
options.addOption(opt);
|
||||
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws Exception {
|
||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
parseFhirContext(theCommandLine);
|
||||
FhirContext ctx = getFhirContext();
|
||||
|
||||
String targetServer = theCommandLine.getOptionValue("t");
|
||||
String targetServer = theCommandLine.getOptionValue(BASE_URL_PARAM);
|
||||
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) {
|
||||
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)) {
|
||||
throw new ParseException("No URL provided");
|
||||
}
|
||||
|
||||
|
||||
String[] datafile = theCommandLine.getOptionValues("d");
|
||||
if (datafile == null || datafile.length == 0) {
|
||||
throw new ParseException("No data file provided");
|
||||
}
|
||||
|
||||
|
||||
String bearerToken = theCommandLine.getOptionValue("b");
|
||||
|
||||
IGenericClient client = super.newClient(ctx, targetServer);
|
||||
IGenericClient client = super.newClient(theCommandLine);
|
||||
IBaseParameters inputParameters;
|
||||
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
Parameters p = new Parameters();
|
||||
|
@ -103,12 +106,12 @@ public class UploadTerminologyCommand extends BaseCommand {
|
|||
if (theCommandLine.hasOption('v')) {
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
}
|
||||
|
||||
|
||||
ourLog.info("Beginning upload - This may take a while...");
|
||||
IBaseParameters response = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("upload-external-code-system")
|
||||
.named(UPLOAD_EXTERNAL_CODE_SYSTEM)
|
||||
.withParameters(inputParameters)
|
||||
.execute();
|
||||
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.fusesource.jansi.Ansi.ansi;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.SingleValidationMessage;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import com.phloc.commons.io.file.FileUtils;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.text.WordUtils;
|
||||
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.instance.model.api.IBaseResource;
|
||||
|
||||
import com.phloc.commons.io.file.FileUtils;
|
||||
import java.io.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.*;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.fusesource.jansi.Ansi.ansi;
|
||||
|
||||
public class ValidateCommand extends BaseCommand {
|
||||
|
||||
|
@ -54,7 +56,9 @@ public class ValidateCommand extends BaseCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws ParseException, Exception {
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
parseFhirContext(theCommandLine);
|
||||
|
||||
String fileName = theCommandLine.getOptionValue("n");
|
||||
String contents = theCommandLine.getOptionValue("c");
|
||||
if (isNotBlank(fileName) && isNotBlank(contents)) {
|
||||
|
@ -68,7 +72,11 @@ public class ValidateCommand extends BaseCommand {
|
|||
String encoding = theCommandLine.getOptionValue("e", "UTF-8");
|
||||
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()));
|
||||
}
|
||||
|
||||
|
@ -77,7 +85,7 @@ public class ValidateCommand extends BaseCommand {
|
|||
throw new ParseException("Could not detect encoding (json/xml) of contents");
|
||||
}
|
||||
|
||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
||||
FhirContext ctx = getFhirContext();
|
||||
FhirValidator val = ctx.newValidator();
|
||||
|
||||
IBaseResource localProfileResource = null;
|
||||
|
|
|
@ -100,10 +100,12 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
|
||||
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);
|
||||
options.addOption(opt);
|
||||
|
||||
addBasicAuthOption(options);
|
||||
|
||||
opt = new Option("e", "exclude", true, "Exclude uploading the given resources, e.g. \"-e dicom-dcim,foo\"");
|
||||
opt.setRequired(false);
|
||||
options.addOption(opt);
|
||||
|
@ -113,6 +115,8 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
parseFhirContext(theCommandLine);
|
||||
|
||||
String targetServer = theCommandLine.getOptionValue("t");
|
||||
if (isBlank(targetServer)) {
|
||||
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'");
|
||||
}
|
||||
|
||||
FhirContext ctx = getSpecVersionContext(theCommandLine);
|
||||
FhirContext ctx = getFhirContext();
|
||||
String exclude = theCommandLine.getOptionValue("e");
|
||||
|
||||
if (isNotBlank(exclude)) {
|
||||
|
@ -134,18 +138,19 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
}
|
||||
|
||||
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU2) {
|
||||
uploadDefinitionsDstu2(targetServer, ctx);
|
||||
uploadDefinitionsDstu2(theCommandLine, ctx);
|
||||
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
|
||||
uploadDefinitionsDstu3(targetServer, ctx);
|
||||
uploadDefinitionsDstu3(theCommandLine, ctx);
|
||||
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.R4) {
|
||||
uploadDefinitionsR4(targetServer, ctx);
|
||||
uploadDefinitionsR4(theCommandLine, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void uploadDefinitionsDstu2(String targetServer, FhirContext ctx) throws CommandFailureException {
|
||||
IGenericClient client = newClient(ctx, targetServer);
|
||||
ourLog.info("Uploading definitions to server: " + targetServer);
|
||||
private void uploadDefinitionsDstu2(CommandLine theCommandLine, FhirContext ctx) throws CommandFailureException {
|
||||
IGenericClient client = newClient(theCommandLine);
|
||||
|
||||
ourLog.info("Uploading definitions to server");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
|
@ -242,9 +247,9 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
||||
}
|
||||
|
||||
private void uploadDefinitionsDstu3(String targetServer, FhirContext ctx) throws CommandFailureException {
|
||||
IGenericClient client = newClient(ctx, targetServer);
|
||||
ourLog.info("Uploading definitions to server: " + targetServer);
|
||||
private void uploadDefinitionsDstu3(CommandLine theCommandLine, FhirContext theCtx) throws CommandFailureException {
|
||||
IGenericClient client = newClient(theCommandLine);
|
||||
ourLog.info("Uploading definitions to server");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
int total = 0;
|
||||
|
@ -253,12 +258,12 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
String vsContents;
|
||||
|
||||
try {
|
||||
ctx.getVersion().getPathToSchemaDefinitions();
|
||||
theCtx.getVersion().getPathToSchemaDefinitions();
|
||||
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/" + "valuesets.xml"), "UTF-8");
|
||||
} catch (IOException e) {
|
||||
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);
|
||||
|
||||
total = bundle.getEntry().size();
|
||||
|
@ -267,7 +272,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
|
||||
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});
|
||||
try {
|
||||
|
@ -287,7 +292,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
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);
|
||||
|
||||
total = bundle.getEntry().size();
|
||||
|
@ -310,7 +315,7 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
} catch (IOException e) {
|
||||
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);
|
||||
total = bundle.getEntry().size();
|
||||
count = 1;
|
||||
|
@ -329,9 +334,9 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
ourLog.info("Finished uploading ValueSets");
|
||||
|
||||
|
||||
uploadDstu3Profiles(ctx, client, "profiles-resources");
|
||||
uploadDstu3Profiles(ctx, client, "profiles-types");
|
||||
uploadDstu3Profiles(ctx, client, "profiles-others");
|
||||
uploadDstu3Profiles(theCtx, client, "profiles-resources");
|
||||
uploadDstu3Profiles(theCtx, client, "profiles-types");
|
||||
uploadDstu3Profiles(theCtx, client, "profiles-others");
|
||||
|
||||
ourLog.info("Finished uploading ValueSets");
|
||||
|
||||
|
@ -340,9 +345,9 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
||||
}
|
||||
|
||||
private void uploadDefinitionsR4(String theTargetServer, FhirContext theCtx) throws CommandFailureException {
|
||||
IGenericClient client = newClient(theCtx, theTargetServer);
|
||||
ourLog.info("Uploading definitions to server: " + theTargetServer);
|
||||
private void uploadDefinitionsR4(CommandLine theCommandLine, FhirContext theCtx) throws CommandFailureException {
|
||||
IGenericClient client = newClient(theCommandLine);
|
||||
ourLog.info("Uploading definitions to server");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
int total = 0;
|
||||
|
|
|
@ -1,30 +1,22 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
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.annotations.*;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
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 {
|
||||
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 ourLog = org.slf4j.LoggerFactory.getLogger(WebsocketSubscribeCommand.class);
|
||||
|
||||
private boolean myQuit;
|
||||
|
@ -38,6 +30,7 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||
public String getCommandName() {
|
||||
return "subscription-client";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options getOptions() {
|
||||
Options options = new Options();
|
||||
|
@ -45,15 +38,16 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||
options.addOption("i", "subscriptionid", true, "Subscription ID, e.g. \"5235\"");
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws ParseException, Exception {
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
String target = theCommandLine.getOptionValue("t");
|
||||
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\"");
|
||||
}
|
||||
|
||||
|
||||
IdDt subsId = new IdDt(theCommandLine.getOptionValue("i"));
|
||||
|
||||
|
||||
WebSocketClient client = new WebSocketClient();
|
||||
SimpleEchoSocket socket = new SimpleEchoSocket(subsId.getIdPart());
|
||||
try {
|
||||
|
@ -68,6 +62,8 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||
}
|
||||
|
||||
ourLog.info("Shutting down websocket client");
|
||||
} catch (Exception e) {
|
||||
throw new CommandFailureException(e);
|
||||
} finally {
|
||||
try {
|
||||
client.stop();
|
||||
|
@ -76,7 +72,7 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Basic Echo Client Socket
|
||||
*/
|
||||
|
@ -84,7 +80,7 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||
public class SimpleEchoSocket {
|
||||
|
||||
private String mySubsId;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Session session;
|
||||
|
||||
|
@ -93,17 +89,6 @@ public class WebsocketSubscribeCommand extends BaseCommand {
|
|||
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
|
||||
public void onClose(int statusCode, String 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
|
||||
public void onMessage(String theMsg) {
|
||||
LOG_RECV.info("{}", theMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<useJansi>true</useJansi>
|
||||
<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>
|
||||
</encoder>
|
||||
</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" />
|
||||
</logger>
|
||||
|
||||
|
@ -20,6 +23,15 @@
|
|||
<appender-ref ref="STDOUT" />
|
||||
</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">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
|
|
@ -127,6 +127,9 @@ fi
|
|||
|
||||
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
|
||||
COLUMNS=$(tput cols)
|
||||
|
||||
exec "$JAVACMD" \
|
||||
-Dcolumns=$COLUMNS \
|
||||
$CLI_OPTS \
|
||||
-jar $SCRIPTDIR/hapi-fhir-cli.jar "$@"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
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.Test;
|
||||
|
||||
import ca.uhn.fhir.cli.App;
|
||||
|
||||
public class ValidateTest {
|
||||
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();
|
||||
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>
|
||||
<version>${commons_codec_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.14</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
|
|
Loading…
Reference in New Issue