Skip to content

Commit

Permalink
dr: Update api definition and translations
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad Vitan committed Sep 11, 2024
1 parent 9744acb commit f7f8cc6
Show file tree
Hide file tree
Showing 7 changed files with 649 additions and 669 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ For details about compatibility between different releases, see the **Commitment
- `ListFrequencyPlans` RPC has a new `gateways-only` flag.
- Option to pause application webhooks.
- Endpoint for claiming gateways using a qr code
- Update the GetTemplate endpoint in device repository to check for profile identifiers in the vendor index.

### Changed

Expand Down
29 changes: 10 additions & 19 deletions config/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -4121,7 +4121,7 @@
"file": "store.go"
}
},
"error:pkg/devicerepository/store/bleve:missing_profile_identifier": {
"error:pkg/devicerepository/store/bleve:missing_profile_identifiers": {
"translations": {
"en": "both vendor ID and vendor profile ID must be provided"
},
Expand All @@ -4130,24 +4130,6 @@
"file": "store.go"
}
},
"error:pkg/devicerepository/store/bleve:multiple_identifiers": {
"translations": {
"en": "multiple identifiers found in the request. Use either EndDeviceVersionIdentifiers or EndDeviceProfileIdentifiers"
},
"description": {
"package": "pkg/devicerepository/store/bleve",
"file": "store.go"
}
},
"error:pkg/devicerepository/store/bleve:no_identifiers": {
"translations": {
"en": "no identifiers provided"
},
"description": {
"package": "pkg/devicerepository/store/bleve",
"file": "store.go"
}
},
"error:pkg/devicerepository/store/remote:band_not_found": {
"translations": {
"en": "band `{band_id}` not found"
Expand Down Expand Up @@ -4193,6 +4175,15 @@
"file": "remote.go"
}
},
"error:pkg/devicerepository/store/remote:missing_profile_identifiers": {
"translations": {
"en": "both vendor ID and vendor profile ID must be provided"
},
"description": {
"package": "pkg/devicerepository/store/remote",
"file": "remote.go"
}
},
"error:pkg/devicerepository/store/remote:model_not_found": {
"translations": {
"en": "model `{brand_id}/{model_id}` not found"
Expand Down
4 changes: 2 additions & 2 deletions pkg/devicerepository/store/bleve/bleve.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ import (
)

const (
// Timeout for opening the index. This is to avoid blocking on the index
// DefaultTimeout for opening the index. This is to avoid blocking on the index
// open call, which hangs indefinitely if the index is already in use by
// a different process.
defaultTimeout = 5 * time.Second

// Size of the cache for brands and models.
// CacheSize for brands and models.
cacheSize = 1024
)

Expand Down
2 changes: 1 addition & 1 deletion pkg/devicerepository/store/bleve/bleve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ func TestBleve(t *testing.T) {
Name: "ZeroProfileID",
Req: &ttnpb.GetTemplateRequest{
EndDeviceProfileIds: &ttnpb.GetTemplateRequest_EndDeviceProfileIdentifiers{
VendorId: 42, // why is it allowed to have a vendor ID but no profile ID?
VendorId: 42,
},
},
Assertion: func(t *ttnpb.EndDeviceTemplate, err error) bool {
Expand Down
101 changes: 41 additions & 60 deletions pkg/devicerepository/store/bleve/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ var (
"invalid_number_of_profiles",
"invalid number of profiles returned",
)
errMultipleIdentifiers = errors.DefineCorruption(
"multiple_identifiers",
"multiple identifiers found in the request. Use either EndDeviceVersionIdentifiers or EndDeviceProfileIdentifiers",
)
errEndDeviceProfileNotFound = errors.DefineNotFound(
"end_device_profile_not_found",
"end device profile not found for vendor ID `{vendor_id}` and vendor profile ID `{vendor_profile_id}`",
)
errMissingProfileIdentifiers = errors.DefineInvalidArgument(
"missing_profile_identifiers",
"both vendor ID and vendor profile ID must be provided",
)
)

// retrieve returns the resulting document from the cache, if available. Otherwise,
Expand Down Expand Up @@ -195,75 +195,56 @@ func (s *bleveStore) GetModels(req store.GetModelsRequest) (*store.GetModelsResp
}, nil
}

var (
errNoIdentifiers = errors.DefineInvalidArgument(
"no_identifiers",
"no identifiers provided",
)
errMissingProfileIdentifier = errors.DefineInvalidArgument(
"missing_profile_identifier",
"both vendor ID and vendor profile ID must be provided",
)
)

// GetTemplate retrieves an end device template for an end device definition.
func (s *bleveStore) GetTemplate(req *ttnpb.GetTemplateRequest) (*ttnpb.EndDeviceTemplate, error) {
profileIDs, versionIDs := req.GetEndDeviceProfileIds(), req.GetVersionIds()
if profileIDs == nil && versionIDs == nil {
return nil, errNoIdentifiers.New()
profileIDs := req.GetEndDeviceProfileIds()
if profileIDs == nil {
return s.store.GetTemplate(req)
}
if profileIDs != nil && versionIDs != nil {
return nil, errMultipleIdentifiers.New()
if profileIDs.VendorId == 0 || profileIDs.VendorProfileId == 0 {
return nil, errMissingProfileIdentifiers.New()
}
documentTypeQuery := bleve.NewTermQuery(templateDocumentType)
documentTypeQuery.SetField("Type")
queries := []query.Query{documentTypeQuery}

if profileIDs != nil {
if profileIDs.VendorId == 0 || profileIDs.VendorProfileId == 0 {
return nil, errMissingProfileIdentifier.New()
}
documentTypeQuery := bleve.NewTermQuery(templateDocumentType)
documentTypeQuery.SetField("Type")
queries := []query.Query{documentTypeQuery}

queryTerm := bleve.NewTermQuery(strconv.Itoa(int(profileIDs.VendorId)))
queryTerm.SetField("VendorID")
queries = append(queries, queryTerm)
queryTerm := bleve.NewTermQuery(strconv.Itoa(int(profileIDs.VendorId)))
queryTerm.SetField("VendorID")
queries = append(queries, queryTerm)

queryTerm = bleve.NewTermQuery(strconv.Itoa(int(profileIDs.VendorProfileId)))
queryTerm.SetField("VendorProfileID")
queries = append(queries, queryTerm)

searchRequest := bleve.NewSearchRequest(bleve.NewConjunctionQuery(queries...))
searchRequest.Fields = []string{"TemplateJSON"}
result, err := s.index.Search(searchRequest)
if err != nil {
return nil, err
}
queryTerm = bleve.NewTermQuery(strconv.Itoa(int(profileIDs.VendorProfileId)))
queryTerm.SetField("VendorProfileID")
queries = append(queries, queryTerm)

if len(result.Hits) == 0 {
return nil, errEndDeviceProfileNotFound.WithAttributes(
"vendor_id", profileIDs.VendorId,
"vendor_profile_id", profileIDs.VendorProfileId)
}
searchRequest := bleve.NewSearchRequest(bleve.NewConjunctionQuery(queries...))
searchRequest.Fields = []string{"TemplateJSON"}
result, err := s.index.Search(searchRequest)
if err != nil {
return nil, err
}

if len(result.Hits) != 1 {
// There can only be one profile for a given tuple.
return nil, errInvalidNumberOfProfiles.New()
}
if len(result.Hits) == 0 {
return nil, errEndDeviceProfileNotFound.WithAttributes(
"vendor_id", profileIDs.VendorId,
"vendor_profile_id", profileIDs.VendorProfileId)
}

hit, err := s.retrieve(result.Hits[0], "TemplateJSON", func() any { return &ttnpb.EndDeviceTemplate{} })
if err != nil {
return nil, err
}
if len(result.Hits) != 1 {
// There can only be one profile for a given tuple.
return nil, errInvalidNumberOfProfiles.New()
}

template, ok := hit.(*ttnpb.EndDeviceTemplate)
if !ok {
return nil, errCorruptedIndex.New()
}
hit, err := s.retrieve(result.Hits[0], "TemplateJSON", func() any { return &ttnpb.EndDeviceTemplate{} })
if err != nil {
return nil, err
}

return template, nil
template, ok := hit.(*ttnpb.EndDeviceTemplate)
if !ok {
return nil, errCorruptedIndex.New()
}

return s.store.GetTemplate(req)
return template, nil
}

// GetUplinkDecoder retrieves the codec for decoding uplink messages.
Expand Down
12 changes: 9 additions & 3 deletions pkg/devicerepository/store/remote/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,12 @@ var (
)
errBandNotFoundForRegion = errors.DefineNotFound(
"band_not_found_for_region",
"band not found for region `{region}`")
"band not found for region `{region}`",
)
errMissingProfileIdentifiers = errors.DefineInvalidArgument(
"missing_profile_identifiers",
"both vendor ID and vendor profile ID must be provided",
)
)

// GetTemplate retrieves an end device template for an end device definition.
Expand Down Expand Up @@ -414,15 +419,16 @@ func (s *remoteStore) getVersionIDsUsingProfileIDs(
ids *ttnpb.GetTemplateRequest_EndDeviceProfileIdentifiers,
) (*ttnpb.EndDeviceVersionIdentifiers, error) {
if ids.VendorProfileId == 0 || ids.VendorId == 0 {
return nil, errors.New("vendor_profile_id and vendor_id must be set")
return nil, errMissingProfileIdentifiers.New()
}

brandID, err := s.getBrandIDByVendorID(ids.VendorId)
if err != nil {
return nil, errBrandWithVendorIDNotFound.WithAttributes("vendor_id", ids.VendorId)
}
endDeviceProfilesIdentifiers, err := s.GetEndDeviceProfileIdentifiers(
store.GetEndDeviceProfileIdentifiersRequest{BrandID: brandID})
store.GetEndDeviceProfileIdentifiersRequest{BrandID: brandID},
)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit f7f8cc6

Please sign in to comment.