• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

knowledgepixels / nanopub-registry / 21167271454

20 Jan 2026 10:01AM UTC coverage: 18.763% (-0.02%) from 18.779%
21167271454

push

github

ashleycaselli
refactor(logging): replace System.err with SLF4J logger for improved logging consistency

96 of 586 branches covered (16.38%)

Branch coverage included in aggregate %.

350 of 1791 relevant lines covered (19.54%)

3.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
src/main/java/com/knowledgepixels/registry/MainVerticle.java
1
package com.knowledgepixels.registry;
2

3
import com.mongodb.client.ClientSession;
4
import io.micrometer.prometheus.PrometheusMeterRegistry;
5
import io.vertx.core.AbstractVerticle;
6
import io.vertx.core.Handler;
7
import io.vertx.core.Promise;
8
import io.vertx.core.http.HttpMethod;
9
import io.vertx.core.http.HttpServer;
10
import io.vertx.ext.web.Router;
11
import io.vertx.ext.web.RoutingContext;
12
import io.vertx.micrometer.PrometheusScrapingHandler;
13
import io.vertx.micrometer.backends.BackendRegistries;
14
import net.trustyuri.TrustyUriUtils;
15
import org.eclipse.rdf4j.rio.RDFFormat;
16
import org.eclipse.rdf4j.rio.Rio;
17
import org.nanopub.MalformedNanopubException;
18
import org.nanopub.Nanopub;
19
import org.nanopub.NanopubImpl;
20
import org.nanopub.extra.server.PublishNanopub;
21
import org.slf4j.Logger;
22
import org.slf4j.LoggerFactory;
23

24
import java.util.concurrent.TimeUnit;
25

26
import static com.knowledgepixels.registry.RegistryDB.has;
27
import static com.knowledgepixels.registry.RegistryDB.isSet;
28

29
public class MainVerticle extends AbstractVerticle {
×
30

31
    private final Logger logger = LoggerFactory.getLogger(MainVerticle.class);
×
32

33
    @Override
34
    public void start(Promise<Void> startPromise) {
35
        HttpServer server = vertx.createHttpServer();
×
36
        Router router = Router.router(vertx);
×
37
        server.requestHandler(router);
×
38
        server.listen(9292);
×
39
        router.route(HttpMethod.GET, "/agent*").handler(c -> {
×
40
            // /agent/... | /agents | /agentAccounts
41
            ListPage.show(c);
×
42
        });
×
43
        router.route(HttpMethod.GET, "/nanopubs*").handler(c -> {
×
44
            ListPage.show(c);
×
45
        });
×
46
        router.route(HttpMethod.GET, "/list*").handler(c -> {
×
47
            ListPage.show(c);
×
48
        });
×
49
        router.route(HttpMethod.GET, "/pubkeys*").handler(c -> {
×
50
            ListPage.show(c);
×
51
        });
×
52
        router.route(HttpMethod.GET, "/np/").handler(c -> {
×
53
            c.response().putHeader("Location", "/").setStatusCode(307).end();
×
54
        });
×
55
        router.route(HttpMethod.GET, "/np/*").handler(c -> {
×
56
            NanopubPage.show(c);
×
57
        });
×
58
        router.route(HttpMethod.GET, "/debug/*").handler(c -> {
×
59
            DebugPage.show(c);
×
60
        });
×
61
        router.route(HttpMethod.GET, "/style.css").handler(c -> {
×
62
            ResourcePage.show(c, "style.css", "text/css");
×
63
        });
×
64

65
        // Metrics
66
        final var metricsHttpServer = vertx.createHttpServer();
×
67
        final var metricsRouter = Router.router(vertx);
×
68
        metricsHttpServer.requestHandler(metricsRouter).listen(9293);
×
69

70
        final var metricsRegistry = (PrometheusMeterRegistry) BackendRegistries.getDefaultNow();
×
71
        final var collector = new MetricsCollector(metricsRegistry);
×
72
        metricsRouter.route("/metrics").handler(PrometheusScrapingHandler.create(metricsRegistry));
×
73

74
        router.route(HttpMethod.GET, "/*").handler(c -> {
×
75
            MainPage.show(c);
×
76
        });
×
77
        router.route(HttpMethod.HEAD, "/*").handler(c -> {
×
78
            MainPage.show(c);
×
79
        });
×
80

81
        Handler<RoutingContext> postHandler = c -> {
×
82
            c.request().bodyHandler(bh -> {
×
83
                try {
84
                    String contentType = c.request().getHeader("Content-Type");
×
85
                    Nanopub np = null;
×
86
                    try {
87
                        np = new NanopubImpl(bh.toString(), Rio.getParserFormatForMIMEType(contentType).orElse(RDFFormat.TRIG));
×
88
                    } catch (MalformedNanopubException ex) {
×
89
                        ex.printStackTrace();
×
90
                    }
×
91
                    if (np != null) {
×
92
                        try (ClientSession s = RegistryDB.getClient().startSession()) {
×
93
                            String ac = TrustyUriUtils.getArtifactCode(np.getUri().toString());
×
94
                            if (has(s, Collection.NANOPUBS.toString(), ac)) {
×
95
                                logger.info("POST: known nanopub {}", ac);
×
96
                            } else {
97
                                logger.info("POST: new nanopub {}", ac);
×
98

99
                                // TODO Run checks here whether we want to register this nanopub (considering quotas etc.)
100

101
                                // Load to nanopub store:
102
                                boolean success = RegistryDB.loadNanopub(s, np);
×
103
                                if (!success)
×
104
                                    throw new RuntimeException("Nanopublication not supported: " + np.getUri());
×
105
                                // Load to lists, if applicable:
106
                                NanopubLoader.simpleLoad(s, np);
×
107

108
                                if (!isSet(s, Collection.SERVER_INFO.toString(), "testInstance")) {
×
109
                                    // Here we publish it also to the first-generation services, so they know about it too:
110
                                    // TODO Remove this at some point
111
                                    try {
112
                                        new PublishNanopub().publishNanopub(np, "https://np.knowledgepixels.com/");
×
113
                                    } catch (Exception ex) {
×
114
                                        ex.printStackTrace();
×
115
                                    }
×
116
                                }
117
                            }
118
                        }
119
                    }
120
                    c.response().setStatusCode(201);
×
121
                } catch (Exception ex) {
×
122
                    c.response().setStatusCode(400).setStatusMessage("Error processing nanopub: " + ex.getMessage());
×
123
                } finally {
124
                    c.response().end();
×
125
                }
126
            });
×
127
        };
×
128
        router.route(HttpMethod.POST, "/").handler(postHandler);
×
129
        router.route(HttpMethod.POST, "/np/").handler(postHandler);
×
130

131
        // INIT
132
        vertx.executeBlocking(() -> {
×
133

134
            RegistryDB.init();
×
135

136
            new Thread(() -> {
×
137
                Task.runTasks();
×
138
            }).start();
×
139

140
            return null;
×
141
        }).onComplete(res -> {
×
142
            logger.info("DB initialization finished");
×
143
        });
×
144

145
        // Periodic metrics update
146
        vertx.setPeriodic(1000, id -> collector.updateMetrics());
×
147

148
        // SHUTDOWN
149
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
×
150
            try {
151
                logger.info("Gracefully shutting down...");
×
152
                RegistryDB.getClient().close();
×
153
                vertx.close().toCompletionStage().toCompletableFuture().get(5, TimeUnit.SECONDS);
×
154
                logger.info("Graceful shutdown completed");
×
155
            } catch (Exception ex) {
×
156
                logger.error("Graceful shutdown failed");
×
157
                ex.printStackTrace();
×
158
            }
×
159
        }));
×
160

161
    }
×
162

163
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc