Skip to content

Commit

Permalink
detect version based on jar file name
Browse files Browse the repository at this point in the history
  • Loading branch information
zeitlinger committed Feb 12, 2024
1 parent d0763d9 commit 6346da7
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import com.google.auto.service.AutoService;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider;
Expand All @@ -19,10 +20,13 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

/**
Expand All @@ -37,6 +41,27 @@ public final class JarServiceNameDetector implements ConditionalResourceProvider
private final Function<String, String> getSystemProperty;
private final Predicate<Path> fileExists;

private static final Pattern JAR_FILE_VERSION_PATTERN = Pattern.compile("[-_]v?\\d.*");

private static final Pattern ANY_DIGIT = Pattern.compile("\\d");

private static class NameAndVersion {
final String name;
final Optional<String> version;

NameAndVersion(String name, Optional<String> version) {
this.name = name;
this.version = version;
}

@Override
public String toString() {
return version
.map(v -> String.format("name: %s, version: %s", name, v))
.orElse(String.format("name: %s", name));
}
}

@SuppressWarnings("unused") // SPI
public JarServiceNameDetector() {
this(ProcessArguments::getProcessArguments, System::getProperty, Files::isRegularFile);
Expand All @@ -61,9 +86,12 @@ public Resource createResource(ConfigProperties config) {
if (jarPath == null) {
return Resource.empty();
}
String serviceName = getServiceName(jarPath);
logger.log(FINE, "Auto-detected service name from the jar file name: {0}", serviceName);
return Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, serviceName));
NameAndVersion nameAndVersion = getServiceNameAndVersion(jarPath);
logger.log(FINE, "Auto-detected service name from the jar file: {0}", nameAndVersion);
AttributesBuilder builder =
Attributes.builder().put(ResourceAttributes.SERVICE_NAME, nameAndVersion.name);
nameAndVersion.version.ifPresent(v -> builder.put(ResourceAttributes.SERVICE_VERSION, v));
return Resource.create(builder.build());
}

@Override
Expand Down Expand Up @@ -121,10 +149,27 @@ private Path pathIfExists(String programArguments) {
return fileExists.test(candidate) ? candidate : null;
}

private static String getServiceName(Path jarPath) {
private static NameAndVersion getServiceNameAndVersion(Path jarPath) {
String jarName = jarPath.getFileName().toString();
int dotIndex = jarName.lastIndexOf(".");
return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex);
if (dotIndex == -1 || ANY_DIGIT.matcher(jarName.substring(dotIndex)).find()) {
// don't change if digit it extension, it's probably a version
return new NameAndVersion(jarName, Optional.empty());
}

return getNameAndVersion(jarName.substring(0, dotIndex));
}

private static NameAndVersion getNameAndVersion(String jarNameWithoutExtension) {
Matcher matcher = JAR_FILE_VERSION_PATTERN.matcher(jarNameWithoutExtension);
if (matcher.find()) {
int start = matcher.start();
String name = jarNameWithoutExtension.substring(0, start);
String version = jarNameWithoutExtension.substring(start + 1);
return new NameAndVersion(name, Optional.of(version));
}

return new NameAndVersion(jarNameWithoutExtension, Optional.empty());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
import io.opentelemetry.semconv.ResourceAttributes;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

Expand Down Expand Up @@ -53,32 +56,38 @@ void createResource_noJarFileInArgs() {
assertThat(resource.getAttributes()).isEmpty();
}

@Test
void createResource_processHandleJar() {
String path = Paths.get("path", "to", "app", "my-service.jar").toString();
@ParameterizedTest(name = "[{index}]: {0} -> {1}, {2}")
@CsvSource({
"my-service, my-service, ",
"my-service.jar0, my-service.jar0, ",
"my-service.jar, my-service, ",
"my-service-1.0.0-SNAPSHOT, my-service-1.0.0-SNAPSHOT, ",
"my-service-1.0.0-SNAPSHOT.jar, my-service, 1.0.0-SNAPSHOT",
"my-service-v1.0.0-SNAPSHOT.jar, my-service, v1.0.0-SNAPSHOT",
"my-service-1.0.0, my-service-1.0.0, ",
"my-service-1.0.0.jar, my-service, 1.0.0",
"my-service-v1.0.0.jar, my-service, v1.0.0",
"my-service2.3-1.0.0.jar, my-service2.3, 1.0.0",
"my-service-2.3-1.0.0.jar, my-service, 2.3-1.0.0",
"my_service_2.3_1.0.0.jar, my_service, 2.3_1.0.0",
})
void createResource_processHandleJar(
String jar, String expectedServiceName, @Nullable String expectedServiceVersion) {
String path = Paths.get("path", "to", "app", jar).toString();
String[] args = new String[] {"-Dtest=42", "-Xmx666m", "-jar", path, "abc", "def"};
JarServiceNameDetector serviceNameProvider =
new JarServiceNameDetector(() -> args, prop -> null, JarServiceNameDetectorTest::failPath);

Resource resource = serviceNameProvider.createResource(config);

assertThat(resource.getAttributes())
.hasSize(1)
.containsEntry(ResourceAttributes.SERVICE_NAME, "my-service");
}
AttributesAssert attributesAssert = assertThat(resource.getAttributes());
attributesAssert.containsEntry(ResourceAttributes.SERVICE_NAME, expectedServiceName);

@Test
void createResource_processHandleJarWithoutExtension() {
String path = Paths.get("path", "to", "app", "my-service.jar").toString();
String[] args = new String[] {"-Dtest=42", "-Xmx666m", "-jar", path};
JarServiceNameDetector serviceNameProvider =
new JarServiceNameDetector(() -> args, prop -> null, JarServiceNameDetectorTest::failPath);

Resource resource = serviceNameProvider.createResource(config);

assertThat(resource.getAttributes())
.hasSize(1)
.containsEntry(ResourceAttributes.SERVICE_NAME, "my-service");
if (expectedServiceVersion == null) {
attributesAssert.doesNotContainKey(ResourceAttributes.SERVICE_VERSION);
} else {
attributesAssert.containsEntry(ResourceAttributes.SERVICE_VERSION, expectedServiceVersion);
}
}

@ParameterizedTest
Expand Down

0 comments on commit 6346da7

Please sign in to comment.