Skip to content

Commit

Permalink
Merge branch 'beta/1.9.0' into cmd-master
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlHembrough committed Jul 9, 2018
2 parents 82b2707 + 72630d4 commit 52f9d93
Show file tree
Hide file tree
Showing 145 changed files with 12,302 additions and 3,842 deletions.
305 changes: 125 additions & 180 deletions api/api.go

Large diffs are not rendered by default.

230 changes: 116 additions & 114 deletions api/dataset.go

Large diffs are not rendered by default.

919 changes: 446 additions & 473 deletions api/dataset_test.go

Large diffs are not rendered by default.

129 changes: 75 additions & 54 deletions api/dimensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import (
"encoding/json"
"fmt"
"net/http"
"strconv"

errs "github.com/ONSdigital/dp-dataset-api/apierrors"
"github.com/ONSdigital/dp-dataset-api/models"
"github.com/ONSdigital/go-ns/audit"
"github.com/ONSdigital/go-ns/common"
"github.com/ONSdigital/go-ns/log"
"github.com/gedge/mgo/bson"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"gopkg.in/mgo.v2/bson"
)

func (api *DatasetAPI) getDimensions(w http.ResponseWriter, r *http.Request) {
Expand All @@ -24,9 +26,8 @@ func (api *DatasetAPI) getDimensions(w http.ResponseWriter, r *http.Request) {
logData := log.Data{"dataset_id": datasetID, "edition": edition, "version": version}
auditParams := common.Params{"dataset_id": datasetID, "edition": edition, "version": version}

if err := api.auditor.Record(ctx, getDimensionsAction, actionAttempted, auditParams); err != nil {
auditActionFailure(ctx, getDimensionsAction, actionAttempted, err, logData)
handleDimensionsErr(ctx, w, err)
if err := api.auditor.Record(ctx, getDimensionsAction, audit.Attempted, auditParams); err != nil {
handleDimensionsErr(ctx, w, err, logData)
return
}

Expand All @@ -40,59 +41,58 @@ func (api *DatasetAPI) getDimensions(w http.ResponseWriter, r *http.Request) {

versionDoc, err := api.dataStore.Backend.GetVersion(datasetID, edition, version, state)
if err != nil {
logError(ctx, errors.WithMessage(err, "getDimensions endpoint: datastore.getversion returned an error"), logData)
log.ErrorCtx(ctx, errors.WithMessage(err, "getDimensions endpoint: datastore.getversion returned an error"), logData)
return nil, err
}

if err = models.CheckState("version", versionDoc.State); err != nil {
logData["state"] = versionDoc.State
logError(ctx, errors.WithMessage(err, "getDimensions endpoint: unpublished version has an invalid state"), logData)
log.ErrorCtx(ctx, errors.WithMessage(err, "getDimensions endpoint: unpublished version has an invalid state"), logData)
return nil, err
}

dimensions, err := api.dataStore.Backend.GetDimensions(datasetID, versionDoc.ID)
if err != nil {
logError(ctx, errors.WithMessage(err, "getDimensions endpoint: failed to get version dimensions"), logData)
log.ErrorCtx(ctx, errors.WithMessage(err, "getDimensions endpoint: failed to get version dimensions"), logData)
return nil, err
}

results, err := api.createListOfDimensions(versionDoc, dimensions)
if err != nil {
logError(ctx, errors.WithMessage(err, "getDimensions endpoint: failed to convert bson to dimension"), logData)
log.ErrorCtx(ctx, errors.WithMessage(err, "getDimensions endpoint: failed to convert bson to dimension"), logData)
return nil, err
}

listOfDimensions := &models.DatasetDimensionResults{Items: results}

b, err := json.Marshal(listOfDimensions)
if err != nil {
logError(ctx, errors.WithMessage(err, "getDimensions endpoint: failed to marshal list of dimension resources into bytes"), logData)
log.ErrorCtx(ctx, errors.WithMessage(err, "getDimensions endpoint: failed to marshal list of dimension resources into bytes"), logData)
return nil, err
}
return b, nil
}()

if err != nil {
if auditErr := api.auditor.Record(ctx, getDimensionsAction, actionUnsuccessful, auditParams); auditErr != nil {
auditActionFailure(ctx, getDimensionsAction, actionUnsuccessful, auditErr, logData)
if auditErr := api.auditor.Record(ctx, getDimensionsAction, audit.Unsuccessful, auditParams); auditErr != nil {
err = auditErr
}
handleDimensionsErr(ctx, w, err)
handleDimensionsErr(ctx, w, err, logData)
return
}

if auditErr := api.auditor.Record(ctx, getDimensionsAction, actionSuccessful, auditParams); auditErr != nil {
auditActionFailure(ctx, getDimensionsAction, actionSuccessful, auditErr, logData)
handleDimensionsErr(ctx, w, auditErr)
if auditErr := api.auditor.Record(ctx, getDimensionsAction, audit.Successful, auditParams); auditErr != nil {
handleDimensionsErr(ctx, w, auditErr, logData)
return
}

setJSONContentType(w)
_, err = w.Write(b)
if err != nil {
logError(ctx, errors.WithMessage(err, "getDimensions endpoint: error writing bytes to response"), logData)
log.ErrorCtx(ctx, errors.WithMessage(err, "getDimensions endpoint: error writing bytes to response"), logData)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
logInfo(ctx, "getDimensions endpoint: request successful", logData)

log.InfoCtx(ctx, "getDimensions endpoint: request successful", logData)
}

func (api *DatasetAPI) createListOfDimensions(versionDoc *models.Version, dimensions []bson.M) ([]models.Dimension, error) {
Expand Down Expand Up @@ -142,50 +142,71 @@ func convertBSONToDimensionOption(data interface{}) (*models.DimensionOption, er
}

func (api *DatasetAPI) getDimensionOptions(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
datasetID := vars["id"]
editionID := vars["edition"]
versionID := vars["version"]
dimension := vars["dimension"]

logData := log.Data{"dataset_id": datasetID, "edition": editionID, "version": versionID, "dimension": dimension}
auditParams := common.Params{"dataset_id": datasetID, "edition": editionID, "version": versionID, "dimension": dimension}

if err := api.auditor.Record(ctx, getDimensionOptionsAction, audit.Attempted, auditParams); err != nil {
handleDimensionsErr(ctx, w, err, logData)
return
}

authorised, logData := api.authenticate(r, logData)
auditParams["authorised"] = strconv.FormatBool(authorised)

var state string
if !authorised {
state = models.PublishedState
}

version, err := api.dataStore.Backend.GetVersion(datasetID, editionID, versionID, state)
if err != nil {
log.ErrorC("failed to get version", err, logData)
handleErrorType(versionDocType, err, w)
return
}
b, err := func() ([]byte, error) {
version, err := api.dataStore.Backend.GetVersion(datasetID, editionID, versionID, state)
if err != nil {
log.ErrorCtx(ctx, errors.WithMessage(err, "failed to get version"), logData)
return nil, err
}

if err = models.CheckState("version", version.State); err != nil {
log.ErrorC("unpublished version has an invalid state", err, log.Data{"state": version.State})
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err = models.CheckState("version", version.State); err != nil {
logData["version_state"] = version.State
log.ErrorCtx(ctx, errors.WithMessage(err, "unpublished version has an invalid state"), logData)
return nil, err
}

results, err := api.dataStore.Backend.GetDimensionOptions(version, dimension)
results, err := api.dataStore.Backend.GetDimensionOptions(version, dimension)
if err != nil {
log.ErrorCtx(ctx, errors.WithMessage(err, "failed to get a list of dimension options"), logData)
return nil, err
}

for i := range results.Items {
results.Items[i].Links.Version.HRef = fmt.Sprintf("%s/datasets/%s/editions/%s/versions/%s",
api.host, datasetID, editionID, versionID)
}

b, err := json.Marshal(results)
if err != nil {
log.ErrorCtx(ctx, errors.WithMessage(err, "failed to marshal list of dimension option resources into bytes"), logData)
return nil, err
}

return b, nil
}()
if err != nil {
log.ErrorC("failed to get a list of dimension options", err, logData)
handleErrorType(dimensionOptionDocType, err, w)
if auditErr := api.auditor.Record(ctx, getDimensionOptionsAction, audit.Unsuccessful, auditParams); auditErr != nil {
err = auditErr
}
handleDimensionsErr(ctx, w, err, logData)
return
}

for i := range results.Items {
results.Items[i].Links.Version.HRef = fmt.Sprintf("%s/datasets/%s/editions/%s/versions/%s",
api.host, datasetID, editionID, versionID)
}

b, err := json.Marshal(results)
if err != nil {
log.ErrorC("failed to marshal list of dimension option resources into bytes", err, logData)
http.Error(w, err.Error(), http.StatusInternalServerError)
if auditErr := api.auditor.Record(ctx, getDimensionOptionsAction, audit.Successful, auditParams); auditErr != nil {
handleDimensionsErr(ctx, w, auditErr, logData)
return
}

Expand All @@ -199,22 +220,22 @@ func (api *DatasetAPI) getDimensionOptions(w http.ResponseWriter, r *http.Reques
log.Debug("get dimension options", logData)
}

func handleDimensionsErr(ctx context.Context, w http.ResponseWriter, err error) {
var responseStatus int
func handleDimensionsErr(ctx context.Context, w http.ResponseWriter, err error, data log.Data) {
if data == nil {
data = log.Data{}
}

var status int
response := err
switch {
case err == errs.ErrDatasetNotFound:
responseStatus = http.StatusNotFound
case err == errs.ErrEditionNotFound:
responseStatus = http.StatusNotFound
case err == errs.ErrVersionNotFound:
responseStatus = http.StatusNotFound
case err == errs.ErrDimensionsNotFound:
responseStatus = http.StatusNotFound
case errs.NotFoundMap[err]:
status = http.StatusNotFound
default:
responseStatus = http.StatusInternalServerError
status = http.StatusInternalServerError
response = errs.ErrInternalServer
}

logError(ctx, errors.WithMessage(err, "request unsuccessful"), log.Data{"responseStatus": responseStatus})
http.Error(w, err.Error(), responseStatus)
data["response_status"] = status
log.ErrorCtx(ctx, errors.WithMessage(err, "request unsuccessful"), data)
http.Error(w, response.Error(), status)
}
Loading

0 comments on commit 52f9d93

Please sign in to comment.