From 7c1255275c123dbcd64ca0ade1e587700f762938 Mon Sep 17 00:00:00 2001 From: haozhang Date: Wed, 18 Dec 2024 13:47:26 +0800 Subject: [PATCH 01/15] eventhubs-integration, eventhubs-messaging, and spring-kafka --- cli/azd/internal/appdetect/appdetect.go | 12 ++ cli/azd/internal/appdetect/spring_boot.go | 111 +++++++++++++++++- cli/azd/internal/repository/app_init.go | 54 +++++++++ .../internal/scaffold/spec_service_binding.go | 8 ++ 4 files changed, 183 insertions(+), 2 deletions(-) diff --git a/cli/azd/internal/appdetect/appdetect.go b/cli/azd/internal/appdetect/appdetect.go index a8d39b70c67..73fd958e968 100644 --- a/cli/azd/internal/appdetect/appdetect.go +++ b/cli/azd/internal/appdetect/appdetect.go @@ -154,10 +154,22 @@ func (a AzureDepServiceBus) ResourceDisplay() string { type AzureDepEventHubs struct { EventHubsNamePropertyMap map[string]string + FromDependency FromDependency UseKafka bool SpringBootVersion string } +type FromDependency string + +const ( + SpringCloudStreamEventHubs = "spring-cloud-azure-stream-binder-eventhubs" + SpringCloudEventHubsStarter = "spring-cloud-azure-starter-eventhubs" + SpringIntegrationEventHubs = "spring-cloud-azure-starter-integration-eventhubs" + SpringMessagingEventHubs = "spring-messaging-azure-eventhubs" + SpringCloudStreamKafka = "spring-cloud-starter-stream-kafka" + SpringKafka = "spring-kafka" +) + func (a AzureDepEventHubs) ResourceDisplay() string { return "Azure Event Hubs" } diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index 0b94564e779..2ed67665fa6 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -183,7 +183,10 @@ func detectEventHubs(azdProject *Project, springBootProject *SpringBootProject) // we need to figure out multiple projects are using the same event hub detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency(azdProject, springBootProject) detectEventHubsAccordingToSpringCloudEventhubsStarterDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringIntegrationEventhubsDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringMessagingEventhubsDependency(azdProject, springBootProject) detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringKafkaDependency(azdProject, springBootProject) } func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( @@ -195,6 +198,7 @@ func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, UseKafka: false, + FromDependency: SpringCloudStreamEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -217,6 +221,7 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: eventHubsNamePropertyMap, UseKafka: false, + FromDependency: SpringCloudEventHubsStarter, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -226,6 +231,36 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterDependency( } } +func detectEventHubsAccordingToSpringIntegrationEventhubsDependency( + azdProject *Project, springBootProject *SpringBootProject) { + var targetGroupId = "com.azure.spring" + var targetArtifactId = "spring-cloud-azure-starter-integration-eventhubs" + if hasDependency(springBootProject, targetGroupId, targetArtifactId) { + newDep := AzureDepEventHubs{ + // eventhubs name is empty here because no autoconfigured property + UseKafka: false, + FromDependency: SpringIntegrationEventHubs, + } + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) + } +} + +func detectEventHubsAccordingToSpringMessagingEventhubsDependency( + azdProject *Project, springBootProject *SpringBootProject) { + var targetGroupId = "com.azure.spring" + var targetArtifactId = "spring-messaging-azure-eventhubs" + if hasDependency(springBootProject, targetGroupId, targetArtifactId) { + newDep := AzureDepEventHubs{ + // eventhubs name is empty here because no autoconfigured property + UseKafka: false, + FromDependency: SpringMessagingEventHubs, + } + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) + } +} + func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "org.springframework.cloud" @@ -236,6 +271,7 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( EventHubsNamePropertyMap: bindingDestinations, UseKafka: true, SpringBootVersion: springBootProject.springBootVersion, + FromDependency: SpringCloudStreamKafka, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -246,8 +282,25 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( } } +func detectEventHubsAccordingToSpringKafkaDependency(azdProject *Project, springBootProject *SpringBootProject) { + var targetGroupId = "org.springframework.kafka" + var targetArtifactId = "spring-kafka" + if hasDependency(springBootProject, targetGroupId, targetArtifactId) { + newDep := AzureDepEventHubs{ + // eventhubs name is empty here because no autoconfigured property + UseKafka: true, + SpringBootVersion: springBootProject.springBootVersion, + FromDependency: SpringMessagingEventHubs, + } + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) + } +} + func detectStorageAccount(azdProject *Project, springBootProject *SpringBootProject) { detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndProperty(azdProject, springBootProject) + detectStorageAccountAccordingToSpringIntegrationEventhubsDependencyAndProperty(azdProject, springBootProject) + detectStorageAccountAccordingToSpringMessagingEventhubsDependencyAndProperty(azdProject, springBootProject) } func detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndProperty( @@ -271,12 +324,66 @@ func detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndPro containerNamePropertyMap[key] = value } } + if len(containerNamePropertyMap) > 0 { + newDep := AzureDepStorageAccount{ + ContainerNamePropertyMap: containerNamePropertyMap, + } + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + logServiceAddedAccordingToMavenDependencyAndExtraCondition(newDep.ResourceDisplay(), targetGroupId, + targetArtifactId, "binding name ["+containsInBindingName+"] contains '-in-'") + for property, containerName := range containerNamePropertyMap { + log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", + containerName, property) + } + } + } + } +} + +func detectStorageAccountAccordingToSpringIntegrationEventhubsDependencyAndProperty( + azdProject *Project, springBootProject *SpringBootProject) { + var targetGroupId = "com.azure.spring" + var targetArtifactId = "spring-cloud-azure-starter-integration-eventhubs" + var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" + if hasDependency(springBootProject, targetGroupId, targetArtifactId) { + containerNamePropertyMap := make(map[string]string) + for key, value := range springBootProject.applicationProperties { + if strings.HasSuffix(key, targetPropertyName) { + containerNamePropertyMap[key] = value + } + } + if len(containerNamePropertyMap) > 0 { + newDep := AzureDepStorageAccount{ + ContainerNamePropertyMap: containerNamePropertyMap, + } + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) + for property, containerName := range containerNamePropertyMap { + log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", + containerName, property) + } + } + } +} + +func detectStorageAccountAccordingToSpringMessagingEventhubsDependencyAndProperty( + azdProject *Project, springBootProject *SpringBootProject) { + var targetGroupId = "com.azure.spring" + var targetArtifactId = "spring-messaging-azure-eventhubs" + var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" + if hasDependency(springBootProject, targetGroupId, targetArtifactId) { + containerNamePropertyMap := make(map[string]string) + for key, value := range springBootProject.applicationProperties { + if strings.HasSuffix(key, targetPropertyName) { + containerNamePropertyMap[key] = value + } + } + if len(containerNamePropertyMap) > 0 { newDep := AzureDepStorageAccount{ ContainerNamePropertyMap: containerNamePropertyMap, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) - logServiceAddedAccordingToMavenDependencyAndExtraCondition(newDep.ResourceDisplay(), targetGroupId, - targetArtifactId, "binding name ["+containsInBindingName+"] contains '-in-'") + logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) for property, containerName := range containerNamePropertyMap { log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", containerName, property) diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 5cf7f370790..18bdf255edb 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -6,6 +6,7 @@ import ( "maps" "os" "path/filepath" + "regexp" "slices" "strings" "time" @@ -154,6 +155,10 @@ func (i *Initializer) InitFromApp( } } // prompt event hubs name if not detected + if len(eventHubs.EventHubsNamePropertyMap) == 0 { + promptMissingEventHubsNameOrExit(i.console, ctx, &eventHubs) + prj.AzureDeps[depIndex] = eventHubs + } for property, eventHubsName := range eventHubs.EventHubsNamePropertyMap { if eventHubsName == "" { promptMissingPropertyAndExit(i.console, ctx, property) @@ -1095,12 +1100,61 @@ func promptSpringBootVersion(console input.Console, ctx context.Context) (string } } +func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context, eventHubs *appdetect.AzureDepEventHubs) { + switch eventHubs.FromDependency { + case appdetect.SpringIntegrationEventHubs, appdetect.SpringMessagingEventHubs, appdetect.SpringKafka: + eventHubsName, err := promptEventHubsName(console, ctx) + if err != nil { + console.Message(ctx, fmt.Sprintf("Error happened when prompt eventhubs name: %s.", err)) + os.Exit(-1) + } + eventHubs.EventHubsNamePropertyMap = map[string]string{ + string(eventHubs.FromDependency): eventHubsName, + } + case appdetect.SpringCloudStreamEventHubs, appdetect.SpringCloudStreamKafka: + promptMissingPropertyAndExit(console, ctx, "spring.cloud.stream.bindings..destination") + os.Exit(0) + case appdetect.SpringCloudEventHubsStarter: + promptMissingPropertyAndExit(console, ctx, "spring.cloud.azure.eventhubs.event-hub-name") + os.Exit(0) + } +} + func promptMissingPropertyAndExit(console input.Console, ctx context.Context, key string) { console.Message(ctx, fmt.Sprintf("No value was provided for %s. Please update the configuration file "+ "(like application.properties or application.yaml) with a valid value.", key)) os.Exit(0) } +func promptEventHubsName(console input.Console, ctx context.Context) (string, error) { + for { + eventHubsName, err := console.Prompt(ctx, input.ConsoleOptions{ + Message: "Input the name of Azure EventHubs (Not EventHubs namespace name):", + Help: "Hint: Azure EventHubs Name, not EventHubs namespace name", + }) + if err != nil { + return "", err + } + if IsValidEventhubsName(eventHubsName) { + return eventHubsName, nil + } else { + console.Message(ctx, "Invalid eventhubs name. Please choose another name.") + } + } +} + +// contain letters, numbers, periods (.), hyphens (-), and underscores (_) +// must begin and end with a letter or number +var eventHubsNameRegex = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$`) + +func IsValidEventhubsName(name string) bool { + // up to 256 characters + if len(name) == 0 || len(name) > 256 { + return false + } + return eventHubsNameRegex.MatchString(name) +} + func appendJavaEurekaServerEnv(svc *project.ServiceConfig, eurekaServerName string) error { if svc.Env == nil { svc.Env = map[string]string{} diff --git a/cli/azd/internal/scaffold/spec_service_binding.go b/cli/azd/internal/scaffold/spec_service_binding.go index 1ac9427051b..76f9479254f 100644 --- a/cli/azd/internal/scaffold/spec_service_binding.go +++ b/cli/azd/internal/scaffold/spec_service_binding.go @@ -563,6 +563,10 @@ func GetServiceBindingEnvsForEventHubsKafka(eventHubs AzureDepEventHubs) ([]Env, Name: "spring.cloud.stream.kafka.binder.brokers", Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), }, + { + Name: "spring.kafka.bootstrap-servers", + Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), + }, { Name: "spring.cloud.azure.eventhubs.credential.managed-identity-enabled", Value: "true", @@ -578,6 +582,10 @@ func GetServiceBindingEnvsForEventHubsKafka(eventHubs AzureDepEventHubs) ([]Env, Name: "spring.cloud.stream.kafka.binder.brokers", Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), }, + { + Name: "spring.kafka.bootstrap-servers", + Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), + }, { Name: "spring.cloud.azure.eventhubs.connection-string", Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeConnectionString), From 2e3d79619692165ad5cbfc5745a0e853c06495e9 Mon Sep 17 00:00:00 2001 From: haozhang Date: Thu, 19 Dec 2024 14:19:14 +0800 Subject: [PATCH 02/15] remove spring-kafka env var --- cli/azd/internal/scaffold/spec_service_binding.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cli/azd/internal/scaffold/spec_service_binding.go b/cli/azd/internal/scaffold/spec_service_binding.go index 18c74ea5761..5b48c878d41 100644 --- a/cli/azd/internal/scaffold/spec_service_binding.go +++ b/cli/azd/internal/scaffold/spec_service_binding.go @@ -579,10 +579,6 @@ func GetServiceBindingEnvsForEventHubsKafka(eventHubs AzureDepEventHubs) ([]Env, Name: "spring.cloud.stream.kafka.binder.brokers", Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), }, - { - Name: "spring.kafka.bootstrap-servers", - Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), - }, { Name: "spring.cloud.azure.eventhubs.credential.managed-identity-enabled", Value: "true", @@ -598,10 +594,6 @@ func GetServiceBindingEnvsForEventHubsKafka(eventHubs AzureDepEventHubs) ([]Env, Name: "spring.cloud.stream.kafka.binder.brokers", Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), }, - { - Name: "spring.kafka.bootstrap-servers", - Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeEndpoint), - }, { Name: "spring.cloud.azure.eventhubs.connection-string", Value: ToServiceBindingEnvValue(ServiceTypeMessagingEventHubs, ServiceBindingInfoTypeConnectionString), From daa8fa87844f9e597eef83cd85118a7739d0f7dd Mon Sep 17 00:00:00 2001 From: haozhang Date: Thu, 19 Dec 2024 14:33:35 +0800 Subject: [PATCH 03/15] cspell fix --- cli/azd/internal/appdetect/spring_boot.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index 87a17e3e271..a2c3ad79320 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -240,7 +240,7 @@ func detectEventHubsAccordingToSpringIntegrationEventhubsDependency( var targetArtifactId = "spring-cloud-azure-starter-integration-eventhubs" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ - // eventhubs name is empty here because no autoconfigured property + // eventhubs name is empty here because no configured property UseKafka: false, FromDependency: SpringIntegrationEventHubs, } @@ -255,7 +255,7 @@ func detectEventHubsAccordingToSpringMessagingEventhubsDependency( var targetArtifactId = "spring-messaging-azure-eventhubs" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ - // eventhubs name is empty here because no autoconfigured property + // eventhubs name is empty here because no configured property UseKafka: false, FromDependency: SpringMessagingEventHubs, } @@ -290,7 +290,7 @@ func detectEventHubsAccordingToSpringKafkaDependency(azdProject *Project, spring var targetArtifactId = "spring-kafka" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ - // eventhubs name is empty here because no autoconfigured property + // eventhubs name is empty here because no configured property UseKafka: true, SpringBootVersion: springBootProject.springBootVersion, FromDependency: SpringMessagingEventHubs, From 71240e773bb0e944b5f9466858610c2a9f50acd8 Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 24 Dec 2024 16:17:55 +0800 Subject: [PATCH 04/15] fix comments --- cli/azd/internal/appdetect/appdetect.go | 16 +-- cli/azd/internal/appdetect/spring_boot.go | 121 +++++++++------------- cli/azd/internal/repository/app_init.go | 4 +- 3 files changed, 59 insertions(+), 82 deletions(-) diff --git a/cli/azd/internal/appdetect/appdetect.go b/cli/azd/internal/appdetect/appdetect.go index 73fd958e968..c8ed0f9f61b 100644 --- a/cli/azd/internal/appdetect/appdetect.go +++ b/cli/azd/internal/appdetect/appdetect.go @@ -154,20 +154,20 @@ func (a AzureDepServiceBus) ResourceDisplay() string { type AzureDepEventHubs struct { EventHubsNamePropertyMap map[string]string - FromDependency FromDependency + MavenDependencyType MavenDependencyType UseKafka bool SpringBootVersion string } -type FromDependency string +type MavenDependencyType string const ( - SpringCloudStreamEventHubs = "spring-cloud-azure-stream-binder-eventhubs" - SpringCloudEventHubsStarter = "spring-cloud-azure-starter-eventhubs" - SpringIntegrationEventHubs = "spring-cloud-azure-starter-integration-eventhubs" - SpringMessagingEventHubs = "spring-messaging-azure-eventhubs" - SpringCloudStreamKafka = "spring-cloud-starter-stream-kafka" - SpringKafka = "spring-kafka" + SpringCloudStreamEventHubs MavenDependencyType = "spring-cloud-azure-stream-binder-eventhubs" + SpringCloudEventHubsStarter MavenDependencyType = "spring-cloud-azure-starter-eventhubs" + SpringIntegrationEventHubs MavenDependencyType = "spring-cloud-azure-starter-integration-eventhubs" + SpringMessagingEventHubs MavenDependencyType = "spring-messaging-azure-eventhubs" + SpringCloudStreamKafka MavenDependencyType = "spring-cloud-starter-stream-kafka" + SpringKafka MavenDependencyType = "spring-kafka" ) func (a AzureDepEventHubs) ResourceDisplay() string { diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index a2c3ad79320..fb2f6cfbbb4 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -185,11 +185,11 @@ func detectServiceBusAccordingToSpringCloudStreamBinderMavenDependency( func detectEventHubs(azdProject *Project, springBootProject *SpringBootProject) { // we need to figure out multiple projects are using the same event hub detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency(azdProject, springBootProject) - detectEventHubsAccordingToSpringCloudEventhubsStarterDependency(azdProject, springBootProject) - detectEventHubsAccordingToSpringIntegrationEventhubsDependency(azdProject, springBootProject) - detectEventHubsAccordingToSpringMessagingEventhubsDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringCloudEventhubsStarterMavenDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringIntegrationEventhubsMavenDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringMessagingEventhubsMavenDependency(azdProject, springBootProject) detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency(azdProject, springBootProject) - detectEventHubsAccordingToSpringKafkaDependency(azdProject, springBootProject) + detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject, springBootProject) } func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( @@ -201,7 +201,7 @@ func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, UseKafka: false, - FromDependency: SpringCloudStreamEventHubs, + MavenDependencyType: SpringCloudStreamEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -212,7 +212,7 @@ func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( } } -func detectEventHubsAccordingToSpringCloudEventhubsStarterDependency( +func detectEventHubsAccordingToSpringCloudEventhubsStarterMavenDependency( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-cloud-azure-starter-eventhubs" @@ -224,7 +224,7 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: eventHubsNamePropertyMap, UseKafka: false, - FromDependency: SpringCloudEventHubsStarter, + MavenDependencyType: SpringCloudEventHubsStarter, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -234,30 +234,30 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterDependency( } } -func detectEventHubsAccordingToSpringIntegrationEventhubsDependency( +func detectEventHubsAccordingToSpringIntegrationEventhubsMavenDependency( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-cloud-azure-starter-integration-eventhubs" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property - UseKafka: false, - FromDependency: SpringIntegrationEventHubs, + UseKafka: false, + MavenDependencyType: SpringIntegrationEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) } } -func detectEventHubsAccordingToSpringMessagingEventhubsDependency( +func detectEventHubsAccordingToSpringMessagingEventhubsMavenDependency( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-messaging-azure-eventhubs" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property - UseKafka: false, - FromDependency: SpringMessagingEventHubs, + UseKafka: false, + MavenDependencyType: SpringMessagingEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -274,7 +274,7 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( EventHubsNamePropertyMap: bindingDestinations, UseKafka: true, SpringBootVersion: springBootProject.springBootVersion, - FromDependency: SpringCloudStreamKafka, + MavenDependencyType: SpringCloudStreamKafka, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -285,15 +285,15 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( } } -func detectEventHubsAccordingToSpringKafkaDependency(azdProject *Project, springBootProject *SpringBootProject) { +func detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "org.springframework.kafka" var targetArtifactId = "spring-kafka" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property - UseKafka: true, - SpringBootVersion: springBootProject.springBootVersion, - FromDependency: SpringMessagingEventHubs, + UseKafka: true, + SpringBootVersion: springBootProject.springBootVersion, + MavenDependencyType: SpringMessagingEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -302,8 +302,8 @@ func detectEventHubsAccordingToSpringKafkaDependency(azdProject *Project, spring func detectStorageAccount(azdProject *Project, springBootProject *SpringBootProject) { detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndProperty(azdProject, springBootProject) - detectStorageAccountAccordingToSpringIntegrationEventhubsDependencyAndProperty(azdProject, springBootProject) - detectStorageAccountAccordingToSpringMessagingEventhubsDependencyAndProperty(azdProject, springBootProject) + detectStorageAccountAccordingToSpringIntegrationEventhubsMavenDependencyAndProperty(azdProject, springBootProject) + detectStorageAccountAccordingToSpringMessagingEventhubsMavenDependencyAndProperty(azdProject, springBootProject) } func detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndProperty( @@ -321,76 +321,53 @@ func detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndPro } } if containsInBindingName != "" { - containerNamePropertyMap := make(map[string]string) - for key, value := range springBootProject.applicationProperties { - if strings.HasSuffix(key, targetPropertyName) { - containerNamePropertyMap[key] = value - } - } - if len(containerNamePropertyMap) > 0 { - newDep := AzureDepStorageAccount{ - ContainerNamePropertyMap: containerNamePropertyMap, - } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) - logServiceAddedAccordingToMavenDependencyAndExtraCondition(newDep.ResourceDisplay(), targetGroupId, - targetArtifactId, "binding name ["+containsInBindingName+"] contains '-in-'") - for property, containerName := range containerNamePropertyMap { - log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", - containerName, property) - } - } + detectStorageAccountAccordingToProperty(azdProject, springBootProject.applicationProperties, + targetGroupId, targetArtifactId, targetPropertyName, + "binding name ["+containsInBindingName+"] contains '-in-'") } } } -func detectStorageAccountAccordingToSpringIntegrationEventhubsDependencyAndProperty( +func detectStorageAccountAccordingToSpringIntegrationEventhubsMavenDependencyAndProperty( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-cloud-azure-starter-integration-eventhubs" var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { - containerNamePropertyMap := make(map[string]string) - for key, value := range springBootProject.applicationProperties { - if strings.HasSuffix(key, targetPropertyName) { - containerNamePropertyMap[key] = value - } - } - if len(containerNamePropertyMap) > 0 { - newDep := AzureDepStorageAccount{ - ContainerNamePropertyMap: containerNamePropertyMap, - } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) - logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) - for property, containerName := range containerNamePropertyMap { - log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", - containerName, property) - } - } + detectStorageAccountAccordingToProperty(azdProject, springBootProject.applicationProperties, + targetGroupId, targetArtifactId, targetPropertyName, "") } } -func detectStorageAccountAccordingToSpringMessagingEventhubsDependencyAndProperty( +func detectStorageAccountAccordingToSpringMessagingEventhubsMavenDependencyAndProperty( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-messaging-azure-eventhubs" var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { - containerNamePropertyMap := make(map[string]string) - for key, value := range springBootProject.applicationProperties { - if strings.HasSuffix(key, targetPropertyName) { - containerNamePropertyMap[key] = value - } + detectStorageAccountAccordingToProperty(azdProject, springBootProject.applicationProperties, + targetGroupId, targetArtifactId, targetPropertyName, "") + } +} + +func detectStorageAccountAccordingToProperty(azdProject *Project, applicationProperties map[string]string, + targetGroupId string, targetArtifactId string, targetPropertyName string, extraCondition string) { + containerNamePropertyMap := make(map[string]string) + for key, value := range applicationProperties { + if strings.HasSuffix(key, targetPropertyName) { + containerNamePropertyMap[key] = value } - if len(containerNamePropertyMap) > 0 { - newDep := AzureDepStorageAccount{ - ContainerNamePropertyMap: containerNamePropertyMap, - } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) - logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) - for property, containerName := range containerNamePropertyMap { - log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", - containerName, property) - } + } + if len(containerNamePropertyMap) > 0 { + newDep := AzureDepStorageAccount{ + ContainerNamePropertyMap: containerNamePropertyMap, + } + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + logServiceAddedAccordingToMavenDependencyAndExtraCondition(newDep.ResourceDisplay(), targetGroupId, + targetArtifactId, extraCondition) + for property, containerName := range containerNamePropertyMap { + log.Printf(" Detected Storage container name: [%s] for [%s] by analyzing property file.", + containerName, property) } } } diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 43d60c096c5..52f9724e81a 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -1113,7 +1113,7 @@ func promptSpringBootVersion(console input.Console, ctx context.Context) (string } func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context, eventHubs *appdetect.AzureDepEventHubs) { - switch eventHubs.FromDependency { + switch eventHubs.MavenDependencyType { case appdetect.SpringIntegrationEventHubs, appdetect.SpringMessagingEventHubs, appdetect.SpringKafka: eventHubsName, err := promptEventHubsName(console, ctx) if err != nil { @@ -1121,7 +1121,7 @@ func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context os.Exit(-1) } eventHubs.EventHubsNamePropertyMap = map[string]string{ - string(eventHubs.FromDependency): eventHubsName, + string(eventHubs.MavenDependencyType): eventHubsName, } case appdetect.SpringCloudStreamEventHubs, appdetect.SpringCloudStreamKafka: promptMissingPropertyAndExit(console, ctx, "spring.cloud.stream.bindings..destination") From 16be768eecad00d018214d244f4ee85a964a5078 Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 24 Dec 2024 16:33:18 +0800 Subject: [PATCH 05/15] update hint message --- cli/azd/internal/repository/app_init.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 52f9724e81a..d9ac6e2f83b 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -1150,7 +1150,8 @@ func promptEventHubsName(console input.Console, ctx context.Context) (string, er if IsValidEventhubsName(eventHubsName) { return eventHubsName, nil } else { - console.Message(ctx, "Invalid eventhubs name. Please choose another name.") + console.Message(ctx, "Invalid eventhubs name. it can contain letters, numbers, periods (.), "+ + "hyphens (-), underscores (_), must begin and end with a letter or number. Please choose another name.") } } } From 828b41561bf9f40e8144313aa88ba3056e5a6645 Mon Sep 17 00:00:00 2001 From: haozhang Date: Wed, 25 Dec 2024 13:05:39 +0800 Subject: [PATCH 06/15] support input multiple eventhubs name --- cli/azd/internal/appdetect/spring_boot.go | 17 ++++++----- cli/azd/internal/repository/app_init.go | 37 +++++++++++++++-------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index fb2f6cfbbb4..8ef28eef88b 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -241,8 +241,9 @@ func detectEventHubsAccordingToSpringIntegrationEventhubsMavenDependency( if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property - UseKafka: false, - MavenDependencyType: SpringIntegrationEventHubs, + EventHubsNamePropertyMap: map[string]string{}, + UseKafka: false, + MavenDependencyType: SpringIntegrationEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -256,8 +257,9 @@ func detectEventHubsAccordingToSpringMessagingEventhubsMavenDependency( if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property - UseKafka: false, - MavenDependencyType: SpringMessagingEventHubs, + EventHubsNamePropertyMap: map[string]string{}, + UseKafka: false, + MavenDependencyType: SpringMessagingEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -291,9 +293,10 @@ func detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject *Project, s if hasDependency(springBootProject, targetGroupId, targetArtifactId) { newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property - UseKafka: true, - SpringBootVersion: springBootProject.springBootVersion, - MavenDependencyType: SpringMessagingEventHubs, + EventHubsNamePropertyMap: map[string]string{}, + UseKafka: true, + SpringBootVersion: springBootProject.springBootVersion, + MavenDependencyType: SpringMessagingEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index d9ac6e2f83b..60abff2e849 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -8,6 +8,7 @@ import ( "path/filepath" "regexp" "slices" + "strconv" "strings" "time" @@ -1115,13 +1116,14 @@ func promptSpringBootVersion(console input.Console, ctx context.Context) (string func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context, eventHubs *appdetect.AzureDepEventHubs) { switch eventHubs.MavenDependencyType { case appdetect.SpringIntegrationEventHubs, appdetect.SpringMessagingEventHubs, appdetect.SpringKafka: - eventHubsName, err := promptEventHubsName(console, ctx) + eventHubsNames, err := promptEventHubsNames(console, ctx) if err != nil { console.Message(ctx, fmt.Sprintf("Error happened when prompt eventhubs name: %s.", err)) os.Exit(-1) } - eventHubs.EventHubsNamePropertyMap = map[string]string{ - string(eventHubs.MavenDependencyType): eventHubsName, + for i, eventHubsName := range eventHubsNames { + propertyName := string(eventHubs.MavenDependencyType) + strconv.Itoa(i) + eventHubs.EventHubsNamePropertyMap[propertyName] = eventHubsName } case appdetect.SpringCloudStreamEventHubs, appdetect.SpringCloudStreamKafka: promptMissingPropertyAndExit(console, ctx, "spring.cloud.stream.bindings..destination") @@ -1138,20 +1140,29 @@ func promptMissingPropertyAndExit(console input.Console, ctx context.Context, ke os.Exit(0) } -func promptEventHubsName(console input.Console, ctx context.Context) (string, error) { +func promptEventHubsNames(console input.Console, ctx context.Context) ([]string, error) { for { - eventHubsName, err := console.Prompt(ctx, input.ConsoleOptions{ - Message: "Input the name of Azure EventHubs (Not EventHubs namespace name):", - Help: "Hint: Azure EventHubs Name, not EventHubs namespace name", + eventHubsNamesInput, err := console.Prompt(ctx, input.ConsoleOptions{ + Message: "Input the names of Azure Event Hubs (not the namespace name), " + + "if you have multiple ones, separate with commas:", + Help: "Hint: Azure Event Hubs Name, not the namespace name", }) if err != nil { - return "", err + return []string{}, err } - if IsValidEventhubsName(eventHubsName) { - return eventHubsName, nil - } else { - console.Message(ctx, "Invalid eventhubs name. it can contain letters, numbers, periods (.), "+ - "hyphens (-), underscores (_), must begin and end with a letter or number. Please choose another name.") + eventHubsNames := strings.Split(eventHubsNamesInput, ",") + allValidEventHubsNames := true + for i, eventHubsName := range eventHubsNames { + eventHubsNames[i] = strings.TrimSpace(eventHubsName) + if !IsValidEventhubsName(eventHubsNames[i]) { + console.Message(ctx, "Invalid eventhubs name. it should contain letters, numbers, periods (.), "+ + "hyphens (-), underscores (_), must begin and end with a letter or number. Please choose another name:") + allValidEventHubsNames = false + break + } + } + if allValidEventHubsNames { + return eventHubsNames, nil } } } From 7dec783613b07c344cb5a21f9e53c26df663526c Mon Sep 17 00:00:00 2001 From: haozhang Date: Wed, 25 Dec 2024 13:22:38 +0800 Subject: [PATCH 07/15] detect multiple azure event hubs properties, see https://learn.microsoft.com/azure/developer/java/spring-framework/configuration-properties-azure-event-hubs --- cli/azd/internal/appdetect/spring_boot.go | 16 +++++++++++++--- cli/azd/internal/repository/app_init.go | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index 8ef28eef88b..54606da60a1 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -216,10 +216,20 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterMavenDependency( azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-cloud-azure-starter-eventhubs" - var targetPropertyName = "spring.cloud.azure.eventhubs.event-hub-name" + // event-hub-name can be specified in different levels, see + // https://learn.microsoft.com/azure/developer/java/spring-framework/configuration-properties-azure-event-hubs + var targetPropertyNames = []string{ + "spring.cloud.azure.eventhubs.event-hub-name", + "spring.cloud.azure.eventhubs.producer.event-hub-name", + "spring.cloud.azure.eventhubs.consumer.event-hub-name", + "spring.cloud.azure.eventhubs.processor.event-hub-name", + } if hasDependency(springBootProject, targetGroupId, targetArtifactId) { - eventHubsNamePropertyMap := map[string]string{ - targetPropertyName: springBootProject.applicationProperties[targetPropertyName], + eventHubsNamePropertyMap := map[string]string{} + for _, propertyName := range targetPropertyNames { + if propertyValue, ok := springBootProject.applicationProperties[propertyName]; ok { + eventHubsNamePropertyMap[propertyName] = propertyValue + } } newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: eventHubsNamePropertyMap, diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 60abff2e849..9daeb895f40 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -1129,7 +1129,8 @@ func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context promptMissingPropertyAndExit(console, ctx, "spring.cloud.stream.bindings..destination") os.Exit(0) case appdetect.SpringCloudEventHubsStarter: - promptMissingPropertyAndExit(console, ctx, "spring.cloud.azure.eventhubs.event-hub-name") + promptMissingPropertyAndExit(console, ctx, "spring.cloud.azure.eventhubs.event-hub-name or "+ + "spring.cloud.azure.eventhubs.[producer|consumer|processor].event-hub-name") os.Exit(0) } } From caac249c73dcc7c2bb8d8d078fb420d4b4b38789 Mon Sep 17 00:00:00 2001 From: haozhang Date: Mon, 30 Dec 2024 14:54:19 +0800 Subject: [PATCH 08/15] add comment --- cli/azd/internal/repository/app_init.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 57c22149556..014dd63d73d 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -1147,6 +1147,7 @@ func promptMissingPropertyAndExit(console input.Console, ctx context.Context, ke os.Exit(0) } +// todo: delete this after we implement to detect eventhubs names from code func promptEventHubsNames(console input.Console, ctx context.Context) ([]string, error) { for { eventHubsNamesInput, err := console.Prompt(ctx, input.ConsoleOptions{ From 1054e7ebc5534e7ef14b733d63491564af52ee4c Mon Sep 17 00:00:00 2001 From: haozhang Date: Mon, 30 Dec 2024 16:43:35 +0800 Subject: [PATCH 09/15] small fix --- cli/azd/internal/appdetect/spring_boot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index 3cc75f02fec..c8e2bcc1d1b 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -300,7 +300,7 @@ func detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject *Project, s // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, UseKafka: true, - SpringBootVersion: springBootProject.springBootVersion, + SpringBootVersion: detectSpringBootVersion(springBootProject.pom), MavenDependencyType: SpringMessagingEventHubs, } azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) From 3bfa597205aecd44aec8c5c8b637523c0b7d15a4 Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 31 Dec 2024 14:19:50 +0800 Subject: [PATCH 10/15] multiple FromDependency and only one event hubs --- cli/azd/internal/appdetect/appdetect.go | 16 ++++---- cli/azd/internal/appdetect/spring_boot.go | 45 +++++++++++++++++------ cli/azd/internal/repository/app_init.go | 40 ++++++++++---------- 3 files changed, 62 insertions(+), 39 deletions(-) diff --git a/cli/azd/internal/appdetect/appdetect.go b/cli/azd/internal/appdetect/appdetect.go index ed4b74dcf69..bc054afe444 100644 --- a/cli/azd/internal/appdetect/appdetect.go +++ b/cli/azd/internal/appdetect/appdetect.go @@ -156,20 +156,20 @@ func (a AzureDepServiceBus) ResourceDisplay() string { type AzureDepEventHubs struct { EventHubsNamePropertyMap map[string]string - MavenDependencyType MavenDependencyType + FromDependency []DependencyType UseKafka bool SpringBootVersion string } -type MavenDependencyType string +type DependencyType string const ( - SpringCloudStreamEventHubs MavenDependencyType = "spring-cloud-azure-stream-binder-eventhubs" - SpringCloudEventHubsStarter MavenDependencyType = "spring-cloud-azure-starter-eventhubs" - SpringIntegrationEventHubs MavenDependencyType = "spring-cloud-azure-starter-integration-eventhubs" - SpringMessagingEventHubs MavenDependencyType = "spring-messaging-azure-eventhubs" - SpringCloudStreamKafka MavenDependencyType = "spring-cloud-starter-stream-kafka" - SpringKafka MavenDependencyType = "spring-kafka" + SpringCloudStreamEventHubs DependencyType = "spring-cloud-azure-stream-binder-eventhubs" + SpringCloudEventHubsStarter DependencyType = "spring-cloud-azure-starter-eventhubs" + SpringIntegrationEventHubs DependencyType = "spring-cloud-azure-starter-integration-eventhubs" + SpringMessagingEventHubs DependencyType = "spring-messaging-azure-eventhubs" + SpringCloudStreamKafka DependencyType = "spring-cloud-starter-stream-kafka" + SpringKafka DependencyType = "spring-kafka" ) func (a AzureDepEventHubs) ResourceDisplay() string { diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index c8e2bcc1d1b..bb9b870b98e 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -196,9 +196,9 @@ func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, UseKafka: false, - MavenDependencyType: SpringCloudStreamEventHubs, + FromDependency: []DependencyType{SpringCloudStreamEventHubs}, } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) for bindingName, destination := range bindingDestinations { log.Printf(" Detected Event Hub [%s] for binding [%s] by analyzing property file.", @@ -229,9 +229,9 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterMavenDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: eventHubsNamePropertyMap, UseKafka: false, - MavenDependencyType: SpringCloudEventHubsStarter, + FromDependency: []DependencyType{SpringCloudEventHubsStarter}, } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) for property, name := range eventHubsNamePropertyMap { log.Printf(" Detected Event Hub [%s] for [%s] by analyzing property file.", property, name) @@ -248,9 +248,9 @@ func detectEventHubsAccordingToSpringIntegrationEventhubsMavenDependency( // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, UseKafka: false, - MavenDependencyType: SpringIntegrationEventHubs, + FromDependency: []DependencyType{SpringIntegrationEventHubs}, } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) } } @@ -264,9 +264,9 @@ func detectEventHubsAccordingToSpringMessagingEventhubsMavenDependency( // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, UseKafka: false, - MavenDependencyType: SpringMessagingEventHubs, + FromDependency: []DependencyType{SpringMessagingEventHubs}, } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) } } @@ -281,9 +281,9 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( EventHubsNamePropertyMap: bindingDestinations, UseKafka: true, SpringBootVersion: detectSpringBootVersion(springBootProject.pom), - MavenDependencyType: SpringCloudStreamKafka, + FromDependency: []DependencyType{SpringCloudStreamKafka}, } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) for bindingName, destination := range bindingDestinations { log.Printf(" Detected Kafka Topic [%s] for binding [%s] by analyzing property file.", @@ -301,13 +301,34 @@ func detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject *Project, s EventHubsNamePropertyMap: map[string]string{}, UseKafka: true, SpringBootVersion: detectSpringBootVersion(springBootProject.pom), - MavenDependencyType: SpringMessagingEventHubs, + FromDependency: []DependencyType{SpringKafka}, } - azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) + addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) } } +func addAzureDepEventHubsIntoProject( + azdProject *Project, + newDep AzureDepEventHubs) { + for index, azureDep := range azdProject.AzureDeps { + if azureDep, ok := azureDep.(AzureDepEventHubs); ok { + // already have existing dependency + for property, eventHubsName := range newDep.EventHubsNamePropertyMap { + azureDep.EventHubsNamePropertyMap[property] = eventHubsName + } + azureDep.FromDependency = append(azureDep.FromDependency, newDep.FromDependency...) + azureDep.UseKafka = newDep.UseKafka + azureDep.SpringBootVersion = newDep.SpringBootVersion + azdProject.AzureDeps[index] = azureDep + return + } + } + + // add new dependency + azdProject.AzureDeps = append(azdProject.AzureDeps, newDep) +} + func detectStorageAccount(azdProject *Project, springBootProject *SpringBootProject) { detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndProperty(azdProject, springBootProject) detectStorageAccountAccordingToSpringIntegrationEventhubsMavenDependencyAndProperty(azdProject, springBootProject) diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 2647f56d71a..e93501b79c1 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -1127,24 +1127,26 @@ func promptSpringBootVersion(console input.Console, ctx context.Context) (string } func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context, eventHubs *appdetect.AzureDepEventHubs) { - switch eventHubs.MavenDependencyType { - case appdetect.SpringIntegrationEventHubs, appdetect.SpringMessagingEventHubs, appdetect.SpringKafka: - eventHubsNames, err := promptEventHubsNames(console, ctx) - if err != nil { - console.Message(ctx, fmt.Sprintf("Error happened when prompt eventhubs name: %s.", err)) - os.Exit(-1) - } - for i, eventHubsName := range eventHubsNames { - propertyName := string(eventHubs.MavenDependencyType) + strconv.Itoa(i) - eventHubs.EventHubsNamePropertyMap[propertyName] = eventHubsName + for _, fromDependency := range eventHubs.FromDependency { + switch fromDependency { + case appdetect.SpringIntegrationEventHubs, appdetect.SpringMessagingEventHubs, appdetect.SpringKafka: + eventHubsNames, err := promptEventHubsNames(console, ctx) + if err != nil { + console.Message(ctx, fmt.Sprintf("Error happened when prompt eventhubs name: %s.", err)) + os.Exit(-1) + } + for i, eventHubsName := range eventHubsNames { + propertyName := string(fromDependency) + strconv.Itoa(i) + eventHubs.EventHubsNamePropertyMap[propertyName] = eventHubsName + } + case appdetect.SpringCloudStreamEventHubs, appdetect.SpringCloudStreamKafka: + promptMissingPropertyAndExit(console, ctx, "spring.cloud.stream.bindings..destination") + os.Exit(0) + case appdetect.SpringCloudEventHubsStarter: + promptMissingPropertyAndExit(console, ctx, "spring.cloud.azure.eventhubs.event-hub-name or "+ + "spring.cloud.azure.eventhubs.[producer|consumer|processor].event-hub-name") + os.Exit(0) } - case appdetect.SpringCloudStreamEventHubs, appdetect.SpringCloudStreamKafka: - promptMissingPropertyAndExit(console, ctx, "spring.cloud.stream.bindings..destination") - os.Exit(0) - case appdetect.SpringCloudEventHubsStarter: - promptMissingPropertyAndExit(console, ctx, "spring.cloud.azure.eventhubs.event-hub-name or "+ - "spring.cloud.azure.eventhubs.[producer|consumer|processor].event-hub-name") - os.Exit(0) } } @@ -1169,7 +1171,7 @@ func promptEventHubsNames(console input.Console, ctx context.Context) ([]string, allValidEventHubsNames := true for i, eventHubsName := range eventHubsNames { eventHubsNames[i] = strings.TrimSpace(eventHubsName) - if !IsValidEventhubsName(eventHubsNames[i]) { + if !isValidEventhubsName(eventHubsNames[i]) { console.Message(ctx, "Invalid eventhubs name. it should contain letters, numbers, periods (.), "+ "hyphens (-), underscores (_), must begin and end with a letter or number. Please choose another name:") allValidEventHubsNames = false @@ -1186,7 +1188,7 @@ func promptEventHubsNames(console input.Console, ctx context.Context) ([]string, // must begin and end with a letter or number var eventHubsNameRegex = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$`) -func IsValidEventhubsName(name string) bool { +func isValidEventhubsName(name string) bool { // up to 256 characters if len(name) == 0 || len(name) > 256 { return false From 54741e7038d17773d74995304ecb68df63fcc9cd Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 31 Dec 2024 15:25:58 +0800 Subject: [PATCH 11/15] remove redundant cases --- cli/azd/internal/appdetect/appdetect_test.go | 78 -------------------- 1 file changed, 78 deletions(-) diff --git a/cli/azd/internal/appdetect/appdetect_test.go b/cli/azd/internal/appdetect/appdetect_test.go index a5c5f6cc3a9..8ae8e2c5f94 100644 --- a/cli/azd/internal/appdetect/appdetect_test.go +++ b/cli/azd/internal/appdetect/appdetect_test.go @@ -173,32 +173,6 @@ func TestDetect(t *testing.T) { JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java", "mvnw.cmd"), }, }, - { - Language: Java, - Path: "java-multi-levels/submodule/subsubmodule1", - DetectionRule: "Inferred by presence of: pom.xml", - Metadata: Metadata{ - ApplicationName: "subsubmodule1", - }, - Options: map[string]interface{}{ - JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), - JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), - JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), - }, - }, - { - Language: Java, - Path: "java-multi-levels/submodule/subsubmodule2", - DetectionRule: "Inferred by presence of: pom.xml", - Metadata: Metadata{ - ApplicationName: "subsubmodule2", - }, - Options: map[string]interface{}{ - JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), - JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), - JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), - }, - }, { Language: Java, Path: "java-multimodules/application", @@ -249,32 +223,6 @@ func TestDetect(t *testing.T) { JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java", "mvnw.cmd"), }, }, - { - Language: Java, - Path: "java-multi-levels/submodule/subsubmodule1", - DetectionRule: "Inferred by presence of: pom.xml", - Metadata: Metadata{ - ApplicationName: "subsubmodule1", - }, - Options: map[string]interface{}{ - JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), - JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), - JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), - }, - }, - { - Language: Java, - Path: "java-multi-levels/submodule/subsubmodule2", - DetectionRule: "Inferred by presence of: pom.xml", - Metadata: Metadata{ - ApplicationName: "subsubmodule2", - }, - Options: map[string]interface{}{ - JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), - JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), - JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), - }, - }, { Language: Java, Path: "java-multimodules/application", @@ -328,32 +276,6 @@ func TestDetect(t *testing.T) { JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java", "mvnw.cmd"), }, }, - { - Language: Java, - Path: "java-multi-levels/submodule/subsubmodule1", - DetectionRule: "Inferred by presence of: pom.xml", - Metadata: Metadata{ - ApplicationName: "subsubmodule1", - }, - Options: map[string]interface{}{ - JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), - JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), - JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), - }, - }, - { - Language: Java, - Path: "java-multi-levels/submodule/subsubmodule2", - DetectionRule: "Inferred by presence of: pom.xml", - Metadata: Metadata{ - ApplicationName: "subsubmodule2", - }, - Options: map[string]interface{}{ - JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), - JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), - JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), - }, - }, { Language: Java, Path: "java-multimodules/application", From 2912464cee7eadb5cce43673716e35bf6b664afb Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 31 Dec 2024 15:52:58 +0800 Subject: [PATCH 12/15] replace `UseKafka` property --- cli/azd/internal/appdetect/appdetect.go | 10 +++++++++- cli/azd/internal/appdetect/spring_boot.go | 7 ------- cli/azd/internal/repository/app_init.go | 8 ++++---- cli/azd/internal/repository/infra_confirm.go | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/cli/azd/internal/appdetect/appdetect.go b/cli/azd/internal/appdetect/appdetect.go index bc054afe444..6073e47957a 100644 --- a/cli/azd/internal/appdetect/appdetect.go +++ b/cli/azd/internal/appdetect/appdetect.go @@ -157,7 +157,6 @@ func (a AzureDepServiceBus) ResourceDisplay() string { type AzureDepEventHubs struct { EventHubsNamePropertyMap map[string]string FromDependency []DependencyType - UseKafka bool SpringBootVersion string } @@ -172,6 +171,15 @@ const ( SpringKafka DependencyType = "spring-kafka" ) +func (a AzureDepEventHubs) UseKafka() bool { + for _, dep := range a.FromDependency { + if dep == SpringCloudStreamKafka || dep == SpringKafka { + return true + } + } + return false +} + func (a AzureDepEventHubs) ResourceDisplay() string { return "Azure Event Hubs" } diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index bb9b870b98e..19464e41e2c 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -195,7 +195,6 @@ func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( bindingDestinations := getBindingDestinationMap(springBootProject.applicationProperties) newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, - UseKafka: false, FromDependency: []DependencyType{SpringCloudStreamEventHubs}, } addAzureDepEventHubsIntoProject(azdProject, newDep) @@ -228,7 +227,6 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterMavenDependency( } newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: eventHubsNamePropertyMap, - UseKafka: false, FromDependency: []DependencyType{SpringCloudEventHubsStarter}, } addAzureDepEventHubsIntoProject(azdProject, newDep) @@ -247,7 +245,6 @@ func detectEventHubsAccordingToSpringIntegrationEventhubsMavenDependency( newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, - UseKafka: false, FromDependency: []DependencyType{SpringIntegrationEventHubs}, } addAzureDepEventHubsIntoProject(azdProject, newDep) @@ -263,7 +260,6 @@ func detectEventHubsAccordingToSpringMessagingEventhubsMavenDependency( newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, - UseKafka: false, FromDependency: []DependencyType{SpringMessagingEventHubs}, } addAzureDepEventHubsIntoProject(azdProject, newDep) @@ -279,7 +275,6 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( bindingDestinations := getBindingDestinationMap(springBootProject.applicationProperties) newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, - UseKafka: true, SpringBootVersion: detectSpringBootVersion(springBootProject.pom), FromDependency: []DependencyType{SpringCloudStreamKafka}, } @@ -299,7 +294,6 @@ func detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject *Project, s newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, - UseKafka: true, SpringBootVersion: detectSpringBootVersion(springBootProject.pom), FromDependency: []DependencyType{SpringKafka}, } @@ -318,7 +312,6 @@ func addAzureDepEventHubsIntoProject( azureDep.EventHubsNamePropertyMap[property] = eventHubsName } azureDep.FromDependency = append(azureDep.FromDependency, newDep.FromDependency...) - azureDep.UseKafka = newDep.UseKafka azureDep.SpringBootVersion = newDep.SpringBootVersion azdProject.AzureDeps[index] = azureDep return diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index e93501b79c1..3288e9cbb5a 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -143,7 +143,7 @@ func (i *Initializer) InitFromApp( for depIndex, dep := range prj.AzureDeps { if eventHubs, ok := dep.(appdetect.AzureDepEventHubs); ok { // prompt spring boot version if not detected for kafka - if eventHubs.UseKafka { + if eventHubs.UseKafka() { hasKafkaDep = true springBootVersion := eventHubs.SpringBootVersion if springBootVersion == appdetect.UnknownSpringBootVersion { @@ -705,7 +705,7 @@ func (i *Initializer) prjConfigFromDetect( }, } case appdetect.AzureDepEventHubs: - if azureDep.UseKafka { + if azureDep.UseKafka() { config.Resources["kafka"] = &project.ResourceConfig{ Type: project.ResourceTypeMessagingKafka, Props: project.KafkaProps{ @@ -776,7 +776,7 @@ func (i *Initializer) prjConfigFromDetect( case appdetect.AzureDepServiceBus: resSpec.Uses = append(resSpec.Uses, "servicebus") case appdetect.AzureDepEventHubs: - if azureDep.UseKafka { + if azureDep.UseKafka() { resSpec.Uses = append(resSpec.Uses, "kafka") } else { resSpec.Uses = append(resSpec.Uses, "eventhubs") @@ -1094,7 +1094,7 @@ func processSpringCloudAzureDepByPrompt(console input.Console, ctx context.Conte // remove Kafka Azure Dep var result []appdetect.AzureDep for _, dep := range project.AzureDeps { - if eventHubs, ok := dep.(appdetect.AzureDepEventHubs); !(ok && eventHubs.UseKafka) { + if eventHubs, ok := dep.(appdetect.AzureDepEventHubs); !(ok && eventHubs.UseKafka()) { result = append(result, dep) } } diff --git a/cli/azd/internal/repository/infra_confirm.go b/cli/azd/internal/repository/infra_confirm.go index dec8e4303c0..e76244ec8f9 100644 --- a/cli/azd/internal/repository/infra_confirm.go +++ b/cli/azd/internal/repository/infra_confirm.go @@ -355,7 +355,7 @@ func (i *Initializer) buildInfraSpecByAzureDep( spec.AzureEventHubs = &scaffold.AzureDepEventHubs{ EventHubNames: appdetect.DistinctValues(dependency.EventHubsNamePropertyMap), AuthType: authType, - UseKafka: dependency.UseKafka, + UseKafka: dependency.UseKafka(), SpringBootVersion: dependency.SpringBootVersion, } case appdetect.AzureDepStorageAccount: From fab1a4168768783f2563c01321e54671895652ba Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 31 Dec 2024 15:54:39 +0800 Subject: [PATCH 13/15] rename as DependencyType --- cli/azd/internal/appdetect/appdetect.go | 6 +++--- cli/azd/internal/appdetect/spring_boot.go | 14 +++++++------- cli/azd/internal/repository/app_init.go | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cli/azd/internal/appdetect/appdetect.go b/cli/azd/internal/appdetect/appdetect.go index 6073e47957a..c7f8e6ebe48 100644 --- a/cli/azd/internal/appdetect/appdetect.go +++ b/cli/azd/internal/appdetect/appdetect.go @@ -156,7 +156,7 @@ func (a AzureDepServiceBus) ResourceDisplay() string { type AzureDepEventHubs struct { EventHubsNamePropertyMap map[string]string - FromDependency []DependencyType + DependencyTypes []DependencyType SpringBootVersion string } @@ -172,8 +172,8 @@ const ( ) func (a AzureDepEventHubs) UseKafka() bool { - for _, dep := range a.FromDependency { - if dep == SpringCloudStreamKafka || dep == SpringKafka { + for _, dependencyType := range a.DependencyTypes { + if dependencyType == SpringCloudStreamKafka || dependencyType == SpringKafka { return true } } diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index 19464e41e2c..d643d149e0a 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -195,7 +195,7 @@ func detectEventHubsAccordingToSpringCloudStreamBinderMavenDependency( bindingDestinations := getBindingDestinationMap(springBootProject.applicationProperties) newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, - FromDependency: []DependencyType{SpringCloudStreamEventHubs}, + DependencyTypes: []DependencyType{SpringCloudStreamEventHubs}, } addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -227,7 +227,7 @@ func detectEventHubsAccordingToSpringCloudEventhubsStarterMavenDependency( } newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: eventHubsNamePropertyMap, - FromDependency: []DependencyType{SpringCloudEventHubsStarter}, + DependencyTypes: []DependencyType{SpringCloudEventHubsStarter}, } addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -245,7 +245,7 @@ func detectEventHubsAccordingToSpringIntegrationEventhubsMavenDependency( newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, - FromDependency: []DependencyType{SpringIntegrationEventHubs}, + DependencyTypes: []DependencyType{SpringIntegrationEventHubs}, } addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -260,7 +260,7 @@ func detectEventHubsAccordingToSpringMessagingEventhubsMavenDependency( newDep := AzureDepEventHubs{ // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, - FromDependency: []DependencyType{SpringMessagingEventHubs}, + DependencyTypes: []DependencyType{SpringMessagingEventHubs}, } addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -276,7 +276,7 @@ func detectEventHubsAccordingToSpringCloudStreamKafkaMavenDependency( newDep := AzureDepEventHubs{ EventHubsNamePropertyMap: bindingDestinations, SpringBootVersion: detectSpringBootVersion(springBootProject.pom), - FromDependency: []DependencyType{SpringCloudStreamKafka}, + DependencyTypes: []DependencyType{SpringCloudStreamKafka}, } addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -295,7 +295,7 @@ func detectEventHubsAccordingToSpringKafkaMavenDependency(azdProject *Project, s // eventhubs name is empty here because no configured property EventHubsNamePropertyMap: map[string]string{}, SpringBootVersion: detectSpringBootVersion(springBootProject.pom), - FromDependency: []DependencyType{SpringKafka}, + DependencyTypes: []DependencyType{SpringKafka}, } addAzureDepEventHubsIntoProject(azdProject, newDep) logServiceAddedAccordingToMavenDependency(newDep.ResourceDisplay(), targetGroupId, targetArtifactId) @@ -311,7 +311,7 @@ func addAzureDepEventHubsIntoProject( for property, eventHubsName := range newDep.EventHubsNamePropertyMap { azureDep.EventHubsNamePropertyMap[property] = eventHubsName } - azureDep.FromDependency = append(azureDep.FromDependency, newDep.FromDependency...) + azureDep.DependencyTypes = append(azureDep.DependencyTypes, newDep.DependencyTypes...) azureDep.SpringBootVersion = newDep.SpringBootVersion azdProject.AzureDeps[index] = azureDep return diff --git a/cli/azd/internal/repository/app_init.go b/cli/azd/internal/repository/app_init.go index 3288e9cbb5a..3e4f69b427f 100644 --- a/cli/azd/internal/repository/app_init.go +++ b/cli/azd/internal/repository/app_init.go @@ -1127,8 +1127,8 @@ func promptSpringBootVersion(console input.Console, ctx context.Context) (string } func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context, eventHubs *appdetect.AzureDepEventHubs) { - for _, fromDependency := range eventHubs.FromDependency { - switch fromDependency { + for _, dependencyType := range eventHubs.DependencyTypes { + switch dependencyType { case appdetect.SpringIntegrationEventHubs, appdetect.SpringMessagingEventHubs, appdetect.SpringKafka: eventHubsNames, err := promptEventHubsNames(console, ctx) if err != nil { @@ -1136,7 +1136,7 @@ func promptMissingEventHubsNameOrExit(console input.Console, ctx context.Context os.Exit(-1) } for i, eventHubsName := range eventHubsNames { - propertyName := string(fromDependency) + strconv.Itoa(i) + propertyName := string(dependencyType) + strconv.Itoa(i) eventHubs.EventHubsNamePropertyMap[propertyName] = eventHubsName } case appdetect.SpringCloudStreamEventHubs, appdetect.SpringCloudStreamKafka: From 8748c9b8cafccb73cc555bc8d8a86031be5c5469 Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 31 Dec 2024 15:58:18 +0800 Subject: [PATCH 14/15] revert test cases --- cli/azd/internal/appdetect/appdetect_test.go | 78 ++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/cli/azd/internal/appdetect/appdetect_test.go b/cli/azd/internal/appdetect/appdetect_test.go index 8ae8e2c5f94..a5c5f6cc3a9 100644 --- a/cli/azd/internal/appdetect/appdetect_test.go +++ b/cli/azd/internal/appdetect/appdetect_test.go @@ -173,6 +173,32 @@ func TestDetect(t *testing.T) { JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java", "mvnw.cmd"), }, }, + { + Language: Java, + Path: "java-multi-levels/submodule/subsubmodule1", + DetectionRule: "Inferred by presence of: pom.xml", + Metadata: Metadata{ + ApplicationName: "subsubmodule1", + }, + Options: map[string]interface{}{ + JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), + JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), + JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), + }, + }, + { + Language: Java, + Path: "java-multi-levels/submodule/subsubmodule2", + DetectionRule: "Inferred by presence of: pom.xml", + Metadata: Metadata{ + ApplicationName: "subsubmodule2", + }, + Options: map[string]interface{}{ + JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), + JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), + JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), + }, + }, { Language: Java, Path: "java-multimodules/application", @@ -223,6 +249,32 @@ func TestDetect(t *testing.T) { JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java", "mvnw.cmd"), }, }, + { + Language: Java, + Path: "java-multi-levels/submodule/subsubmodule1", + DetectionRule: "Inferred by presence of: pom.xml", + Metadata: Metadata{ + ApplicationName: "subsubmodule1", + }, + Options: map[string]interface{}{ + JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), + JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), + JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), + }, + }, + { + Language: Java, + Path: "java-multi-levels/submodule/subsubmodule2", + DetectionRule: "Inferred by presence of: pom.xml", + Metadata: Metadata{ + ApplicationName: "subsubmodule2", + }, + Options: map[string]interface{}{ + JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), + JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), + JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), + }, + }, { Language: Java, Path: "java-multimodules/application", @@ -276,6 +328,32 @@ func TestDetect(t *testing.T) { JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java", "mvnw.cmd"), }, }, + { + Language: Java, + Path: "java-multi-levels/submodule/subsubmodule1", + DetectionRule: "Inferred by presence of: pom.xml", + Metadata: Metadata{ + ApplicationName: "subsubmodule1", + }, + Options: map[string]interface{}{ + JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), + JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), + JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), + }, + }, + { + Language: Java, + Path: "java-multi-levels/submodule/subsubmodule2", + DetectionRule: "Inferred by presence of: pom.xml", + Metadata: Metadata{ + ApplicationName: "subsubmodule2", + }, + Options: map[string]interface{}{ + JavaProjectOptionParentPomDir: filepath.Join(dir, "java-multi-levels"), + JavaProjectOptionPosixMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw"), + JavaProjectOptionWinMavenWrapperPath: filepath.Join(dir, "java-multi-levels", "mvnw.cmd"), + }, + }, { Language: Java, Path: "java-multimodules/application", From 814b033d078fd7ab12cd66af24621215a2e888ac Mon Sep 17 00:00:00 2001 From: haozhang Date: Tue, 31 Dec 2024 16:03:01 +0800 Subject: [PATCH 15/15] Rename targetPropertyName to targetPropertyNameSuffix --- cli/azd/internal/appdetect/spring_boot.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cli/azd/internal/appdetect/spring_boot.go b/cli/azd/internal/appdetect/spring_boot.go index d643d149e0a..45660d21e55 100644 --- a/cli/azd/internal/appdetect/spring_boot.go +++ b/cli/azd/internal/appdetect/spring_boot.go @@ -332,7 +332,7 @@ func detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndPro azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-cloud-azure-stream-binder-eventhubs" - var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" + var targetPropertyNameSuffix = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { bindingDestinations := getBindingDestinationMap(springBootProject.applicationProperties) containsInBindingName := "" @@ -344,7 +344,7 @@ func detectStorageAccountAccordingToSpringCloudStreamBinderMavenDependencyAndPro } if containsInBindingName != "" { detectStorageAccountAccordingToProperty(azdProject, springBootProject.applicationProperties, - targetGroupId, targetArtifactId, targetPropertyName, + targetGroupId, targetArtifactId, targetPropertyNameSuffix, "binding name ["+containsInBindingName+"] contains '-in-'") } } @@ -354,10 +354,10 @@ func detectStorageAccountAccordingToSpringIntegrationEventhubsMavenDependencyAnd azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-cloud-azure-starter-integration-eventhubs" - var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" + var targetPropertyNameSuffix = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { detectStorageAccountAccordingToProperty(azdProject, springBootProject.applicationProperties, - targetGroupId, targetArtifactId, targetPropertyName, "") + targetGroupId, targetArtifactId, targetPropertyNameSuffix, "") } } @@ -365,18 +365,18 @@ func detectStorageAccountAccordingToSpringMessagingEventhubsMavenDependencyAndPr azdProject *Project, springBootProject *SpringBootProject) { var targetGroupId = "com.azure.spring" var targetArtifactId = "spring-messaging-azure-eventhubs" - var targetPropertyName = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" + var targetPropertyNameSuffix = "spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name" if hasDependency(springBootProject, targetGroupId, targetArtifactId) { detectStorageAccountAccordingToProperty(azdProject, springBootProject.applicationProperties, - targetGroupId, targetArtifactId, targetPropertyName, "") + targetGroupId, targetArtifactId, targetPropertyNameSuffix, "") } } func detectStorageAccountAccordingToProperty(azdProject *Project, applicationProperties map[string]string, - targetGroupId string, targetArtifactId string, targetPropertyName string, extraCondition string) { + targetGroupId string, targetArtifactId string, targetPropertyNameSuffix string, extraCondition string) { containerNamePropertyMap := make(map[string]string) for key, value := range applicationProperties { - if strings.HasSuffix(key, targetPropertyName) { + if strings.HasSuffix(key, targetPropertyNameSuffix) { containerNamePropertyMap[key] = value } }