Skip to content

Commit

Permalink
Fix opentelemetry semantic-conventions alignment processing
Browse files Browse the repository at this point in the history
  • Loading branch information
rnc committed Sep 26, 2024
1 parent 6a58f2b commit af17359
Show file tree
Hide file tree
Showing 15 changed files with 873 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.jboss.gm.analyzer.alignment;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Collection;

import org.commonjava.maven.atlas.ident.ref.ProjectVersionRef;
import org.commonjava.maven.ext.common.ManipulationException;
import org.commonjava.maven.ext.io.rest.DefaultTranslator;
import org.gradle.util.GradleVersion;
import org.jboss.byteman.contrib.bmunit.BMUnitRunner;
import org.jboss.gm.analyzer.alignment.TestUtils.TestManipulationModel;
import org.jboss.gm.common.Configuration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assume.assumeTrue;

@RunWith(BMUnitRunner.class)
public class SemanticConventionsFunctionalTest extends AbstractWiremockTest {
@Rule
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog().muteForSuccessfulTests();

@Rule
public final TestRule restoreSystemProperties = new RestoreSystemProperties();

@Rule
public TemporaryFolder tempDir = new TemporaryFolder();

@Before
public void setup() throws IOException, URISyntaxException {
stubFor(post(urlEqualTo("/da/rest/v-1/" + DefaultTranslator.Endpoint.LOOKUP_LATEST))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json;charset=utf-8")
.withBody(readSampleDAResponse("semantic-conventions-da-response-project.json"))));
stubFor(post(urlEqualTo("/da/rest/v-1/" + DefaultTranslator.Endpoint.LOOKUP_GAVS))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json;charset=utf-8")
.withBody("[]")));

System.setProperty(Configuration.DA, "http://127.0.0.1:" + wireMockRule.port() + "/da/rest/v-1");
}

@Test
public void verifySemanticConventions() throws IOException, URISyntaxException, ManipulationException {
assumeTrue(GradleVersion.current().compareTo(GradleVersion.version("8.2")) >= 0);

final File projectRoot = tempDir.newFolder("semantic-conventions-java");

final TestManipulationModel alignmentModel = TestUtils.align(
projectRoot, projectRoot.getName());

assertThat(new File(projectRoot, AlignmentTask.GME)).exists();
assertThat(new File(projectRoot, AlignmentTask.GRADLE + File.separator + AlignmentTask.GME_REPOS)).exists();
assertThat(new File(projectRoot, AlignmentTask.GME_PLUGINCONFIGS)).exists();

assertThat(alignmentModel).isNotNull().satisfies(am -> {
assertThat(am.getOriginalVersion()).isEqualTo("1.26.0-alpha");
assertThat(am.getGroup()).isEqualTo("io.opentelemetry.semconv");
assertThat(am.getName()).isEqualTo("semantic-conventions-java");
assertThat(am.findCorrespondingChild("semconv-incubating")).satisfies(root -> {
assertThat(root.getVersion()).isEqualTo("1.26.0.alpha-redhat-00002");
assertThat(root.getName()).isEqualTo("opentelemetry-semconv-incubating");
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"latestVersion": "1.26.0.alpha-redhat-00001",
"version": "1.26.0-alpha",
"groupId": "io.opentelemetry.semconv",
"artifactId": "semantic-conventions-java"
},
{
"latestVersion": "1.26.0.alpha-redhat-00001",
"version": "1.26.0-alpha",
"groupId": "io.opentelemetry.semconv",
"artifactId": "opentelemetry-semconv"
},
{
"latestVersion": "1.26.0.alpha-redhat-00001",
"version": "1.26.0-alpha",
"groupId": "io.opentelemetry.semconv",
"artifactId": "opentelemetry-semconv-incubating"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import de.undercouch.gradle.tasks.download.Download
import java.time.Duration

plugins {
id("de.undercouch.download")
id("io.github.gradle-nexus.publish-plugin")

id("org.jboss.gm.analyzer")
}

subprojects {
apply(plugin = "org.jboss.gm.analyzer")
}

// start - updated by ./.github/workflows/prepare-release-branch.yml
val snapshot = false
// end

// The release version of https://github.com/open-telemetry/semantic-conventions used to generate classes
var semanticConventionsVersion = "1.26.0"
val schemaUrlVersions = listOf(
semanticConventionsVersion,
"1.25.0",
"1.24.0",
"1.23.1",
"1.22.0")

// Compute the artifact version, which includes the "-alpha" suffix and includes "-SNAPSHOT" suffix if not releasing
// Release example: version=1.21.0-alpha
// Snapshot example: version=1.21.0-alpha-SNAPSHOT
var releaseVersion = semanticConventionsVersion + "-alpha"
if (snapshot) {
releaseVersion += "-SNAPSHOT"
}

allprojects {
version = releaseVersion
}

nexusPublishing {
packageGroup.set("io.opentelemetry.semconv")

repositories {
sonatype {
username.set(System.getenv("SONATYPE_USER"))
password.set(System.getenv("SONATYPE_KEY"))
}
}

connectTimeout.set(Duration.ofMinutes(5))
clientTimeout.set(Duration.ofMinutes(5))

transitionCheckOptions {
// We have many artifacts so Maven Central takes a long time on its compliance checks. This sets
// the timeout for waiting for the repository to close to a comfortable 50 minutes.
maxRetries.set(300)
delayBetween.set(Duration.ofSeconds(10))
}
}

// start - define tasks to download, unzip, and generate from opentelemetry/semantic-conventions
var generatorVersion = "0.24.0"
val semanticConventionsRepoZip = "https://github.com/open-telemetry/semantic-conventions/archive/v${semanticConventionsVersion}.zip"
val schemaUrl = "https://opentelemetry.io/schemas/$semanticConventionsVersion"

val downloadSemanticConventions by tasks.registering(Download::class) {
src(semanticConventionsRepoZip)
dest("$buildDir/semantic-conventions-${semanticConventionsVersion}/semantic-conventions.zip")
overwrite(false)
}

val unzipConfigurationSchema by tasks.registering(Copy::class) {
dependsOn(downloadSemanticConventions)

from(zipTree(downloadSemanticConventions.get().dest))
eachFile(closureOf<FileCopyDetails> {
// Remove the top level folder "/semantic-conventions-$semanticConventionsVersion"
val pathParts = path.split("/")
path = pathParts.subList(1, pathParts.size).joinToString("/")
})
into("$buildDir/semantic-conventions-${semanticConventionsVersion}/")
}

fun generateTask(taskName: String, incubating: Boolean) {
tasks.register(taskName, Exec::class) {
dependsOn(unzipConfigurationSchema)

standardOutput = System.out
executable = "docker"

var filter = if (incubating) "any" else "is_stable"
var classPrefix = if (incubating) "Incubating" else ""
val outputDir = if (incubating) "semconv-incubating/src/main/java/io/opentelemetry/semconv/incubating/" else "semconv/src/main/java/io/opentelemetry/semconv/"
val packageNameArg = if (incubating) "io.opentelemetry.semconv.incubating" else "io.opentelemetry.semconv"
val stablePackageNameArg = if (incubating) "io.opentelemetry.semconv" else ""

setArgs(listOf(
"run",
"--rm",
"-v", "$buildDir/semantic-conventions-${semanticConventionsVersion}/model:/source",
"-v", "$projectDir/buildscripts/templates:/templates",
"-v", "$projectDir/$outputDir:/output",
"otel/semconvgen:$generatorVersion",
"--yaml-root", "/source",
"--continue-on-validation-errors",
"code",
"--template", "/templates/SemanticAttributes.java.j2",
"--output", "/output/{{pascal_prefix}}${classPrefix}Attributes.java",
"--file-per-group", "root_namespace",
// Space delimited list of root namespaces to excluded (i.e. "foo bar")
"-Dexcluded_namespaces=ios aspnetcore signalr",
"-Dexcluded_attributes=messaging.client_id",
"-Dfilter=${filter}",
"-DclassPrefix=${classPrefix}",
"-Dpkg=$packageNameArg",
"-DstablePkg=$stablePackageNameArg"))
}
}

generateTask("generateStableSemanticAttributes", false)
generateTask("generateIncubatingSemanticAttributes", true)

tasks.register("checkSchemaUrls") {
val schemaUrlsClass = File("$projectDir/semconv/src/main/java/io/opentelemetry/semconv/SchemaUrls.java")
if (!schemaUrlsClass.exists()) {
throw GradleException("SchemaUrls file does not exist")
}

for (schemaUrlVersion: String in schemaUrlVersions) {
val expectedLine = "public static final String V" + schemaUrlVersion.replace(".", "_") + " = \"https://opentelemetry.io/schemas/" + schemaUrlVersion + "\";"
if (!schemaUrlsClass.readLines().any { it.contains(expectedLine) }) {
throw GradleException("SchemaUrls file does not contain: $expectedLine")
}
}
}

val generateSemanticConventions by tasks.registering {
dependsOn(tasks.getByName("generateStableSemanticAttributes"))
dependsOn(tasks.getByName("generateIncubatingSemanticAttributes"))
dependsOn(tasks.getByName("checkSchemaUrls"))
}

tasks.register("build") {
dependsOn(tasks.getByName("checkSchemaUrls"))
}

// end
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
`kotlin-dsl`
}

repositories {
mavenCentral()
gradlePluginPortal()
mavenLocal()
}

dependencies {
implementation("com.diffplug.spotless:spotless-plugin-gradle:6.20.0")
implementation("ru.vyarus:gradle-animalsniffer-plugin:1.7.1")
implementation("me.champeau.gradle:japicmp-gradle-plugin:0.4.2")
// Needed for japicmp but not automatically brought in for some reason.
implementation("com.google.guava:guava:32.1.3-jre")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.gradle

import org.gradle.api.provider.Property

abstract class OtelJavaExtension {
abstract val moduleName: Property<String>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer

plugins {
`java-library`

id("ru.vyarus.animalsniffer")
}

dependencies {
add("signature", "com.toasttab.android:gummy-bears-api-21:0.3.0:coreLib@signature")
}

animalsniffer {
sourceSets = listOf(java.sourceSets.main.get())
}

tasks.withType<AnimalSniffer> {
// always having declared output makes this task properly participate in tasks up-to-date checks
reports.text.required.set(true)
}
Loading

0 comments on commit af17359

Please sign in to comment.