-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
datasets_data_create.go
117 lines (101 loc) · 4.27 KB
/
datasets_data_create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package v1
import (
"net/http"
"strconv"
"github.com/tidepool-org/platform/data"
dataNormalizer "github.com/tidepool-org/platform/data/normalizer"
dataService "github.com/tidepool-org/platform/data/service"
dataTypesFactory "github.com/tidepool-org/platform/data/types/factory"
"github.com/tidepool-org/platform/log"
"github.com/tidepool-org/platform/permission"
"github.com/tidepool-org/platform/request"
"github.com/tidepool-org/platform/service"
structureParser "github.com/tidepool-org/platform/structure/parser"
structureValidator "github.com/tidepool-org/platform/structure/validator"
)
func DataSetsDataCreate(dataServiceContext dataService.Context) {
ctx := dataServiceContext.Request().Context()
lgr := log.LoggerFromContext(ctx)
dataSetID := dataServiceContext.Request().PathParam("dataSetId")
if dataSetID == "" {
dataServiceContext.RespondWithError(ErrorDataSetIDMissing())
return
}
dataSet, err := dataServiceContext.DataSession().GetDataSetByID(ctx, dataSetID)
if err != nil {
dataServiceContext.RespondWithInternalServerFailure("Unable to get data set by id", err)
return
}
if dataSet == nil {
dataServiceContext.RespondWithError(ErrorDataSetIDNotFound(dataSetID))
return
}
if details := request.DetailsFromContext(ctx); !details.IsService() {
var permissions permission.Permissions
permissions, err = dataServiceContext.PermissionClient().GetUserPermissions(ctx, details.UserID(), *dataSet.UserID)
if err != nil {
if request.IsErrorUnauthorized(err) {
dataServiceContext.RespondWithError(service.ErrorUnauthorized())
} else {
dataServiceContext.RespondWithInternalServerFailure("Unable to get user permissions", err)
}
return
}
if _, ok := permissions[permission.Write]; !ok {
dataServiceContext.RespondWithError(service.ErrorUnauthorized())
return
}
}
if (dataSet.State != nil && *dataSet.State == "closed") || (dataSet.DataState != nil && *dataSet.DataState == "closed") { // TODO: Deprecated DataState (after data migration)
dataServiceContext.RespondWithError(ErrorDataSetClosed(dataSetID))
return
}
var rawDatumArray []interface{}
if err = dataServiceContext.Request().DecodeJsonPayload(&rawDatumArray); err != nil {
dataServiceContext.RespondWithError(service.ErrorJSONMalformed())
return
}
parser := structureParser.NewArray(&rawDatumArray)
validator := structureValidator.New()
normalizer := dataNormalizer.New()
datumArray := []data.Datum{}
for _, reference := range parser.References() {
if datum := dataTypesFactory.ParseDatum(parser.WithReferenceObjectParser(reference)); datum != nil && *datum != nil {
(*datum).Validate(validator.WithReference(strconv.Itoa(reference)))
(*datum).Normalize(normalizer.WithReference(strconv.Itoa(reference)))
datumArray = append(datumArray, *datum)
}
}
parser.NotParsed()
if err = parser.Error(); err != nil {
request.MustNewResponder(dataServiceContext.Response(), dataServiceContext.Request()).Error(http.StatusBadRequest, err)
return
}
if err = validator.Error(); err != nil {
request.MustNewResponder(dataServiceContext.Response(), dataServiceContext.Request()).Error(http.StatusBadRequest, err)
return
}
if err = normalizer.Error(); err != nil {
request.MustNewResponder(dataServiceContext.Response(), dataServiceContext.Request()).Error(http.StatusBadRequest, err)
return
}
datumArray = append(datumArray, normalizer.Data()...)
for _, datum := range datumArray {
datum.SetUserID(dataSet.UserID)
datum.SetDataSetID(dataSet.UploadID)
}
if deduplicator, getErr := dataServiceContext.DataDeduplicatorFactory().Get(dataSet); getErr != nil {
dataServiceContext.RespondWithInternalServerFailure("Unable to get deduplicator", getErr)
return
} else if deduplicator == nil {
dataServiceContext.RespondWithInternalServerFailure("Deduplicator not found")
return
} else if err = deduplicator.AddData(ctx, dataServiceContext.DataSession(), dataSet, datumArray); err != nil {
dataServiceContext.RespondWithInternalServerFailure("Unable to add data", err)
return
}
if err = dataServiceContext.MetricClient().RecordMetric(ctx, "data_sets_data_create", map[string]string{"count": strconv.Itoa(len(datumArray))}); err != nil {
lgr.WithError(err).Error("Unable to record metric")
}
dataServiceContext.RespondWithStatusAndData(http.StatusOK, []struct{}{})
}