forked from Azure/azure-dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Split spec_service_binding.go by app type: Spring Boot app, other app
#105
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
Merged
rujche
merged 24 commits into
azure-javaee:feature/sjad
from
rujche:split-spec_service_binding
Jan 23, 2025
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
7466e88
Split spec_service_binding.go by app type: Spring Boot app, other app.
rujche b979bc4
Merge remote-tracking branch 'azure-javaee/feature/sjad' into split-s…
rujche ce86fed
Update cli/azd/internal/binding/binding_spring_boot.go
rujche 6a95216
Fix test failure in infra_confirm_test.go.
rujche 0ea4b48
Update the text of test.
rujche ad6cd7a
Fix error in bicep_env.go
rujche 6e263c0
Fix error in bicep_env.go: "$service$name" -> "$service $name"
rujche 636d1fa
Delete "type Env" because it's not used anymore.
rujche 0376e59
In bicep_env_test.go, add test: "Eureka server" and "Config server". …
rujche bb5682d
Enhance test by renaming "configServerName" to "config-server-name"
rujche 6f6e5d2
Fix GitHub action failure reported by lint.
rujche 203cd4c
Skip test whose failure is not cause by current PR.
rujche 8d1453a
Fix test failure: Test_ImportManager_ProjectInfrastructure_FromResources
rujche abe4b42
Delete "bindingEnvValuePrefix" because it's not used.
rujche c487900
Rename "EnvManagedIdentityClientId" to "SourceUserAssignedManagedIden…
rujche 8905e23
Add unit test in TestIsBindingEnvValue, And fix test failure.
rujche 8d880d4
Improve ToBicepEnv, and add unit test.
rujche 79d5a0f
Change placeholder value to make it easier to understand.
rujche 2a19da5
Create func: isPlaceholderOfSourceClientId
rujche 19a6473
Fix error: UnmatchedPrincipalType: The PrincipalId 'xxx' has type 'Us…
rujche a601e70
Merge branch 'azure-javaee/feature/sjad' into split-spec_service_binding
rujche 46e63cd
Remove duplicated codes in spec_service_binding.go by adding a new func.
rujche 45a49a7
Use "map[MetadataType]string" to avoid contains spring boot related i…
rujche 6fe9c3f
Merge branch 'azure-javaee/feature/sjad' into split-spec_service_binding
rujche File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| package binding | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "strings" | ||
|
|
||
| "github.com/azure/azure-dev/cli/azd/internal" | ||
| ) | ||
|
|
||
| func GetBindingEnvs(source Source, target Target) (map[string]string, | ||
| error) { | ||
| switch source.Type { | ||
| case Java, SpringBoot: // todo: support other Java types | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This todo will not be done in current PR. |
||
| return GetBindingEnvsForSpringBoot(source, target) | ||
| default: | ||
| return GetBindingEnvsForCommonSource(target) | ||
| } | ||
| } | ||
|
|
||
| type Source struct { | ||
| Type SourceType | ||
| Metadata map[MetadataType]string | ||
| } | ||
|
|
||
| type SourceType string | ||
| type MetadataType string | ||
|
|
||
| const ( | ||
| Java SourceType = "java" | ||
| SpringBoot SourceType = "springBoot" | ||
| Unknown SourceType = "unknown" | ||
| ) | ||
|
|
||
| type Target struct { | ||
| Type TargetType | ||
| Name string | ||
| AuthType internal.AuthType | ||
| } | ||
|
|
||
| type TargetType string | ||
|
|
||
| const ( | ||
| AzureDatabaseForPostgresql TargetType = "azure.db.postgresql" | ||
| AzureDatabaseForMysql TargetType = "azure.db.mysql" | ||
| AzureCacheForRedis TargetType = "azure.db.redis" | ||
| AzureCosmosDBForMongoDB TargetType = "azure.db.cosmos.mongo" | ||
| AzureCosmosDBForNoSQL TargetType = "azure.db.cosmos.nosql" | ||
| AzureContainerApp TargetType = "azure.host.containerapp" | ||
| AzureOpenAiModel TargetType = "azure.ai.openai.model" | ||
| AzureServiceBus TargetType = "azure.messaging.servicebus" | ||
| AzureEventHubs TargetType = "azure.messaging.eventhubs" | ||
| AzureStorageAccount TargetType = "azure.storage" | ||
| ) | ||
|
|
||
| type InfoType string | ||
|
|
||
| const ( | ||
| InfoTypeHost InfoType = "host" | ||
| InfoTypePort InfoType = "port" | ||
| InfoTypeEndpoint InfoType = "endpoint" | ||
| InfoTypeDatabaseName InfoType = "databaseName" | ||
| InfoTypeNamespace InfoType = "namespace" | ||
| InfoTypeAccountName InfoType = "accountName" | ||
| InfoTypeUsername InfoType = "username" | ||
| InfoTypePassword InfoType = "password" | ||
| InfoTypeUrl InfoType = "url" | ||
| InfoTypeJdbcUrl InfoType = "jdbcUrl" | ||
| InfoTypeConnectionString InfoType = "connectionString" | ||
| InfoTypeSourceUserAssignedManagedIdentityClientId InfoType = "sourceUserAssignedManagedIdentityClientId" | ||
| ) | ||
|
|
||
| const bindingEnvPrefix = "${binding:" | ||
| const bindingEnvSuffix = "}" | ||
| const bindingEnvFormat = bindingEnvPrefix + "%s:%s:%s" + bindingEnvSuffix | ||
| const SourceUserAssignedManagedIdentityClientId = bindingEnvPrefix + | ||
| "*:*:" + string(InfoTypeSourceUserAssignedManagedIdentityClientId) + bindingEnvSuffix | ||
|
|
||
| func IsBindingEnv(value string) bool { | ||
| _, infoType := ToTargetAndInfoType(value) | ||
| return infoType != "" | ||
| } | ||
|
|
||
| func ToBindingEnv(target Target, infoType InfoType) string { | ||
| return fmt.Sprintf(bindingEnvFormat, target.Type, target.Name, infoType) | ||
| } | ||
|
|
||
| func ReplaceBindingEnv(value string, substr string) string { | ||
| prefixIndex := strings.Index(value, bindingEnvPrefix) | ||
| if prefixIndex == -1 { | ||
| return value | ||
| } | ||
| suffixIndex := strings.Index(value, bindingEnvSuffix) | ||
| if suffixIndex == -1 { | ||
| return value | ||
| } | ||
| if prefixIndex >= suffixIndex { | ||
| return value | ||
| } | ||
| return value[0:prefixIndex] + substr + value[suffixIndex+1:] | ||
| } | ||
|
|
||
| func ToTargetAndInfoType(value string) (target Target, infoType InfoType) { | ||
| prefixIndex := strings.Index(value, bindingEnvPrefix) | ||
| if prefixIndex == -1 { | ||
| return Target{}, "" | ||
| } | ||
| suffixIndex := strings.Index(value, bindingEnvSuffix) | ||
| if suffixIndex == -1 { | ||
| return Target{}, "" | ||
| } | ||
| if prefixIndex >= suffixIndex { | ||
| return Target{}, "" | ||
| } | ||
| bindingEnv := value[prefixIndex:suffixIndex] | ||
| a := strings.Split(bindingEnv, ":") | ||
| if len(a) != 4 { | ||
| return Target{}, "" | ||
| } | ||
| targetTypeString := a[1] | ||
| targetNameString := a[2] | ||
| infoTypeString := a[3] | ||
| return Target{Type: TargetType(targetTypeString), Name: targetNameString}, InfoType(infoTypeString) | ||
| } | ||
|
|
||
| func MergeMapWithDuplicationCheck(a map[string]string, b map[string]string) (map[string]string, error) { | ||
| result := make(map[string]string) | ||
| for k, v := range a { | ||
| result[k] = v | ||
| } | ||
| for key, value := range b { | ||
| if existingValue, exist := result[key]; exist { | ||
| if value != existingValue { | ||
| return nil, duplicatedEnvError(existingValue, value) | ||
| } | ||
| } else { | ||
| result[key] = value | ||
| } | ||
| } | ||
| return result, nil | ||
| } | ||
|
|
||
| func duplicatedEnvError(existingValue string, newValue string) error { | ||
| return fmt.Errorf( | ||
| "duplicated environment variable. existingValue = %s, newValue = %s", | ||
| existingValue, newValue, | ||
| ) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package binding | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/azure/azure-dev/cli/azd/internal" | ||
| ) | ||
|
|
||
| func GetBindingEnvsForCommonSource(target Target) (map[string]string, error) { | ||
| switch target.Type { | ||
| case AzureDatabaseForPostgresql: | ||
| return GetBindingEnvsForCommonSourceToPostgresql(target.AuthType) | ||
| case AzureDatabaseForMysql: | ||
| return GetBindingEnvsForCommonSourceToMysql(target.AuthType) | ||
| case AzureCosmosDBForMongoDB: | ||
| return GetBindingEnvsForCommonSourceToMongoDB(target.AuthType) | ||
| case AzureCacheForRedis: | ||
| return GetBindingEnvsForCommonSourceToRedis(target.AuthType) | ||
| case AzureOpenAiModel: | ||
| return GetServiceBindingEnvsForAIModel(target.AuthType) | ||
| default: | ||
| return nil, fmt.Errorf("unsupported target type when binding for spring boot app, target.Type = %s", | ||
| target.Type) | ||
| } | ||
| } | ||
|
|
||
| func GetBindingEnvsForCommonSourceToPostgresql(authType internal.AuthType) (map[string]string, error) { | ||
| switch authType { | ||
| case internal.AuthTypePassword: | ||
| return map[string]string{ | ||
| "POSTGRES_USERNAME": ToBindingEnv(Target{Type: AzureDatabaseForPostgresql}, InfoTypeUsername), | ||
| "POSTGRES_PASSWORD": ToBindingEnv(Target{Type: AzureDatabaseForPostgresql}, InfoTypePassword), | ||
| "POSTGRES_HOST": ToBindingEnv(Target{Type: AzureDatabaseForPostgresql}, InfoTypeHost), | ||
| "POSTGRES_DATABASE": ToBindingEnv(Target{Type: AzureDatabaseForPostgresql}, InfoTypeDatabaseName), | ||
| "POSTGRES_PORT": ToBindingEnv(Target{Type: AzureDatabaseForPostgresql}, InfoTypePort), | ||
| "POSTGRES_URL": ToBindingEnv(Target{Type: AzureDatabaseForPostgresql}, InfoTypeUrl), | ||
| }, nil | ||
| default: | ||
| return nil, unsupportedAuthTypeError(AzureDatabaseForPostgresql, authType) | ||
| } | ||
| } | ||
|
|
||
| func GetBindingEnvsForCommonSourceToMysql(authType internal.AuthType) (map[string]string, error) { | ||
| switch authType { | ||
| case internal.AuthTypePassword: | ||
| return map[string]string{ | ||
| "MYSQL_USERNAME": ToBindingEnv(Target{Type: AzureDatabaseForMysql}, InfoTypeUsername), | ||
| "MYSQL_PASSWORD": ToBindingEnv(Target{Type: AzureDatabaseForMysql}, InfoTypePassword), | ||
| "MYSQL_HOST": ToBindingEnv(Target{Type: AzureDatabaseForMysql}, InfoTypeHost), | ||
| "MYSQL_DATABASE": ToBindingEnv(Target{Type: AzureDatabaseForMysql}, InfoTypeDatabaseName), | ||
| "MYSQL_PORT": ToBindingEnv(Target{Type: AzureDatabaseForMysql}, InfoTypePort), | ||
| "MYSQL_URL": ToBindingEnv(Target{Type: AzureDatabaseForMysql}, InfoTypeUrl), | ||
| }, nil | ||
| default: | ||
| return nil, unsupportedAuthTypeError(AzureDatabaseForMysql, authType) | ||
| } | ||
| } | ||
|
|
||
| func GetBindingEnvsForCommonSourceToMongoDB(authType internal.AuthType) (map[string]string, error) { | ||
| switch authType { | ||
| case internal.AuthTypeConnectionString: | ||
| return map[string]string{ | ||
| "MONGODB_URL": ToBindingEnv(Target{Type: AzureCosmosDBForMongoDB}, InfoTypeUrl), | ||
| }, nil | ||
| default: | ||
| return nil, unsupportedAuthTypeError(AzureCosmosDBForMongoDB, authType) | ||
| } | ||
| } | ||
|
|
||
| func GetBindingEnvsForCommonSourceToRedis(authType internal.AuthType) (map[string]string, error) { | ||
| switch authType { | ||
| case internal.AuthTypePassword: | ||
| return map[string]string{ | ||
| "REDIS_HOST": ToBindingEnv(Target{Type: AzureCacheForRedis}, InfoTypeHost), | ||
| "REDIS_PORT": ToBindingEnv(Target{Type: AzureCacheForRedis}, InfoTypePort), | ||
| "REDIS_ENDPOINT": ToBindingEnv(Target{Type: AzureCacheForRedis}, InfoTypeEndpoint), | ||
| "REDIS_URL": ToBindingEnv(Target{Type: AzureCacheForRedis}, InfoTypeUrl), | ||
| "REDIS_PASSWORD": ToBindingEnv(Target{Type: AzureCacheForRedis}, InfoTypePassword), | ||
| }, nil | ||
| default: | ||
| return nil, unsupportedAuthTypeError(AzureCacheForRedis, authType) | ||
| } | ||
| } | ||
|
|
||
| func GetServiceBindingEnvsForAIModel(authType internal.AuthType) (map[string]string, error) { | ||
| switch authType { | ||
| case internal.AuthTypeUserAssignedManagedIdentity: | ||
| return map[string]string{ | ||
| "AZURE_OPENAI_ENDPOINT": ToBindingEnv(Target{Type: AzureOpenAiModel}, InfoTypeEndpoint), | ||
| }, nil | ||
| default: | ||
| return nil, unsupportedAuthTypeError(AzureOpenAiModel, authType) | ||
| } | ||
| } | ||
|
|
||
| func unsupportedAuthTypeError(targetType TargetType, authType internal.AuthType) error { | ||
| return fmt.Errorf("unsupported auth type, serviceType = %s, authType = %s", targetType, authType) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore the test failure in current PR because it's not caused by current PR. The failure already exists in previous PR: #104
Maybe this failure can be fixed by merge upstream main, but I'm not sure. Anyway, skip related test in current PR.