Проблема с подтверждением связи Azure EventHub при автоматической настройке весенней загрузки

Я пишу приложение с использованием автоматической настройки Java Spring Boot, которое безуспешно пытается отправить сообщение в Azure EventHub с использованием SPN для аутентификации, поскольку у меня возникает проблема с сертификатом. Мой код выглядит следующим образом:

Среда:

Java 17
Spring Boot: solace-spring-boot-starter:2.0.0
Spring Azure: spring-cloud-azure-starter-integration-eventhubs:5.13.0

EventHubProducerService

package com.mysample.producer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.azure.messaging.eventhubs.EventData;
import com.azure.messaging.eventhubs.EventHubProducerClient;

import java.util.Collections;

@Service
public class EventHubProducerService {

    @Autowired
    private EventHubProducerClient producerClient;

    public void sendEventHubMessage(String message){
        producerClient.send(Collections.singletonList(new EventData(message)));
        log.info("message sent successfully to EventHub");
    }
}

application.yml

spring.cloud.azure:
  eventhubs:
    namespace: "<namespaceName>"
    eventHubName: "<eventHubName>"
  credential:
    client-id: "<SPN ClientId>"
    client-secret: "<SPN SecretValue>"
  profile:
    tenant-id: "<TenantId>"

При выполнении sendEventHubMessage("Hello World") возникает следующая ошибка:

2024-07-11T14:57:45.612-04:00  WARN 9632 --- [ctor-http-nio-1] r.netty.http.client.HttpClientConnect    : [330ebfae, L:/<ip>:<port> - R:login.microsoftonline.com/<ip>:443] The connection observed an error

javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.handshakeException(ReferenceCountedOpenSslEngine.java:1927) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.wrap(ReferenceCountedOpenSslEngine.java:848) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at java.base/javax.net.ssl.SSLEngine.wrap(SSLEngine.java:564) ~[na:na]
        at io.netty.handler.ssl.SslHandler.wrap(SslHandler.java:1129) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.wrapNonAppData(SslHandler.java:973) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1509) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.decodeNonJdkCompatible(SslHandler.java:1347) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1387) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530) ~[netty-codec-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) ~[netty-codec-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.111.Final.jar:4.1.111.Final]        
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]  
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]     
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994) ~[netty-common-4.1.111.Final.jar:4.1.111.Final] 
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.111.Final.jar:4.1.111.Final]        
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439) ~[na:na]
        at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306) ~[na:na]
        at java.base/sun.security.validator.Validator.validate(Validator.java:264) ~[na:na]
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:285) ~[na:na]
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144) ~[na:na]
        at io.netty.handler.ssl.EnhancingX509ExtendedTrustManager.checkServerTrusted(EnhancingX509ExtendedTrustManager.java:69) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback.verify(ReferenceCountedOpenSslClientContext.java:235) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:797) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.internal.tcnative.CertificateVerifierTask.runTask(CertificateVerifierTask.java:36) ~[netty-tcnative-classes-2.0.65.Final.jar:2.0.65.Final]
        at io.netty.internal.tcnative.SSLTask.run(SSLTask.java:48) ~[netty-tcnative-classes-2.0.65.Final.jar:2.0.65.Final]
        at io.netty.internal.tcnative.SSLTask.run(SSLTask.java:42) ~[netty-tcnative-classes-2.0.65.Final.jar:2.0.65.Final]
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.runAndResetNeedTask(ReferenceCountedOpenSslEngine.java:1533) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.access$700(ReferenceCountedOpenSslEngine.java:94) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.ReferenceCountedOpenSslEngine$TaskDecorator.run(ReferenceCountedOpenSslEngine.java:1505) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1649) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1495) ~[netty-handler-4.1.111.Final.jar:4.1.111.Final]
        ... 21 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[na:na]
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[na:na]
        at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) ~[na:na]
        at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434) ~[na:na]
        ... 36 common frames omitted

Есть идеи? если я подключаюсь к EvenHub с помощью строки подключения, все работает нормально, только когда я использую SPN, выдает ли мне эту ошибку, я полагаю, мне нужно получить сертификат где-то в Azure и импортировать его в Java-cacert?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь вам нужно изменить указанный выше application.yml формат файла, а также, кроме того, необходима небольшая корректировка, как вы можете проверить это, выполнив следующие шаги.

приложение.yml:

spring:
  cloud:
    azure:
      credential:
        client-id: "<SPN ClientId>"
        client-secret: "<SPN SecretValue>"
        tenant-id: "<TenantId>"
      eventhubs:
        namespace: "<namespaceName>"
        producer:
          event-hub-name: "<eventHubName>"
  • Имена ключей правильно согласованы со стартовыми свойствами Spring Cloud Azure EventHub.

Проверьте это приложение ниже, которое подбирает EventHub по классу конфигурации.

import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.messaging.eventhubs.EventHubProducerClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class EventHubConfig {

    @Value("${spring.cloud.azure.credential.client-id}")
    private String clientId;

    @Value("${spring.cloud.azure.credential.client-secret}")
    private String clientSecret;

    @Value("${spring.cloud.azure.credential.tenant-id}")
    private String tenantId;

    @Value("${spring.cloud.azure.eventhubs.namespace}")
    private String namespace;

    @Value("${spring.cloud.azure.eventhubs.producer.event-hub-name}")
    private String eventHubName;

    @Bean
    public EventHubProducerClient producerClient() {
        ClientSecretCredential credential = new ClientSecretCredentialBuilder()
            .clientId(clientId)
            .clientSecret(clientSecret)
            .tenantId(tenantId)
            .build();

        return new EventHubClientBuilder()
            .credential(namespace, eventHubName, credential)
            .buildProducerClient();
    }
}
  • Создайте класс конфигурации EventHubConfig для настройки клиента-производителя EventHub с использованием учетных данных SPN.

Дерево приложений:

my-spring-boot-app/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   ├── com/
│   │   │   │   ├── mysample/
│   │   │   │   │   ├── MySpringBootApplication.java
│   │   │   │   │   ├── config/
│   │   │   │   │   │   └── EventHubConfig.java
│   │   │   │   │   ├── consumer/
│   │   │   │   │   │   └── SomeClass.java
│   │   │   │   │   ├── producer/
│   │   │   │   │   │   └── EventHubProducerService.java
│   │   ├── resources/
│   │   │   ├── application.yml
│   │   │   └── logback-spring.xml (optional, for logging configuration)
├── pom.xml

Приложение работает успешно:

Настройка SPN:

Центр событий:

Спасибо, к сожалению, я получаю эту ошибку, используя «имя-концентратора событий» в подходе к конфигурации «производитель»: «org.springframework.beans.factory.BeanCreationException: ошибка при создании bean-компонента с именем eventHubProducerAsyncClient, определенным в ресурсе пути к классу [com/azure] /spring/cloud/autoconfigure/implementation/eventhu‌​bs/AzureEventHubsPro‌ducerClientConfigura‌​tion$SharedProducerC‌​onnectionConfigurati‌​on.class]: не удалось создать экземпляр [com.azure.messaging.eventhubs.EventHubProducerAsyncClient]: фабричный метод 'eventHubProducerA syncClient' выдал исключение с сообщением: «eventHubName» не может быть пустой строкой».

Klam 15.07.2024 16:27

Другие вопросы по теме