I am trying utilise the ProxyOptions
to re-route the blob upload to a proxy URL. In this case localhost
Demo Project:
Gradle Dependency:
implementation 'com.azure:azure-storage-blob'
implementation 'com.azure:azure-core'
implementation 'com.azure:azure-core-http-netty'
implementation 'com.azure:azure-identity'
implementation 'com.azure:azure-security-keyvault-secrets'
implementation ('com.azure.resourcemanager:azure-resourcemanager:2.18.0') {
exclude group: 'com.azure', module: 'azure-core'
}
configurations.all{
resolutionStrategy{
force 'com.azure:azure-storage-common:12.18.0', 'com.azure:azure-storage-common:12.14.3'
}
}
@Bean
public BlobClient blobClient() throws URISyntaxException, UnknownHostException {
HttpClient client = new NettyAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 8080)))
.build();
String accountName = "xxxx";
String accountkey = "yyyyy";
String endPoint = String.format(java.util.Locale.ROOT, "https://%s.blob.core.windows.net", accountName);
BlobClient blobClient = new BlobClientBuilder()
.endpoint(endPoint)
.credential(new StorageSharedKeyCredential(accountName, accountkey))
.containerName("test-bucket-1")
.blobName("test.txt")
.httpClient(client)
.buildClient();
return blobClient;
}
and the controller which consumes the above blobClient:
@PutMapping(value ={"/azure/test"})
public boolean uploadAzureBlob(
@RequestParam("containerName") String containerName,
@RequestParam("blobName") Optional\<String\> blobName,
HttpServletRequest request, HttpServletResponse response) throws IOException, URISyntaxException {
InputStream inputStream = request.getInputStream();
BinaryData binaryData = BinaryData.fromStream(inputStream);
BlobParallelUploadOptions blobParallelUploadOptions = new BlobParallelUploadOptions(binaryData);
Response\<BlockBlobItem\> blobItemResponse =
blobClient.uploadWithResponse(
blobParallelUploadOptions,
Duration.ofSeconds(120L),
Context.NONE);
return true;
}
When the blobClient is trying to upload the blob object it should re-route to the following controller which is running in my local machine. I want to basically intercept the API call and redirect it to the proxy application running in my local. At least to the @RequestMapping(value ={"\*"})
Proxy Project:
Gradle Dependency:
implementation platform('com.azure:azure-sdk-bom:1.1.1')
implementation 'com.azure:azure-storage-blob'
implementation 'com.azure:azure-core'
implementation 'com.azure:azure-core-http-netty'
implementation 'com.azure:azure-identity'
implementation 'com.azure:azure-security-keyvault-secrets'
implementation ('com.azure.resourcemanager:azure-resourcemanager:2.18.0') {
exclude group: 'com.azure', module: 'azure-core'
}
configurations.all{
resolutionStrategy{
force 'com.azure:azure-storage-common:12.18.0', 'com.azure:azure-storage-common:12.14.3'
}
}
The controller code of the proxy:
@RequestMapping("/v2/azure-proxy")
public class AzureBlobProxyController {
@PutMapping(value ={"/{containerName}/{blobName}"})
public boolean uploadSecureStream(@PathVariable("containerName") String containerName,
@PathVariable("blobName") String blobName,
HttpServletRequest request, HttpServletResponse response) throws Exception
{
return true;
}
@RequestMapping(value ={"/*"})
public boolean getBlobContainerAsyncClient(
HttpServletRequest request,
HttpServletResponse httpServletResponse) throws Exception
{
return true;
}
}
But i am getting the following exception:
2022-11-28 00:22:12.535 WARN 86304 --- \[r-http-kqueue-1\] r.netty.http.client.HttpClientConnect : \[c80a00e1, L:/127.0.0.1:54822 - R:localhost/127.0.0.1:8080\] The connection observed an error
javax.net.ssl.SSLException: failure when writing TLS control frames
at io.netty.handler.ssl.SslHandler.setHandshakeFailureTransportFailure(SslHandler.java:1896) \~\[netty-handler-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.ssl.SslHandler.access$600(SslHandler.java:168) \~\[netty-handler-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.ssl.SslHandler$2.operationComplete(SslHandler.java:933) \~\[netty-handler-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.ssl.SslHandler$2.operationComplete(SslHandler.java:928) \~\[netty-handler-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:609) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.PendingWriteQueue.safeFail(PendingWriteQueue.java:288) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.PendingWriteQueue.removeAndFailAll(PendingWriteQueue.java:186) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.proxy.ProxyHandler.failPendingWrites(ProxyHandler.java:434) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.proxy.ProxyHandler.failPendingWritesAndClose(ProxyHandler.java:351) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.proxy.ProxyHandler.setConnectFailure(ProxyHandler.java:346) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.proxy.ProxyHandler.channelRead(ProxyHandler.java:266) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327) \~\[netty-codec-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299) \~\[netty-codec-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.proxy.HttpProxyHandler$HttpClientCodecWrapper.channelRead(HttpProxyHandler.java:272) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) \~\[netty-transport-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.kqueue.AbstractKQueueStreamChannel$KQueueStreamUnsafe.readReady(AbstractKQueueStreamChannel.java:544) \~\[netty-transport-classes-kqueue-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.kqueue.AbstractKQueueChannel$AbstractKQueueUnsafe.readReady(AbstractKQueueChannel.java:383) \~\[netty-transport-classes-kqueue-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.kqueue.KQueueEventLoop.processReady(KQueueEventLoop.java:211) \~\[netty-transport-classes-kqueue-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.channel.kqueue.KQueueEventLoop.run(KQueueEventLoop.java:289) \~\[netty-transport-classes-kqueue-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) \~\[netty-common-4.1.77.Final.jar:4.1.77.Final\]
at java.base/java.lang.Thread.run(Thread.java:832) \~\[na:na\]
Caused by: io.netty.handler.proxy.HttpProxyHandler$HttpProxyConnectException: http, none, localhost/127.0.0.1:8080 =\> xxxx.blob.core.windows.net/\<unresolved\>:443, status: 400
at io.netty.handler.proxy.HttpProxyHandler.handleResponse(HttpProxyHandler.java:200) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
at io.netty.handler.proxy.ProxyHandler.channelRead(ProxyHandler.java:257) \~\[netty-handler-proxy-4.1.77.Final.jar:4.1.77.Final\]
... 23 common frames omitted
Caused by: io.netty.handler.proxy.HttpProxyHandler$HttpProxyConnectException: http, none, localhost/127.0.0.1:8080 =\> xxxx.blob.core.windows.net/\<unresolved\>:443, status: 400
How to fix the above issue and how can i make the proxy reach the @RequestMapping("/v2/azure-proxy"). In the socketAddress i am able to give hostname how can i give the path variables?
I have tried using the com.azure.core.http.HttpClient to re-route:
HttpClient client = new NettyAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 8080)))
.build();
but i need to be able to use the proxy path:
http://localhost:8080/v2/azure-proxy