Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions api/internal/db/batch.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions api/internal/dto/instrument.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ type InstrumentDTO struct {
ShowCwmsTab bool `json:"show_cwms_tab" required:"false"`
RawOpts json.RawMessage `json:"opts" required:"false"`
Opts struct {
SaaOpts SaaOptsDTO
IpiOpts IpiOptsDTO
InclOpts InclOptsDTO
SaaOpts DepthOptsDTO
IpiOpts DepthOptsDTO
InclOpts DepthOptsDTO
SeisOpts SeisOptsDTO
} `json:"-"`
AuditInfo
}

type DepthOptsDTO struct {
NumSegments int `json:"num_segments"`
BottomElevation float64 `json:"bottom_elevation"`
InitialTime *time.Time `json:"initial_time" required:"false"`
}

func (d *InstrumentDTO) Resolve(ctx huma.Context, prefix *huma.PathBuffer) []error {
var err error
switch d.TypeID {
Expand Down
8 changes: 0 additions & 8 deletions api/internal/dto/instrument_incl.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
package dto

import (
"time"

"github.com/google/uuid"
)

type InclOptsDTO struct {
NumSegments int `json:"num_segments"`
BottomElevation float64 `json:"bottom_elevation"`
InitialTime *time.Time `json:"initial_time" required:"false"`
}

type InclSegmentDTO struct {
ID int `json:"id"`
DepthTimeseriesID *uuid.UUID `json:"depth_timeseries_id" required:"false"`
Expand Down
9 changes: 0 additions & 9 deletions api/internal/dto/instrument_ipi.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
package dto

import (
"time"

"github.com/google/uuid"
)

type IpiOptsDTO struct {
NumSegments int `json:"num_segments"`
BottomElevationTimeseriesID uuid.UUID `json:"bottom_elevation_timeseries_id"`
BottomElevation float64 `json:"bottom_elevation"`
InitialTime *time.Time `json:"initial_time" required:"false"`
}

type IpiSegmentDTO struct {
ID int `json:"id"`
Length *float64 `json:"length" required:"false"`
Expand Down
9 changes: 0 additions & 9 deletions api/internal/dto/instrument_saa.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
package dto

import (
"time"

"github.com/google/uuid"
)

type SaaOptsDTO struct {
NumSegments int `json:"num_segments"`
BottomElevationTimeseriesID uuid.UUID `json:"bottom_elevation_timeseries_id"`
BottomElevation float64 `json:"bottom_elevation"`
InitialTime *time.Time `json:"initial_time" required:"false"`
}

type SaaSegmentDTO struct {
ID int `json:"id"`
Length *float64 `json:"length" required:"false"`
Expand Down
10 changes: 3 additions & 7 deletions api/internal/handler/instrument.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ var (
instrumentDTOType = reflect.TypeFor[dto.InstrumentDTO]()
vInstrumentType = reflect.TypeFor[[]db.VInstrument]()
featureCollectionType = reflect.TypeFor[geojson.FeatureCollection]()
saaOptsDTOType = reflect.TypeFor[dto.SaaOptsDTO]()
ipiOptsDTOType = reflect.TypeFor[dto.IpiOptsDTO]()
inclOptsDTOType = reflect.TypeFor[dto.InclOptsDTO]()
depthOptsDTOType = reflect.TypeFor[dto.DepthOptsDTO]()
seisOptsDTOType = reflect.TypeFor[dto.SeisOptsDTO]()
instrumentCreateBatchRowType = reflect.TypeFor[db.InstrumentCreateBatchRow]()
instrumentsValidationType = reflect.TypeFor[service.InstrumentsValidation]()
Expand Down Expand Up @@ -401,10 +399,8 @@ func (h *ApiHandler) RegisterInstrument(api huma.API) {
})

instrumentOptsDTOSchema := &huma.Schema{
AnyOf: []*huma.Schema{
registry.Schema(saaOptsDTOType, true, ""),
registry.Schema(ipiOptsDTOType, true, ""),
registry.Schema(inclOptsDTOType, true, ""),
OneOf: []*huma.Schema{
registry.Schema(depthOptsDTOType, true, ""),
registry.Schema(seisOptsDTOType, true, ""),
},
Nullable: true,
Expand Down
13 changes: 8 additions & 5 deletions api/internal/middleware/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package middleware

import (
"context"
"crypto/subtle"
"errors"

"github.com/USACE/instrumentation-api/api/v4/internal/ctxkey"
Expand All @@ -13,10 +14,12 @@ import (
// AppKeyAuth does a key check for ?key=<ApplicationKey>
func (m *apiMw) AppKeyAuth(ctx huma.Context, next func(huma.Context)) {
provided := ctx.Query("key")
if provided == m.Config.ApplicationKey && provided != "" {
newCtx := context.WithValue(ctx.Context(), ctxkey.AppKeyAuthSuccess, true)
next(huma.WithContext(ctx, newCtx))
return
if provided != "" {
if res := subtle.ConstantTimeCompare([]byte(provided), []byte(m.Config.ApplicationKey)); res == 1 {
newCtx := context.WithValue(ctx.Context(), ctxkey.AppKeyAuthSuccess, true)
next(huma.WithContext(ctx, newCtx))
return
}
}

m.httperr.SetResponse(ctx, httperr.Unauthorized(errors.New("Unauthorized: invalid or missing key")))
Expand All @@ -32,7 +35,7 @@ func (m *apiMw) keyAuth(isDisabled bool, appKey string, h HashExtractorFunc) fun
return
}

if providedKey == appKey {
if res := subtle.ConstantTimeCompare([]byte(providedKey), []byte(appKey)); res == 1 {
newCtx := context.WithValue(ctx.Context(), ctxkey.AppKeyAuthSuccess, true)
next(huma.WithContext(ctx, newCtx))
return
Expand Down
3 changes: 1 addition & 2 deletions api/internal/service/instrument_incl.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,9 @@ func createInclOptsBatch(ctx context.Context, q *db.Queries, ii []dto.Instrument
func updateInclOptsBatch(ctx context.Context, q *db.Queries, ii []dto.InstrumentDTO) error {
updateInclOptsParams := make([]db.InclOptsUpdateBatchParams, len(ii))
for idx, inst := range ii {
opts := inst.Opts.InclOpts
updateInclOptsParams[idx] = db.InclOptsUpdateBatchParams{
InstrumentID: inst.ID,
InitialTime: opts.InitialTime,
InitialTime: inst.Opts.InclOpts.InitialTime,
}
}
var err error
Expand Down
17 changes: 10 additions & 7 deletions api/internal/service/instrument_ipi.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func createIpiOptsBatch(ctx context.Context, q *db.Queries, ii []dto.InstrumentD
createBottomElevationMmtParams := make([]db.TimeseriesMeasurementCreateBatchParams, len(ii))

for idx, inst := range ii {
opts := inst.Opts.InclOpts
opts := inst.Opts.IpiOpts
createTimeseriesBatchParams[idx] = make([]db.TimeseriesCreateBatchParams, opts.NumSegments)
createIpiSegmentBatchParams[idx] = make([]db.IpiSegmentCreateBatchParams, opts.NumSegments)

Expand Down Expand Up @@ -151,17 +151,20 @@ func updateIpiOptsBatch(ctx context.Context, q *db.Queries, ii []dto.InstrumentD
InstrumentID: inst.ID,
InitialTime: opts.InitialTime,
}
createMmtParams[idx] = db.TimeseriesMeasurementCreateBatchParams{
TimeseriesID: opts.BottomElevationTimeseriesID,
Time: time.Now(),
Value: opts.BottomElevation,
}
}
var err error
q.IpiOptsUpdateBatch(ctx, updateIpiOptsParams).Exec(batchExecErr(&err))
tsIDs := make([]uuid.UUID, len(ii))
q.IpiOptsUpdateBatch(ctx, updateIpiOptsParams).QueryRow(batchQueryRowCollect(tsIDs, &err))
if err != nil {
return err
}
for idx, inst := range ii {
createMmtParams[idx] = db.TimeseriesMeasurementCreateBatchParams{
TimeseriesID: tsIDs[idx],
Time: time.Now(),
Value: inst.Opts.IpiOpts.BottomElevation,
}
}
q.TimeseriesMeasurementCreateBatch(ctx, createMmtParams).Exec(batchExecErr(&err))
return err
}
18 changes: 10 additions & 8 deletions api/internal/service/instrument_saa.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,22 +136,24 @@ func updateSaaOptsBatch(ctx context.Context, q *db.Queries, ii []dto.InstrumentD
updateSaaOptsParams := make([]db.SaaOptsUpdateBatchParams, len(ii))
createMmtParams := make([]db.TimeseriesMeasurementCreateBatchParams, len(ii))
for idx, inst := range ii {
opts := inst.Opts.SaaOpts
updateSaaOptsParams[idx] = db.SaaOptsUpdateBatchParams{
InstrumentID: inst.ID,
InitialTime: opts.InitialTime,
}
createMmtParams[idx] = db.TimeseriesMeasurementCreateBatchParams{
TimeseriesID: opts.BottomElevationTimeseriesID,
Time: time.Now(),
Value: opts.BottomElevation,
InitialTime: inst.Opts.SaaOpts.InitialTime,
}
}
var err error
q.SaaOptsUpdateBatch(ctx, updateSaaOptsParams).Exec(batchExecErr(&err))
tsIDs := make([]uuid.UUID, len(ii))
q.SaaOptsUpdateBatch(ctx, updateSaaOptsParams).QueryRow(batchQueryRowCollect(tsIDs, &err))
if err != nil {
return err
}
for idx, inst := range ii {
createMmtParams[idx] = db.TimeseriesMeasurementCreateBatchParams{
TimeseriesID: tsIDs[idx],
Time: time.Now(),
Value: inst.Opts.SaaOpts.BottomElevation,
}
}
q.TimeseriesMeasurementCreateBatch(ctx, createMmtParams).Exec(batchExecErr(&err))
return err
}
2 changes: 1 addition & 1 deletion api/queries/instrument_ipi.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ insert into ipi_opts (instrument_id, num_segments, bottom_elevation_timeseries_i
values ($1, $2, $3, $4);


-- name: IpiOptsUpdateBatch :batchexec
-- name: IpiOptsUpdateBatch :batchone
update ipi_opts set
initial_time = $2
where instrument_id = $1
Expand Down
2 changes: 1 addition & 1 deletion api/queries/instrument_saa.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ insert into saa_opts (instrument_id, num_segments, bottom_elevation_timeseries_i
values ($1, $2, $3, $4);


-- name: SaaOptsUpdateBatch :batchexec
-- name: SaaOptsUpdateBatch :batchone
update saa_opts set
initial_time = $2
where instrument_id = $1
Expand Down
Loading