Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External requests api Closes #2587 #2591

Merged
merged 7 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.digma.intellij.plugin.model.rest.assets.AssetDisplayInfo;
import org.digma.intellij.plugin.model.rest.codelens.*;
import org.digma.intellij.plugin.model.rest.codespans.CodeContextSpans;
import org.digma.intellij.plugin.model.rest.common.SpanHistogramQuery;
import org.digma.intellij.plugin.model.rest.common.*;
import org.digma.intellij.plugin.model.rest.debugger.DebuggerEventRequest;
import org.digma.intellij.plugin.model.rest.env.*;
import org.digma.intellij.plugin.model.rest.environment.Env;
Expand Down Expand Up @@ -172,4 +172,6 @@ public interface AnalyticsProvider extends Closeable {
List<SpanEnvironment> getSpanEnvironmentsStats(String spanCodeObjectId);

DiscoveredDataResponse getDiscoveredData();

SpanInfoByUid resolveSpanByUid(String uid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.digma.intellij.plugin.model.rest.assets.AssetDisplayInfo;
import org.digma.intellij.plugin.model.rest.codelens.*;
import org.digma.intellij.plugin.model.rest.codespans.CodeContextSpans;
import org.digma.intellij.plugin.model.rest.common.SpanHistogramQuery;
import org.digma.intellij.plugin.model.rest.common.*;
import org.digma.intellij.plugin.model.rest.debugger.DebuggerEventRequest;
import org.digma.intellij.plugin.model.rest.env.*;
import org.digma.intellij.plugin.model.rest.environment.Env;
Expand Down Expand Up @@ -489,6 +489,11 @@ public DiscoveredDataResponse getDiscoveredData() {
return execute(client.analyticsProvider::getDiscoveredData);
}

@Override
public SpanInfoByUid resolveSpanByUid(String uid){
return execute(() -> client.analyticsProvider.resolveSpanByUid(uid));
}

@Override
public HttpResponse lowLevelCall(HttpRequest request) {

Expand Down Expand Up @@ -1284,5 +1289,11 @@ Call<Void> setInsightCustomStartTime(
})
@GET("CodeAnalytics/discovered-data")
Call<DiscoveredDataResponse> getDiscoveredData();

@Headers({
"Content-Type:application/json"
})
@GET("spans/spanCodeObjectId/{uid}")
Call<SpanInfoByUid> resolveSpanByUid(@Path("uid") String uid);
}
}
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ pluginRepositoryUrl=https://github.com/digma-ai/digma-intellij-plugin.git
##change buildProfile to load the profile dependencies in the IDE. refresh gradle after change.
##it is necessary when need to debug something in a specific version of intellij. changing the profile here
## will load that version's dependencies to the IDE
#buildProfile=p231 - its the default so not necessary
#buildProfile=p231 - it's the default
#buildProfile=p232
#buildProfile=p233
#buildProfile=p241
#buildProfile=p242
#buildProfile=p243

##build with real ide, will load the ide dependencies in the project. refresh gradle after change.
##its is necessary when need to debug something for a specific IDE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.ui.JBColor;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.digma.intellij.plugin.auth.AuthManager;
import org.digma.intellij.plugin.common.*;
import org.digma.intellij.plugin.errorreporting.ErrorReporter;
Expand All @@ -14,7 +15,7 @@
import org.digma.intellij.plugin.model.rest.assets.AssetDisplayInfo;
import org.digma.intellij.plugin.model.rest.codelens.*;
import org.digma.intellij.plugin.model.rest.codespans.CodeContextSpans;
import org.digma.intellij.plugin.model.rest.common.SpanHistogramQuery;
import org.digma.intellij.plugin.model.rest.common.*;
import org.digma.intellij.plugin.model.rest.debugger.DebuggerEventRequest;
import org.digma.intellij.plugin.model.rest.env.*;
import org.digma.intellij.plugin.model.rest.environment.Env;
Expand All @@ -32,7 +33,7 @@
import org.digma.intellij.plugin.persistence.PersistenceService;
import org.digma.intellij.plugin.posthog.ActivityMonitor;
import org.digma.intellij.plugin.ui.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.*;

import java.io.Closeable;
import java.lang.reflect.*;
Expand Down Expand Up @@ -379,7 +380,7 @@ public String getIssuesReportStats(@NotNull Map<String, Object> queryParams) thr
analyticsProviderProxy.getIssuesReportStats(queryParams));
}

public String getServiceReport(@NotNull String queryParams) throws AnalyticsServiceException {
public String getServiceReport(@NotNull String queryParams) throws AnalyticsServiceException {
return executeCatching(() ->
analyticsProviderProxy.getServiceReport(queryParams));
}
Expand Down Expand Up @@ -560,6 +561,34 @@ public HttpResponse lowLevelCall(HttpRequest request) throws AnalyticsServiceExc
return executeCatching(() -> analyticsProviderProxy.lowLevelCall(request));
}


@Nullable
public SpanInfoByUid resolveSpanByUid(String uid) throws AnalyticsServiceException {

if (backendVersionOlderThen("0.3.155")) {
return null;
}

return executeCatching(() -> analyticsProviderProxy.resolveSpanByUid(uid));

}


private boolean backendVersionOlderThen(String version) {
String backendVersion = BackendInfoHolder.getInstance(project).getAbout().getApplicationVersion();

//dev environment may return unknown
if ("unknown".equalsIgnoreCase(backendVersion)) {
return false;
}

ComparableVersion currentBackendVersion = new ComparableVersion(backendVersion);
ComparableVersion requiredBackendVersion = new ComparableVersion(version);

return currentBackendVersion.compareTo(requiredBackendVersion) < 0;
}


@Override
public void dispose() {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
package org.digma.intellij.plugin.analytics

import com.intellij.openapi.project.Project
import org.digma.intellij.plugin.common.findActiveProject

fun isCentralized(project: Project): Boolean {
return BackendInfoHolder.getInstance(project).isCentralized()
}

fun getVersion(project: Project): String {
return BackendInfoHolder.getInstance(project).getAbout()?.applicationVersion ?: "unknown";
}
fun getBackendVersion(project: Project): String {
return BackendInfoHolder.getInstance(project).getAbout()?.applicationVersion ?: "unknown"
}

fun getBackendVersion(): String {
val project = findActiveProject()
return project?.let {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backend is responsible to return ApplicationVersion with "unknown" value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the case where there is no connection to backend

BackendInfoHolder.getInstance(it).getAbout()?.applicationVersion ?: "unknown"
} ?: "unknown"
}

fun getBackendDeploymentType(): String {
val project = findActiveProject()
return project?.let {
BackendInfoHolder.getInstance(it).getAbout()?.deploymentType?.name ?: "unknown"
} ?: "unknown"
}

fun isCentralized(): Boolean {
val project = findActiveProject()
return project?.let {
BackendInfoHolder.getInstance(it).getAbout()?.isCentralize ?: false
} ?:false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.digma.intellij.plugin.api

import com.fasterxml.jackson.core.JsonFactory
import com.fasterxml.jackson.core.JsonGenerator
import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.application.ApplicationNamesInfo
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
import com.intellij.util.PlatformUtils
import com.intellij.util.io.jackson.array
import com.intellij.util.io.jackson.obj
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.QueryStringDecoder
import org.digma.intellij.plugin.analytics.getBackendDeploymentType
import org.digma.intellij.plugin.analytics.getBackendVersion
import org.digma.intellij.plugin.analytics.isCentralized
import org.digma.intellij.plugin.semanticversion.SemanticVersionUtil
import java.io.OutputStream

/**
* {get} /digma/about The application info
*/
internal class AboutHttpService : AbstractHttpService() {

override fun getServiceName() = "digma/about"


override fun execute(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): String? {
val byteOut = BufferExposingByteArrayOutputStream()
writeApplicationInfoJson(byteOut)
send(byteOut, request, context)
return null
}


private fun writeApplicationInfoJson(out: OutputStream) {
JsonFactory().createGenerator(out).useDefaultPrettyPrinter().use { writer ->
writer.obj {
writeAboutJson(writer)
}
}
}


private fun writeAboutJson(writer: JsonGenerator) {
writer.writeStringField("source", "Digma Plugin")
var appName = ApplicationInfo.getInstance().fullApplicationName
@Suppress("UnstableApiUsage")
if (!PlatformUtils.isIdeaUltimate()) {
val productName = ApplicationNamesInfo.getInstance().productName
appName = appName
.replace("$productName ($productName)", productName)
.removePrefix("JetBrains ")
}
writer.writeStringField("name", appName)
writer.writeStringField("productName", ApplicationNamesInfo.getInstance().productName)
writer.writeStringField("edition", ApplicationNamesInfo.getInstance().editionName)

val build = ApplicationInfo.getInstance().build
writer.writeNumberField("baselineVersion", build.baselineVersion)
if (!build.isSnapshot) {
writer.writeStringField("buildNumber", build.asStringWithoutProductCode())
}

writer.writeStringField("pluginVersion", SemanticVersionUtil.getPluginVersionWithoutBuildNumberAndPreRelease("unknown"))
writer.writeStringField("backendVersion", getBackendVersion())
writer.writeStringField("backendDeploymentType", getBackendDeploymentType())
writer.writeBooleanField("isCentralized", isCentralized())

writer.array("openProjects") {
for (project in ProjectManager.getInstance().openProjects) {
writer.writeString(project.name)
}
}
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.digma.intellij.plugin.api

import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import io.netty.handler.codec.http.QueryStringDecoder

abstract class AbstractApiCommand {

protected val logger: Logger = Logger.getInstance(this::class.java)

abstract fun execute(project: Project, urlDecoder: QueryStringDecoder)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.digma.intellij.plugin.api

import com.intellij.openapi.diagnostic.Logger
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.HttpRequest
import io.netty.handler.codec.http.QueryStringDecoder
import org.jetbrains.ide.RestService

/**
* base http service that allows all origin hosts
*/
abstract class AbstractHttpService : RestService() {

protected val logger: Logger = Logger.getInstance(this::class.java)

override fun isOriginAllowed(request: HttpRequest): OriginCheckResult {
return OriginCheckResult.ALLOW
}

override fun isHostTrusted(request: FullHttpRequest, urlDecoder: QueryStringDecoder): Boolean {
return true
}

@Deprecated("Use {@link #isHostTrusted(FullHttpRequest, QueryStringDecoder)}", ReplaceWith("true"))
override fun isHostTrusted(request: FullHttpRequest): Boolean {
return true
}
}
Loading
Loading