This repository has been archived by the owner on Sep 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MedCo v0.2.0
- Loading branch information
Showing
71 changed files
with
4,875 additions
and
1,047 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,23 @@ | ||
validate: | ||
swagger validate ./swagger.yml | ||
EXCLUDE_LINT = "_test.go" | ||
|
||
gen: validate | ||
# generate/update go server based on swagger specifications | ||
swagger-gen: | ||
swagger validate ./swagger/swagger.yml | ||
swagger generate server \ | ||
--target=./ \ | ||
--spec=./swagger.yml \ | ||
--principal=models.User \ | ||
--target=./swagger/ \ | ||
--spec=./swagger/swagger.yml \ | ||
--name=medco-connector | ||
|
||
.PHONY: install gen validate | ||
test_lint: | ||
@echo Checking linting of files | ||
@{ \ | ||
go install golang.org/x/lint/golint; \ | ||
el=$(EXCLUDE_LINT); \ | ||
lintfiles=$$( golint ./... | egrep -v "$$el" ); \ | ||
if [ -n "$$lintfiles" ]; then \ | ||
echo "Lint errors:"; \ | ||
echo "$$lintfiles"; \ | ||
exit 1; \ | ||
fi \ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
FROM golang:1.11 as build | ||
|
||
COPY ./ /src | ||
|
||
# compile and install medco-connector | ||
WORKDIR /src | ||
RUN CGO_ENABLED=0 go build -v ./... && \ | ||
CGO_ENABLED=0 go install -v ./... | ||
|
||
# ------------------------------------------- | ||
FROM golang:1.11-alpine as release | ||
|
||
COPY deployment/docker-entrypoint.sh /usr/local/bin/ | ||
RUN apk update && apk add bash && rm -rf /var/cache/apk/* && \ | ||
chmod a+x /usr/local/bin/docker-entrypoint.sh | ||
|
||
COPY --from=build /go/bin/medco-connector-server /go/bin/ | ||
|
||
# swagger server configuration | ||
ENV HOST=0.0.0.0 \ | ||
PORT=1999 | ||
|
||
# run-time environment | ||
ENV I2B2_HIVE_URL=http://i2b2:8080/i2b2/services \ | ||
I2B2_LOGIN_DOMAIN=i2b2medco \ | ||
I2B2_LOGIN_PROJECT=MedCo \ | ||
I2B2_LOGIN_USER=e2etest \ | ||
I2B2_LOGIN_PASSWORD=e2etest \ | ||
LOG_LEVEL=5 \ | ||
UNLYNX_GROUP_FILE_PATH=/medco-configuration/group.toml \ | ||
UNLYNX_GROUP_FILE_IDX=0 \ | ||
JWKS_URL=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs \ | ||
OIDC_JWT_ISSUER=http://keycloak:8080/auth/realms/master \ | ||
OIDC_CLIENT_ID=medco \ | ||
OIDC_JWT_USER_ID_CLAIM=preferred_username | ||
|
||
EXPOSE 1999 | ||
ENTRYPOINT ["docker-entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
version: '3.5' | ||
services: | ||
medco-connector: | ||
image: medco/medco-connector:dev | ||
build: | ||
context: ../ | ||
dockerfile: deployment/Dockerfile | ||
ports: | ||
- "1999" | ||
environment: | ||
- I2B2_HIVE_URL=http://i2b2:8080/i2b2/services | ||
- I2B2_LOGIN_DOMAIN=i2b2medco | ||
- I2B2_LOGIN_PROJECT=MedCo | ||
- I2B2_LOGIN_USER=e2etest | ||
- I2B2_LOGIN_PASSWORD=e2etest | ||
- LOG_LEVEL=5 | ||
- UNLYNX_GROUP_FILE_PATH=/medco-configuration/group.toml | ||
- UNLYNX_GROUP_FILE_IDX=0 | ||
- JWKS_URL=http://keycloak:8080/auth/realms/master/protocol/openid-connect/certs | ||
- OIDC_JWT_ISSUER=http://keycloak:8080/auth/realms/master | ||
- OIDC_CLIENT_ID=medco | ||
- OIDC_JWT_USER_ID_CLAIM=preferred_username | ||
volumes: | ||
- ./configuration-profile:/medco-configuration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env bash | ||
set -Eeuo pipefail | ||
|
||
# trust the certificates of other nodes | ||
if [[ `ls -1 /medco-configuration/srv*-certificate.crt 2>/dev/null | wc -l` != 0 ]]; then | ||
/bin/cp -f /medco-configuration/srv*-certificate.crt /usr/local/share/ca-certificates/ | ||
update-ca-certificates | ||
fi | ||
|
||
exec medco-connector-server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,27 @@ | ||
module github.com/lca1/medco-connector | ||
|
||
require ( | ||
github.com/PuerkitoBio/purell v1.1.1 // indirect | ||
github.com/go-openapi/analysis v0.18.0 // indirect | ||
github.com/go-openapi/errors v0.18.0 | ||
github.com/go-openapi/jsonpointer v0.18.0 // indirect | ||
github.com/go-openapi/jsonreference v0.18.0 // indirect | ||
github.com/go-openapi/loads v0.18.0 | ||
github.com/go-openapi/runtime v0.18.0 | ||
github.com/go-openapi/spec v0.18.0 | ||
github.com/go-openapi/strfmt v0.18.0 | ||
github.com/go-openapi/swag v0.18.0 | ||
github.com/go-openapi/validate v0.18.0 | ||
github.com/google/uuid v1.1.1 // indirect | ||
github.com/jessevdk/go-flags v1.4.0 | ||
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 | ||
github.com/lca1/medco-unlynx v0.0.0-20190326092154-e12359adb567 | ||
github.com/lca1/unlynx v0.0.0-20190312131415-2e3533f65afe | ||
github.com/lestrrat-go/jwx v0.0.0-20190415045601-bee008e7f2ee | ||
github.com/lestrrat-go/pdebug v0.0.0-20180220043849-39f9a71bcabe // indirect | ||
github.com/mailru/easyjson v0.0.0-20190221075403-6243d8e04c3f // indirect | ||
github.com/pkg/errors v0.8.1 // indirect | ||
github.com/sirupsen/logrus v1.4.0 | ||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect | ||
go.dedis.ch/onet/v3 v3.0.0 | ||
golang.org/x/net v0.0.0-20190311183353-d8887717615a | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package i2b2 | ||
|
||
import ( | ||
"encoding/xml" | ||
"errors" | ||
"github.com/lca1/medco-connector/util" | ||
"strconv" | ||
"time" | ||
) | ||
|
||
// NewRequest creates a new ready-to-use i2b2 request, with a nil message body | ||
func NewRequest() Request { | ||
now := time.Now() | ||
return Request{ | ||
XMLNSMSG: "http://www.i2b2.org/xsd/hive/msg/1.1/", | ||
XMLNSONT: "http://www.i2b2.org/xsd/cell/ont/1.1/", | ||
XMLNSPDO: "http://www.i2b2.org/xsd/hive/pdo/1.1/", | ||
XMLNSCRCPDO: "http://www.i2b2.org/xsd/cell/crc/pdo/1.1/", | ||
XMLNSCRCPSM: "http://www.i2b2.org/xsd/cell/crc/psm/1.1/", | ||
|
||
MessageHeader: MessageHeader{ | ||
I2b2VersionCompatible: "0.3", | ||
Hl7VersionCompatible: "2.4", | ||
SendingApplicationApplicationName: "MedCo Connector", | ||
SendingApplicationApplicationVersion: "0.2", | ||
SendingFacilityFacilityName: "MedCo", | ||
ReceivingApplicationApplicationName: "i2b2 cell", | ||
ReceivingApplicationApplicationVersion: "1.7", | ||
ReceivingFacilityFacilityName: "i2b2 hive", | ||
DatetimeOfMessage: now.Format(time.RFC3339), | ||
SecurityDomain: util.I2b2LoginDomain, | ||
SecurityUsername: util.I2b2LoginUser, | ||
SecurityPassword: util.I2b2LoginPassword, | ||
MessageTypeMessageCode: "EQQ", | ||
MessageTypeEventType: "Q04", | ||
MessageTypeMessageStructure: "EQQ_Q04", | ||
MessageControlIDSessionID: now.Format(time.RFC3339), | ||
MessageControlIDMessageNum: strconv.FormatInt(now.Unix(), 10), | ||
MessageControlIDInstanceNum: "0", | ||
ProcessingIDProcessingID: "P", | ||
ProcessingIDProcessingMode: "I", | ||
AcceptAcknowledgementType: "messageId", | ||
ApplicationAcknowledgementType: "", | ||
CountryCode: "CH", | ||
ProjectID: util.I2b2LoginProject, | ||
}, | ||
RequestHeader: RequestHeader{ | ||
ResultWaittimeMs: strconv.Itoa(util.I2b2TimeoutSeconds* 1000), | ||
}, | ||
} | ||
} | ||
|
||
// NewRequestWithBody creates a new ready-to-use i2b2 request, with a message body | ||
func NewRequestWithBody(body MessageBody) (req Request) { | ||
req = NewRequest() | ||
req.MessageBody = body | ||
return | ||
} | ||
|
||
// Request is an i2b2 XML request | ||
type Request struct { | ||
XMLName xml.Name `xml:"msgns:request"` | ||
XMLNSMSG string `xml:"xmlns:msgns,attr"` | ||
XMLNSPDO string `xml:"xmlns:pdons,attr"` | ||
XMLNSONT string `xml:"xmlns:ontns,attr"` | ||
XMLNSCRCPDO string `xml:"xmlns:crcpdons,attr"` | ||
XMLNSCRCPSM string `xml:"xmlns:crcpsmns,attr"` | ||
|
||
MessageHeader MessageHeader `xml:"message_header"` | ||
RequestHeader RequestHeader `xml:"request_header"` | ||
MessageBody MessageBody `xml:"message_body"` | ||
} | ||
|
||
// Response is an i2b2 XML response | ||
type Response struct { | ||
XMLName xml.Name `xml:"response"` | ||
MessageHeader MessageHeader `xml:"message_header"` | ||
RequestHeader RequestHeader `xml:"request_header"` | ||
ResponseHeader ResponseHeader `xml:"response_header"` | ||
MessageBody MessageBody `xml:"message_body"` | ||
} | ||
|
||
func (response *Response) checkStatus() error { | ||
if response.ResponseHeader.ResultStatus.Status.Type != "DONE" { | ||
return errors.New(response.ResponseHeader.ResultStatus.Status.Text) | ||
} | ||
return nil | ||
} | ||
|
||
// MessageHeader is an i2b2 XML header embedded in a request or response | ||
type MessageHeader struct { | ||
XMLName xml.Name `xml:"message_header"` | ||
|
||
I2b2VersionCompatible string `xml:"i2b2_version_compatible"` | ||
Hl7VersionCompatible string `xml:"hl7_version_compatible"` | ||
|
||
SendingApplicationApplicationName string `xml:"sending_application>application_name"` | ||
SendingApplicationApplicationVersion string `xml:"sending_application>application_version"` | ||
|
||
SendingFacilityFacilityName string `xml:"sending_facility>facility_name"` | ||
|
||
ReceivingApplicationApplicationName string `xml:"receiving_application>application_name"` | ||
ReceivingApplicationApplicationVersion string `xml:"receiving_application>application_version"` | ||
|
||
ReceivingFacilityFacilityName string `xml:"receiving_facility>facility_name"` | ||
|
||
DatetimeOfMessage string `xml:"datetime_of_message"` | ||
|
||
SecurityDomain string `xml:"security>domain"` | ||
SecurityUsername string `xml:"security>username"` | ||
SecurityPassword string `xml:"security>password"` | ||
|
||
MessageTypeMessageCode string `xml:"message_type>message_code"` | ||
MessageTypeEventType string `xml:"message_type>event_type"` | ||
MessageTypeMessageStructure string `xml:"message_type>message_structure"` | ||
|
||
MessageControlIDSessionID string `xml:"message_control_id>session_id"` | ||
MessageControlIDMessageNum string `xml:"message_control_id>message_num"` | ||
MessageControlIDInstanceNum string `xml:"message_control_id>instance_num"` | ||
|
||
ProcessingIDProcessingID string `xml:"processing_id>processing_id"` | ||
ProcessingIDProcessingMode string `xml:"processing_id>processing_mode"` | ||
|
||
AcceptAcknowledgementType string `xml:"accept_acknowledgement_type"` | ||
ApplicationAcknowledgementType string `xml:"application_acknowledgement_type"` | ||
CountryCode string `xml:"country_code"` | ||
ProjectID string `xml:"project_id"` | ||
} | ||
|
||
// RequestHeader is an i2b2 XML header embedded in a request | ||
type RequestHeader struct { | ||
XMLName xml.Name `xml:"request_header"` | ||
ResultWaittimeMs string `xml:"result_waittime_ms"` | ||
} | ||
|
||
// ResponseHeader is an i2b2 XML header embedded in a response | ||
type ResponseHeader struct { | ||
XMLName xml.Name `xml:"response_header"` | ||
Info struct { | ||
Text string `xml:",chardata"` | ||
URL string `xml:"url,attr"` | ||
} `xml:"info"` | ||
ResultStatus struct { | ||
Status struct { | ||
Text string `xml:",chardata"` | ||
Type string `xml:"type,attr"` | ||
} `xml:"status"` | ||
PollingURL struct { | ||
Text string `xml:",chardata"` | ||
IntervalMs string `xml:"interval_ms,attr"` | ||
} `xml:"polling_url"` | ||
Conditions struct { | ||
Condition []struct { | ||
Text string `xml:",chardata"` | ||
Type string `xml:"type,attr"` | ||
CodingSystem string `xml:"coding_system,attr"` | ||
} `xml:"condition"` | ||
} `xml:"conditions"` | ||
} `xml:"result_status"` | ||
} | ||
|
||
// MessageBody is an i2b2 XML generic body | ||
type MessageBody interface{} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package i2b2 | ||
|
||
import ( | ||
"bytes" | ||
"encoding/xml" | ||
"github.com/sirupsen/logrus" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
// todo doc | ||
func i2b2XMLRequest(url string, xmlRequest interface{}, xmlResponse *Response) error { | ||
logrus.Info("i2b2 XML request to " + url) | ||
|
||
// marshal request | ||
marshaledRequest, err := xml.MarshalIndent(xmlRequest, " ", " ") | ||
if err != nil { | ||
logrus.Error("error in i2b2 request marshalling:", err) | ||
return err | ||
} | ||
marshaledRequest = append([]byte(xml.Header), marshaledRequest...) | ||
logrus.Debug("i2b2 request:\n", string(marshaledRequest)) | ||
|
||
// execute HTTP request | ||
httpResponse, err := http.Post(url, "application/xml", bytes.NewBuffer(marshaledRequest)) | ||
if err != nil { | ||
logrus.Error("error in i2b2 request HTTP POST:", err) | ||
return err | ||
} | ||
defer httpResponse.Body.Close() | ||
|
||
// unmarshal response | ||
httpBody, err := ioutil.ReadAll(httpResponse.Body) | ||
logrus.Debug("i2b2 response:\n", string(httpBody)) | ||
|
||
err = xml.Unmarshal(httpBody, xmlResponse) | ||
if err != nil { | ||
logrus.Error("error in i2b2 response unmarshalling:", err) | ||
return err | ||
} | ||
|
||
// check i2b2 request status | ||
err = xmlResponse.checkStatus() | ||
if err != nil { | ||
logrus.Error("i2b2 error:", err) | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.