Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools/data-api-repository: consolidating the reading/writing of data into data-api-repository / updated support for Common Types #4217

Merged
merged 28 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3d792ed
temp: commenting out the `repositories` folder
tombuildsstuff Jun 11, 2024
3979a20
tools/data-api: refactoring the arguments into their own file
tombuildsstuff Jun 11, 2024
adee2bd
`tools/data-api-repository`: updating the `NewRepository` function to…
tombuildsstuff Jun 11, 2024
c64ec4b
`tools/importer-rest-api-specs`: updating to account for `NewReposito…
tombuildsstuff Jun 11, 2024
c0d523b
`tools/data-api-sdk`: adding `Name` to Service and `APIVersion` to AP…
tombuildsstuff Jun 13, 2024
3ffadea
`tools/importer-rest-api-specs`: updating to account for the reposito…
tombuildsstuff Jun 13, 2024
19b3aff
api-definitions: fixing the model name
tombuildsstuff Jun 18, 2024
8375426
`tools/importer-rest-api-specs`: skipping outputting Constants and Mo…
tombuildsstuff Jun 18, 2024
9c4eb82
`tools/data-api-repository`: support for loading/saving data
tombuildsstuff Jun 18, 2024
0c0fcf5
tools/data-api: refactoring to use the `data-api-repository` package …
tombuildsstuff Jun 18, 2024
4fb9edb
`tools/data-api-repository`: support for filtering to `serviceNamesTo…
tombuildsstuff Jun 18, 2024
2d84db8
`tools/data-api-sdk`: updating the example values for consistency & a…
tombuildsstuff Jun 18, 2024
f4c78ff
`tools/data-api-repository`: aligining on TitleCase for the constant …
tombuildsstuff Jun 18, 2024
6c0f48f
`tools/data-api-repository`: reserving a directory/service name for `…
tombuildsstuff Jun 18, 2024
a7df51a
`tools/data-api-repository`: refactoring how the metadata/other files…
tombuildsstuff Jun 19, 2024
2faf8b7
`tools/importer-rest-api-specs`: updating to use the new `PurgeExisti…
tombuildsstuff Jun 19, 2024
8c722af
`tools/data-api` and `tools/data-api-repository` and `tools/data-api-…
tombuildsstuff Jun 19, 2024
caae8dc
`tools/data-api-differ`: removing the outdated todo
tombuildsstuff Jun 19, 2024
8ceb110
cleanup: removing usage of the old aliases
tombuildsstuff Jun 19, 2024
d69ac8e
refactor: imports
tombuildsstuff Jun 19, 2024
2ca58e9
`tools/data-api`: re-introducing the "is the data valid" test for the…
tombuildsstuff Jun 19, 2024
6edf0c8
`tools/data-api-repository`: adding missing headers
tombuildsstuff Jun 20, 2024
995e511
`tools/data-api`: reintroducing the `v1` import which got stripped du…
tombuildsstuff Jun 20, 2024
41f3522
`tools/importer-rest-api-specs`: fixing the fmt/test
tombuildsstuff Jun 20, 2024
ca5eb50
`tools/data-api-differ`: fixing some remaining usages of the old alia…
tombuildsstuff Jun 20, 2024
1fd7b80
`tools/data-api-differ`: updating the `launchAndWait` command to wait…
tombuildsstuff Jun 20, 2024
968dbaf
Update tools/data-api-differ/internal/dataapi/data_api_cmd.go
tombuildsstuff Jun 21, 2024
099946c
Update tools/data-api-repository/repository/remove_common_types.go
tombuildsstuff Jun 21, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"resources": [
"Tenants"
],
"source": "handwritten"
"source": "HandWritten"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "TenantProperties",
"name": "UpdateTenantProperties",
"fields": [
{
"containsDiscriminatedTypeValue": false,
Expand Down
13 changes: 3 additions & 10 deletions tools/data-api-differ/internal/dataapi/data_api_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,11 @@ func (p *dataApiCmd) launchAndWait(ctx context.Context, client *v1.Client) error
log.Logger.Trace(fmt.Sprintf("Data API is launched at %q.", p.endpoint))

// then ensure it's accepting requests prior to hitting it (e.g. firewalls)
for attempts := 0; attempts < 30; attempts++ {
log.Logger.Trace(fmt.Sprintf("Checking the health of the Data API - attempt %d/30", attempts+1))
for attempts := 0; attempts < 50; attempts++ {
log.Logger.Trace(fmt.Sprintf("Checking the health of the Data API - attempt %d/50", attempts+1))

result, err := client.Health(ctx)
if err != nil {
if result != nil && result.HttpResponse != nil {
return fmt.Errorf("unexpected status code %d", result.HttpResponse.StatusCode)
}
return fmt.Errorf("connection failure")
}

if result.Available {
if result != nil && result.Available {
log.Logger.Trace("API available")
return nil
}
Expand Down
6 changes: 0 additions & 6 deletions tools/data-api-differ/internal/dataapi/todo.go

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestDiff_APIVersionAdded_WithNestedDetails(t *testing.T) {
"2023-01-01": {
Resources: map[string]models.APIResource{
"Example": {
Constants: map[string]models.ConstantDetails{
Constants: map[string]models.SDKConstant{
"SomeConst": {
Type: models.StringSDKConstantType,
Values: map[string]string{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ func TestDiff_OperationResponseObjectChanged(t *testing.T) {
updated := map[string]models.SDKOperation{
"First": {
ResponseObject: &models.SDKObjectDefinition{
Type: models.ReferenceApiObjectDefinitionType,
Type: models.ReferenceSDKObjectDefinitionType,
ReferenceName: pointer.To("SomeConstant"),
},
},
Expand Down
10 changes: 10 additions & 0 deletions tools/data-api-repository/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## `./tools/data-api-sdk`

This package provides a Repository which can be used to load/store API Definitions on-disk in a consistent manner.

This is currently used in:

* `./tools/data-api` - to load and serve the API Definitions, for use in other tooling.
* `./tools/importer-rest-api-specs` - to remove any existing and then import all-new API Definitions for Azure Resource Manager.

This package isn't intended to be used directly, and other tooling should interact with the Data API instead.
6 changes: 0 additions & 6 deletions tools/data-api-repository/models/README.md

This file was deleted.

57 changes: 57 additions & 0 deletions tools/data-api-repository/repository/directory_for_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package repository

import (
"fmt"
"path/filepath"

sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

func (r *repositoryImpl) directoryForService(serviceName string, sourceDataOrigin sdkModels.SourceDataOrigin) (*string, error) {
// use the existing directory if we've parsed it
if dataSource, ok := r.availableDataSources[serviceName]; ok {
if dataSource.sourceDataOrigin != sourceDataOrigin {
return nil, fmt.Errorf("an existing Service named %q uses the SourceDataOrigin %q but found a duplicate for the SourceDataOrigin %q", serviceName, dataSource.sourceDataOrigin, sourceDataOrigin)
}

return &dataSource.workingDirectory, nil
}

// else fallback to the default ones
path, err := r.defaultDirectoryForSourceDataOrigin(sourceDataOrigin)
if err != nil {
return nil, err
}
serviceDirectory := filepath.Join(*path, serviceName)
return &serviceDirectory, nil
}

func (r *repositoryImpl) defaultDirectoryForSourceDataOrigin(sourceDataOrigin sdkModels.SourceDataOrigin) (*string, error) {
sourceDataOriginsToDefaultDirectories, ok := defaultDataDirectories[r.sourceDataType]
if !ok {
return nil, fmt.Errorf("missing a default directory for SourceDataType %q", string(r.sourceDataType))
}
defaultDirectory, ok := sourceDataOriginsToDefaultDirectories[sourceDataOrigin]
if !ok {
return nil, fmt.Errorf("missing a default directory for SourceDataOrigin %q within SourceDataType %q", sourceDataOrigin, string(r.sourceDataType))
}
dataDirectory := filepath.Join(r.workingDirectory, defaultDirectory)
return &dataDirectory, nil
}

var defaultDataDirectories = map[sdkModels.SourceDataType]map[sdkModels.SourceDataOrigin]string{
// NOTE: the ordering matters here, we want to load the imported data before any handwritten data
// This is to ensure that if the imported data contains a Discriminated Parent Type that we can add
// additional Implementations within the HandWritten Data which inherits from that, so this is automatically
// unmarshalled as required.
sdkModels.MicrosoftGraphSourceDataType: {
sdkModels.MicrosoftGraphMetaDataSourceDataOrigin: "microsoft-graph",
},
sdkModels.ResourceManagerSourceDataType: {
sdkModels.AzureRestAPISpecsSourceDataOrigin: "resource-manager",
sdkModels.HandWrittenSourceDataOrigin: "handwritten-resource-manager",
},
}
35 changes: 35 additions & 0 deletions tools/data-api-repository/repository/get_all_services.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package repository

import (
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

// GetAllServices returns all the Services supported for this SourceDataType as a map of
// Service Name (key) to Service (value).
func (r *repositoryImpl) GetAllServices() (*map[string]sdkModels.Service, error) {
r.cacheLock.Lock()
defer r.cacheLock.Unlock()

output := make(map[string]sdkModels.Service)
for serviceName := range r.availableDataSources {
service, exists := r.cachedServices[serviceName]
if !exists {
// otherwise let's populate it in the cache
svc, err := r.loadService(serviceName)
if err != nil {
return nil, err
}
if svc == nil {
return nil, nil
}
r.cachedServices[serviceName] = *svc
service = *svc
}

output[serviceName] = service
}
return &output, nil
}
18 changes: 18 additions & 0 deletions tools/data-api-repository/repository/get_common_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package repository

import (
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

// GetCommonTypes returns all the Common Types (Constants and Models) for this SourceDataType
// this returns a map of APIVersion (key) to CommonTypes (value).
func (r *repositoryImpl) GetCommonTypes() (*map[string]sdkModels.CommonTypes, error) {
// The CommonTypes are loaded/cached when the Repository is initialized, as such we
// can just return those.
// When the Common Types are updated, the cache is invalidated/updated, so this should
// always be fresh.
return &r.cachedCommonTypes, nil
}
30 changes: 30 additions & 0 deletions tools/data-api-repository/repository/get_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package repository

import (
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

// GetService returns the specified Service by its `name` if it exists.
// When the Service doesn't exist, `nil` will be returned.
func (r *repositoryImpl) GetService(name string) (*sdkModels.Service, error) {
r.cacheLock.Lock()
defer r.cacheLock.Unlock()

service, exists := r.cachedServices[name]
if !exists {
// otherwise let's populate the cache
svc, err := r.loadService(name)
if err != nil {
return nil, err
}
if svc == nil {
return nil, nil
}
r.cachedServices[name] = *svc
service = *svc
}
return &service, nil
}
49 changes: 49 additions & 0 deletions tools/data-api-repository/repository/helpers_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package repository

import (
"fmt"

"github.com/hashicorp/go-hclog"
sdkModels "github.com/hashicorp/pandora/tools/data-api-sdk/v1/models"
)

func (r *repositoryImpl) populateCacheInternal() error {
r.logger.Trace("Refreshing the cache of Available Services..")
availableDataSources, err := populateAvailableServicesCache(r.workingDirectory, r.sourceDataType, r.serviceNamesToLimitTo, r.logger)
if err != nil {
return fmt.Errorf("populating the Available Services: %+v", err)
}
r.availableDataSources = *availableDataSources

commonTypes, err := discoverCommonTypesWithin(r.workingDirectory, r.sourceDataType, r.logger)
if err != nil {
return fmt.Errorf("populating the Common Types: %+v", err)
}
r.cachedCommonTypes = *commonTypes

return nil
}

func populateAvailableServicesCache(workingDirectory string, sourceDataType sdkModels.SourceDataType, serviceNamesToLimitTo *[]string, logger hclog.Logger) (*map[string]availableService, error) {
availableDataSources, err := discoverAvailableSourceDataWithin(workingDirectory, sourceDataType, logger)
if err != nil {
return nil, fmt.Errorf("discovering the available data sources within %q: %+v", workingDirectory, err)
}

if serviceNamesToLimitTo != nil && len(*serviceNamesToLimitTo) > 0 {
filtered := make(map[string]availableService)

for _, serviceName := range *serviceNamesToLimitTo {
if v, ok := (*availableDataSources)[serviceName]; ok {
filtered[serviceName] = v
}
}

availableDataSources = &filtered
}

return availableDataSources, nil
}
Loading
Loading