Можно ли подключиться к Azure Cosmos DB через обратный прокси-сервер с помощью Java SDK?

#java #azure #ssl #azure-cosmosdb

Вопрос:

Я пытаюсь использовать java sdk для подключения к cosmos. У меня есть прокси-сервер Nginx, работающий в AKS, указывающем на мой экземпляр cosmos (подмножество nginx.conf ниже).:

   server {
    listen {{ .Values.cosmosDB.port }} so_keepalive=on;
    proxy_connect_timeout 5s;
    proxy_timeout 60m;
    proxy_buffer_size 30M;
    proxy_socket_keepalive on;
    proxy_ssl_session_reuse on;
    proxy_pass my-instance-cosmos-dev.documents.azure.com:443;
  }
 

Я думал, что с помощью переадресации портов я смогу использовать свой локальный адрес в качестве URL-адреса хоста cosmos через этот прокси:

 kubectl port-forward svc/data-proxy 3308:443
 

Запустив быстрый запуск для java (созданный с помощью портала Azure), я не могу настроить подключающийся клиент cosmos. Я перепробовал пару конфигураций:

Режим шлюза по умолчанию:

         client = new CosmosClientBuilder()
            .endpoint(AccountSettings.HOST)
            .key(AccountSettings.MASTER_KEY)
            .endpointDiscoveryEnabled(true)
            .gatewayMode()
            .userAgentSuffix("CosmosDBJavaQuickstart")
            .consistencyLevel(ConsistencyLevel.EVENTUAL)
            .buildClient();
 

Однако это возвращает ошибку при запуске Database Account localhost does not exist :

 CosmosException{userAgent=azsdk-java-cosmos/4.4.0 MacOSX/10.15.7 JRE/15.0.2, 
error={"code":"Forbidden","message":"Database Account localhost does not existrnActivityId: 742a632d-cd00-42b7-8599-8fc6ff1eccad, Microsoft.Azure.Documents.Common/2.14.0, StatusCode: Forbidden","additionalErrorInfo":null}, resourceAddress='null', requestUri='null', statusCode=403, message=Database Account localhost does not exist
 

Затем я попытался передать конфигурацию прокси-сервера следующим образом, но вместо этого получил ошибки проверки SSL:

     ProxyOptions opts = new ProxyOptions(ProxyOptions.Type.HTTP,  InetSocketAddress.createUnresolved("127.0.0.1", 3308));
    gatewayConnectionConfig.setProxy(opts);


    gatewayConnectionConfig.setMaxConnectionPoolSize(5);
    
    //  Create sync client
    client = new CosmosClientBuilder()
        .endpoint(AccountSettings.HOST)
        .key(AccountSettings.MASTER_KEY)
        .endpointDiscoveryEnabled(true)
        .gatewayMode(gatewayConnectionConfig)
        .userAgentSuffix("CosmosDBJavaQuickstart")
        .consistencyLevel(ConsistencyLevel.EVENTUAL)
        .buildClient();
 

Выход:

 INFO: Getting database account endpoint from http://localhost:3308
Oct 07, 2021 10:01:31 AM com.azure.cosmos.implementation.RxGatewayStoreModel 
lambda$toDocumentServiceResponse$2
SEVERE: Network failure
javax.net.ssl.SSLException: failure when writing TLS control frames
    at io.netty.handler.ssl.SslHandler.setHandshakeFailureTransportFailure(SslHandler.java:1863)
    at io.netty.handler.ssl.SslHandler.access$600(SslHandler.java:167)
    at io.netty.handler.ssl.SslHandler$2.operationComplete(SslHandler.java:978)
    at io.netty.handler.ssl.SslHandler$2.operationComplete(SslHandler.java:973)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608)
    at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
    at io.netty.channel.PendingWriteQueue.safeFail(PendingWriteQueue.java:279)
    at io.netty.channel.PendingWriteQueue.removeAndFailAll(PendingWriteQueue.java:177)
    at io.netty.handler.proxy.ProxyHandler.failPendingWrites(ProxyHandler.java:435)
    at io.netty.handler.proxy.ProxyHandler.failPendingWritesAndClose(ProxyHandler.java:352)
    at io.netty.handler.proxy.ProxyHandler.setConnectFailure(ProxyHandler.java:347)
    at io.netty.handler.proxy.ProxyHandler.access$100(ProxyHandler.java:39)
    at io.netty.handler.proxy.ProxyHandler$2.run(ProxyHandler.java:199)
    at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
    at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:170)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: io.netty.handler.proxy.ProxyConnectException: http, none, /127.0.0.1:3308 => localhost/<unresolved>:3308, timeout
    ... 10 more
 

Я не знаю, как поступить дальше. Это поддерживаемый шаблон подключения? Возможно, я неправильно понимаю настройку клиента с помощью SDK здесь…

Ответ №1:

Я думаю, что прокси-подход должен работать, но вы должны написать исходный URL-адрес Cosmos-DB в строке подключения, в которой вы используете AccountSettings.HOST .

Я предполагаю, что там все еще есть ссылка на «локальный хост» из-за вашей первой попытки с прямым доступом. Но поскольку вы сейчас проходите через прокси-сервер, там должен быть реальный URL-адрес. (my-instance-cosmos-dev.documents.azure.com)

Кроме того, вы не получаете ошибку проверки SSL, это похоже на тайм-аут. (Потому что прокси пытался подключиться к локальному хосту)


Если вы хотите использовать первый (прямой) подход, вы можете добавить запись в свой /etc/hosts, которая должна заставить пакет SDK cosmos-db отправить правильный заголовок хоста в запросе.

 127.0.0.1 my-instance-cosmos-dev.documents.azure.com
 

А затем вам также нужно указать реальный URL-адрес в строке подключения, которая затем указывает на localhost.