Git Product home page Git Product logo

mirthsync's Introduction

mirthSync

mirthSync is a command line tool for synchronizing Mirth Connect code between servers by allowing you to push or pull channels, code templates, configuration map and global scripts. The tool can also be integrated with Git or other version control systems for the purpose of tracking changes to Mirth Connect code and configuration.

The only requirements are having credentials for the server that is being synced and the server also needs to support and allow access to Mirth Connect's REST API.

Suggestions for use

  • Use mirthSync in conjunction with Git (or any VCS) to back up and track changes to code and settings
  • Pull and push changes between Mirth Connect servers
  • Utilize Git branches to track and merge code between dev, test, and prod environments
  • Use mirthSync as part of your CI/CD workflow
    • Please see our mirthsync-ci repository for an example that works with Github Actions
  • Work on mirth javascript locally with your favorite editor without having to edit XML

Current version

The latest version of mirthSync is "3.1.0". Note the changes below. Version 3 of mirthSync changed the layout of the target directory structure. Javascript is extracted into separate files and top level channels are now placed in a default group directory.

Changes

3.1.0

  • NOTE that this version respects the --include-configuration-map (false by default) parameter during both a "push" and a "pull". Previous versions would always "pull" the configuration map even if the parameter was not set or was false. If you want to include the configuration map now during a "pull" please ensure that you set the flag.

  • New "--skip-disabled" flag to indicate whether the item (only channels currently) being pushed or pulled should be included based on its status. The flag defaults to 'false' and all items are pushed or pulled no matter what the 'enabled' setting is. NOTE - this feature only works on mirth versions >= 3.9.

  • New "--disk-mode" setting that alters behavior around how granular the resulting files are in the target directory.

    • Mode "backup" pushes and pulls a full backup XML file and doesn't produce any other disk artifacts.
    • Mode "groups" pushes and pulls code at the next most granular level which means that channel groups and code template library XML actually contains the assocated channels and javascript
    • Mode "items" extracts code templates and channels from the respective library or group XML.
    • Mode "code" extracts even further pulling all code from XML files into individual language specific files.

3.0.2

  • Support for getting the password from the MIRTHSYNC_PASSWORD environment variable if --password is not specified
  • Prompt for password on console if no password is set, the console is available and the interactive "-I" flag is set
  • Fix bug preventing local modifications from being pushed even with --force flag specified

3.0.1

  • New feature to enable optional deployment of channel(s) during a push

3.0.0

  • Major feature - javascript in channels, code templates, and global scripts is now extracted into its own file
  • Breaking change - place top level channels beneath a 'Default Group' directory
  • restrict-to-path now filters pulls (previously only pushes were filtered)
  • code refactoring to use multimethods instead of passing around functions
  • code clarity work
  • more tests
  • support for Mirth Connect 3.12

2.1.1

  • Support for pushing/pulling Alerts
  • Fix bug related to directory/xml ordering and zip/remove

2.1.0 (Pre-Release)

  • Selective push
  • Testing against mirth 3.11

"2.1.x" versions of mirthSync support selectively pushing/pulling arbitrary paths in the target directory to Mirth. This allows, for instance, the ability to push/pull only the ConfigurationMap or a single channel or channel group by specifying a base path within the target directory to use as a starting point for find the files to push/pull.

NOTE 2.1.x versions include new features that break compatibility in minor ways from the 2.0.x versions.

  • There are new command line options and new defaults for the ConfigurationMap. You must now add a flag to your command line to allow for pushing the ConfigurationMap - without the flag, it will not get included in the push.
  • Resources are now properly included in a push.
  • Alerts are supported

If you're trying out 2.1.x after using 2.0.x, be careful to test thoroughly in a dev environment first.

2.0.10

Small change that shouldn't impact the current directory layout. This change allows for forward and backward slashes in channel group names by encoding the slashes using an HTTP URL encode syntax.

2.0.9

Support for syncing Resources and a more comprehensive test suite for validating functionality across multiple versions of Mirth.

2.0.3-SNAPSHOT

Bi-directional groups support.

You can check out the 2.0.3-SNAPSHOT release here - https://github.com/SagaHealthcareIT/mirthsync/releases/tag/2.0.3-SNAPSHOT

2.0.2-SNAPSHOT

Changed the local directory structure to nest channels within their respective group.

Future plans

  • Support Mirth > version 3.11 (should be ready soon)
  • Extract javascript from xml (should be ready soon)
  • Support filtering pulls just like we currently are able to filter pushes.
  • Addressing reported issues.
  • Implement more tests.

Installation

$ git clone https://github.com/SagaHealthcareIT/mirthsync.git

Prerequisites

Requires Java JRE or JDK version 8 (versions 9 and above are not currently supported)

For MacOS users

To be able to run the script on MacOS, you need to install the following tools:

  • coreutils
  • gnu-sed

like this:

  • brew install coreutils
  • brew install gnu-sed

Put this line in your shell config file (.zshrc or .bashrc) to use commands from coreutils as standard MacOS commands

export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH"

Help

How to generate help dialogue:

$ java -jar mirthsync.jar -h

Help Dialogue:

Usage: mirthsync [options] action

Options:
  -s, --server SERVER_URL                              Full HTTP(s) url of the Mirth Connect server
  -u, --username USERNAME                              Username used for authentication
  -p, --password PASSWORD                  <computed>  Password used for authentication
  -i, --ignore-cert-warnings                           Ignore certificate warnings
  -v                                                   Verbosity level
        May be specified multiple times to increase level.
  -f, --force                                          
        Overwrite existing local files during a pull and overwrite remote items
        without regard for revisions during a push.
  -t, --target TARGET_DIR                              Base directory used for pushing or pulling files
  -m, --disk-mode DISK_MODE                code        Use this flag to specify the target directory
        disk format.
        - backup : Equivalent to Mirth Administrator backup and restore.
        - groups : All items expanded to "Group" or "Library" level.
        - items  : Expand items one level deeper than 'groups' to the individual XML level.
            In other words - Channels and Code Templates are in their own individual
            XML files.
        - code   : Default behavior. Expands everything to the most granular level
            (Javascript, Sql, etc).
  -r, --restrict-to-path RESTRICT_TO_PATH              
        A path within the target directory to limit the scope of the push. This
        path may refer to a filename specifically or a directory. If the path
        refers to a file - only that file will be pushed. If the path refers to
        a directory - the push will be limited to resources contained within
        that directory. The RESTRICT_TO_PATH must be specified relative to
        the target directory.
      --include-configuration-map                       A boolean flag to include the
        configuration map in a push or pull. Default: false
      --skip-disabled                                   A boolean flag that indicates whether
        disabled channels should be pushed or pulled. Default: false
  -d, --deploy                                         Deply channels on push
        During a push, deploy each included channel immediately
        after saving the channel to Mirth.
  -I, --interactive                                    
        Allow for console prompts for user input
  -h, --help

Actions:
  push     Push filesystem code to server
  pull     Pull server code to filesystem

Environment variables:
  MIRTHSYNC_PASSWORD     Alternative to --password command line option

Examples

CLI

NOTE - The "-p" or "--password" option may be omitted from the the commands below if the environment variable MIRTHSYNC_PASSWORD is set. When interactive input is allowed (-I) and no password can be found, you will be prompted to enter the password at the terminal.

How to pull Mirth Connect code from a Mirth Connect instance:

$ java -jar mirthsync.jar -s https://localhost:8443/api -u admin -p admin pull -t /home/user/

Note that the -t parameter accepts absolute and relative paths.

Pulling code from a Mirth Connect instance allowing for overwriting existing files:

$ java -jar mirthsync.jar -s https://localhost:8443/api -u admin -p admin -f pull -t /home/user/

Pushing code to a Mirth Connect instance (doesn't have to be the same instance that the code was originally pulled from):

$ java -jar mirthsync.jar -s https://otherserver.localhost/api -u admin -p admin push -t /home/user/

Pushing a channel group and its channels to a Mirth Connect instance

$ java -jar mirthsync.jar -s https://otherserver.localhost/api -u admin -p admin push -t /home/user/  -r "Channels/This is a group"

Cron

There is a sample script (git-cron-sample.sh) packaged that can be customized and utilized from a cron job and/or the command line. The script can take an optional commit message in cases where it is desirable to immediately pull and commit changes to git with meaningful commit messages.

Sample crontab...

# At 02:24 on every day-of-week from Sunday through Saturday 
24 2 * * 0-6 /opt/mirthsync/git-cron-sample.sh >/dev/null 2>&1

REPL

Pull/Push from a REPL.

The following pulls code to a directory called 'tmp' (relative to the execution environment), overwriting existing files ("-f") and ignoring the validity of the server certificate ("-i"), and then pushes back to the local server from the same directory.

(mirthsync.core/main-func "-s" "https://localhost:8443/api" "-u" "admin" "-p" "admin" "-t" "target/tmp" "-f" "-i" "pull")
(mirthsync.core/main-func "-s" "https://localhost:8443/api" "-u" "admin" "-p" "admin" "-t" "target/tmp" "-f" "-i" "push")

Build from Source

Requires Leiningen

$ lein uberjar

Todo

  • Gracefully handle renames and deletions

License

Copyright © 2017-2022 Saga IT LLC

Distributed under the Eclipse Public License either version 1.0 or any later version.

Disclaimer

This tool is still under development. Use at your own discretion.

mirthsync's People

Contributors

fdawgs avatar jcdlbs avatar jessesaga avatar morgan-saga avatar sagamorgan avatar vikram-rajan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mirthsync's Issues

Resources Not Pulling in 3.1.0

Resources do not pull in 3.1.0 from mirth 4.3.0.

I get the resources AML at the itesm level but it does not contain the reference to the one loaded jarfile in custom-lib. (happens to be the mirthsync jar)

Tried in the root folder and in a new folder.

Jar is loaded into mirth ok, shows in the loaded jars window.

Gracefully handle renames and deletions

Currently, mirthSync does not clean up channels, groups, or code templates that have been renamed or deleted. This can be worked around by deleting all files locally and doing another pull but it would be preferable for mirthSync to handle that logic.

Push stops after Channel Groups fail to be imported

It seems that during a push there are multiple attempts to create the Channel Groups. An underlying DB primary key violation is being thrown. This occurs using the force option too.

←[39mDEBUG←[0;39m: posting xml to: /channelgroups/_bulkUpdate
clojure.lang.ExceptionInfo: clj-http: status 500 {:cached nil, :request-time 125, :repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor 1}, :streaming? true, :http-client #object[org.apache.http.impl.client.InternalHttpClient 0x5a237731 "org.apache.http.impl.client.InternalHttpClient@5a237731"], :chunked? true, :type :clj-http.client/unexceptional-status, :reason-phrase "Internal Server Error", :headers {"Access-Control-Allow-Headers" "Content-Type", "Server" "nginx", "Content-Type" "application/xml", "Access-Control-Allow-Origin" "*", "X-Frame-Options" "DENY", "Strict-Transport-Security" ["max-age=31536000; includeSubDomains" "max-age=31536000; includeSubDomains"], "Connection" "close", "Transfer-Encoding" "chunked", "Access-Control-Allow-Methods" "GET, POST, DELETE, PUT", "Date" "Wed, 27 Apr 2022 15:27:01 GMT", "Access-Control-Allow-Credentials" "false", "Content-Security-Policy" ["frame-ancestors 'none'" "upgrade-insecure-requests"]}, :orig-content-encoding nil, :status 500, :length -1, :body "<com.mirth.connect.client.core.ControllerException>\n org.apache.ibatis.exceptions.PersistenceException: \n### Error updating database. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK__CHANNEL___3214EC27E4615C0E'. Cannot insert duplicate key in object 'dbo.CHANNEL_GROUP'. The duplicate key value is (3e807410-ed18-4217-a4e7-d924df8cc5d4). \n### The error may involve Channel.insertChannelGroup-Inline \n### The error occurred while setting parameters \n### SQL: INSERT INTO CHANNEL_GROUP (ID, NAME, REVISION, CHANNEL_GROUP) VALUES (?, ?, ?, ?) \n### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK__CHANNEL___3214EC27E4615C0E'. Cannot insert duplicate key in object 'dbo.CHANNEL_GROUP'. The duplicate key value is (3e807410-ed18-4217-a4e7-d924df8cc5d4).\n <cause class="com.mirth.connect.client.core.api.PersistenceException">\n \n### Error updating database. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK__CHANNEL___3214EC27E4615C0E'. Cannot insert duplicate key in object 'dbo.CHANNEL_GROUP'. The duplicate key value is (3e807410-ed18-4217-a4e7-d924df8cc5d4). \n### The error may involve Channel.insertChannelGroup-Inline \n### The error occurred while setting parameters \n### SQL: INSERT INTO CHANNEL_GROUP (ID, NAME, REVISION, CHANNEL_GROUP) VALUES (?, ?, ?, ?) \n### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK__CHANNEL___3214EC27E4615C0E'. Cannot insert duplicate key in object 'dbo.CHANNEL_GROUP'. The duplicate key value is (3e807410-ed18-4217-a4e7-d924df8cc5d4).\n <cause class="com.microsoft.sqlserver.jdbc.SQLServerException">\n Violation of PRIMARY KEY constraint 'PK__CHANNEL___3214EC27E4615C0E'. Cannot insert duplicate key in object 'dbo.CHANNEL_GROUP'. The duplicate key value is (3e807410-ed18-4217-a4e7-d924df8cc5d4).\n \n com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)\n com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1632)\n com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:602)\n com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:524)

Can't rebuild Project in intellij

Hi,

I downloaded MirthSync and after some fiddling (first time seeing anything in Clojure) I got it built and can do pulls, yet to try a push anywhere. But, I ran into a problem in intellij, in that it will not build: I get what the error is saying, but I am using the same JVM as the first build, so I don't know how it got built in the first instance!!

I used the uberjar task to build it - was that correct? I assume it was since it built and the pull works!

This is the error, I understand what it means, just not how it can exist 30 minutes after I built the first jar. Luckily I move the jar file out to a "lib" folder just so the batch file would work unedited.

`"C:\Program Files\Amazon Corretto\jdk1.8.0_252\bin\java.exe" -Dfile.encoding=UTF-8 -Dmaven.wagon.http.ssl.easy=false -Dmaven.wagon.rto=10000 -javaagent:C:\Users\Stewart\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\231.9011.34\lib\idea_rt.jar=49929:C:\Users\Stewart\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\231.9011.34\bin -classpath C:\Users\Stewart.lein\self-installs\leiningen-2.10.0-standalone.jar clojure.main -m leiningen.core.main uberjar
Compiling mirthsync.core
Syntax error macroexpanding at (logging.clj:338:3).
Execution error (UnsupportedClassVersionError) at java.lang.ClassLoader/defineClass1 (ClassLoader.java:-2).
ch/qos/logback/classic/spi/LogbackServiceProvider has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

Full report at:
C:\Users\Stewart\AppData\Local\Temp\clojure-7711196913088364982.edn
Compilation failed: Subprocess failed (exit code: 1)

Process finished with exit code 1
`

Files dates matching Mirth's Last Modified

It would be great if local files modification datetimes matched the metadata/lastModified from the channel itself.

Plus: this would call for an update mode:

  • when pulling, allows overwriting for local files that are older than the copy on Mirth, preserving files that where locally modified (thus newer)
  • when pushing, allows overwriting remote channels only if our local copy is newer, preserving channels that where remotelly modified, and also preserving their remote lastUpdate in case no changes were made (locally and remotely).

Option to skip disabled channels

Sometimes major changes to channels are made on cloned channels, preserving their previous version in a disabled state, with the goal of switching back to them in case of problems (rollback).
The whole concept would be ok if we could get rid of those backup channels after a few days or weeks.

That's not always the case, since a few customers like to keep a very large attic of obsolete objects, with the result of having up to 70% of disabled channels.
I wrote a bash script that, using channels' statuses fetched from here /api/channels/statuses?includeUndeployed=false deletes channels from the local mirthsync'd target dir (see attachment).

Now, it works, but it would be certainly more elegant and efficient to have an option switch into mirthsync.
I'd like to provide a patch, but I literally have got no time left to learn another language such as Clojure.

Script:
I had to rename it to .txt in order to upload it.
mirth_purge_disabled.sh.txt

It's a post processing script, but I realize now it would be more practical if it were a wrapper to mirthsync.sh

Update: probably related to these #45, #26, #34

javascript based database reader - code not extracted

hi there,

first i need to say: great development!

i was playing with your tool a bit and found that javascript i use in a database reader source is not extracted as a separate javascript file.
it would be great if that could be extracted as well.

Question: Timing of deploy with new flag

I don't know if this is an issue or not. (It would be nice for you to add a Discussion section to GitHub for questions.)

The help text for the new "--deploy" flag for mirthSync says, "deploy each included channel immediately after saving the channel to Mirth."

That sounds like a problem, as Code Templates are pushed after Channels, so the deploy might occur before the new Code Template code has been pushed. Is the description wrong (i.e., the deploy happens after the rest of the push is complete) or does the deploy really happen immediately after saving each channel?

FYI, the ReadMe refers to version 3.1.0 instead of 3.0.1.

Option to get monolithic channel exports (backward compatibility?)

Current version unpacks channels in their sub components, introducing references to external files in the channel export xml, in the form of msync-fileref attributes.

It would be great to also have an alternative "monolithic" mode to export channels with their standard xml, in a way that they can be imported using Mirth itself, instead of issuing a mirthsynch push.
I would be using both modes (unpacked and monolithic) for different purposes.
I just made a PoC using Mirth API, I see I could get this done with curl and a bash script, but of course having it all in the same tool would be ideal.

If I understand correctly from issue #27, the current behaviour replaced a mode that sounds very similar to what I'm asking, so maybe I'm just requesting some kind of backward compatibility switch.

Deploy all channels in one API call.

Please add an option to --deploy so that it issues one API call to deploy all of the loaded channels at the end, rather than deploying each as it is loaded. This would allow Mirth's dependency logic to control which channels are deployed first.

HTTP method POST is not supported by this URL

When I try to use mirthSync to connect to a Mirth server in our workplace, I get the following response:

/usr/bin/java
found java executable in PATH
version 1.8.0_211
Authenticating to server at http://10.250.10.100:8000/api as admin
Exception in thread "main" clojure.lang.ExceptionInfo: clj-http: status 405 {:cached nil, :request-time 333, :repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor 1}, :streaming? true, :http-client #object[org.apache.http.impl.client.InternalHttpClient 0x7c2a69b4 "org.apache.http.impl.client.InternalHttpClient@7c2a69b4"], :chunked? false, :type :clj-http.client/unexceptional-status, :reason-phrase "HTTP method POST is not supported by this URL", :headers {"Date" "Thu, 17 Oct 2019 17:22:44 GMT", "Cache-Control" "must-revalidate,no-cache,no-store", "Content-Type" "text/html;charset=iso-8859-1", "Content-Length" "369", "Connection" "close", "Server" "Jetty(9.3.14.v20161028)"}, :orig-content-encoding nil, :status 405, :length 369, :body "\n\n<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>\n<title>Error 405 </title>\n\n\n

HTTP ERROR: 405

\n

Problem accessing /api/users/login. Reason:\n

    HTTP method POST is not supported by this URL

\n
<a href="http://eclipse.org/jetty\">Powered by Jetty:// 9.3.14.v20161028
\n\n\n", :trace-redirects []}
at slingshot.support$stack_trace.invoke(support.clj:201)
at clj_http.client$exceptions_response.invokeStatic(client.clj:245)
at clj_http.client$exceptions_response.invoke(client.clj:236)
at clj_http.client$wrap_exceptions$fn__2394.invoke(client.clj:254)
at clj_http.client$wrap_accept$fn__2596.invoke(client.clj:737)
at clj_http.client$wrap_accept_encoding$fn__2603.invoke(client.clj:759)
at clj_http.client$wrap_content_type$fn__2590.invoke(client.clj:720)
at clj_http.client$wrap_form_params$fn__2689.invoke(client.clj:961)
at clj_http.client$wrap_nested_params$fn__2710.invoke(client.clj:995)
at clj_http.client$wrap_flatten_nested_params$fn__2719.invoke(client.clj:1019)
at clj_http.client$wrap_method$fn__2657.invoke(client.clj:895)
at clj_http.cookies$wrap_cookies$fn__1074.invoke(cookies.clj:131)
at clj_http.links$wrap_links$fn__2199.invoke(links.clj:63)
at clj_http.client$wrap_unknown_host$fn__2727.invoke(client.clj:1048)
at clj_http.client$request_STAR
.invokeStatic(client.clj:1176)
at clj_http.client$request_STAR_.invoke(client.clj:1169)
at clj_http.client$post.invokeStatic(client.clj:1194)
at clj_http.client$post.doInvoke(client.clj:1190)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at mirthsync.http_client$with_authentication.invokeStatic(http_client.clj:45)
at mirthsync.http_client$with_authentication.invoke(http_client.clj:39)
at mirthsync.core$run.invokeStatic(core.clj:19)
at mirthsync.core$run.invoke(core.clj:8)
at mirthsync.core$_main.invokeStatic(core.clj:39)
at mirthsync.core$_main.doInvoke(core.clj:35)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at mirthsync.core.main(Unknown Source)

I need help

This error occurred when I was
5(R@L4GF$1KAMQI)ODETS
pushing code to the server

Exception in thread "main" java.lang.Exception: called children on a leaf node

This problem seems to be occurring again.

The push command works fine when ran against a clean mirth instance. But when I do a force push against an instance which has channels, code templates and global scripts the command fails.

CMD:
java -jar mirthsync/mirthsync.jar -s https://localhost:8444/api -u admin -p admin push -f -i -t .

Exception:
Authenticating to server at https://localhost:8444/api as admin
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x0000000800b7d440 (file:/Users/vikramrajan/dev/bpm/fhir-mirth/mirthsync/mirthsync.jar) to method com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLStreamReader(java.io.Reader)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x0000000800b7d440
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Uploading from ./. to /server/configurationMap
File: ././ConfigurationMap.xml
Uploading from ./GlobalScripts to /server/globalScripts
File: ./GlobalScripts/globalScripts.xml
Uploading from ./CodeTemplates to /codeTemplateLibraries
File: ./CodeTemplates/FHIR Helper Functions/index.xml
Exception in thread "main" java.lang.Exception: called children on a leaf node
at clojure.zip$children.invokeStatic(zip.clj:80)
at clojure.zip$append_child.invokeStatic(zip.clj:223)
at clojure.zip$append_child.invoke(zip.clj:223)
at mirthsync.apis$pre_node_action.invokeStatic(apis.clj:73)
at mirthsync.apis$pre_node_action.invoke(apis.clj:53)
at clojure.core$partial$fn__5828.invoke(core.clj:2638)
at mirthsync.actions$process.invokeStatic(actions.clj:73)
at mirthsync.actions$process.invoke(actions.clj:62)
at mirthsync.actions$upload.invokeStatic(actions.clj:97)
at mirthsync.actions$upload.invoke(actions.clj:90)
at mirthsync.apis$apis_action.invokeStatic(apis.clj:277)
at mirthsync.apis$apis_action.invoke(apis.clj:271)
at mirthsync.core$run$fn__3283.invoke(core.clj:25)
at mirthsync.http_client$with_authentication.invokeStatic(http_client.clj:49)
at mirthsync.http_client$with_authentication.invoke(http_client.clj:37)
at mirthsync.core$run.invokeStatic(core.clj:21)
at mirthsync.core$run.invoke(core.clj:10)
at mirthsync.core$_main.invokeStatic(core.clj:48)
at mirthsync.core$_main.doInvoke(core.clj:39)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at mirthsync.core.main(Unknown Source)

Sort configuration map alphabetically when exporting

Problem
Currently, the order of key-value pairs in the exported configuration map (XML) is not deterministic. This makes it difficult to compare differences between two exported configuration maps.

Solution
I propose to sort the configuration map alphabetically by key during export.

Background
We have a reference MirtConnect server where we do the development of channels etc. When the development is done, we do an export using mirthsync. This export is distributed to several other Mirth servers.
Before the export can be imported on those servers, the configuration map currently used on that server and the one from the export have to be compared and merged (so that new configuration entries are added and existing entries are not overwritten by the values from the export). This task is currently difficult because the order of the configuration map entries changes from time to time, causing diff tools to not work properly.
If both configuration maps were sorted by key, it would be much easier to see the differences between them (especially when using Linux's diff tool or similar).

push -f for Code Template Libraries and Channel Groups

I'm using mirthSync 3.0.0.

If I have a Code Template Library and/or a Channel Group that has (a) has different revision numbers in Mirth and in the XML and (b) any modifications, I get the following, even with "push -f":

←[31mWARN ←[0;39m: An unexpected response was received from the server...
←[31mWARN ←[0;39m: Status: 200, Phrase: OK

This seems to be the same as #8, which supposedly was resolved in #9.

Authentication issue with Connect 3.12

mirthsync version: 2.1.1
connect version: 3.12

MirthSync is returning a 400 error when authenticating, which is likely related to a CSRF fix in Connect 3.12 (https://github.com/nextgenhealthcare/connect/wiki/3.12.0---What's-New) and the new require-requested-with setting:

/usr/bin/java found java executable in PATH version 11.0.11 Authenticating to server at https://localhost:8443/api as admin clojure.lang.ExceptionInfo: clj-http: status 400 {:cached nil, :request-time 270, :repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor 1}, :streaming? true, :http-client #object[org.apache.http.impl.client.InternalHttpClient 0x4f486211 "org.apache.http.impl.client.InternalHttpClient@4f486211"], :chunked? false, :type :clj-http.client/unexceptional-status, :reason-phrase "Bad Request", :headers {"Access-Control-Allow-Headers" "Content-Type", "Server" "Jetty(9.4.21.v20190926)", "Content-Type" "text/html;charset=iso-8859-1", "Access-Control-Allow-Origin" "*", "Content-Length" "653", "X-Frame-Options" "DENY", "Connection" "close", "Access-Control-Allow-Methods" "GET, POST, DELETE, PUT", "Access-Control-Allow-Credentials" "false", "Content-Security-Policy" "frame-ancestors 'none'", "Cache-Control" "must-revalidate,no-cache,no-store"}, :orig-content-encoding nil, :status 400, :length 653, :body "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\n<title>Error 400 All requests must have &apos;X-Requested-With&apos; header</title>\n</head>\n<body><h2>HTTP ERROR 400 All requests must have &apos;X-Requested-With&apos; header</h2>\n<table>\n<tr><th>URI:</th><td>/api/users/_login</td></tr>\n<tr><th>STATUS:</th><td>400</td></tr>\n<tr><th>MESSAGE:</th><td>All requests must have &apos;X-Requested-With&apos; header</td></tr>\n<tr><th>SERVLET:</th><td>org.glassfish.jersey.servlet.ServletContainer-7dd8c3da</td></tr>\n</table>\n<hr><a href=\"http://eclipse.org/jetty\">Powered by Jetty:// 9.4.21.v20190926</a><hr/>\n\n</body>\n</html>\n", :trace-redirects []} at slingshot.support$stack_trace.invoke(support.clj:201) at clj_http.client$exceptions_response.invokeStatic(client.clj:240) at clj_http.client$exceptions_response.invoke(client.clj:231) at clj_http.client$wrap_exceptions$fn__2641.invoke(client.clj:249) at clj_http.client$wrap_accept$fn__2851.invoke(client.clj:726) at clj_http.client$wrap_accept_encoding$fn__2858.invoke(client.clj:748) at clj_http.client$wrap_content_type$fn__2845.invoke(client.clj:709) at clj_http.client$wrap_form_params$fn__2944.invoke(client.clj:950) at clj_http.client$wrap_nested_params$fn__2965.invoke(client.clj:984) at clj_http.client$wrap_flatten_nested_params$fn__2974.invoke(client.clj:1008) at clj_http.client$wrap_method$fn__2912.invoke(client.clj:884) at clj_http.cookies$wrap_cookies$fn__1320.invoke(cookies.clj:131) at clj_http.links$wrap_links$fn__2446.invoke(links.clj:63) at clj_http.client$wrap_unknown_host$fn__2982.invoke(client.clj:1037) at clj_http.client$request_STAR_.invokeStatic(client.clj:1165) at clj_http.client$request_STAR_.invoke(client.clj:1158) at clj_http.client$post.invokeStatic(client.clj:1183) at clj_http.client$post.doInvoke(client.clj:1179) at clojure.lang.RestFn.invoke(RestFn.java:423) at mirthsync.http_client$with_authentication.invokeStatic(http_client.clj:47) at mirthsync.http_client$with_authentication.invoke(http_client.clj:41) at mirthsync.core$run.invokeStatic(core.clj:21) at mirthsync.core$run.invoke(core.clj:10) at mirthsync.core$main_func$fn__3394.invoke(core.clj:46) at mirthsync.core$main_func.invokeStatic(core.clj:45) at mirthsync.core$main_func.doInvoke(core.clj:37) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invokeStatic(core.clj:665) at clojure.core$apply.invoke(core.clj:660) at mirthsync.core$_main.invokeStatic(core.clj:57) at mirthsync.core$_main.doInvoke(core.clj:55) at clojure.lang.RestFn.applyTo(RestFn.java:137) at mirthsync.core.main(Unknown Source) clj-http: status 400

Thanks for this project!

Channels and groups not removed on push

When I push my configuration to mirth, the existing channels/groups that exist in Mirth but not in the configuration folder are not removed.

I expect to have the exact same configuration in Mirth and in git after push. This is useful e.g. when switching from branch to another with different channels and groups.

For information, I use the following command for push:

mirthsync push --force --server $server --username $username --password $password --target ./mirth --ignore-cert-warnings --include-configuration-map

Is this by design? Is it a bug or a feature? Maybe my use case is different than yours.

I am willing to develop this functionality in a PR.

File not found when pulling

When I pull from our dev env I see this error and it aborts.

.\Channels\Scheduling\AriaIE API - Appointments - Dest BIG DB\sourceConnector-transformer-step-0.js (The system cannot find the path specified)

Any ideas why this would happen? In our Prod it worked fine.

mirthsync -s https://url:8443/api -u xx -p xx -i -f -t . pull

Add support for pushing configuration map

Mirthsync doesn't currently push the configuration map - it only pulls the configuration map. It would be useful to have an additional flag to tell Mirthsync to push the configuration map instead of omitting it.

Unable to add new code templates to existing code template libraries while doing a push -f

Hi,

I am facing a problem where I am not able to push a recently created code template. I have made sure the index.xml contains the new code template's UUID.

Steps to replicate the problem:

  1. There are 2 Mirth connect instances that are identical DEV and TEST.
  2. Created the new code template in DEV using Mirth GUI.
  3. Did a mirthsync pull to a local directory from the DEV environment
  4. Did a mirthsync push from local directory to the TEST environment which has everything except the newly created code template.

CMD: java -jar ~/dev/bpm/mirthsync/target/uberjar/mirthsync-2.0.7-standalone.jar -s https://dev:8444/api -u admin -p admin -f pull -i -t .

CMD: java -jar ~/dev/bpm/mirthsync/target/uberjar/mirthsync-2.0.7-standalone.jar -s https://test:8444/api -u admin -p admin -f push -i -t .

'Exception in thread "main" java.lang.Exception: called children on a leaf node'

Exception in thread "main" java.lang.Exception: called children on a leaf node
	at clojure.zip$children.invokeStatic(zip.clj:80)
	at clojure.zip$append_child.invokeStatic(zip.clj:223)
	at clojure.zip$append_child.invoke(zip.clj:223)
	at mirthsync.apis$pre_node_action.invokeStatic(apis.clj:72)
	at mirthsync.apis$pre_node_action.invoke(apis.clj:52)
	at clojure.core$partial$fn__5828.invoke(core.clj:2638)
	at mirthsync.actions$process.invokeStatic(actions.clj:65)
	at mirthsync.actions$process.invoke(actions.clj:54)
	at mirthsync.actions$upload.invokeStatic(actions.clj:89)
	at mirthsync.actions$upload.invoke(actions.clj:82)
	at mirthsync.apis$apis_action.invokeStatic(apis.clj:225)
	at mirthsync.apis$apis_action.invoke(apis.clj:219)
	at mirthsync.core$run$fn__3047.invoke(core.clj:23)
	at mirthsync.http_client$with_authentication.invokeStatic(http_client.clj:51)
	at mirthsync.http_client$with_authentication.invoke(http_client.clj:39)
	at mirthsync.core$run.invokeStatic(core.clj:19)
	at mirthsync.core$run.invoke(core.clj:8)
	at mirthsync.core$_main.invokeStatic(core.clj:39)
	at mirthsync.core$_main.doInvoke(core.clj:35)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at mirthsync.core.main(Unknown Source)

I get the above error trying to use our Jenkins server to deploy our updated mirth code to our other environments. I'm able to use the same exact script I'm calling in the Jenkins' job on my local machine, both using my windows powershell terminal and in my Linux subsystem terminal.

both the Jenkins server and my linux terminal are running this java version

OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.16.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

and I'm running the most recent release snapshot

Any help anyone can provide I would be very grateful for.

Called children on a leaf node

#2 seems to be the same as this but it was closed.

i'm noticing this happens with every import unless i log into mirth and disassociate all channels from their groups and do a push again:

image

In another scenario - i can delete one group and all its channels - it still fails with the exact same error. viewing the server, i can see that the channel groups get created and no channels have been imported yet before it fails.

Failure(s) were encountered during the push with An unexpected response was received from the server

I saw this today while testing.

mirthsync -s https://localhost:8443/api -u admin-p admin -i -t . push

WARN : An unexpected response was received from the server...
WARN : Status: 200, Phrase: OK, Body: {"boolean":false}

Failure(s) were encountered during the push

At the end the channels were there but they were not in the groups they were in before.

Using -f fixed it though (after delete all the channels).

500 error when pushing to mirth instance

Using mirthsync 3.0.0 on AWS codebuild to deploy from a repo that uses the pull feature of mirthsync, I get a 500 error. See below;

DEBUG: posting xml to: /channelgroups/_bulkUpdate

291 | clojure.lang.ExceptionInfo: clj-http: status 500 {:cached nil, :request-time 55, :repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor 1}, :streaming? true, :http-client #object[org.apache.http.impl.client.InternalHttpClient 0x68631b1d "org.apache.http.impl.client.InternalHttpClient@68631b1d"], :chunked? false, :type :clj-http.client/unexceptional-status, :reason-phrase "Internal Server Error", :headers {"Access-Control-Allow-Headers" "Content-Type", "Server" "Jetty(9.4.21.v20190926)", "Content-Type" "application/xml", "Access-Control-Allow-Origin" "*", "Content-Length" "7621", "X-Frame-Options" "DENY", "Strict-Transport-Security" "max-age=31536000; includeSubDomains", "Connection" "close", "Access-Control-Allow-Methods" "GET, POST, DELETE, PUT", "Date" "Thu, 27 Jan 2022 15:44:00 GMT", "Access-Control-Allow-Credentials" "false", "Content-Security-Policy" "frame-ancestors 'none'"}, :orig-content-encoding nil, :status 500, :length 7621, :body "<com.mirth.connect.client.core.ControllerException>\n Channel "84bbbe53-b03e-46bb-82af-1291ae479b7b" belongs to more than one group.\n \n com.mirth.connect.server.controllers.DefaultChannelController.updateChannelGroups(DefaultChannelController.java:823)\n com.mirth.connect.server.api.servlets.ChannelGroupServlet.updateChannelGroups(ChannelGroupServlet.java:54)\n sun.reflect.GeneratedMethodAccessor433.invoke(Unknown Source)\n sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)\n java.lang.reflect.Method.invoke(Unknown Source)\n com.mirth.connect.server.api.providers.MirthResourceInvocationHandlerProvider$1.invoke(MirthResourceInvocationHandlerProvider.java:219)\n org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)\n org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)\n org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)\n org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)\n org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)\n org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)\n org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)\n org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)\n org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)\n org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)\n org.glassfish.jersey.internal.Errors.process(Errors.java:315)\n org.glassfish.jersey.internal.Errors.process(Errors.java:297)\n org.glassfish.jersey.internal.Errors.process(Errors.java:267)\n org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)\n org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)\n org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)\n org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471)\n org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)\n org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)\n org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)\n org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)\n org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:760)\n org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1617)\n com.mirth.connect.server.api.providers.StrictTransportSecurityFilter.doFilter(StrictTransportSecurityFilter.java:33)\n org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1604)\n com.mirth.connect.server.MethodFilter.doFilter(MethodFilter.java:37)\n org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1604)\n com.mirth.connect.server.api.providers.ClickjackingFilter.doFilter(ClickjackingFilter.java:44)\n org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1604)\n com.mirth.connect.server.api.providers.ApiOriginFilter.doFilter(ApiOriginFilter.java:71)\n org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1604)\n org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:545)\n org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)\n org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1589)\n org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)\n org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1296)\n org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)\n org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)\n org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1559)\n org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)\n org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1211)\n org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)\n org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\n org.eclipse.jetty.server.Server.handle(Server.java:500)\n org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:386)\n org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:560)\n org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:378)\n org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:268)\n org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)\n org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)\n org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:426)\n org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:320)\n org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:158)\n org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)\n org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)\n org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)\n org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)\n org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)\n org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)\n org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367)\n org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782)\n org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:914)\n java.lang.Thread.run(Unknown Source)\n \n <suppressedExceptions class="java.util.Collections$UnmodifiableRandomAccessList" resolves-to="java.util.Collections$UnmodifiableList">\n <c class="list"/>\n \n \n</com.mirth.connect.client.core.ControllerException>", :trace-redirects []}

Include Server and SSL Manager settings on export/import

Currently, these are only available through API or the backup disk mode (full backup):

  • SSL Manager (/extensions/ssl/allStoreBytes on the API)
  • Server (/server/publicSettings on the API)

It would be great to have these exported and restored by Mirth Sync as well.

Bonus: have everything that's available on the backup disk mode also available the code disk mode.

Inner actions names may not be valid filesystem names

I have this transformer step called: "patient.identifier.extCode -> patient.identifier[type = 'PI'].value"
When pulling, this is the result:

.\Channels\MPI_NEW\MPI_ADT_DB_READER\destinationConnector-ToDispatcher-transformer-step-0-patient.identifier.extCode -> patient.identifier[type = 'PI'].value.js The filename, directory name, or volume label syntax is incorrect.

I can change that with no consequences, but that's not always the case and not always simple to achieve, especially when you've got lots of channels and you find out about such a limitation at the very last minute.

"Found a match" stdout messages are noisy when --restrict-to-path is not set

Found a match: dev-resources/mirth-11-baseline/Channels/%2Fthis%5C is %2Fa %5C group%2F%5Cwith weird%5Ccharacters%2F/index.xml
File: dev-resources/mirth-11-baseline/Channels/%2Fthis%5C is %2Fa %5C group%2F%5Cwith weird%5Ccharacters%2F/index.xml

"Found a match" and "File:" are redundant when restrict-to-path is not set. This is true for push and pull code.

Javascript for Attachment processing

If a channel is configured with "Javascript" attachment processing, mirthSync leaves the JS inside the XML on a pull, rather than extracting it to a new file, as is done for other JS.

Issue pulling data from Mirth instance

EDIT: This can be cancelled. It was an issue with our instance.
When using any version of MirthSync via a pull command I receive:

File: D:\CodeTemplates\Database \index.xml
D:\CodeTemplates\Database \index.xml (The system cannot find the path specified)

I've verified permissions on the directory its writing to. Using an elevated command prompt or an elevated powershell yields the same result. I've tried this on many different Mirth Connect instances from versions 3.6 to 3.8. I have manually placed the index.xml into the CodeTemplates\Database directory with the contents it was trying to receive, but the issue persists. I thought it was the trailing space after the directory in .\Database \ but I'm pretty sure Java.IO can handle the space in there, and I can resolve it just fine in windows. Any help with this would be greatly appreciated.

example output with stack trace
image

Error handling on push

I've had a number of situations where a "push" encounters an error. When this happens, there's this huge dump of data. It can be very hard to identify what the problem was.

Some examples:

  • Failure to deploy the channels (when -d is used).
  • Bad password
  • Channel already exists in Mirth and is being pushed, but it's in a different (unpushed) channel group already
  • A Channel Group exists with the same name as one being loaded, with a different id

Please intercept the errors and display something concise. If desired, provide an option for dumping the full error text to a specified file (or maybe to a default file).

Pull with restrict-to-path fails if the target folder is empty

If I try to pull to the target folder (which is empty) with a restrict-to-path set to a specific channel (group), Mirthsync runs and throws an exception at the end that it cannot find a file. The file the exception is thrown on is not part of the channel (path) I want to pull.

I realise that this may be by design or that at least there is an expectation to have done a full groups pull followed by specific channels, so just looking for clarification if that is the suggested workflow?

Sorry, only just found this great tool and playing with it to see how I can incorporate into something close to CI/CD.

ta

Stewart

Certificate error

I am using mirth 3.11 on an appliance.

ln -s mirthsync-2.1.1/lib/mirthsync-2.1.1-standalone.jar mirthsync.jar

mkdir mirthtest

java -jar mirthsync.jar -s https://172.20.100.61:8443/api -u admin -p admin pull -t mirthtest
Authenticating to server at https://172.20.100.61:8443/api as admin
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:458)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:200)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1500)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1415)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:421)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
at org.apache.http.impl.conn.BasicHttpClientConnectionManager.connect(BasicHttpClientConnectionManager.java:313)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at clj_http.core$request.invokeStatic(core.clj:641)
at clj_http.core$request.invoke(core.clj:566)
at clj_http.core$request.invokeStatic(core.clj:567)
at clj_http.core$request.invoke(core.clj:566)
at clojure.lang.Var.invoke(Var.java:384)
at clj_http.client$wrap_request_timing$fn__2997.invoke(client.clj:1074)
at clj_http.headers$wrap_header_map$fn__2113.invoke(headers.clj:152)
at clj_http.client$wrap_query_params$fn__2887.invoke(client.clj:808)
at clj_http.client$wrap_basic_auth$fn__2893.invoke(client.clj:831)
at clj_http.client$wrap_oauth$fn__2898.invoke(client.clj:848)
at clj_http.client$wrap_user_info$fn__2907.invoke(client.clj:868)
at clj_http.client$wrap_url$fn__2979.invoke(client.clj:1026)
at clj_http.client$wrap_decompression$fn__2688.invoke(client.clj:415)
at clj_http.client$wrap_input_coercion$fn__2811.invoke(client.clj:628)
at clj_http.client$wrap_additional_header_parsing$fn__2836.invoke(client.clj:683)
at clj_http.client$wrap_output_coercion$fn__2798.invoke(client.clj:572)
at clj_http.client$wrap_exceptions$fn__2641.invoke(client.clj:249)
at clj_http.client$wrap_accept$fn__2851.invoke(client.clj:726)
at clj_http.client$wrap_accept_encoding$fn__2858.invoke(client.clj:748)
at clj_http.client$wrap_content_type$fn__2845.invoke(client.clj:709)
at clj_http.client$wrap_form_params$fn__2944.invoke(client.clj:950)
at clj_http.client$wrap_nested_params$fn__2965.invoke(client.clj:984)
at clj_http.client$wrap_flatten_nested_params$fn__2974.invoke(client.clj:1008)
at clj_http.client$wrap_method$fn__2912.invoke(client.clj:884)
at clj_http.cookies$wrap_cookies$fn__1320.invoke(cookies.clj:131)
at clj_http.links$wrap_links$fn__2446.invoke(links.clj:63)
at clj_http.client$wrap_unknown_host$fn__2982.invoke(client.clj:1037)
at clj_http.client$request_STAR_.invokeStatic(client.clj:1165)
at clj_http.client$request_STAR_.invoke(client.clj:1158)
at clj_http.client$post.invokeStatic(client.clj:1183)
at clj_http.client$post.doInvoke(client.clj:1179)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at mirthsync.http_client$with_authentication.invokeStatic(http_client.clj:47)
at mirthsync.http_client$with_authentication.invoke(http_client.clj:41)
at mirthsync.core$run.invokeStatic(core.clj:21)
at mirthsync.core$run.invoke(core.clj:10)
at mirthsync.core$main_func$fn__3394.invoke(core.clj:46)
at mirthsync.core$main_func.invokeStatic(core.clj:45)
at mirthsync.core$main_func.doInvoke(core.clj:37)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:665)
at clojure.core$apply.invoke(core.clj:660)
at mirthsync.core$_main.invokeStatic(core.clj:57)
at mirthsync.core$_main.doInvoke(core.clj:55)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at mirthsync.core.main(Unknown Source)
unable to find valid certification path to requested target

Mirthsync giving false positive push in AWS CodeBuild Container

I am using a Jenkins job to pull the MirthConnect config files from a BitBucket repo, zip up the files and send them to an AWS CodeBuild Ubuntu container. I am using (and have used) the 2.0.10 version of Mirthsync. From the container I am using a push command to a MirthConnect instance in the same AWS region. The output from Mirthsync says that it has uploaded the files without any issues, but when I go to check the instance, the files that Mirthsync said it uploaded, the changes aren't there.

image

The target directory $CODEBUILD_SOURCE/src directory has the file structure:
image

No [Default Group] subdirectory

Just a usability suggestion. Mirthsync places channel xml files in subfolders based upon their assigned subgroup - which makes sense. However, channels that aren't explicitly assigned to a group seem to be placed by Mirth into a group called [Default Group], yet mirthsync places them in the root of the "Channels" directory in the target. For consistency, consider either replicating the entire group structure (including a directory for Default Group) or dispense with groups entirely and place all files in a single (root) directory similar to the channel view (my personal preference). Perhaps a flag to choose whether you want a group-based directory tree created, or not?
Mirthsync_default_group

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.