glacieruploader
glacieruploader copied to clipboard
Add a flag to output data in JSON
It would be nice to have a way to output the data in JSON to make it machine-parsable.
The use case here is to have a script that operates at a high-level while glacieruploader handles all of the operations/credentials.
Part of the changes that seems to be done include:
- adding an option: "--json-output" and "-j"
- redirecting the logging output to the error stream (to separate data and logs)
- passing a new boolean to all commands: json_output
- displaying in JSON when asked
Good idea. I'm using more and more JSON output myself, so I can understand the usecase. Will see how easy it is to add JSON.
Thanks for the feedback!
I added https://github.com/MoriTanosuke/glacieruploader/blob/master/src/main/java/de/kopis/glacier/printers/VaultPrinter.java pretty early, but it's hardcoded in a lot of places and probably not fit for the task.
At the moment the Commands do not output anything, just logging. Also there is no return value, so probably the exec
method https://github.com/MoriTanosuke/glacieruploader/blob/master/src/main/java/de/kopis/glacier/commands/AbstractCommand.java#L74 needs to return an optional CommandResult
to https://github.com/MoriTanosuke/glacieruploader/blob/master/src/main/java/de/kopis/glacier/GlacierUploader.java#L111 where I can then instantiate a new CommandPrinter
with a JSON implementation. Will take a closer look in the evening.
I've got a working prototype that works but i'm not a big fan of having to have the printer have a switch for raw/json.
I also had to make it output an array of JSON objects instead so I used a single instance of the printer and buffered the output until it's flushed. The auto-flush is ensure using the try-with-resource block which works nicely.
I'm thinking of keeping the printers but trying to have different classes and have something along the lines:
- VaultPrinter (abstract)
- VaultTextPrinter
- VaultJSONPrinter
- VaultPrinterFactory
It might be over-engineering the thing :-)
I'll put theses changes up tomorrow night (PST time).
Nice, that would be a great starting point. 👍 I'd expect a major refactoring for this in any case, so I'll start thinking about it as well.
What comes to mind first is a modification on the interface for AbstractCommand
like this:
public abstract Optional<CommandResult> exec(OptionSet options, GlacierUploaderOptionParser optionParser);
Then all commands can return a CommandResult
with a definitive status and a custom message. Probably an exception as well. Could look like this:
package de.kopis.glacier.commands;
import com.amazonaws.AmazonClientException;
public class CommandResult {
public enum CommandResultStatus {
SUCCESS,
FAILURE,
UNKNOWN
}
private final String message;
private final CommandResultStatus status;
private Exception exception;
public CommandResult(CommandResultStatus failure, String s, AmazonClientException exception) {
this(failure, s);
this.exception = exception;
}
public CommandResult(CommandResultStatus status, String message) {
this.status = status;
this.message = message;
}
public Exception getException() {
return exception;
}
public String getMessage() {
return message;
}
public CommandResultStatus getStatus() {
return status;
}
}
There should still be something like a XXX
, maybe like this:
package de.kopis.glacier.printers;
import de.kopis.glacier.commands.CommandResult;
import java.io.PrintStream;
public class JsonCommandResultPrinter {
public void print(PrintStream out, CommandResult result) {
//TODO create JSON representation of CommandResult
}
}
That way the GlacierUploader
can still use different implementations, switchable by command line parameters at https://github.com/MoriTanosuke/glacieruploader/blob/master/src/main/java/de/kopis/glacier/GlacierUploader.java#L111
I'll give it a go and see how far I come.
@Megra Does this sound like what you had in mind in any case :question:
Ok, I pushed my local branch. See https://github.com/MoriTanosuke/glacieruploader/tree/optional-command-responses for my changes so far and let me know what you think. I'll leave the branch open until this issue is solved.
I pushed a small change to the branch and https://github.com/MoriTanosuke/glacieruploader/blob/optional-command-responses/src/main/java/de/kopis/glacier/GlacierUploader.java#L119 now takes the CommandResult
and prints it to STDOUT.
This is what I got for an invalid command:
INFO Using end point: https://glacier.eu-west-1.amazonaws.com
INFO Creating vault myvaultname...
ERROR Couldn't create vault.
{status: 'FAILURE', message: 'Can not create vault: The security token included in the request is invalid. (Service: AmazonGlacier; Status Code: 403; Error Code: UnrecognizedClientException; Request ID: Uh0rH-Z7UTmUzmIv1YlJ3FR-MNZhUZy1yNC81yipzEza4sc)', requestId: 'Uh0rH-Z7UTmUzmIv1YlJ3FR-MNZhUZy1yNC81yipzEza4sc', exception: 'class com.amazonaws.AmazonServiceException'}
The first 3 lines are from my logging configuration. The last line prints the result as a JSON String. If there is a more information from the Amazon classes available, there would also be a field originalMessage with more information.
I also added the request ID in its own field in the JSON for easier access. Should be useful if a script has to remember or report those errors.