Skip to content

Commit

Permalink
Add generic object retrieval
Browse files Browse the repository at this point in the history
Now that the minimum Go version has been raised to 1.1 we can use
generics. This allows us to simplify a lot of the GetXXX calls to use
common code and avoid a lot of duplication.

Signed-off-by: Sean McGinnis <[email protected]>
  • Loading branch information
stmcginnis committed Jul 5, 2024
1 parent aef51a9 commit bc70b42
Show file tree
Hide file tree
Showing 183 changed files with 401 additions and 1,733 deletions.
19 changes: 10 additions & 9 deletions common/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,29 +139,32 @@ func CollectCollection(get func(string), links []string) {
wg.Wait()
}

func GetCollectionObjects[E any](c Client, link string, getFn func(Client, string) (*E, error)) ([]*E, error) {
var result []*E
if link == "" {
func GetCollectionObjects[T any, PT interface {
*T
SchemaObject
}](c Client, uri string) ([]*T, error) {
var result []*T
if uri == "" {
return result, nil
}

type GetResult struct {
Item *E
Item *T
Link string
Error error
}

ch := make(chan GetResult)
collectionError := NewCollectionError()
get := func(link string) {
entity, err := getFn(c, link)
entity, err := GetObject[T, PT](c, link)
ch <- GetResult{Item: entity, Link: link, Error: err}
}

go func() {
err := CollectList(get, c, link)
err := CollectList(get, c, uri)
if err != nil {
collectionError.Failures[link] = err
collectionError.Failures[uri] = err
}
close(ch)
}()
Expand All @@ -174,8 +177,6 @@ func GetCollectionObjects[E any](c Client, link string, getFn func(Client, strin
}
}

fmt.Printf("Got here, %d objects in collection\n", len(result))

if collectionError.Empty() {
return result, nil
}
Expand Down
34 changes: 34 additions & 0 deletions common/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func (e *Entity) SetClient(c Client) {
e.client = c
}

// SetETag sets the etag value of this API object.
func (e *Entity) SetETag(tag string) {
e.etag = tag
}

// GetClient get the API client connection to use for accessing this
// entity.
func (e *Entity) GetClient() Client {
Expand Down Expand Up @@ -242,3 +247,32 @@ func getPatchPayloadFromUpdate(originalEntity, updatedEntity reflect.Value) (pay
}
return payload
}

type SchemaObject interface {
SetClient(Client)
SetETag(string)
}

// GetObject retrieves an API object from the service.
func GetObject[T any, PT interface {
*T
SchemaObject
}](c Client, uri string) (*T, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

entity := PT(new(T))
err = json.NewDecoder(resp.Body).Decode(&entity)
if err != nil {
return nil, err
}

if resp.Header["Etag"] != nil {
entity.SetETag(resp.Header["Etag"][0])
}
entity.SetClient(c)
return entity, nil
}
17 changes: 2 additions & 15 deletions redfish/accelerationfunction.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,13 @@ func (accelerationfunction *AccelerationFunction) UnmarshalJSON(b []byte) error

// GetAccelerationFunction will get a AccelerationFunction instance from the service.
func GetAccelerationFunction(c common.Client, uri string) (*AccelerationFunction, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var accelerationfunction AccelerationFunction
err = json.NewDecoder(resp.Body).Decode(&accelerationfunction)
if err != nil {
return nil, err
}

accelerationfunction.SetClient(c)
return &accelerationfunction, nil
return common.GetObject[AccelerationFunction](c, uri)
}

// ListReferencedAccelerationFunctions gets the collection of AccelerationFunction from
// a provided reference.
func ListReferencedAccelerationFunctions(c common.Client, link string) ([]*AccelerationFunction, error) {
return common.GetCollectionObjects(c, link, GetAccelerationFunction)
return common.GetCollectionObjects[AccelerationFunction](c, link)
}

// Endpoints gets the endpoints connected to this accelerator.
Expand Down
3 changes: 1 addition & 2 deletions redfish/accountservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,7 @@ func (accountservice *AccountService) Update() error {
// GetAccountService will get the AccountService instance from the Redfish
// service.
func GetAccountService(c common.Client, uri string) (*AccountService, error) {
var accountService AccountService
return &accountService, accountService.Get(c, uri, &accountService)
return common.GetObject[AccountService](c, uri)
}

// Accounts get the accounts from the account service
Expand Down
17 changes: 2 additions & 15 deletions redfish/addresspool.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,13 @@ func (addresspool *AddressPool) UnmarshalJSON(b []byte) error {

// GetAddressPool will get a AddressPool instance from the service.
func GetAddressPool(c common.Client, uri string) (*AddressPool, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var addresspool AddressPool
err = json.NewDecoder(resp.Body).Decode(&addresspool)
if err != nil {
return nil, err
}

addresspool.SetClient(c)
return &addresspool, nil
return common.GetObject[AddressPool](c, uri)
}

// ListReferencedAddressPools gets the collection of AddressPool from
// a provided reference.
func ListReferencedAddressPools(c common.Client, link string) ([]*AddressPool, error) {
return common.GetCollectionObjects(c, link, GetAddressPool)
return common.GetCollectionObjects[AddressPool](c, link)
}

// Endpoints gets the endpoints connected to this address pool.
Expand Down
17 changes: 2 additions & 15 deletions redfish/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,24 +134,11 @@ func (aggregate *Aggregate) SetDefaultBootOrder() error {

// GetAggregate will get a Aggregate instance from the service.
func GetAggregate(c common.Client, uri string) (*Aggregate, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var aggregate Aggregate
err = json.NewDecoder(resp.Body).Decode(&aggregate)
if err != nil {
return nil, err
}

aggregate.SetClient(c)
return &aggregate, nil
return common.GetObject[Aggregate](c, uri)
}

// ListReferencedAggregates gets the collection of Aggregate from
// a provided reference.
func ListReferencedAggregates(c common.Client, link string) ([]*Aggregate, error) {
return common.GetCollectionObjects(c, link, GetAggregate)
return common.GetCollectionObjects[Aggregate](c, link)
}
17 changes: 2 additions & 15 deletions redfish/aggregationservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,24 +144,11 @@ func (aggregationservice *AggregationService) Update() error {

// GetAggregationService will get a AggregationService instance from the service.
func GetAggregationService(c common.Client, uri string) (*AggregationService, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var aggregationservice AggregationService
err = json.NewDecoder(resp.Body).Decode(&aggregationservice)
if err != nil {
return nil, err
}

aggregationservice.SetClient(c)
return &aggregationservice, nil
return common.GetObject[AggregationService](c, uri)
}

// ListReferencedAggregationServices gets the collection of AggregationService from
// a provided reference.
func ListReferencedAggregationServices(c common.Client, link string) ([]*AggregationService, error) {
return common.GetCollectionObjects(c, link, GetAggregationService)
return common.GetCollectionObjects[AggregationService](c, link)
}
17 changes: 2 additions & 15 deletions redfish/aggregationsource.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,26 +190,13 @@ func (aggregationsource *AggregationSource) Update() error {

// GetAggregationSource will get a AggregationSource instance from the service.
func GetAggregationSource(c common.Client, uri string) (*AggregationSource, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var aggregationsource AggregationSource
err = json.NewDecoder(resp.Body).Decode(&aggregationsource)
if err != nil {
return nil, err
}

aggregationsource.SetClient(c)
return &aggregationsource, nil
return common.GetObject[AggregationSource](c, uri)
}

// ListReferencedAggregationSources gets the collection of AggregationSource from
// a provided reference.
func ListReferencedAggregationSources(c common.Client, link string) ([]*AggregationSource, error) {
return common.GetCollectionObjects(c, link, GetAggregationSource)
return common.GetCollectionObjects[AggregationSource](c, link)
}

// SNMPSettings shall contain the settings for an SNMP aggregation source.
Expand Down
17 changes: 2 additions & 15 deletions redfish/allowdeny.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,24 +127,11 @@ func (allowdeny *AllowDeny) Update() error {

// GetAllowDeny will get a AllowDeny instance from the service.
func GetAllowDeny(c common.Client, uri string) (*AllowDeny, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var allowdeny AllowDeny
err = json.NewDecoder(resp.Body).Decode(&allowdeny)
if err != nil {
return nil, err
}

allowdeny.SetClient(c)
return &allowdeny, nil
return common.GetObject[AllowDeny](c, uri)
}

// ListReferencedAllowDenys gets the collection of AllowDeny from
// a provided reference.
func ListReferencedAllowDenys(c common.Client, link string) ([]*AllowDeny, error) {
return common.GetCollectionObjects(c, link, GetAllowDeny)
return common.GetCollectionObjects[AllowDeny](c, link)
}
17 changes: 2 additions & 15 deletions redfish/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,26 +75,13 @@ func (application *Application) UnmarshalJSON(b []byte) error {

// GetApplication will get a Application instance from the service.
func GetApplication(c common.Client, uri string) (*Application, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var application Application
err = json.NewDecoder(resp.Body).Decode(&application)
if err != nil {
return nil, err
}

application.SetClient(c)
return &application, nil
return common.GetObject[Application](c, uri)
}

// ListReferencedApplications gets the collection of Application from
// a provided reference.
func ListReferencedApplications(c common.Client, link string) ([]*Application, error) {
return common.GetCollectionObjects(c, link, GetApplication)
return common.GetCollectionObjects[Application](c, link)
}

// SoftwareImage returns a `SoftwareInventory“ that represents the software image from which this application runs.
Expand Down
5 changes: 2 additions & 3 deletions redfish/assembly.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,13 @@ func (assembly *Assembly) Update() error {

// GetAssembly will get a Assembly instance from the service.
func GetAssembly(c common.Client, uri string) (*Assembly, error) {
var assembly Assembly
return &assembly, assembly.Get(c, uri, &assembly)
return common.GetObject[Assembly](c, uri)
}

// ListReferencedAssemblys gets the collection of Assembly from
// a provided reference.
func ListReferencedAssemblys(c common.Client, link string) ([]*Assembly, error) {
return common.GetCollectionObjects(c, link, GetAssembly)
return common.GetCollectionObjects[Assembly](c, link)
}

// AssemblyData is information about an assembly.
Expand Down
3 changes: 1 addition & 2 deletions redfish/attributeregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,5 @@ type AttributeRegistry struct {
// GetAttributeRegistry will get an AttributeRegistry instance from the Redfish service,
// e.g. BiosAttributeRegistry
func GetAttributeRegistry(c common.Client, uri string) (*AttributeRegistry, error) {
var attributeRegistry AttributeRegistry
return &attributeRegistry, attributeRegistry.Get(c, uri, &attributeRegistry)
return common.GetObject[AttributeRegistry](c, uri)
}
17 changes: 2 additions & 15 deletions redfish/battery.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,26 +188,13 @@ func (battery *Battery) Update() error {

// GetBattery will get a Battery instance from the service.
func GetBattery(c common.Client, uri string) (*Battery, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var battery Battery
err = json.NewDecoder(resp.Body).Decode(&battery)
if err != nil {
return nil, err
}

battery.SetClient(c)
return &battery, nil
return common.GetObject[Battery](c, uri)
}

// ListReferencedBatterys gets the collection of Battery from
// a provided reference.
func ListReferencedBatterys(c common.Client, link string) ([]*Battery, error) {
return common.GetCollectionObjects(c, link, GetBattery)
return common.GetCollectionObjects[Battery](c, link)
}

// Assembly get the containing assembly of this battery.
Expand Down
19 changes: 2 additions & 17 deletions redfish/batterymetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
package redfish

import (
"encoding/json"

"github.com/stmcginnis/gofish/common"
)

Expand Down Expand Up @@ -72,24 +70,11 @@ type BatteryMetrics struct {

// GetBatteryMetrics will get a BatteryMetrics instance from the service.
func GetBatteryMetrics(c common.Client, uri string) (*BatteryMetrics, error) {
resp, err := c.Get(uri)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var batterymetrics BatteryMetrics
err = json.NewDecoder(resp.Body).Decode(&batterymetrics)
if err != nil {
return nil, err
}

batterymetrics.SetClient(c)
return &batterymetrics, nil
return common.GetObject[BatteryMetrics](c, uri)
}

// ListReferencedBatteryMetricss gets the collection of BatteryMetrics from
// a provided reference.
func ListReferencedBatteryMetricss(c common.Client, link string) ([]*BatteryMetrics, error) {
return common.GetCollectionObjects(c, link, GetBatteryMetrics)
return common.GetCollectionObjects[BatteryMetrics](c, link)
}
Loading

0 comments on commit bc70b42

Please sign in to comment.