server

package
v0.0.0-...-838d5f2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2020 License: Apache-2.0 Imports: 47 Imported by: 4

Documentation

Index

Constants

View Source
const (
	// OK when returned by MongoDB is really a float (0.0 = false, 1.0 = true)
	OK = float64(1)
)

Variables

View Source
var DefaultConfig = Config{
	ServerURL:                    "",
	IndexConfigPath:              "config/indexes.conf",
	DatabaseURI:                  "mongodb://localhost:27017/?replicaSet=rs0",
	DatabaseSuffix:               "_fhir",
	DatabaseSocketTimeout:        2 * time.Minute,
	DatabaseOpTimeout:            90 * time.Second,
	DatabaseKillOpPeriod:         10 * time.Second,
	Auth:                         auth.None(),
	EnableCISearches:             true,
	TokenParametersCaseSensitive: false,
	EnableHistory:                true,
	BatchConcurrency:             1,
	EnableXML:                    true,
	CountTotalResults:            true,
	ReadOnly:                     false,
	Debug:                        false,
}

DefaultConfig is the default server configuration

View Source
var ErrDeleted = errors.New("Resource deleted")

ErrDeleted indicates that the resource has been deleted (HTTP 410)

View Source
var ErrNotFound = errors.New("Resource Not Found")

ErrNotFound indicates that the resource was not found (HTTP 404)

View Source
var ErrOpInterrupted = errors.New("Operation Interrupted")

ErrOpInterrupted indicates that the query was interrupted by a killOp() operation

Functions

func AbortNonFhirXMLorJSONRequestsMiddleware

func AbortNonFhirXMLorJSONRequestsMiddleware(c *gin.Context)

AbortNonFhirXMLorJSONRequestsMiddleware is middleware that responds to any request that Accepts a Content-Type other than FHIR JSON or XML with a 406 Not Acceptable status.

func AbortNonJSONRequestsMiddleware

func AbortNonJSONRequestsMiddleware(c *gin.Context)

AbortNonJSONRequestsMiddleware is middleware that responds to any request that Accepts a Content-Type other than JSON (or a JSON flavor) with a 406 Not Acceptable status.

func CreateCollections

func CreateCollections(db *mongowrapper.WrappedDatabase)

func EnableXmlToJsonConversionMiddleware

func EnableXmlToJsonConversionMiddleware() gin.HandlerFunc

func ErrorToOpOutcome

func ErrorToOpOutcome(err interface{}) (statusCode int, outcome *models.OperationOutcome)

func FHIRBind

func FHIRBind(c *gin.Context, validatorURL string) (resource *models2.Resource, err error)

func FhirJsFormatConverterJavascript

func FhirJsFormatConverterJavascript() string

func ReadOnlyMiddleware

func ReadOnlyMiddleware(c *gin.Context)

ReadOnlyMiddleware makes the API read-only and responds to any requests that are not GET, HEAD, or OPTIONS with a 405 Method Not Allowed error.

func RegisterController

func RegisterController(name string, e *gin.Engine, m []gin.HandlerFunc, dal DataAccessLayer, config Config)

RegisterController registers the CRUD routes (and middleware) for a FHIR resource

func RegisterRoutes

func RegisterRoutes(e *gin.Engine, config map[string][]gin.HandlerFunc, dal DataAccessLayer, serverConfig Config)

RegisterRoutes registers the routes for each of the FHIR resources

func RequestLoggerHandler

func RequestLoggerHandler(c *gin.Context)

RequestLoggerHandler is a handler intended to be used during debugging to log out the request details including the request headers and the request body. This should not be used in production as it has performance implications.

Types

type AfterRoutes

type AfterRoutes func(*gin.Engine)

type BatchController

type BatchController struct {
	DAL    DataAccessLayer
	Config Config
}

BatchController handles FHIR batch operations via input bundles

func NewBatchController

func NewBatchController(dal DataAccessLayer, config Config) *BatchController

NewBatchController creates a new BatchController based on the passed in DAL

func (*BatchController) Post

func (b *BatchController) Post(c *gin.Context)

Handles batch and transaction requests

type Config

type Config struct {
	// ServerURL is the full URL for the root of the server. This may be used
	// by other middleware to compute redirect URLs
	ServerURL string

	// Auth determines what, if any authentication and authorization will be used
	// by the FHIR server
	Auth auth.Config

	// Whether to create indexes on startup
	CreateIndexes bool

	// IndexConfigPath is the path to an indexes.conf configuration file, specifying
	// what mongo indexes the server should create (or verify) on startup
	IndexConfigPath string

	// DatabaseURI is the url of the mongo replica set to use for the FHIR database.
	// A replica set is required for transactions support
	// e.g. mongodb://db1:27017,db2:27017/?replicaSet=rs1
	DatabaseURI string

	// DatabaseName is the name of the mongo database used for the fhir database by default.
	// Typically this will be the "fhir".
	DefaultDatabaseName string

	// EnableMultiDB allows requests to specify a specific Mongo database instead of the default
	// e.g. to use test4_fhir http://fhir-server/db/test4_fhir/Patient?name=alex
	EnableMultiDB bool

	// All custom database names should end with this suffix (default is "_fhir")
	DatabaseSuffix string

	// DatabaseSocketTimeout is the amount of time the mgo driver will wait for a response
	// from mongo before timing out.
	DatabaseSocketTimeout time.Duration

	// DatabaseOpTimeout is the amount of time GoFHIR will wait before killing a long-running
	// database process. This defaults to a reasonable upper bound for slow, pipelined queries: 30s.
	DatabaseOpTimeout time.Duration

	// DatabaseKillOpPeriod is the length of time between scans of the database to kill long-running ops.
	DatabaseKillOpPeriod time.Duration

	// CountTotalResults toggles whether the searcher should also get a total
	// count of the total results of a search. In practice this is a performance hit
	// for large datasets.
	CountTotalResults bool

	// EnableCISearches toggles whether the mongo searches uses regexes to maintain
	// case-insesitivity when performing searches on string fields, codes, etc.
	EnableCISearches bool

	// Whether to use case-sensitive search for token-type search parameters
	// Slower but default off for backwards compatibility and strict STU3 support
	// R4 leans towards case-sensitive, whereas STU3 text suggests case-insensitive (https://github.com/HL7/fhir/commit/13fb1c1f102caf7de7266d6e78ab261efac06a1f)
	TokenParametersCaseSensitive bool

	// Whether to support storing previous versions of each resource
	EnableHistory bool

	// Number of concurrent operations to do during batch bundle processing
	BatchConcurrency int

	// Whether to allow retrieving resources with no meta component,
	// meaning Last-Modified & ETag headers can't be generated (breaking spec compliance)
	// May be needed to support previous databases
	AllowResourcesWithoutMeta bool

	// ValidatorURL is an endpoint to which validation requests will be sent
	ValidatorURL string

	// ReadOnly toggles whether the server is in read-only mode. In read-only
	// mode any HTTP verb other than GET, HEAD or OPTIONS is rejected.
	ReadOnly bool

	// Enables requests and responses using FHIR XML MIME-types
	EnableXML bool

	// Debug toggles debug-level logging.
	Debug bool

	// Where to dump failed requests for debugging
	FailedRequestsDir string
}

Config is used to hold information about the configuration of the FHIR server.

type CurrentOp

type CurrentOp struct {
	Active           bool   `bson:"active" json:"active"`
	OpID             uint32 `bson:"opid" json:"opid"`
	SecsRunning      uint32 `bson:"secs_running" json:"secs_running"`
	MicrosecsRunning uint64 `bson:"microsecs_running" json:"microsecs_running"`
	OpType           string `bson:"op" json:"op"`
	Namespace        string `bson:"ns" json:"ns"`
	KillPending      bool   `bson:"killPending" json:"killPending"`
	Query            bson.D `bson:"query" json:"query"`
}

CurrentOp is a database operation currently in-progress.

type CurrentOps

type CurrentOps struct {
	InProg []CurrentOp `bson:"inprog" json:"inprog"`
	Info   string      `bson:"info,omitempty" json:"info,omitempty"`
	Ok     float64     `bson:"ok" json:"ok"`
}

CurrentOps is returned by db.currentOp() and contains a list of all operations currently in-progress. The db.currentOp() operation will itself be an element of InProg[].

type CustomFhirRenderer

type CustomFhirRenderer struct {
	// contains filtered or unexported fields
}

CustomFhirRenderer replaces gin's default JSON renderer and ensures that the special characters "<", ">", and "&" are not escaped after the the JSON is marshaled. Escaping these special HTML characters is the default behavior of Go's json.Marshal(). It also outputs XML if that is required

func (CustomFhirRenderer) Render

func (u CustomFhirRenderer) Render(w http.ResponseWriter) (err error)

func (CustomFhirRenderer) WriteContentType

func (u CustomFhirRenderer) WriteContentType(w http.ResponseWriter)

type DataAccessLayer

type DataAccessLayer interface {
	StartSession(ctx context.Context, dbname string) DataAccessSession
}

func NewMongoDataAccessLayer

func NewMongoDataAccessLayer(client *mongowrapper.WrappedClient, defaultDbName string, enableMultiDB bool, dbSuffix string, interceptors map[string]InterceptorList, config Config) DataAccessLayer

NewMongoDataAccessLayer returns an implementation of DataAccessLayer that is backed by a Mongo database

type DataAccessSession

type DataAccessSession interface {
	// Starts a transaction
	StartTransaction() error
	// Commits a transaction
	CommmitIfTransaction() error
	// Ends the session (aborts any running transactions) - for use in defer statements after StartSession
	Finish()

	// Get retrieves a single resource instance identified by its resource type and ID
	Get(id, resourceType string) (resource *models2.Resource, err error)
	// GetVersion retrieves a single resource instance identified by its resource type, ID and versionId
	GetVersion(id, versionId, resourceType string) (resource *models2.Resource, err error)
	// Post creates a resource instance, returning its new ID.
	Post(resource *models2.Resource) (id string, err error)
	// ConditionalPost creates a resource if the query finds no matches
	ConditionalPost(query search.Query, resource *models2.Resource) (httpStatus int, id string, outputResource *models2.Resource, err error)
	// PostWithID creates a resource instance with the given ID.
	PostWithID(id string, resource *models2.Resource) error
	// Put creates or updates a resource instance with the given ID.
	Put(id string, conditionalVersionId string, resource *models2.Resource) (createdNew bool, err error)
	// ConditionalPut creates or updates a resource based on search criteria.  If the criteria results in zero matches,
	// the resource is created.  If the criteria results in one match, it is updated.  Otherwise, a ErrMultipleMatches
	// error is returned.
	ConditionalPut(query search.Query, conditionalVersionId string, resource *models2.Resource) (id string, createdNew bool, err error)
	// Delete removes the resource instance with the given ID.  This operation cannot be undone.
	Delete(id, resourceType string) (newVersionId string, err error)
	// ConditionalDelete removes zero or more resources matching the passed in search criteria.  This operation cannot
	// be undone.
	ConditionalDelete(query search.Query) (count int64, err error)
	// Search executes a search given the baseURL and searchQuery.
	Search(baseURL url.URL, searchQuery search.Query) (bundle *models2.ShallowBundle, err error)
	// FindIDs executes a search given the searchQuery and returns only the matching IDs.  This function ignores
	// search options that don't make sense in this context: _include, _revinclude, _summary, _elements, _contained,
	// and _containedType.  It honors search options such as _count, _sort, and _offset.
	FindIDs(searchQuery search.Query) (result []string, err error)
	// History executes the history operation (partial support)
	History(baseURL url.URL, resoureType string, id string) (bundle *models2.ShallowBundle, err error)
}

DataAccessLayer is an interface for the various interactions that can occur on a FHIR data store.

type ErrConflict

type ErrConflict struct {
	// contains filtered or unexported fields
}

func (ErrConflict) Error

func (e ErrConflict) Error() string

type ErrMultipleMatches

type ErrMultipleMatches struct {
	// contains filtered or unexported fields
}

ErrMultipleMatches indicates that the conditional update query returned multiple matches

func (ErrMultipleMatches) Error

func (e ErrMultipleMatches) Error() string

type FHIRServer

type FHIRServer struct {
	Config           Config
	Engine           *gin.Engine
	MiddlewareConfig map[string][]gin.HandlerFunc
	AfterRoutes      []AfterRoutes
	Interceptors     map[string]InterceptorList
}

func NewServer

func NewServer(config Config) *FHIRServer

func (*FHIRServer) AddInterceptor

func (f *FHIRServer) AddInterceptor(op, resourceType string, handler InterceptorHandler) error

AddInterceptor adds a new interceptor for a particular database operation and FHIR resource. For example: AddInterceptor("Create", "Patient", patientInterceptorHandler) would register the patientInterceptorHandler methods to be run against a Patient resource when it is created.

To run a handler against ALL resources pass "*" as the resourceType.

Supported database operations are: "Create", "Update", "Delete"

func (*FHIRServer) AddMiddleware

func (f *FHIRServer) AddMiddleware(key string, middleware gin.HandlerFunc)

func (*FHIRServer) InitDB

func (f *FHIRServer) InitDB(databaseName string)

func (*FHIRServer) InitEngine

func (f *FHIRServer) InitEngine()

func (*FHIRServer) Run

func (f *FHIRServer) Run(port int, localhostOnly bool)

type FhirFormatConverter

type FhirFormatConverter struct {
	// contains filtered or unexported fields
}

Converts between FHIR JSON and XML encodings using the FHIR.js library developed by the Lantana Consulting Group (https://github.com/lantanagroup/FHIR.js) It is executed using the goja JavaScript engine

func NewFhirFormatConverter

func NewFhirFormatConverter() *FhirFormatConverter

func (*FhirFormatConverter) JsonToXml

func (c *FhirFormatConverter) JsonToXml(json string) (xml string, err error)

func (*FhirFormatConverter) SendXML

func (c *FhirFormatConverter) SendXML(statusCode int, obj interface{}, context *gin.Context) error

func (*FhirFormatConverter) XmlToJson

func (c *FhirFormatConverter) XmlToJson(xml string) (json string, err error)

type IndexMap

type IndexMap map[string][]mongo.IndexModel

IndexMap is a map of index arrays with the collection name as the key. Each index array contains one or more indexes.

type Indexer

type Indexer struct {
	// contains filtered or unexported fields
}

Indexer is the top-level interface for managing MongoDB indexes.

func NewIndexer

func NewIndexer(dbName string, config Config) *Indexer

NewIndexer returns a pointer to a newly configured Indexer.

func (*Indexer) ConfigureIndexes

func (i *Indexer) ConfigureIndexes(db *mongowrapper.WrappedDatabase)

ConfigureIndexes ensures that all indexes listed in the provided indexes.conf file are part of the Mongodb fhir database. If an index does not exist yet ConfigureIndexes creates a new index in the background using mgo.collection.EnsureIndex(). Depending on the size of the collection it may take some time before the index is created. This will block the current thread until the indexing completes, but will not block other connections to the mongo database.

type Interceptor

type Interceptor struct {
	ResourceType string
	Handler      InterceptorHandler
}

Interceptor optionally executes functions on a specified resource type before and after a database operation involving that resource. To register an interceptor for ALL resource types use a "*" as the resourceType.

type InterceptorHandler

type InterceptorHandler interface {
	Before(resource interface{})
	After(resource interface{})
	OnError(err error, resource interface{})
}

InterceptorHandler is an interface that defines three methods that are executed on a resource before the database operation, after the database operation SUCCEEDS, and after the database operation FAILS.

type InterceptorList

type InterceptorList []Interceptor

InterceptorList is a list of interceptors registered for a given database operation

type Reply

type Reply struct {
	Info string  `bson:"info,omitempty" json:"info,omitempty"`
	Ok   float64 `bson:"ok" json:"ok"`
}

Reply is a response from a MongoDB command that doesn't return any results.

type ResourceController

type ResourceController struct {
	Name   string
	DAL    DataAccessLayer
	Config Config
}

ResourceController provides the necessary CRUD handlers for a given resource.

func NewResourceController

func NewResourceController(name string, dal DataAccessLayer, config Config) *ResourceController

NewResourceController creates a new resource controller for the passed in resource name and the passed in DataAccessLayer.

func (*ResourceController) ConditionalDeleteHandler

func (rc *ResourceController) ConditionalDeleteHandler(c *gin.Context)

ConditionalDeleteHandler handles requests to delete resources identified by search criteria. All resources matching the search criteria will be deleted.

func (*ResourceController) ConditionalUpdateHandler

func (rc *ResourceController) ConditionalUpdateHandler(c *gin.Context)

ConditionalUpdateHandler handles requests for conditional updates. These requests contain search criteria for the resource to update. If the criteria results in no found resources, a new resource is created. If the criteria results in one found resource, that resource will be updated. Criteria resulting in more than one found resource is considered an error.

func (*ResourceController) CreateHandler

func (rc *ResourceController) CreateHandler(c *gin.Context)

CreateHandler handles requests to create a new resource instance, assigning it a new ID.

func (*ResourceController) DeleteHandler

func (rc *ResourceController) DeleteHandler(c *gin.Context)

DeleteHandler handles requests to delete a resource instance identified by its ID.

func (*ResourceController) EverythingHandler

func (rc *ResourceController) EverythingHandler(c *gin.Context)

EverythingHandler handles requests for everything related to a Patient or Encounter resource.

func (*ResourceController) HistoryHandler

func (rc *ResourceController) HistoryHandler(c *gin.Context)

func (*ResourceController) IndexHandler

func (rc *ResourceController) IndexHandler(c *gin.Context)

IndexHandler handles requests to list resource instances or search for them.

func (*ResourceController) LoadResource

func (rc *ResourceController) LoadResource(c *gin.Context) (resourceId string, resource *models2.Resource, err error)

LoadResource uses the resource id in the request to get a resource from the DataAccessLayer and store it in the context.

func (*ResourceController) ShowHandler

func (rc *ResourceController) ShowHandler(c *gin.Context)

ShowHandler handles requests to get a particular resource by ID.

func (*ResourceController) UpdateHandler

func (rc *ResourceController) UpdateHandler(c *gin.Context)

UpdateHandler handles requests to update a resource having a given ID. If the resource with that ID does not exist, a new resource is created with that ID.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL