Define record import routes
This commit is contained in:
@@ -667,6 +667,68 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "importInit",
|
||||
"path": "/import",
|
||||
"method": "POST",
|
||||
"title": "Initiate record import session",
|
||||
"parameters": {
|
||||
"post": [
|
||||
{
|
||||
"name": "upload",
|
||||
"type": "*multipart.FileHeader",
|
||||
"required": true,
|
||||
"title": "File import"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "importRun",
|
||||
"path": "/import/{sessionID}",
|
||||
"method": "PATCH",
|
||||
"title": "Run record import",
|
||||
"parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"type": "uint64",
|
||||
"required": true,
|
||||
"title": "Import session"
|
||||
}
|
||||
],
|
||||
"post": [
|
||||
{
|
||||
"name": "fields",
|
||||
"type": "json.RawMessage",
|
||||
"required": true,
|
||||
"title": "Fields defined by import file"
|
||||
},
|
||||
{
|
||||
"name": "onError",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"title": "What happens if record fails to import"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "importProgress",
|
||||
"path": "/import/{sessionID}",
|
||||
"method": "GET",
|
||||
"title": "Get import progress",
|
||||
"parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"type": "uint64",
|
||||
"required": true,
|
||||
"title": "Import session"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "export",
|
||||
"path": "/export{filename}.{ext}",
|
||||
|
||||
@@ -91,6 +91,68 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "importInit",
|
||||
"Method": "POST",
|
||||
"Title": "Initiate record import session",
|
||||
"Path": "/import",
|
||||
"Parameters": {
|
||||
"post": [
|
||||
{
|
||||
"name": "upload",
|
||||
"required": true,
|
||||
"title": "File import",
|
||||
"type": "*multipart.FileHeader"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "importRun",
|
||||
"Method": "PATCH",
|
||||
"Title": "Run record import",
|
||||
"Path": "/import/{sessionID}",
|
||||
"Parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"required": true,
|
||||
"title": "Import session",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"post": [
|
||||
{
|
||||
"name": "fields",
|
||||
"required": true,
|
||||
"title": "Fields defined by import file",
|
||||
"type": "json.RawMessage"
|
||||
},
|
||||
{
|
||||
"name": "onError",
|
||||
"required": true,
|
||||
"title": "What happens if record fails to import",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "importProgress",
|
||||
"Method": "GET",
|
||||
"Title": "Get import progress",
|
||||
"Path": "/import/{sessionID}",
|
||||
"Parameters": {
|
||||
"path": [
|
||||
{
|
||||
"name": "sessionID",
|
||||
"required": true,
|
||||
"title": "Import session",
|
||||
"type": "uint64"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "export",
|
||||
"Method": "GET",
|
||||
|
||||
@@ -31,6 +31,9 @@ import (
|
||||
type RecordAPI interface {
|
||||
Report(context.Context, *request.RecordReport) (interface{}, error)
|
||||
List(context.Context, *request.RecordList) (interface{}, error)
|
||||
ImportInit(context.Context, *request.RecordImportInit) (interface{}, error)
|
||||
ImportRun(context.Context, *request.RecordImportRun) (interface{}, error)
|
||||
ImportProgress(context.Context, *request.RecordImportProgress) (interface{}, error)
|
||||
Export(context.Context, *request.RecordExport) (interface{}, error)
|
||||
Create(context.Context, *request.RecordCreate) (interface{}, error)
|
||||
Read(context.Context, *request.RecordRead) (interface{}, error)
|
||||
@@ -41,14 +44,17 @@ type RecordAPI interface {
|
||||
|
||||
// HTTP API interface
|
||||
type Record struct {
|
||||
Report func(http.ResponseWriter, *http.Request)
|
||||
List func(http.ResponseWriter, *http.Request)
|
||||
Export func(http.ResponseWriter, *http.Request)
|
||||
Create func(http.ResponseWriter, *http.Request)
|
||||
Read func(http.ResponseWriter, *http.Request)
|
||||
Update func(http.ResponseWriter, *http.Request)
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
Upload func(http.ResponseWriter, *http.Request)
|
||||
Report func(http.ResponseWriter, *http.Request)
|
||||
List func(http.ResponseWriter, *http.Request)
|
||||
ImportInit func(http.ResponseWriter, *http.Request)
|
||||
ImportRun func(http.ResponseWriter, *http.Request)
|
||||
ImportProgress func(http.ResponseWriter, *http.Request)
|
||||
Export func(http.ResponseWriter, *http.Request)
|
||||
Create func(http.ResponseWriter, *http.Request)
|
||||
Read func(http.ResponseWriter, *http.Request)
|
||||
Update func(http.ResponseWriter, *http.Request)
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
Upload func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
func NewRecord(h RecordAPI) *Record {
|
||||
@@ -93,6 +99,66 @@ func NewRecord(h RecordAPI) *Record {
|
||||
resputil.JSON(w, value)
|
||||
}
|
||||
},
|
||||
ImportInit: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewRecordImportInit()
|
||||
if err := params.Fill(r); err != nil {
|
||||
logger.LogParamError("Record.ImportInit", r, err)
|
||||
resputil.JSON(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.ImportInit(r.Context(), params)
|
||||
if err != nil {
|
||||
logger.LogControllerError("Record.ImportInit", r, err, params.Auditable())
|
||||
resputil.JSON(w, err)
|
||||
return
|
||||
}
|
||||
logger.LogControllerCall("Record.ImportInit", r, params.Auditable())
|
||||
if !serveHTTP(value, w, r) {
|
||||
resputil.JSON(w, value)
|
||||
}
|
||||
},
|
||||
ImportRun: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewRecordImportRun()
|
||||
if err := params.Fill(r); err != nil {
|
||||
logger.LogParamError("Record.ImportRun", r, err)
|
||||
resputil.JSON(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.ImportRun(r.Context(), params)
|
||||
if err != nil {
|
||||
logger.LogControllerError("Record.ImportRun", r, err, params.Auditable())
|
||||
resputil.JSON(w, err)
|
||||
return
|
||||
}
|
||||
logger.LogControllerCall("Record.ImportRun", r, params.Auditable())
|
||||
if !serveHTTP(value, w, r) {
|
||||
resputil.JSON(w, value)
|
||||
}
|
||||
},
|
||||
ImportProgress: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewRecordImportProgress()
|
||||
if err := params.Fill(r); err != nil {
|
||||
logger.LogParamError("Record.ImportProgress", r, err)
|
||||
resputil.JSON(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.ImportProgress(r.Context(), params)
|
||||
if err != nil {
|
||||
logger.LogControllerError("Record.ImportProgress", r, err, params.Auditable())
|
||||
resputil.JSON(w, err)
|
||||
return
|
||||
}
|
||||
logger.LogControllerCall("Record.ImportProgress", r, params.Auditable())
|
||||
if !serveHTTP(value, w, r) {
|
||||
resputil.JSON(w, value)
|
||||
}
|
||||
},
|
||||
Export: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewRecordExport()
|
||||
@@ -221,6 +287,9 @@ func (h Record) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http
|
||||
r.Use(middlewares...)
|
||||
r.Get("/namespace/{namespaceID}/module/{moduleID}/record/report", h.Report)
|
||||
r.Get("/namespace/{namespaceID}/module/{moduleID}/record/", h.List)
|
||||
r.Post("/namespace/{namespaceID}/module/{moduleID}/record/import", h.ImportInit)
|
||||
r.Patch("/namespace/{namespaceID}/module/{moduleID}/record/import/{sessionID}", h.ImportRun)
|
||||
r.Get("/namespace/{namespaceID}/module/{moduleID}/record/import/{sessionID}", h.ImportProgress)
|
||||
r.Get("/namespace/{namespaceID}/module/{moduleID}/record/export{filename}.{ext}", h.Export)
|
||||
r.Post("/namespace/{namespaceID}/module/{moduleID}/record/", h.Create)
|
||||
r.Get("/namespace/{namespaceID}/module/{moduleID}/record/{recordID}", h.Read)
|
||||
|
||||
@@ -175,6 +175,192 @@ func (r *RecordList) Fill(req *http.Request) (err error) {
|
||||
|
||||
var _ RequestFiller = NewRecordList()
|
||||
|
||||
// Record importInit request parameters
|
||||
type RecordImportInit struct {
|
||||
Upload *multipart.FileHeader
|
||||
NamespaceID uint64 `json:",string"`
|
||||
ModuleID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
func NewRecordImportInit() *RecordImportInit {
|
||||
return &RecordImportInit{}
|
||||
}
|
||||
|
||||
func (r RecordImportInit) Auditable() map[string]interface{} {
|
||||
var out = map[string]interface{}{}
|
||||
|
||||
out["upload.size"] = r.Upload.Size
|
||||
out["upload.filename"] = r.Upload.Filename
|
||||
|
||||
out["namespaceID"] = r.NamespaceID
|
||||
out["moduleID"] = r.ModuleID
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (r *RecordImportInit) Fill(req *http.Request) (err error) {
|
||||
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(req.Body).Decode(r)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return errors.Wrap(err, "error parsing http request body")
|
||||
}
|
||||
}
|
||||
|
||||
if err = req.ParseMultipartForm(32 << 20); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
get := map[string]string{}
|
||||
post := map[string]string{}
|
||||
urlQuery := req.URL.Query()
|
||||
for name, param := range urlQuery {
|
||||
get[name] = string(param[0])
|
||||
}
|
||||
postVars := req.Form
|
||||
for name, param := range postVars {
|
||||
post[name] = string(param[0])
|
||||
}
|
||||
|
||||
if _, r.Upload, err = req.FormFile("upload"); err != nil {
|
||||
return errors.Wrap(err, "error procesing uploaded file")
|
||||
}
|
||||
|
||||
r.NamespaceID = parseUInt64(chi.URLParam(req, "namespaceID"))
|
||||
r.ModuleID = parseUInt64(chi.URLParam(req, "moduleID"))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ RequestFiller = NewRecordImportInit()
|
||||
|
||||
// Record importRun request parameters
|
||||
type RecordImportRun struct {
|
||||
SessionID uint64 `json:",string"`
|
||||
NamespaceID uint64 `json:",string"`
|
||||
ModuleID uint64 `json:",string"`
|
||||
Fields json.RawMessage
|
||||
OnError string
|
||||
}
|
||||
|
||||
func NewRecordImportRun() *RecordImportRun {
|
||||
return &RecordImportRun{}
|
||||
}
|
||||
|
||||
func (r RecordImportRun) Auditable() map[string]interface{} {
|
||||
var out = map[string]interface{}{}
|
||||
|
||||
out["sessionID"] = r.SessionID
|
||||
out["namespaceID"] = r.NamespaceID
|
||||
out["moduleID"] = r.ModuleID
|
||||
out["fields"] = r.Fields
|
||||
out["onError"] = r.OnError
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (r *RecordImportRun) Fill(req *http.Request) (err error) {
|
||||
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(req.Body).Decode(r)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return errors.Wrap(err, "error parsing http request body")
|
||||
}
|
||||
}
|
||||
|
||||
if err = req.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
get := map[string]string{}
|
||||
post := map[string]string{}
|
||||
urlQuery := req.URL.Query()
|
||||
for name, param := range urlQuery {
|
||||
get[name] = string(param[0])
|
||||
}
|
||||
postVars := req.Form
|
||||
for name, param := range postVars {
|
||||
post[name] = string(param[0])
|
||||
}
|
||||
|
||||
r.SessionID = parseUInt64(chi.URLParam(req, "sessionID"))
|
||||
r.NamespaceID = parseUInt64(chi.URLParam(req, "namespaceID"))
|
||||
r.ModuleID = parseUInt64(chi.URLParam(req, "moduleID"))
|
||||
if val, ok := post["fields"]; ok {
|
||||
r.Fields = json.RawMessage(val)
|
||||
}
|
||||
if val, ok := post["onError"]; ok {
|
||||
r.OnError = val
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ RequestFiller = NewRecordImportRun()
|
||||
|
||||
// Record importProgress request parameters
|
||||
type RecordImportProgress struct {
|
||||
SessionID uint64 `json:",string"`
|
||||
NamespaceID uint64 `json:",string"`
|
||||
ModuleID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
func NewRecordImportProgress() *RecordImportProgress {
|
||||
return &RecordImportProgress{}
|
||||
}
|
||||
|
||||
func (r RecordImportProgress) Auditable() map[string]interface{} {
|
||||
var out = map[string]interface{}{}
|
||||
|
||||
out["sessionID"] = r.SessionID
|
||||
out["namespaceID"] = r.NamespaceID
|
||||
out["moduleID"] = r.ModuleID
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (r *RecordImportProgress) Fill(req *http.Request) (err error) {
|
||||
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
|
||||
err = json.NewDecoder(req.Body).Decode(r)
|
||||
|
||||
switch {
|
||||
case err == io.EOF:
|
||||
err = nil
|
||||
case err != nil:
|
||||
return errors.Wrap(err, "error parsing http request body")
|
||||
}
|
||||
}
|
||||
|
||||
if err = req.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
get := map[string]string{}
|
||||
post := map[string]string{}
|
||||
urlQuery := req.URL.Query()
|
||||
for name, param := range urlQuery {
|
||||
get[name] = string(param[0])
|
||||
}
|
||||
postVars := req.Form
|
||||
for name, param := range postVars {
|
||||
post[name] = string(param[0])
|
||||
}
|
||||
|
||||
r.SessionID = parseUInt64(chi.URLParam(req, "sessionID"))
|
||||
r.NamespaceID = parseUInt64(chi.URLParam(req, "namespaceID"))
|
||||
r.ModuleID = parseUInt64(chi.URLParam(req, "moduleID"))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
var _ RequestFiller = NewRecordImportProgress()
|
||||
|
||||
// Record export request parameters
|
||||
type RecordExport struct {
|
||||
Filter string
|
||||
|
||||
@@ -956,6 +956,9 @@ Compose records
|
||||
| ------ | -------- | ------- |
|
||||
| `GET` | `/namespace/{namespaceID}/module/{moduleID}/record/report` | Generates report from module records |
|
||||
| `GET` | `/namespace/{namespaceID}/module/{moduleID}/record/` | List/read records from module section |
|
||||
| `POST` | `/namespace/{namespaceID}/module/{moduleID}/record/import` | Initiate record import session |
|
||||
| `PATCH` | `/namespace/{namespaceID}/module/{moduleID}/record/import/{sessionID}` | Run record import |
|
||||
| `GET` | `/namespace/{namespaceID}/module/{moduleID}/record/import/{sessionID}` | Get import progress |
|
||||
| `GET` | `/namespace/{namespaceID}/module/{moduleID}/record/export{filename}.{ext}` | Exports records that match |
|
||||
| `POST` | `/namespace/{namespaceID}/module/{moduleID}/record/` | Create record in module section |
|
||||
| `GET` | `/namespace/{namespaceID}/module/{moduleID}/record/{recordID}` | Read records by ID from module section |
|
||||
@@ -1000,6 +1003,56 @@ Compose records
|
||||
| namespaceID | uint64 | PATH | Namespace ID | N/A | YES |
|
||||
| moduleID | uint64 | PATH | Module ID | N/A | YES |
|
||||
|
||||
## Initiate record import session
|
||||
|
||||
#### Method
|
||||
|
||||
| URI | Protocol | Method | Authentication |
|
||||
| --- | -------- | ------ | -------------- |
|
||||
| `/namespace/{namespaceID}/module/{moduleID}/record/import` | HTTP/S | POST | |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Method | Description | Default | Required? |
|
||||
| --------- | ---- | ------ | ----------- | ------- | --------- |
|
||||
| upload | *multipart.FileHeader | POST | File import | N/A | YES |
|
||||
| namespaceID | uint64 | PATH | Namespace ID | N/A | YES |
|
||||
| moduleID | uint64 | PATH | Module ID | N/A | YES |
|
||||
|
||||
## Run record import
|
||||
|
||||
#### Method
|
||||
|
||||
| URI | Protocol | Method | Authentication |
|
||||
| --- | -------- | ------ | -------------- |
|
||||
| `/namespace/{namespaceID}/module/{moduleID}/record/import/{sessionID}` | HTTP/S | PATCH | |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Method | Description | Default | Required? |
|
||||
| --------- | ---- | ------ | ----------- | ------- | --------- |
|
||||
| sessionID | uint64 | PATH | Import session | N/A | YES |
|
||||
| namespaceID | uint64 | PATH | Namespace ID | N/A | YES |
|
||||
| moduleID | uint64 | PATH | Module ID | N/A | YES |
|
||||
| fields | json.RawMessage | POST | Fields defined by import file | N/A | YES |
|
||||
| onError | string | POST | What happens if record fails to import | N/A | YES |
|
||||
|
||||
## Get import progress
|
||||
|
||||
#### Method
|
||||
|
||||
| URI | Protocol | Method | Authentication |
|
||||
| --- | -------- | ------ | -------------- |
|
||||
| `/namespace/{namespaceID}/module/{moduleID}/record/import/{sessionID}` | HTTP/S | GET | |
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Method | Description | Default | Required? |
|
||||
| --------- | ---- | ------ | ----------- | ------- | --------- |
|
||||
| sessionID | uint64 | PATH | Import session | N/A | YES |
|
||||
| namespaceID | uint64 | PATH | Namespace ID | N/A | YES |
|
||||
| moduleID | uint64 | PATH | Module ID | N/A | YES |
|
||||
|
||||
## Exports records that match
|
||||
|
||||
#### Method
|
||||
|
||||
Reference in New Issue
Block a user