From 3cf2059fd2d4a81e390ebd60d40b4b4090352868 Mon Sep 17 00:00:00 2001 From: rmanach Date: Wed, 28 Aug 2024 10:31:15 +0200 Subject: [PATCH 1/3] datasource to get one transport product --- .../transport_product_data_source.go | 142 ++++------ .../transport_products_data_source.go | 261 ++++++++++++++++++ internal/provider/provider.go | 1 + 3 files changed, 319 insertions(+), 85 deletions(-) create mode 100644 internal/data_sources/transport_products_data_source.go diff --git a/internal/data_sources/transport_product_data_source.go b/internal/data_sources/transport_product_data_source.go index 99d2230..008d766 100644 --- a/internal/data_sources/transport_product_data_source.go +++ b/internal/data_sources/transport_product_data_source.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "sort" "github.com/intercloud/terraform-provider-autonomi/external/products/models" @@ -19,34 +20,10 @@ type transportProductDataSource struct { client *meilisearch.Client } -type transportHits struct { - ID types.Int64 `tfsdk:"id"` - Provider types.String `tfsdk:"provider"` - Duration types.Int64 `tfsdk:"duration"` - Location types.String `tfsdk:"location"` - LocationUnderlay types.String `tfsdk:"location_underlay"` - Bandwidth types.Int64 `tfsdk:"bandwidth"` - Date types.String `tfsdk:"date"` - PriceNRC types.Float64 `tfsdk:"price_nrc"` - PriceMRC types.Float64 `tfsdk:"price_mrc"` - CostNRC types.Float64 `tfsdk:"cost_nrc"` - CostMRC types.Float64 `tfsdk:"cost_mrc"` - SKU types.String `tfsdk:"sku"` - LocationTo types.String `tfsdk:"location_to"` - LocationToUnderlay types.String `tfsdk:"location_to_underlay"` -} - -type transportFacetDistributionDataSourceModel struct { - Bandwidth map[string]int `tfsdk:"bandwidth"` - Location map[string]int `tfsdk:"location"` - LocationTo map[string]int `tfsdk:"location_to"` - Provider map[string]int `tfsdk:"provider"` -} - -type transportsProductDataSourceModel struct { +type transportProductDataSourceModel struct { + Cheapest *bool `tfsdk:"cheapest"` Filters []filter `tfsdk:"filters"` - Sort []sortFacet `tfsdk:"sort"` - Hits []transportHits `tfsdk:"hits"` + Hit *transportHits `tfsdk:"hit"` FacetDistribution *transportFacetDistributionDataSourceModel `tfsdk:"facet_distribution"` } @@ -62,13 +39,17 @@ func NewTransportProductDataSource() datasource.DataSource { // Metadata returns the data source type name. func (d *transportProductDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_transport_products" + resp.TypeName = req.ProviderTypeName + "_transport_product" } // Schema defines the schema for the data source. func (d *transportProductDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ + "cheapest": schema.BoolAttribute{ + MarkdownDescription: "To ensure only one hit is returned we advise to set at true", + Optional: true, + }, "filters": schema.ListNestedAttribute{ MarkdownDescription: "List of filters: [location, locationTo, bandwidth, provider]", Optional: true, @@ -87,42 +68,25 @@ func (d *transportProductDataSource) Schema(_ context.Context, _ datasource.Sche }, }, }, - "sort": schema.ListNestedAttribute{ - MarkdownDescription: `List of sort: [location, locationTo, bandwidth, provider, -priceNrc, priceMrc, costNrc, costMrc]`, - Optional: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "name": schema.StringAttribute{ - Optional: true, - }, - "value": schema.StringAttribute{ - Optional: true, - }, - }, - }, - }, - "hits": schema.ListNestedAttribute{ + "hit": schema.SingleNestedAttribute{ MarkdownDescription: `The **hits** attribute contains the list of transport products returned by the Meilisearch query. Each hit represents a transport product that matches the specified search criteria.`, Computed: true, - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "id": schema.Int64Attribute{Computed: true}, - "provider": schema.StringAttribute{Computed: true}, - "duration": schema.Int64Attribute{Computed: true}, - "location": schema.StringAttribute{Computed: true}, - "location_underlay": schema.StringAttribute{Computed: true}, - "location_to": schema.StringAttribute{Computed: true}, - "location_to_underlay": schema.StringAttribute{Computed: true}, - "bandwidth": schema.Int64Attribute{Computed: true}, - "date": schema.StringAttribute{Computed: true}, - "price_nrc": schema.Int64Attribute{Computed: true}, - "price_mrc": schema.Int64Attribute{Computed: true}, - "cost_nrc": schema.Int64Attribute{Computed: true}, - "cost_mrc": schema.Int64Attribute{Computed: true}, - "sku": schema.StringAttribute{Computed: true}, - }, + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{Computed: true}, + "provider": schema.StringAttribute{Computed: true}, + "duration": schema.Int64Attribute{Computed: true}, + "location": schema.StringAttribute{Computed: true}, + "location_underlay": schema.StringAttribute{Computed: true}, + "location_to": schema.StringAttribute{Computed: true}, + "location_to_underlay": schema.StringAttribute{Computed: true}, + "bandwidth": schema.Int64Attribute{Computed: true}, + "date": schema.StringAttribute{Computed: true}, + "price_nrc": schema.Int64Attribute{Computed: true}, + "price_mrc": schema.Int64Attribute{Computed: true}, + "cost_nrc": schema.Int64Attribute{Computed: true}, + "cost_mrc": schema.Int64Attribute{Computed: true}, + "sku": schema.StringAttribute{Computed: true}, }, }, "facet_distribution": schema.SingleNestedAttribute{ @@ -165,7 +129,7 @@ func (d *transportProductDataSource) Configure(_ context.Context, req datasource // Read refreshes the Terraform state with the latest data. func (d *transportProductDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data transportsProductDataSourceModel + var data transportProductDataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) @@ -177,12 +141,10 @@ func (d *transportProductDataSource) Read(ctx context.Context, req datasource.Re if err != nil { resp.Diagnostics.AddError("error getting filters", err.Error()) } - sortStrings := getSortString(data.Sort) // Define the search request searchRequest := &meilisearch.SearchRequest{ Filter: filtersStrings, - Sort: sortStrings, Facets: []string{ "location", "locationTo", @@ -219,29 +181,39 @@ func (d *transportProductDataSource) Read(ctx context.Context, req datasource.Re return } - state := transportsProductDataSourceModel{ - Filters: data.Filters, - Sort: data.Sort, + // If Meiliesearch return more than one hit, check if `cheapest` filter has been set. + // If not, an error is returned, otherwise a sort will be done to order the list by price mrc. The first entry will be returned + if len(transportProducts.Hits) > 1 { + if data.Cheapest == nil || !*data.Cheapest { + resp.Diagnostics.AddError("Request got more than one hit, please set cheapest=true", "") + return + } + // sort slice by price mrc if cheapest=true is set + sort.Slice(transportProducts.Hits, func(i, j int) bool { + return transportProducts.Hits[i].PriceMRC < transportProducts.Hits[j].PriceMRC + }) + } + + state := transportProductDataSourceModel{ + Cheapest: data.Cheapest, + Filters: data.Filters, } - // Map response body to model - for _, cp := range transportProducts.Hits { - transportProductState := transportHits{ - ID: types.Int64Value(int64(cp.ID)), - Provider: types.StringValue(cp.Provider), - Location: types.StringValue(cp.Location), - LocationUnderlay: types.StringValue(cp.LocationUnderlay), - Bandwidth: types.Int64Value(int64(cp.Bandwidth)), - Date: types.StringValue(cp.Date), - PriceNRC: types.Float64Value(float64(cp.PriceNRC)), - PriceMRC: types.Float64Value(float64(cp.PriceMRC)), - CostNRC: types.Float64Value(float64(cp.CostNRC)), - CostMRC: types.Float64Value(float64(cp.CostMRC)), - SKU: types.StringValue(cp.SKU), - LocationTo: types.StringValue(cp.LocationTo), - LocationToUnderlay: types.StringValue(cp.LocationToUnderlay), - } - state.Hits = append(state.Hits, transportProductState) + tp := transportProducts.Hits[0] + state.Hit = &transportHits{ + ID: types.Int64Value(int64(tp.ID)), + Provider: types.StringValue(tp.Provider), + Location: types.StringValue(tp.Location), + LocationUnderlay: types.StringValue(tp.LocationUnderlay), + Bandwidth: types.Int64Value(int64(tp.Bandwidth)), + Date: types.StringValue(tp.Date), + PriceNRC: types.Float64Value(float64(tp.PriceNRC)), + PriceMRC: types.Float64Value(float64(tp.PriceMRC)), + CostNRC: types.Float64Value(float64(tp.CostNRC)), + CostMRC: types.Float64Value(float64(tp.CostMRC)), + SKU: types.StringValue(tp.SKU), + LocationTo: types.StringValue(tp.LocationTo), + LocationToUnderlay: types.StringValue(tp.LocationToUnderlay), } // Set the bandwidth map in the state diff --git a/internal/data_sources/transport_products_data_source.go b/internal/data_sources/transport_products_data_source.go new file mode 100644 index 0000000..364300e --- /dev/null +++ b/internal/data_sources/transport_products_data_source.go @@ -0,0 +1,261 @@ +package datasources + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/intercloud/terraform-provider-autonomi/external/products/models" + + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + + "github.com/meilisearch/meilisearch-go" +) + +type transportProductsDataSource struct { + client *meilisearch.Client +} + +type transportHits struct { + ID types.Int64 `tfsdk:"id"` + Provider types.String `tfsdk:"provider"` + Duration types.Int64 `tfsdk:"duration"` + Location types.String `tfsdk:"location"` + LocationUnderlay types.String `tfsdk:"location_underlay"` + Bandwidth types.Int64 `tfsdk:"bandwidth"` + Date types.String `tfsdk:"date"` + PriceNRC types.Float64 `tfsdk:"price_nrc"` + PriceMRC types.Float64 `tfsdk:"price_mrc"` + CostNRC types.Float64 `tfsdk:"cost_nrc"` + CostMRC types.Float64 `tfsdk:"cost_mrc"` + SKU types.String `tfsdk:"sku"` + LocationTo types.String `tfsdk:"location_to"` + LocationToUnderlay types.String `tfsdk:"location_to_underlay"` +} + +type transportFacetDistributionDataSourceModel struct { + Bandwidth map[string]int `tfsdk:"bandwidth"` + Location map[string]int `tfsdk:"location"` + LocationTo map[string]int `tfsdk:"location_to"` + Provider map[string]int `tfsdk:"provider"` +} + +type transportProductsDataSourceModel struct { + Filters []filter `tfsdk:"filters"` + Sort []sortFacet `tfsdk:"sort"` + Hits []transportHits `tfsdk:"hits"` + FacetDistribution *transportFacetDistributionDataSourceModel `tfsdk:"facet_distribution"` +} + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ datasource.DataSource = &transportProductDataSource{} + _ datasource.DataSourceWithConfigure = &transportProductDataSource{} +) + +func NewTransportProductsDataSource() datasource.DataSource { + return &transportProductsDataSource{} +} + +// Metadata returns the data source type name. +func (d *transportProductsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_transport_products" +} + +// Schema defines the schema for the data source. +func (d *transportProductsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "filters": schema.ListNestedAttribute{ + MarkdownDescription: "List of filters: [location, locationTo, bandwidth, provider]", + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Optional: true, + }, + "operator": schema.StringAttribute{ + Optional: true, + }, + "values": schema.ListAttribute{ + ElementType: types.StringType, + Optional: true, + }, + }, + }, + }, + "sort": schema.ListNestedAttribute{ + MarkdownDescription: `List of sort: [location, locationTo, bandwidth, provider, +priceNrc, priceMrc, costNrc, costMrc]`, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Optional: true, + }, + "value": schema.StringAttribute{ + Optional: true, + }, + }, + }, + }, + "hits": schema.ListNestedAttribute{ + MarkdownDescription: `The **hits** attribute contains the list of transport products returned by the Meilisearch query. +Each hit represents a transport product that matches the specified search criteria.`, + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{Computed: true}, + "provider": schema.StringAttribute{Computed: true}, + "duration": schema.Int64Attribute{Computed: true}, + "location": schema.StringAttribute{Computed: true}, + "location_underlay": schema.StringAttribute{Computed: true}, + "location_to": schema.StringAttribute{Computed: true}, + "location_to_underlay": schema.StringAttribute{Computed: true}, + "bandwidth": schema.Int64Attribute{Computed: true}, + "date": schema.StringAttribute{Computed: true}, + "price_nrc": schema.Int64Attribute{Computed: true}, + "price_mrc": schema.Int64Attribute{Computed: true}, + "cost_nrc": schema.Int64Attribute{Computed: true}, + "cost_mrc": schema.Int64Attribute{Computed: true}, + "sku": schema.StringAttribute{Computed: true}, + }, + }, + }, + "facet_distribution": schema.SingleNestedAttribute{ + MarkdownDescription: `The **facet_distribution** attribute provides an overview of the distribution of various facets +within the transport products returned by the Meilisearch query. This attribute allows you to analyze the frequency +of different categories or attributes in the search results.`, + Computed: true, + Attributes: map[string]schema.Attribute{ + "provider": int64MapAttr, + "bandwidth": int64MapAttr, + "location": int64MapAttr, + "location_to": int64MapAttr, + }, + }, + }, + } +} + +// Configure adds the provider configured client to the data source. +func (d *transportProductsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Add a nil check when handling ProviderData because Terraform + // sets that data after it calls the ConfigureProvider RPC. + if req.ProviderData == nil { + return + } + + catalogClient, ok := req.ProviderData.(*meilisearch.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *catalog.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + d.client = catalogClient +} + +// Read refreshes the Terraform state with the latest data. +func (d *transportProductsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + + var data transportProductsDataSourceModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + filtersStrings, err := getFiltersString(data.Filters) + if err != nil { + resp.Diagnostics.AddError("error getting filters", err.Error()) + } + sortStrings := getSortString(data.Sort) + + // Define the search request + searchRequest := &meilisearch.SearchRequest{ + Filter: filtersStrings, + Sort: sortStrings, + Facets: []string{ + "location", + "locationTo", + "bandwidth", + "provider", + }, + } + + respProducts, err := d.client.Index("transportproduct").Search("", searchRequest) + if err != nil { + resp.Diagnostics.AddError( + "Unable to Read Autonomi Transport Products", + err.Error(), + ) + return + } + + transportProducts := models.TransportProducts{} + productsJSON, err := json.Marshal(respProducts) // Marshal the hits to JSON + if err != nil { + resp.Diagnostics.AddError( + "Unable to Read Autonomi Transport Products", + err.Error(), + ) + return + } + + err = json.Unmarshal(productsJSON, &transportProducts) // Unmarshal JSON into the TransportProduct slice + if err != nil { + resp.Diagnostics.AddError( + "Unable to Read Autonomi Transport Products", + err.Error(), + ) + return + } + + state := transportProductsDataSourceModel{ + Filters: data.Filters, + Sort: data.Sort, + } + + // Map response body to model + for _, cp := range transportProducts.Hits { + transportProductState := transportHits{ + ID: types.Int64Value(int64(cp.ID)), + Provider: types.StringValue(cp.Provider), + Location: types.StringValue(cp.Location), + LocationUnderlay: types.StringValue(cp.LocationUnderlay), + Bandwidth: types.Int64Value(int64(cp.Bandwidth)), + Date: types.StringValue(cp.Date), + PriceNRC: types.Float64Value(float64(cp.PriceNRC)), + PriceMRC: types.Float64Value(float64(cp.PriceMRC)), + CostNRC: types.Float64Value(float64(cp.CostNRC)), + CostMRC: types.Float64Value(float64(cp.CostMRC)), + SKU: types.StringValue(cp.SKU), + LocationTo: types.StringValue(cp.LocationTo), + LocationToUnderlay: types.StringValue(cp.LocationToUnderlay), + } + state.Hits = append(state.Hits, transportProductState) + } + + // Set the bandwidth map in the state + state.FacetDistribution = &transportFacetDistributionDataSourceModel{ + Bandwidth: transportProducts.FacetDistribution.Bandwidth, + Location: transportProducts.FacetDistribution.Location, + LocationTo: transportProducts.FacetDistribution.LocationTo, + Provider: transportProducts.FacetDistribution.Provider, + } + + // Set state + diags := resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 914c8aa..542437e 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -182,6 +182,7 @@ func (p *autonomiProvider) DataSources(_ context.Context) []func() datasource.Da datasources.NewCloudProductsDataSource, datasources.NewCloudProductDataSource, datasources.NewTransportProductDataSource, + datasources.NewTransportProductsDataSource, datasources.NewAccessProductsDataSource, datasources.NewAccessProductDataSource, } From d6b1e4d1eafd41a07e1bff674c9f53ddfe6827b2 Mon Sep 17 00:00:00 2001 From: rmanach Date: Wed, 28 Aug 2024 10:58:13 +0200 Subject: [PATCH 2/3] add doc --- docs/data-sources/transport_product.md | 93 ++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 docs/data-sources/transport_product.md diff --git a/docs/data-sources/transport_product.md b/docs/data-sources/transport_product.md new file mode 100644 index 0000000..0dc705d --- /dev/null +++ b/docs/data-sources/transport_product.md @@ -0,0 +1,93 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "autonomi_transport_product Data Source - autonomi" +subcategory: "" +description: |- + +--- + +# autonomi_transport_product (Data Source) + +```terraform +data "autonomi_transport_product" "transport" { + filters = [ + { + name = "provider" + operator = "=" + values = ["EQUINIX"] + }, + { + name = "locationTo" + operator = "IN" + values = ["EQUINIX FR5", "EQUINIX LD5"] + }, + { + name = "location" + operator = "IN" + values = ["EQUINIX FR5", "EQUINIX LD5"] + }, + { + name = "bandwidth" + operator = "TO" + values = ["100", "500"] + }, + ] + cheapest = true +} +``` + + +## Schema + +### Optional + +- `cheapest` (Boolean) To ensure only one hit is returned we advise to set at true +- `filters` (Attributes List) List of filters: [location, locationTo, bandwidth, provider] (see [below for nested schema](#nestedatt--filters)) + +### Read-Only + +- `facet_distribution` (Attributes) The **facet_distribution** attribute provides an overview of the distribution of various facets +within the transport products returned by the Meilisearch query. This attribute allows you to analyze the frequency +of different categories or attributes in the search results. (see [below for nested schema](#nestedatt--facet_distribution)) +- `hit` (Attributes) The **hits** attribute contains the list of transport products returned by the Meilisearch query. +Each hit represents a transport product that matches the specified search criteria. (see [below for nested schema](#nestedatt--hit)) + + +### Nested Schema for `filters` + +Optional: + +- `name` (String) +- `operator` (String) +- `values` (List of String) + + +### Nested Schema for `facet_distribution` + +Read-Only: + +- `bandwidth` (Map of Number) +- `location` (Map of Number) +- `location_to` (Map of Number) +- `provider` (Map of Number) + + + +### Nested Schema for `hit` + +Read-Only: + +- `bandwidth` (Number) +- `cost_mrc` (Number) +- `cost_nrc` (Number) +- `date` (String) +- `duration` (Number) +- `id` (Number) +- `location` (String) +- `location_to` (String) +- `location_to_underlay` (String) +- `location_underlay` (String) +- `price_mrc` (Number) +- `price_nrc` (Number) +- `provider` (String) +- `sku` (String) From a199a1c6039014cc261e538391cee4b65145834f Mon Sep 17 00:00:00 2001 From: rmanach Date: Wed, 28 Aug 2024 11:07:42 +0200 Subject: [PATCH 3/3] fix lint issues + check hits length before access --- docs/data-sources/transport_product.md | 3 +-- internal/data_sources/access_product_data_source.go | 2 +- internal/data_sources/cloud_product_data_source.go | 2 +- internal/data_sources/transport_product_data_source.go | 7 ++++++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/data-sources/transport_product.md b/docs/data-sources/transport_product.md index 0dc705d..e6cd5e9 100644 --- a/docs/data-sources/transport_product.md +++ b/docs/data-sources/transport_product.md @@ -49,7 +49,7 @@ data "autonomi_transport_product" "transport" { - `facet_distribution` (Attributes) The **facet_distribution** attribute provides an overview of the distribution of various facets within the transport products returned by the Meilisearch query. This attribute allows you to analyze the frequency of different categories or attributes in the search results. (see [below for nested schema](#nestedatt--facet_distribution)) -- `hit` (Attributes) The **hits** attribute contains the list of transport products returned by the Meilisearch query. +- `hit` (Attributes) The **hit** attribute contains the transport product returned by the Meilisearch query. Each hit represents a transport product that matches the specified search criteria. (see [below for nested schema](#nestedatt--hit)) @@ -71,7 +71,6 @@ Read-Only: - `location_to` (Map of Number) - `provider` (Map of Number) - ### Nested Schema for `hit` diff --git a/internal/data_sources/access_product_data_source.go b/internal/data_sources/access_product_data_source.go index 616a20c..fcc97aa 100644 --- a/internal/data_sources/access_product_data_source.go +++ b/internal/data_sources/access_product_data_source.go @@ -181,7 +181,7 @@ func (d *accessProductDataSource) Read(ctx context.Context, req datasource.ReadR return } - if accessProducts.Hits == nil { + if len(accessProducts.Hits) == 0 { resp.Diagnostics.AddError("Not hit found", "") return } diff --git a/internal/data_sources/cloud_product_data_source.go b/internal/data_sources/cloud_product_data_source.go index 56ad7e0..ef5bb82 100644 --- a/internal/data_sources/cloud_product_data_source.go +++ b/internal/data_sources/cloud_product_data_source.go @@ -184,7 +184,7 @@ func (d *cloudProductDataSource) Read(ctx context.Context, req datasource.ReadRe return } - if cloudProducts.Hits == nil { + if len(cloudProducts.Hits) == 0 { resp.Diagnostics.AddError("Not hit found", "") return } diff --git a/internal/data_sources/transport_product_data_source.go b/internal/data_sources/transport_product_data_source.go index 008d766..919d768 100644 --- a/internal/data_sources/transport_product_data_source.go +++ b/internal/data_sources/transport_product_data_source.go @@ -69,7 +69,7 @@ func (d *transportProductDataSource) Schema(_ context.Context, _ datasource.Sche }, }, "hit": schema.SingleNestedAttribute{ - MarkdownDescription: `The **hits** attribute contains the list of transport products returned by the Meilisearch query. + MarkdownDescription: `The **hit** attribute contains the transport product returned by the Meilisearch query. Each hit represents a transport product that matches the specified search criteria.`, Computed: true, Attributes: map[string]schema.Attribute{ @@ -181,6 +181,11 @@ func (d *transportProductDataSource) Read(ctx context.Context, req datasource.Re return } + if len(transportProducts.Hits) == 0 { + resp.Diagnostics.AddError("Not hit found", "") + return + } + // If Meiliesearch return more than one hit, check if `cheapest` filter has been set. // If not, an error is returned, otherwise a sort will be done to order the list by price mrc. The first entry will be returned if len(transportProducts.Hits) > 1 {