Skip to content

Commit

Permalink
feat(dp): Support fetching multiple grants for given cbsd (#13453)
Browse files Browse the repository at this point in the history
* feat(dp): Support fetching multiple grants for given cbsd

Signed-off-by: Kuba Marciniszyn <kuba@freedomfi.com>

* feat(nms): support multiple grants per CBSD

- Add new column "Grant Status" to CBSD table
- Update NMS CBSDs Table to handle multiple grants per CBSD
  (previously we had only one).
  This means each CBSD can have multiple values for each of
  the following fields:
  - bandwidth_mhz
  - frequency_mhz
  - grant_expire_time
  - max_eirp
  - status
  - transmit_expire_time

For each of the fields the table now displays multiple values in a
single cell, with <hr /> seprator.

Note: this is a quick solution to get it into v1.8 release.
It is planned to improve UX after the release.

Signed-off-by: Ivan Sergiienko <ivan@freedomfi.com>

Co-authored-by: Ivan Sergiienko <ivan@freedomfi.com>
  • Loading branch information
jkmar and ivan-freedomfi committed Aug 1, 2022
1 parent 07af4af commit cf2efed
Show file tree
Hide file tree
Showing 17 changed files with 598 additions and 386 deletions.
156 changes: 78 additions & 78 deletions dp/cloud/go/protos/cbsd.pb.go

Large diffs are not rendered by default.

92 changes: 36 additions & 56 deletions dp/cloud/go/services/dp/builders/builders.go
Expand Up @@ -214,8 +214,8 @@ func NewDBGrantBuilder() *DBGrantBuilder {
Grant: &storage.DBGrant{
GrantExpireTime: db.MakeTime(time.Unix(123, 0).UTC()),
TransmitExpireTime: db.MakeTime(time.Unix(456, 0).UTC()),
LowFrequency: db.MakeInt(3600 * 1e6),
HighFrequency: db.MakeInt(3620 * 1e6),
LowFrequency: db.MakeInt(3590 * 1e6),
HighFrequency: db.MakeInt(3610 * 1e6),
MaxEirp: db.MakeFloat(35),
GrantId: db.MakeString("some_grant_id"),
},
Expand All @@ -242,6 +242,12 @@ func (b *DBGrantBuilder) WithGrantId(id string) *DBGrantBuilder {
return b
}

func (b *DBGrantBuilder) WithFrequency(frequencyMHz int64) *DBGrantBuilder {
b.Grant.LowFrequency = db.MakeInt((frequencyMHz - 10) * 1e6)
b.Grant.HighFrequency = db.MakeInt((frequencyMHz + 10) * 1e6)
return b
}

type CbsdProtoPayloadBuilder struct {
Payload *protos.CbsdData
}
Expand Down Expand Up @@ -327,60 +333,34 @@ type DetailedDBCbsdBuilder struct {
Details *storage.DetailedCbsd
}

func NewDetailedDBCbsdBuilder(builder *DBCbsdBuilder) *DetailedDBCbsdBuilder {
return &DetailedDBCbsdBuilder{
Details: &storage.DetailedCbsd{
Cbsd: builder.Cbsd,
},
}
}

func (b *DetailedDBCbsdBuilder) WithGrant() *DetailedDBCbsdBuilder {
b.Details.Grant = &storage.DBGrant{
GrantExpireTime: db.MakeTime(time.Unix(123, 0).UTC()),
TransmitExpireTime: db.MakeTime(time.Unix(456, 0).UTC()),
LowFrequency: db.MakeInt(3600 * 1e6),
HighFrequency: db.MakeInt(3620 * 1e6),
MaxEirp: db.MakeFloat(35),
}
return b
}

func (b *DetailedDBCbsdBuilder) WithEmptyGrant() *DetailedDBCbsdBuilder {
b.Details.Grant = &storage.DBGrant{}
return b
}

func (b *DetailedDBCbsdBuilder) WithEmptyGrantState() *DetailedDBCbsdBuilder {
b.Details.GrantState = &storage.DBGrantState{}
return b
func NewDetailedDBCbsdBuilder() *DetailedDBCbsdBuilder {
return &DetailedDBCbsdBuilder{Details: &storage.DetailedCbsd{}}
}

func (b *DetailedDBCbsdBuilder) WithCbsdState(state string) *DetailedDBCbsdBuilder {
b.Details.CbsdState = &storage.DBCbsdState{
Name: db.MakeString(state),
}
func (b *DetailedDBCbsdBuilder) WithCbsd(cbsd *storage.DBCbsd, state string, desiredState string) *DetailedDBCbsdBuilder {
b.Details.Cbsd = cbsd
b.Details.CbsdState = &storage.DBCbsdState{Name: db.MakeString(state)}
b.Details.DesiredState = &storage.DBCbsdState{Name: db.MakeString(desiredState)}
return b
}

func (b *DetailedDBCbsdBuilder) WithGrantState(state string) *DetailedDBCbsdBuilder {
b.Details.GrantState = &storage.DBGrantState{
Name: db.MakeString(state),
}
return b
}

func (b *DetailedDBCbsdBuilder) WithDesiredState(state string) *DetailedDBCbsdBuilder {
b.Details.DesiredState = &storage.DBCbsdState{
Name: db.MakeString(state),
func (b *DetailedDBCbsdBuilder) WithGrant(state string, frequencyMHz int64) *DetailedDBCbsdBuilder {
grant := &storage.DetailedGrant{
Grant: &storage.DBGrant{
GrantExpireTime: db.MakeTime(time.Unix(123, 0).UTC()),
TransmitExpireTime: db.MakeTime(time.Unix(456, 0).UTC()),
LowFrequency: db.MakeInt((frequencyMHz - 10) * 1e6),
HighFrequency: db.MakeInt((frequencyMHz + 10) * 1e6),
MaxEirp: db.MakeFloat(35),
},
GrantState: &storage.DBGrantState{
Name: db.MakeString(state),
},
}
b.Details.Grants = append(b.Details.Grants, grant)
return b
}

func (b *DetailedDBCbsdBuilder) WithDefaultTestData() *DetailedDBCbsdBuilder {
return b.WithGrant().WithGrantState(authorized).WithCbsdState(registered).WithDesiredState(registered)
}

type DetailedProtoCbsdBuilder struct {
Details *protos.CbsdDetails
}
Expand All @@ -391,6 +371,7 @@ func NewDetailedProtoCbsdBuilder(builder *CbsdProtoPayloadBuilder) *DetailedProt
Data: builder.Payload,
State: registered,
IsActive: false,
Grants: []*protos.GrantDetails{},
},
}
}
Expand All @@ -416,14 +397,14 @@ func (b *DetailedProtoCbsdBuilder) Active() *DetailedProtoCbsdBuilder {
}

func (b *DetailedProtoCbsdBuilder) WithGrant() *DetailedProtoCbsdBuilder {
b.Details.Grant = &protos.GrantDetails{
b.Details.Grants = append(b.Details.Grants, &protos.GrantDetails{
BandwidthMhz: 20,
FrequencyMhz: 3610,
MaxEirp: 35,
State: authorized,
TransmitExpireTimestamp: 456,
GrantExpireTimestamp: 123,
}
})
return b
}

Expand All @@ -447,12 +428,11 @@ func GetMutableDBCbsd(cbsd *storage.DBCbsd, state string) *storage.MutableCbsd {
}
}

func GetDetailedDBCbsdList(builder *DetailedDBCbsdBuilder) *storage.DetailedCbsdList {
cbsdList := &storage.DetailedCbsdList{
Cbsds: []*storage.DetailedCbsd{builder.Details},
func GetDetailedDBCbsdList(cbsd *storage.DetailedCbsd) *storage.DetailedCbsdList {
return &storage.DetailedCbsdList{
Cbsds: []*storage.DetailedCbsd{cbsd},
Count: 1,
}
cbsdList.Count = int64(len(cbsdList.Cbsds))
return cbsdList
}

type CbsdModelPayloadBuilder struct {
Expand Down Expand Up @@ -495,14 +475,14 @@ func (b *CbsdModelPayloadBuilder) WithCbsdCategory(c string) *CbsdModelPayloadBu
}

func (b *CbsdModelPayloadBuilder) WithGrant() *CbsdModelPayloadBuilder {
b.Payload.Grant = &models.Grant{
b.Payload.Grants = append(b.Payload.Grants, &models.Grant{
BandwidthMhz: 20,
FrequencyMhz: 3610,
GrantExpireTime: to_pointer.TimeToDateTime(123),
MaxEirp: 35,
State: authorized,
TransmitExpireTime: to_pointer.TimeToDateTime(456),
}
})
return b
}

Expand Down
72 changes: 42 additions & 30 deletions dp/cloud/go/services/dp/obsidian/models/cbsd_swaggergen.go

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

25 changes: 13 additions & 12 deletions dp/cloud/go/services/dp/obsidian/models/conversion.go
Expand Up @@ -63,7 +63,7 @@ func CbsdFromBackend(details *protos.CbsdDetails) *Cbsd {
CbsdID: details.CbsdId,
DesiredState: details.Data.DesiredState,
FccID: details.Data.FccId,
Grant: getGrant(details.Grant),
Grants: getGrants(details.Grants),
ID: details.Id,
IsActive: details.IsActive,
SerialNumber: details.Data.SerialNumber,
Expand All @@ -82,18 +82,19 @@ func makeSliceNotNil(s []int64) []int64 {
return s
}

func getGrant(grant *protos.GrantDetails) *Grant {
if grant == nil {
return nil
}
return &Grant{
BandwidthMhz: grant.BandwidthMhz,
FrequencyMhz: grant.FrequencyMhz,
GrantExpireTime: to_pointer.TimeToDateTime(grant.GrantExpireTimestamp),
MaxEirp: grant.MaxEirp,
State: grant.State,
TransmitExpireTime: to_pointer.TimeToDateTime(grant.TransmitExpireTimestamp),
func getGrants(grants []*protos.GrantDetails) []*Grant {
res := make([]*Grant, len(grants))
for i, g := range grants {
res[i] = &Grant{
BandwidthMhz: g.BandwidthMhz,
FrequencyMhz: g.FrequencyMhz,
GrantExpireTime: to_pointer.TimeToDateTime(g.GrantExpireTimestamp),
MaxEirp: g.MaxEirp,
State: g.State,
TransmitExpireTime: to_pointer.TimeToDateTime(g.TransmitExpireTimestamp),
}
}
return res
}

func getModelInstallationParam(params *protos.InstallationParam) InstallationParam {
Expand Down
30 changes: 16 additions & 14 deletions dp/cloud/go/services/dp/obsidian/models/conversion_test.go
Expand Up @@ -42,11 +42,11 @@ func TestCbsdToBackend(t *testing.T) {
assert.Equal(t, data.GrantRedundancy, *cbsd.GrantRedundancy)
}

func TestCbsdFromBackendWithoutGrant(t *testing.T) {
func TestCbsdFromBackendWithoutGrants(t *testing.T) {
details := b.NewDetailedProtoCbsdBuilder(
b.NewCbsdProtoPayloadBuilder()).Details
data := models.CbsdFromBackend(details)
assert.Nil(t, data.Grant)
assert.Empty(t, data.Grants)
assert.Equal(t, data.ID, details.Id)
assert.Equal(t, data.IsActive, details.IsActive)
assert.Equal(t, data.CbsdID, details.CbsdId)
Expand All @@ -66,6 +66,20 @@ func TestCbsdFromBackendWithoutGrant(t *testing.T) {
assert.Equal(t, data.GrantRedundancy, details.Data.GrantRedundancy)
}

func TestCbsdFromBackendWithGrants(t *testing.T) {
details := b.NewDetailedProtoCbsdBuilder(
b.NewCbsdProtoPayloadBuilder()).WithGrant().Details
data := models.CbsdFromBackend(details)
assert.Len(t, data.Grants, len(details.Grants))
expected, actual := data.Grants[0], details.Grants[0]
assert.Equal(t, expected.BandwidthMhz, actual.BandwidthMhz)
assert.Equal(t, expected.FrequencyMhz, actual.FrequencyMhz)
assert.Equal(t, expected.GrantExpireTime, to_pointer.TimeToDateTime(actual.GrantExpireTimestamp))
assert.Equal(t, expected.TransmitExpireTime, to_pointer.TimeToDateTime(actual.TransmitExpireTimestamp))
assert.Equal(t, expected.MaxEirp, actual.MaxEirp)
assert.Equal(t, expected.State, actual.State)
}

func TestCbsdFromBackendWithEmptyInstallationParam(t *testing.T) {
details := b.NewDetailedProtoCbsdBuilder(
b.NewCbsdProtoPayloadBuilder().WithEmptyInstallationParam()).Details
Expand All @@ -78,18 +92,6 @@ func TestCbsdFromBackendWithEmptyInstallationParam(t *testing.T) {
assert.Nil(t, data.InstallationParam.AntennaGain)
}

func TestCbsdFromBackendWithGrant(t *testing.T) {
details := b.NewDetailedProtoCbsdBuilder(
b.NewCbsdProtoPayloadBuilder()).WithGrant().Details
data := models.CbsdFromBackend(details)
assert.Equal(t, data.Grant.BandwidthMhz, details.Grant.BandwidthMhz)
assert.Equal(t, data.Grant.FrequencyMhz, details.Grant.FrequencyMhz)
assert.Equal(t, data.Grant.GrantExpireTime, to_pointer.TimeToDateTime(details.Grant.GrantExpireTimestamp))
assert.Equal(t, data.Grant.TransmitExpireTime, to_pointer.TimeToDateTime(details.Grant.TransmitExpireTimestamp))
assert.Equal(t, data.Grant.MaxEirp, details.Grant.MaxEirp)
assert.Equal(t, data.Grant.State, details.Grant.State)
}

func TestCbsdFromBackendWithoutInstallationParam(t *testing.T) {
details := b.NewDetailedProtoCbsdBuilder(
b.NewCbsdProtoPayloadBuilder()).Details
Expand Down

0 comments on commit cf2efed

Please sign in to comment.