Skip to content
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
13 changes: 13 additions & 0 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ jobs:
name: Build and test
runs-on: ubuntu-latest
steps:
- name: Check secrets
if: ${{ !github.event.pull_request.head.repo.fork }}
run: |
[ -z "${{secrets.VAADIN_PRO_KEY}}" ] \
&& echo "🚫 **VAADIN_PRO_KEY** is not defined, check that **${{github.repository}}** repo has a valid secret" \
| tee -a $GITHUB_STEP_SUMMARY && exit 1 || exit 0

- name: Checkout
uses: actions/checkout@v4

Expand All @@ -26,6 +33,12 @@ jobs:
java-version: '21'
cache: maven

- name: Set TB License
run: |
TB_LICENSE=${{secrets.VAADIN_PRO_KEY}}
mkdir -p ~/.vaadin/
echo '{"username":"'$(echo $TB_LICENSE | cut -d / -f1)'","proKey":"'$(echo $TB_LICENSE | cut -d / -f2)'"}' > ~/.vaadin/proKey

- name: Check formatting (Spotless)
run: mvn -B -ntp spotless:check

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ Thumbs.db

# Superpowers specs & plans (local only, not committed)
docs/superpowers/
*.bundle
**/src/main/frontend/generated
136 changes: 136 additions & 0 deletions observability-kit-tests/observability-kit-micrometer-tests/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>observability-kit-micrometer-test</artifactId>
<version>5.0-SNAPSHOT</version>
</parent>
<artifactId>observability-kit-micrometer-tests</artifactId>

<packaging>war</packaging>
<name>Test Vaadin Micrometer integration on a real Jetty deployment</name>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>observability-kit-micrometer</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-testbench-core-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-server</artifactId>
<version>${flow.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-client</artifactId>
<version>${flow.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-html-components</artifactId>
<version>${flow.version}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>${servlet.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-html-components-testbench</artifactId>
<version>${flow.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<defaultGoal>jetty:run</defaultGoal>
<plugins>
<!-- Run flow plugin to build frontend -->
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>flow-maven-plugin</artifactId>
<version>${flow.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
<!-- Run jetty before integration tests, and stop after -->
<plugin>
<groupId>org.eclipse.jetty.ee10</groupId>
<artifactId>jetty-ee10-maven-plugin</artifactId>
<version>12.1.8</version>

<configuration>
<!-- Control port/key the stop goal uses to talk to the running
server; without these the stop-jetty execution fails with
"Please specify a valid port". -->
<stopPort>8089</stopPort>
<stopKey>observability-kit-micrometer</stopKey>
<stopWait>5</stopWait>
</configuration>

<executions>
<!-- start and stop jetty (running our app) when running
integration tests -->
<execution>
<id>start-jetty</id>
<goals>
<goal>start</goal>
</goals>
<phase>pre-integration-test</phase>
</execution>
<execution>
<id>stop-jetty</id>
<goals>
<goal>stop</goal>
</goals>
<phase>post-integration-test</phase>
</execution>
</executions>
</plugin>
<!-- Run the *IT browser tests against the running Jetty. The tests are
JUnit 5 TestBench tests (@BrowserTest), so failsafe uses the JUnit
Platform provider (active via junit-jupiter on the test classpath).
Unlike flow-tests we do not force the surefire-junit47 provider,
which only runs JUnit 4 tests and would skip these. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<!--
This file is auto-generated by Vaadin.
-->

<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<style>
html, body, #outlet {
height: 100%;
width: 100%;
margin: 0;
}
</style>
<!-- index.ts is included here automatically (either by the dev server or during the build) -->
</head>
<body>
<!-- This outlet div is where the views are rendered -->
<div id="outlet"></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.observability.micrometer.tests;

import jakarta.servlet.annotation.WebServlet;

import com.vaadin.flow.server.VaadinServlet;

/**
* Explicit {@link VaadinServlet} declaration. Required here because the WAR
* also declares {@link MetricsServlet}, which suppresses Vaadin's automatic
* servlet registration. The more-specific {@code /metrics} mapping still wins
* over this catch-all for that path.
*/
@WebServlet(asyncSupported = true, urlPatterns = { "/*" })
public class AppServlet extends VaadinServlet {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.observability.micrometer.tests;

import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.router.Route;

/**
* Simple landing view; opening it drives a real Vaadin session, UI and
* navigation through the framework so the micrometer binders fire.
*/
@Route("")
public class HelloView extends Div {

public HelloView() {
Span greeting = new Span("Hello micrometer");
greeting.setId("greeting");
add(greeting);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.observability.micrometer.tests;

import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;

/**
* Dumps the shared {@link MicrometerRegistry} as a deterministic, sorted
* plain-text format that the IT can scrape via HTTP.
*/
@WebServlet(urlPatterns = "/metrics", asyncSupported = false)
public class MetricsServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/plain; charset=utf-8");
try (PrintWriter writer = resp.getWriter()) {
MicrometerRegistry.INSTANCE.getMeters().stream()
.sorted((a, b) -> a.getId().getName()
.compareTo(b.getId().getName()))
.forEach(meter -> writeMeter(writer, meter));
}
}

private void writeMeter(PrintWriter writer, Meter meter) {
String id = formatId(meter);
if (meter instanceof Counter c) {
writer.printf("%s count=%.0f%n", id, c.count());
} else if (meter instanceof Gauge g) {
writer.printf("%s value=%.0f%n", id, g.value());
} else if (meter instanceof Timer t) {
writer.printf("%s count=%d total_ms=%.3f%n", id, t.count(),
t.totalTime(java.util.concurrent.TimeUnit.MILLISECONDS));
}
}

private String formatId(Meter meter) {
StringBuilder sb = new StringBuilder(meter.getId().getName());
for (Tag tag : meter.getId().getTagsAsIterable()) {
sb.append(' ').append(tag.getKey()).append('=')
.append(tag.getValue());
}
return sb.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.observability.micrometer.tests;

import io.micrometer.core.instrument.simple.SimpleMeterRegistry;

/**
* Static holder so the Vaadin micrometer binders and the {@link MetricsServlet}
* share the same {@link SimpleMeterRegistry} for the duration of the
* deployment.
*/
public final class MicrometerRegistry {

static final SimpleMeterRegistry INSTANCE = new SimpleMeterRegistry();

private MicrometerRegistry() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.observability.micrometer.tests;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;

import com.vaadin.observability.micrometer.ObservabilityKit;
import com.vaadin.observability.micrometer.ObservabilitySettings;

/**
* Boots observability-kit-micrometer at servlet-context startup so the
* SPI-loaded {@code MetricsServiceInitListener} can pick up the registry when
* Vaadin's service initializes.
*/
@WebListener
public class MicrometerSetup implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent sce) {
ObservabilityKit.install(MicrometerRegistry.INSTANCE,
ObservabilitySettings.builder().build());
}
}
Loading
Loading