Skip to content
This repository has been archived by the owner on Sep 17, 2022. It is now read-only.

Commit

Permalink
Merge pull request #21 from ldsec/dev
Browse files Browse the repository at this point in the history
MedCo v0.3.0
  • Loading branch information
mickmis authored Feb 11, 2020
2 parents 064a470 + 416f301 commit eac54f6
Show file tree
Hide file tree
Showing 138 changed files with 10,389 additions and 8,911 deletions.
18 changes: 12 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
EXCLUDE_LINT = "_test.go"

# generate/update go server based on swagger specifications
swagger-gen:
swagger validate ./swagger/medco-connector-server.yml
swagger-gen: swagger
swagger validate ./swagger/medco-connector.yml
swagger generate server \
--server-package=restapi/server \
--model-package=restapi/models \
--principal=models.User \
--target=./ \
--spec=./swagger/medco-connector-server.yml \
--spec=./swagger/medco-connector.yml \
--name=medco-connector
swagger validate ./swagger/medco-cli-client.yml
swagger generate client \
--client-package=restapi/client \
--existing-models=github.com/lca1/medco-connector/restapi/models \
--existing-models=github.com/ldsec/medco-connector/restapi/models \
--skip-models \
--principal=models.User \
--target=./ \
--spec=./swagger/medco-cli-client.yml \
--spec=./swagger/medco-connector.yml \
--name=medco-cli \
--default-scheme=https

.PHONY: swagger
swagger:
@if ! which swagger >/dev/null; then \
go install github.com/go-swagger/go-swagger/cmd/swagger && \
echo "swagger installed"; \
fi

test_lint:
@echo Checking linting of files
@{ \
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# MedCo Connector

## Source code organization
- *client*: client logic
- *cmd*: runnable applications
- *cmd/medco-cli-client*: client application
- *cmd/medco-connector-server*: server application
- *deployment*: docker image definition and docker-compose deployment
- *restapi*: go-swagger generated code for REST API
- *restapi/client*: client-related generated code
- *restapi/models*: generated models
- *restapi/server*: server-related generated code
- *server*: server logic
- *server/handlers*: server REST API endpoints handlers
- *swagger*: swagger REST API definitions
- *util*: utility code (configuration, security, etc.)
- *util*:
- *wrappers*: client library wrappers for external service (i2b2, unlynx, etc.)
106 changes: 89 additions & 17 deletions medco/client/client.go → client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"encoding/csv"
"errors"
"fmt"
"github.com/lca1/medco-connector/restapi/models"
"github.com/lca1/medco-connector/unlynx"
utilclient "github.com/lca1/medco-connector/util/client"
"github.com/lca1/medco-loader/loader/identifiers"
"github.com/ldsec/medco-connector/restapi/models"
utilclient "github.com/ldsec/medco-connector/util/client"
"github.com/ldsec/medco-connector/wrappers/unlynx"
"github.com/ldsec/medco-loader/loader/identifiers"
"github.com/sirupsen/logrus"
"io"
"os"
Expand All @@ -19,7 +19,7 @@ import (
)

// ExecuteClientQuery execute and display the results of the MedCo client query
func ExecuteClientQuery(token, username, password, queryType, queryString, resultOutputFilePath string, disableTLSCheck bool, bypassPicsure bool) (err error) {
func ExecuteClientQuery(token, username, password, queryType, queryString, resultOutputFilePath string, disableTLSCheck bool) (err error) {

// get token
var accessToken string
Expand All @@ -34,7 +34,7 @@ func ExecuteClientQuery(token, username, password, queryType, queryString, resul
}

// parse query type
queryTypeParsed := models.QueryType(queryType)
queryTypeParsed := models.ExploreQueryType(queryType)
err = queryTypeParsed.Validate(nil)
if err != nil {
logrus.Error("invalid query type")
Expand Down Expand Up @@ -62,7 +62,7 @@ func ExecuteClientQuery(token, username, password, queryType, queryString, resul
}

// execute query
clientQuery, err := NewQuery(accessToken, queryTypeParsed, encPanelsItemKeys, panelsIsNot, disableTLSCheck, bypassPicsure)
clientQuery, err := NewExploreQuery(accessToken, queryTypeParsed, encPanelsItemKeys, panelsIsNot, disableTLSCheck)
if err != nil {
return
}
Expand Down Expand Up @@ -91,15 +91,15 @@ func ExecuteClientQuery(token, username, password, queryType, queryString, resul
}

// printResultsCSV prints on a specified output in a CSV format the results, each node being one line
func printResultsCSV(nodesResult map[string]*QueryResult, output io.Writer) (err error) {
func printResultsCSV(nodesResult map[int]*ExploreQueryResult, output io.Writer) (err error) {

csvHeaders := []string{"node_name", "count", "patient_list"}
csvNodesResults := make([][]string, 0)

// CSV values: results
for nodeName, queryResult := range nodesResult {
for nodeIdx, queryResult := range nodesResult {
csvNodesResults = append(csvNodesResults, []string{
nodeName,
strconv.Itoa(nodeIdx),
strconv.FormatInt(queryResult.Count, 10),
fmt.Sprint(queryResult.PatientList),
})
Expand All @@ -124,14 +124,18 @@ func printResultsCSV(nodesResult map[string]*QueryResult, output io.Writer) (err

// CSV values: timers: iter over results, then iter over timer names from csvHeaders
for csvNodeResultsIdx, csvNodeResults := range csvNodesResults {
nodeName := csvNodeResults[0]
nodeIdx, err := strconv.Atoi(csvNodeResults[0])
if err != nil {
logrus.Error("error parsing node number: ", err)
return err
}

for timerNameIdx := 3 ; timerNameIdx < len(csvHeaders) ; timerNameIdx++ {
for timerNameIdx := 3; timerNameIdx < len(csvHeaders); timerNameIdx++ {
timerName := csvHeaders[timerNameIdx]
timerValue := nodesResult[nodeName].Times[timerName]
timerValue := nodesResult[nodeIdx].Times[timerName]

csvNodesResults[csvNodeResultsIdx] = append(csvNodesResults[csvNodeResultsIdx],
strconv.FormatInt(int64(timerValue / time.Millisecond), 10))
strconv.FormatInt(int64(timerValue/time.Millisecond), 10))
}
}

Expand Down Expand Up @@ -193,7 +197,7 @@ func parseQueryString(queryString string) (panelsItemKeys [][]int64, panelsIsNot
return nil, nil, intMultiplierErr
}

for i := 0 ; i < int(intMultiplier) ; i++ {
for i := 0; i < int(intMultiplier); i++ {
itemKeys = append(itemKeys, queryInt)
}

Expand All @@ -207,7 +211,7 @@ func parseQueryString(queryString string) (panelsItemKeys [][]int64, panelsIsNot
// if a parsable integer: use as is
itemKeys = append(itemKeys, parsedInt)

// case 3: query file
// case 3: query file
} else {
logrus.Debug("Client query file item: ", queryItem)

Expand Down Expand Up @@ -266,7 +270,7 @@ func loadQueryFile(queryFilePath string) (queryTerms []int64, err error) {
}

} else {
err = errors.New("dataset with "+ string(len(queryTermFields)) + " fields is not supported")
err = errors.New("dataset with " + string(len(queryTermFields)) + " fields is not supported")
logrus.Error(err)
return
}
Expand All @@ -276,3 +280,71 @@ func loadQueryFile(queryFilePath string) (queryTerms []int64, err error) {

return
}

// ExecuteClientGenomicAnnotationsGetValues displays the genomic annotations values matching the "annotation" parameter
func ExecuteClientGenomicAnnotationsGetValues(token, username, password, annotation, value string, limit int64, disableTLSCheck bool) (err error) {

// get token
var accessToken string
if len(token) > 0 {
accessToken = token
} else {
logrus.Debug("No token provided, requesting token for user ", username, ", disable TLS check: ", disableTLSCheck)
accessToken, err = utilclient.RetrieveAccessToken(username, password, disableTLSCheck)
if err != nil {
return
}
}

// execute query
clientGenomicAnnotationsGetValues, err := NewGenomicAnnotationsGetValues(accessToken, annotation, value, &limit, disableTLSCheck)
if err != nil {
return
}

result, err := clientGenomicAnnotationsGetValues.Execute()
if err != nil {
return
}

for _, annotation := range result {
fmt.Printf("%s\n", annotation)
}

return

}

// ExecuteClientGenomicAnnotationsGetVariants displays the variant ids corresponding to the annotation and value parameters
func ExecuteClientGenomicAnnotationsGetVariants(token, username, password, annotation, value string, zygosity string, encrypted bool, disableTLSCheck bool) (err error) {

// get token
var accessToken string
if len(token) > 0 {
accessToken = token
} else {
logrus.Debug("No token provided, requesting token for user ", username, ", disable TLS check: ", disableTLSCheck)
accessToken, err = utilclient.RetrieveAccessToken(username, password, disableTLSCheck)
if err != nil {
return
}
}

// execute query
clientGenomicAnnotationsGetVariants, err := NewGenomicAnnotationsGetVariants(accessToken, annotation, value, zygosity, &encrypted, disableTLSCheck)
if err != nil {
return
}

result, err := clientGenomicAnnotationsGetVariants.Execute()
if err != nil {
return
}

for _, variant := range result {
fmt.Printf("%s\n", variant)
}

return

}
150 changes: 150 additions & 0 deletions client/genomic_annotations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package medcoclient

import (
"crypto/tls"
httptransport "github.com/go-openapi/runtime/client"
"github.com/ldsec/medco-connector/restapi/client"
"github.com/ldsec/medco-connector/restapi/client/genomic_annotations"
utilclient "github.com/ldsec/medco-connector/util/client"
"github.com/sirupsen/logrus"
"net/http"
"net/url"
"strings"
"time"
)

// GenomicAnnotationsGetValues is a MedCo client genomic-annotations get-values request
type GenomicAnnotationsGetValues struct {

// httpMedCoClient is the HTTP client for the MedCo connector
httpMedCoClient *client.MedcoCli
// authToken is the OIDC authentication JWT
authToken string

annotation string

value string

limit *int64
}

// GenomicAnnotationsGetVariants is a MedCo client genomic-annotations get-variants request
type GenomicAnnotationsGetVariants struct {

// httpMedCoClient is the HTTP client for the MedCo connector
httpMedCoClient *client.MedcoCli
// authToken is the OIDC authentication JWT
authToken string

annotation string

value string

zygosity []string

encrypted *bool
}

// NewGenomicAnnotationsGetValues creates a new MedCo client genomic-annotations get-values request
func NewGenomicAnnotationsGetValues(authToken, annotation, value string, limit *int64, disableTLSCheck bool) (q *GenomicAnnotationsGetValues, err error) {

q = &GenomicAnnotationsGetValues{
authToken: authToken,
annotation: annotation,
value: value,
limit: limit,
}

parsedURL, err := url.Parse(utilclient.MedCoConnectorURL)
if err != nil {
logrus.Error("cannot parse MedCo connector URL: ", err)
return
}

transport := httptransport.New(parsedURL.Host, parsedURL.Path, []string{parsedURL.Scheme})
transport.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: disableTLSCheck}

q.httpMedCoClient = client.New(transport, nil)

return
}

// NewGenomicAnnotationsGetVariants creates a new MedCo client genomic-annotations get-variants request
func NewGenomicAnnotationsGetVariants(authToken, annotation, value string, zygosity string, encrypted *bool, disableTLSCheck bool) (q *GenomicAnnotationsGetVariants, err error) {

q = &GenomicAnnotationsGetVariants{
authToken: authToken,
annotation: annotation,
value: value,
zygosity: strings.Split(zygosity, "|"),
encrypted: encrypted,
}

parsedURL, err := url.Parse(utilclient.MedCoConnectorURL)
if err != nil {
logrus.Error("cannot parse MedCo connector URL: ", err)
return
}

transport := httptransport.New(parsedURL.Host, parsedURL.Path, []string{parsedURL.Scheme})
transport.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: disableTLSCheck}

q.httpMedCoClient = client.New(transport, nil)

return
}

// Execute executes the MedCo client get-values query
func (clientGenomicAnnotationsGetValues *GenomicAnnotationsGetValues) Execute() (result []string, err error) {

result, err = clientGenomicAnnotationsGetValues.submitToNode()
return

}

// Execute executes the MedCo client get-variants query
func (clientGenomicAnnotationsGetVariants *GenomicAnnotationsGetVariants) Execute() (result []string, err error) {

result, err = clientGenomicAnnotationsGetVariants.submitToNode()
return

}

func (clientGenomicAnnotationsGetValues *GenomicAnnotationsGetValues) submitToNode() (result []string, err error) {

params := genomic_annotations.NewGetValuesParamsWithTimeout(time.Duration(utilclient.GenomicAnnotationsQueryTimeoutSeconds) * time.Second)
params.Annotation = clientGenomicAnnotationsGetValues.annotation
params.Value = clientGenomicAnnotationsGetValues.value
if *clientGenomicAnnotationsGetValues.limit != 0 {
params.Limit = clientGenomicAnnotationsGetValues.limit
}

response, err := clientGenomicAnnotationsGetValues.httpMedCoClient.GenomicAnnotations.GetValues(params, httptransport.BearerToken(clientGenomicAnnotationsGetValues.authToken))

if err != nil {
logrus.Error("Genomic annotations get values error: ", err)
return nil, err
}

return response.Payload, nil

}

func (clientGenomicAnnotationsGetVariants *GenomicAnnotationsGetVariants) submitToNode() (result []string, err error) {

params := genomic_annotations.NewGetVariantsParamsWithTimeout(time.Duration(utilclient.GenomicAnnotationsQueryTimeoutSeconds) * time.Second)
params.Annotation = clientGenomicAnnotationsGetVariants.annotation
params.Value = clientGenomicAnnotationsGetVariants.value
params.Zygosity = clientGenomicAnnotationsGetVariants.zygosity
params.Encrypted = clientGenomicAnnotationsGetVariants.encrypted

response, err := clientGenomicAnnotationsGetVariants.httpMedCoClient.GenomicAnnotations.GetVariants(params, httptransport.BearerToken(clientGenomicAnnotationsGetVariants.authToken))

if err != nil {
logrus.Error("Genomic annotations get variants error: ", err)
return nil, err
}

return response.Payload, nil

}
Loading

0 comments on commit eac54f6

Please sign in to comment.