Skip to content

Commit cf57c32

Browse files
authored
Merge pull request #2641 from digma-ai/api-proxy
api proxy Closes #2249
2 parents f8db91d + 164e4eb commit cf57c32

File tree

13 files changed

+407
-94
lines changed

13 files changed

+407
-94
lines changed

analytics-provider/src/main/java/org/digma/intellij/plugin/analytics/AnalyticsProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public interface AnalyticsProvider extends Closeable {
153153

154154
InsightsStatsResult getInsightsStats(Map<String, Object> queryParams);
155155

156-
HttpResponse lowLevelCall(HttpRequest request);
156+
HttpResponse proxyCall(HttpRequest request);
157157

158158
String getHighlightsPerformance(Map<String, Object> queryParams);
159159

analytics-provider/src/main/java/org/digma/intellij/plugin/analytics/RestAnalyticsProvider.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public String getGlobalErrorsFilters(String payload) {
178178

179179
@Override
180180
public String getErrorTimeseries(String errorId, Map<String, Object> payload) {
181-
return execute(() -> client.analyticsProvider.getErrorTimeseries( errorId, payload));
181+
return execute(() -> client.analyticsProvider.getErrorTimeseries(errorId, payload));
182182
}
183183

184184
@Override
@@ -490,36 +490,42 @@ public DiscoveredDataResponse getDiscoveredData() {
490490
}
491491

492492
@Override
493-
public SpanInfoByUid resolveSpanByUid(String uid){
493+
public SpanInfoByUid resolveSpanByUid(String uid) {
494494
return execute(() -> client.analyticsProvider.resolveSpanByUid(uid));
495495
}
496496

497497
@Override
498-
public HttpResponse lowLevelCall(HttpRequest request) {
498+
public HttpResponse proxyCall(HttpRequest request) {
499499

500-
okhttp3.Response okHttp3Response;
501500
try {
502501
var okHttp3Request = toOkHttp3Request(request);
503-
okHttp3Response = client.okHttpClient.newCall(okHttp3Request).execute();
502+
okhttp3.Response okHttp3Response = client.okHttpClient.newCall(okHttp3Request).execute();
503+
//handle only authentication error so the plugin will login or redirect the ui to login.
504+
//any other error should be propagated to the UI
505+
if (okHttp3Response.code() == HTTPConstants.UNAUTHORIZED) {
506+
try (ResponseBody errorBody = okHttp3Response.body()) {
507+
throw createUnsuccessfulResponseException(okHttp3Response.code(), errorBody);
508+
}
509+
}
510+
511+
return toHttpResponse(okHttp3Response);
512+
504513
} catch (Exception e) {
505514
throw new AnalyticsProviderException(e);
506515
}
516+
}
507517

508-
if (okHttp3Response.isSuccessful()) {
509-
return toHttpResponse(okHttp3Response);
510-
} else {
511-
try (ResponseBody errorBody = okHttp3Response.body()) {
512-
throw createUnsuccessfulResponseException(okHttp3Response.code(), errorBody);
513-
} catch (IOException e) {
514-
throw new AnalyticsProviderException(e.getMessage(), e);
518+
private Request toOkHttp3Request(HttpRequest request) {
519+
RequestBody okHttp3Body = null;
520+
if (request.getBody() != null) {
521+
var contentType = request.getHeader("Content-Type");
522+
if (contentType == null) {
523+
okHttp3Body = RequestBody.create(null, request.getBody().getContent());
524+
} else {
525+
okHttp3Body = RequestBody.create(MediaType.parse(contentType), request.getBody().getContent());
515526
}
516527
}
517-
}
518528

519-
private Request toOkHttp3Request(HttpRequest request) {
520-
var okHttp3Body = request.getBody() != null
521-
? RequestBody.create(MediaType.parse(request.getBody().getContentType()), request.getBody().getContent())
522-
: null;
523529
var okHttp3RequestBuilder = new Request.Builder()
524530
.method(request.getMethod(), okHttp3Body)
525531
.url(request.getUrl());
@@ -532,8 +538,12 @@ private HttpResponse toHttpResponse(okhttp3.Response response) {
532538
var headers = response.headers().toMultimap().entrySet().stream()
533539
.filter(i -> !i.getValue().isEmpty())
534540
.collect(HashMap<String, String>::new, (m, i) -> m.put(i.getKey(), i.getValue().get(0)), Map::putAll);
541+
535542
var contentLength = body != null ? body.contentLength() : null;
536-
MediaType mediaType = body != null ? body.contentType() : null;
543+
var contentTypeHeaderName = response.headers().names().stream().filter(s -> s != null && s.equalsIgnoreCase("content-type")).findFirst().orElse(null);
544+
var contentTypeHeader = contentTypeHeaderName != null ? response.header(contentTypeHeaderName) : null;
545+
MediaType mediaType = (body != null && body.contentType() != null) ? body.contentType() :
546+
(contentTypeHeader != null) ? MediaType.parse(contentTypeHeader) : null;
537547
var contentType = mediaType != null ? mediaType.toString() : null;
538548
var contentStream = body != null ? body.byteStream() : null;
539549

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ tasks {
333333
//custom compose file url
334334
//"org.digma.plugin.custom.docker-compose.url" to "https://raw.githubusercontent.com/digma-ai/digma/refs/heads/0.2.73/docker/docker-compose.yml"
335335
//ui bundle path
336-
//"org.digma.plugin.ui.bundle.path" to "/home/shalom/Downloads/digma-ui-4.0.12.zip"
336+
////"org.digma.plugin.ui.bundle.path" to "/home/shalom/Downloads/digma-ui-5.1.1.zip"
337337

338338
)
339339

ide-common/src/main/java/org/digma/intellij/plugin/analytics/AnalyticsService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,8 @@ public DiscoveredDataResponse getDiscoveredData() throws AnalyticsServiceExcepti
558558
return executeCatching(() -> analyticsProviderProxy.getDiscoveredData());
559559
}
560560

561-
public HttpResponse lowLevelCall(HttpRequest request) throws AnalyticsServiceException {
562-
return executeCatching(() -> analyticsProviderProxy.lowLevelCall(request));
561+
public HttpResponse proxyCall(HttpRequest request) throws AnalyticsServiceException {
562+
return executeCatching(() -> analyticsProviderProxy.proxyCall(request));
563563
}
564564

565565

model/src/main/kotlin/org/digma/intellij/plugin/model/rest/lowlevel/HttpRequest.kt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,25 @@ class HttpRequest(
77
val url: URL,
88
val headers: MutableMap<String, String>,
99
val body: HttpRequestBody?
10-
)
10+
) {
11+
fun getHeader(headerName: String): String? {
12+
val actualHeaderName = headers.keys.find { it.equals(headerName,true) }
13+
return actualHeaderName?.let {
14+
headers[it]
15+
}
16+
}
17+
18+
override fun toString(): String {
19+
return "HttpRequest(method='$method', url=$url, headers=$headers, body=$body)"
20+
}
21+
22+
23+
}
1124

1225
class HttpRequestBody(
13-
val contentType: String,
14-
val content: String
15-
)
26+
val content: ByteArray
27+
){
28+
override fun toString(): String {
29+
return "HttpRequestBody(content=${String(content, Charsets.UTF_8)})"
30+
}
31+
}

model/src/main/kotlin/org/digma/intellij/plugin/model/rest/lowlevel/HttpResponse.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,11 @@ class HttpResponse(
88
val contentLength: Long?,
99
val contentType: String?,
1010
val contentStream: InputStream?
11-
)
11+
12+
13+
) {
14+
override fun toString(): String {
15+
//don't convert contentStream to string, this input stream should be read by the http layer. and it may be a large stream.
16+
return "HttpResponse(status=$status, headers=$headers, contentLength=$contentLength, contentType=$contentType, contentStream=$contentStream)"
17+
}
18+
}

src/main/java/org/digma/intellij/plugin/jaegerui/JaegerUiProxyResourceHandler.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package org.digma.intellij.plugin.jaegerui;
22

3-
import com.fasterxml.jackson.core.JsonProcessingException;
43
import com.intellij.openapi.diagnostic.Logger;
54
import com.posthog.java.shaded.okhttp3.*;
65
import org.cef.callback.CefCallback;
76
import org.cef.handler.CefResourceHandler;
87
import org.cef.misc.*;
98
import org.cef.network.*;
109
import org.digma.intellij.plugin.auth.account.CredentialsHolder;
11-
import org.digma.intellij.plugin.common.JsonUtilsKt;
1210
import org.digma.intellij.plugin.log.Log;
1311
import org.digma.intellij.plugin.ui.jcef.JCefException;
1412
import org.jetbrains.annotations.*;
@@ -24,7 +22,7 @@ public class JaegerUiProxyResourceHandler implements CefResourceHandler {
2422
private final URL jaegerQueryUrl;
2523
private Response okHttp3Response;
2624

27-
public JaegerUiProxyResourceHandler(URL jaegerQueryUrl){
25+
public JaegerUiProxyResourceHandler(URL jaegerQueryUrl) {
2826
this.jaegerQueryUrl = jaegerQueryUrl;
2927
okHttpClient = new OkHttpClient.Builder().build();
3028
}
@@ -59,10 +57,10 @@ public boolean processRequest(CefRequest cefRequest, CefCallback callback) {
5957
}
6058

6159
@Nullable
62-
private static String getAuthFailureReason(Response response){
60+
private static String getAuthFailureReason(Response response) {
6361
final var headerName = "X-Auth-Fail-Reason";
6462
var reason = response.header(headerName);
65-
if(reason == null && response.priorResponse() != null)
63+
if (reason == null && response.priorResponse() != null)
6664
reason = response.priorResponse().header(headerName);
6765
return reason;
6866
}
@@ -90,12 +88,12 @@ private URL getApiUrl(CefRequest cefRequest) throws MalformedURLException {
9088
}
9189

9290
@NotNull
93-
private static HashMap<String, String> getHeaders(CefRequest cefRequest) throws JsonProcessingException {
91+
private static HashMap<String, String> getHeaders(CefRequest cefRequest) {
9492
var headers = new HashMap<String, String>();
9593
cefRequest.getHeaderMap(headers);
9694
var digmaCredentials = CredentialsHolder.INSTANCE.getDigmaCredentials();
97-
if (digmaCredentials != null){
98-
headers.put("Cookie", "auth_token_a="+digmaCredentials.getAccessToken());
95+
if (digmaCredentials != null) {
96+
headers.put("Cookie", "auth_token_a=" + digmaCredentials.getAccessToken());
9997
}
10098
return headers;
10199
}
@@ -117,18 +115,19 @@ public void getResponseHeaders(CefResponse cefResponse, IntRef responseLength, S
117115
cefResponse.setHeaderMap(headersMap);
118116

119117
var body = okHttp3Response.body();
120-
if (body != null){
118+
if (body != null) {
121119
cefResponse.setMimeType(body.contentType().toString());
122-
responseLength.set((int)body.contentLength());
120+
responseLength.set((int) body.contentLength());
123121
}
124122
}
125123

124+
126125
@Override
127126
public boolean readResponse(byte[] dataOut, int bytesToRead, IntRef bytesRead, CefCallback cefCallback) {
128127
try{
129128
var inputStream = okHttp3Response.body().byteStream();
130129
var read = inputStream.read(dataOut, 0, bytesToRead);
131-
if (read == -1) {
130+
if (read <= 0) {
132131
bytesRead.set(0);
133132
inputStream.close();
134133
return false;
@@ -143,6 +142,8 @@ public boolean readResponse(byte[] dataOut, int bytesToRead, IntRef bytesRead, C
143142

144143
@Override
145144
public void cancel() {
146-
okHttp3Response.close();
145+
if (okHttp3Response != null) {
146+
okHttp3Response.close();
147+
}
147148
}
148149
}

src/main/java/org/digma/intellij/plugin/jaegerui/JaegerUiSchemeHandlerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public CefResourceHandler createProxyHandler(@NotNull Project project, @NotNull
2525
JaegerUiProxyResourceHandler.isJaegerQueryCall(url)) {
2626
return new JaegerUiProxyResourceHandler(jaegerQueryUrl);
2727
}
28-
return null;
28+
return super.createProxyHandler(project, url);
2929
}
3030

3131
@NotNull

0 commit comments

Comments
 (0)