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

knowledgepixels / nanopub-registry / 20660876709

02 Jan 2026 03:22PM UTC coverage: 10.597% (+2.0%) from 8.593%
20660876709

push

github

ashleycaselli
refactor(RegistryDB): streamline environment variable retrieval to ease testing

54 of 588 branches covered (9.18%)

Branch coverage included in aggregate %.

198 of 1790 relevant lines covered (11.06%)

2.0 hits per line

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

77.3
src/main/java/com/knowledgepixels/registry/Utils.java
1
package com.knowledgepixels.registry;
2

3
import com.github.jsonldjava.shaded.com.google.common.base.Charsets;
4
import com.github.jsonldjava.shaded.com.google.common.reflect.TypeToken;
5
import com.google.common.hash.Hashing;
6
import com.google.gson.Gson;
7
import com.google.gson.JsonIOException;
8
import com.google.gson.JsonSyntaxException;
9
import com.mongodb.client.ClientSession;
10
import io.vertx.ext.web.RoutingContext;
11
import net.trustyuri.TrustyUriUtils;
12
import org.apache.commons.lang.StringUtils;
13
import org.commonjava.mimeparse.MIMEParse;
14
import org.eclipse.rdf4j.common.exception.RDF4JException;
15
import org.eclipse.rdf4j.model.IRI;
16
import org.eclipse.rdf4j.model.Resource;
17
import org.eclipse.rdf4j.model.Statement;
18
import org.eclipse.rdf4j.model.ValueFactory;
19
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
20
import org.nanopub.MalformedNanopubException;
21
import org.nanopub.Nanopub;
22
import org.nanopub.NanopubImpl;
23
import org.nanopub.NanopubUtils;
24
import org.nanopub.extra.setting.NanopubSetting;
25
import org.nanopub.vocabulary.NPX;
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
28

29
import java.io.File;
30
import java.io.IOException;
31
import java.io.InputStreamReader;
32
import java.lang.reflect.Type;
33
import java.net.URI;
34
import java.net.URISyntaxException;
35
import java.net.URLEncoder;
36
import java.nio.charset.StandardCharsets;
37
import java.util.*;
38

39
public class Utils {
40

41
    private static final Logger logger = LoggerFactory.getLogger(Utils.class);
9✔
42

43
    private Utils() {
44
    }  // no instances allowed
45

46
    public static String getMimeType(RoutingContext context, String supported) {
47
        List<String> supportedList = Arrays.asList(StringUtils.split(supported, ','));
×
48
        String mimeType = supportedList.getFirst();
×
49
        try {
50
            mimeType = MIMEParse.bestMatch(supportedList, context.request().getHeader("Accept"));
×
51
        } catch (Exception ex) {
×
52
            logger.error("Error parsing Accept header.", ex);
×
53
        }
×
54
        return mimeType;
×
55
    }
56

57
    public static String urlEncode(Object o) {
58
        return URLEncoder.encode((o == null ? "" : o.toString()), StandardCharsets.UTF_8);
27✔
59
    }
60

61
    public static String getHash(String s) {
62
        return Hashing.sha256().hashString(s, Charsets.UTF_8).toString();
18✔
63
    }
64

65
    public static Set<IRI> getInvalidatedNanopubIds(Nanopub np) {
66
        Set<IRI> l = new HashSet<IRI>();
×
67
        for (Statement st : NanopubUtils.getStatements(np)) {
×
68
            if (!(st.getObject() instanceof IRI)) continue;
×
69
            Resource s = st.getSubject();
×
70
            IRI p = st.getPredicate();
×
71
            if ((p.equals(NPX.RETRACTS) || p.equals(NPX.INVALIDATES)) || (p.equals(NPX.SUPERSEDES) && s.equals(np.getUri()))) {
×
72
                if (TrustyUriUtils.isPotentialTrustyUri(st.getObject().stringValue())) {
×
73
                    l.add((IRI) st.getObject());
×
74
                }
75
            }
76
        }
×
77
        return l;
×
78
    }
79

80
    private static ReadsEnvironment ENV_READER = new ReadsEnvironment(System::getenv);
15✔
81

82
    static void setEnvReader(ReadsEnvironment reader) {
83
        ENV_READER = reader;
6✔
84
    }
3✔
85

86
    public static String getEnv(String name, String defaultValue) {
87
        logger.info("Retrieving environment variable: {}", name);
12✔
88
        String value = ENV_READER.getEnv(name);
12✔
89
        if (value == null) {
6✔
90
            value = defaultValue;
6✔
91
            logger.info("The variable: {} is not set. Using default value: {}", name, defaultValue);
15✔
92
        }
93
        return value;
6✔
94
    }
95

96
    public static String getTypeHash(ClientSession mongoSession, Object type) {
97
        String typeHash = Utils.getHash(type.toString());
12✔
98
        if (type.toString().equals("$")) {
15✔
99
            typeHash = "$";
9✔
100
        } else {
101
            RegistryDB.recordHash(mongoSession, type.toString());
12✔
102
        }
103
        return typeHash;
6✔
104
    }
105

106
    public static String getAgentLabel(String agentId) {
107
        if (agentId == null || agentId.isBlank()) {
15✔
108
            throw new IllegalArgumentException("Agent ID cannot be null or blank");
15✔
109
        }
110
        agentId = agentId.replaceFirst("^https://orcid\\.org/", "orcid:");
15✔
111
        if (agentId.length() > 55) {
12✔
112
            return agentId.substring(0, 50) + "...";
18✔
113
        }
114
        return agentId;
6✔
115
    }
116

117
    public static boolean isUnloadedStatus(String status) {
118
        if (status.equals(EntryStatus.seen.getValue())) return true;  // only exists in "accounts_loading"?
21✔
119
        return status.equals(EntryStatus.skipped.getValue());
15✔
120
    }
121

122
    public static boolean isCoreLoadedStatus(String status) {
123
        if (status.equals(EntryStatus.visited.getValue())) return true;  // only exists in "accounts_loading"?
21✔
124
        if (status.equals(EntryStatus.expanded.getValue())) return true;  // only exists in "accounts_loading"?
21✔
125
        if (status.equals(EntryStatus.processed.getValue())) return true;  // only exists in "accounts_loading"?
21✔
126
        if (status.equals(EntryStatus.aggregated.getValue())) return true;  // only exists in "accounts_loading"?
21✔
127
        if (status.equals(EntryStatus.approved.getValue())) return true;  // only exists in "accounts_loading"?
21✔
128
        if (status.equals(EntryStatus.contested.getValue())) return true;
21✔
129
        if (status.equals(EntryStatus.toLoad.getValue())) return true;  // only exists in "accounts_loading"?
21✔
130
        return status.equals(EntryStatus.loaded.getValue());
15✔
131
    }
132

133
    public static boolean isFullyLoadedStatus(String status) {
134
        return status.equals(EntryStatus.loaded.getValue());
15✔
135
    }
136

137
    private static ValueFactory vf = SimpleValueFactory.getInstance();
6✔
138
    public static final IRI APPROVES_OF = vf.createIRI("http://purl.org/nanopub/x/approvesOf");
12✔
139

140
    public static final String TYPE_JSON = "application/json";
141
    public static final String TYPE_TRIG = "application/trig";
142
    public static final String TYPE_JELLY = "application/x-jelly-rdf";
143
    public static final String TYPE_JSONLD = "application/ld+json";
144
    public static final String TYPE_NQUADS = "application/n-quads";
145
    public static final String TYPE_TRIX = "application/trix";
146
    public static final String TYPE_HTML = "text/html";
147

148
    // Content types supported on a ListPage
149
    public static final String SUPPORTED_TYPES_LIST = TYPE_JSON + "," + TYPE_JELLY + "," + TYPE_HTML;
150
    // Content types supported on a NanopubPage
151
    public static final String SUPPORTED_TYPES_NANOPUB = TYPE_TRIG + "," + TYPE_JELLY + "," + TYPE_JSONLD + "," + TYPE_NQUADS + "," + TYPE_TRIX + "," + TYPE_HTML;
152

153
    private static Map<String, String> extensionTypeMap;
154

155
    public static String getType(String extension) {
156
        if (extension == null) {
6✔
157
            return null;
6✔
158
        }
159
        if (extensionTypeMap == null) {
6✔
160
            extensionTypeMap = new HashMap<>();
12✔
161
            extensionTypeMap.put("trig", TYPE_TRIG);
15✔
162
            extensionTypeMap.put("jelly", TYPE_JELLY);
15✔
163
            extensionTypeMap.put("jsonld", TYPE_JSONLD);
15✔
164
            extensionTypeMap.put("nq", TYPE_NQUADS);
15✔
165
            extensionTypeMap.put("xml", TYPE_TRIX);
15✔
166
            extensionTypeMap.put("html", TYPE_HTML);
15✔
167
            extensionTypeMap.put("json", TYPE_JSON);
15✔
168
        }
169
        return extensionTypeMap.get(extension);
15✔
170
    }
171

172
    private static List<String> peerUrls;
173

174
    public static List<String> getPeerUrls() {
175
        if (peerUrls == null) {
6✔
176
            peerUrls = new ArrayList<>();
12✔
177
            String envPeerUrls = getEnv("REGISTRY_PEER_URLS", "");
12✔
178
            String thisRegistryUrl = getEnv("REGISTRY_SERVICE_URL", "");
12✔
179
            if (!envPeerUrls.isEmpty()) {
9✔
180
                for (String peerUrl : envPeerUrls.split(";")) {
57✔
181
                    if (thisRegistryUrl.equals(peerUrl)) {
12!
182
                        continue;
×
183
                    }
184
                    peerUrls.add(peerUrl);
12✔
185
                }
186
            } else {
187
                NanopubSetting setting;
188
                try {
189
                    setting = getSetting();
6✔
190
                } catch (MalformedNanopubException | IOException ex) {
3✔
191
                    logger.error("Error loading registry setting: {}", ex.getMessage());
15✔
192
                    throw new RuntimeException(ex);
15✔
193
                }
3✔
194
                for (IRI iri : setting.getBootstrapServices()) {
33✔
195
                    String peerUrl = iri.stringValue();
9✔
196
                    if (thisRegistryUrl.equals(peerUrl)) {
12!
197
                        continue;
×
198
                    }
199
                    peerUrls.add(peerUrl);
12✔
200
                }
3✔
201
            }
202
        }
203
        return peerUrls;
6✔
204
    }
205

206
    private static volatile NanopubSetting settingNp;
207

208
    public static NanopubSetting getSetting() throws RDF4JException, MalformedNanopubException, IOException {
209
        if (settingNp == null) {
6✔
210
            synchronized (Utils.class) {
12✔
211
                if (settingNp == null) {
6!
212
                    String settingPath = getEnv("REGISTRY_SETTING_FILE", "/data/setting.trig");
12✔
213
                    settingNp = new NanopubSetting(new NanopubImpl(new File(settingPath)));
33✔
214
                }
215
            }
9✔
216
        }
217
        return settingNp;
6✔
218
    }
219

220
    public static String getRandomPeer() throws RDF4JException {
221
        List<String> peerUrls = getPeerUrls();
6✔
222
        return peerUrls.get(random.nextInt(peerUrls.size()));
24✔
223
    }
224

225
    private static final Random random = new Random();
12✔
226

227
    public static Random getRandom() {
228
        return random;
6✔
229
    }
230

231
    private static final Gson g = new Gson();
12✔
232
    private static Type listType = new TypeToken<List<String>>() {
21✔
233
    }.getType();
6✔
234

235
    public static List<String> retrieveListFromJsonUrl(String url) throws JsonIOException, JsonSyntaxException, IOException, URISyntaxException {
236
        return g.fromJson(new InputStreamReader(new URI(url).toURL().openStream()), listType);
×
237
    }
238

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