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

knowledgepixels / nanopub-registry / 20413250445

21 Dec 2025 05:19PM UTC coverage: 0.924% (-0.03%) from 0.954%
20413250445

push

github

ashleycaselli
chore: minor code cleanup

6 of 592 branches covered (1.01%)

Branch coverage included in aggregate %.

16 of 1789 relevant lines covered (0.89%)

0.11 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

22
import java.util.concurrent.TimeUnit;
23

24
import static com.knowledgepixels.registry.RegistryDB.has;
25
import static com.knowledgepixels.registry.RegistryDB.isSet;
26

27
public class MainVerticle extends AbstractVerticle {
×
28

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

61
        // Metrics
62
        final var metricsHttpServer = vertx.createHttpServer();
×
63
        final var metricsRouter = Router.router(vertx);
×
64
        metricsHttpServer.requestHandler(metricsRouter).listen(9293);
×
65

66
        final var metricsRegistry = (PrometheusMeterRegistry) BackendRegistries.getDefaultNow();
×
67
        final var collector = new MetricsCollector(metricsRegistry);
×
68
        metricsRouter.route("/metrics").handler(PrometheusScrapingHandler.create(metricsRegistry));
×
69

70
        router.route(HttpMethod.GET, "/*").handler(c -> {
×
71
            MainPage.show(c);
×
72
        });
×
73
        router.route(HttpMethod.HEAD, "/*").handler(c -> {
×
74
            MainPage.show(c);
×
75
        });
×
76

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

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

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

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

127
        // INIT
128
        vertx.executeBlocking(() -> {
×
129

130
            RegistryDB.init();
×
131

132
            new Thread(() -> {
×
133
                Task.runTasks();
×
134
            }).start();
×
135

136
            return null;
×
137
        }).onComplete(res -> {
×
138
            System.err.println("DB initialization finished");
×
139
        });
×
140

141
        // Periodic metrics update
142
        vertx.setPeriodic(1000, id -> collector.updateMetrics());
×
143

144
        // SHUTDOWN
145
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
×
146
            try {
147
                System.err.println("Gracefully shutting down...");
×
148
                RegistryDB.getClient().close();
×
149
                vertx.close().toCompletionStage().toCompletableFuture().get(5, TimeUnit.SECONDS);
×
150
                System.err.println("Graceful shutdown completed");
×
151
            } catch (Exception ex) {
×
152
                System.err.println("Graceful shutdown failed");
×
153
                ex.printStackTrace();
×
154
            }
×
155
        }));
×
156

157
    }
×
158

159
}
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