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

FIWARE / mintaka / #449

31 Jul 2024 12:25PM UTC coverage: 83.538% (+0.1%) from 83.392%
#449

push

web-flow
fix context usage (#166)

* fix context usage

* fix not found response

* remove the whitespace

1426 of 1707 relevant lines covered (83.54%)

0.84 hits per line

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

81.08
src/main/java/org/fiware/mintaka/context/LdContextCache.java
1
package org.fiware.mintaka.context;
2

3
import com.apicatalog.jsonld.JsonLdError;
4
import com.apicatalog.jsonld.document.Document;
5
import com.apicatalog.jsonld.document.JsonDocument;
6
import com.fasterxml.jackson.core.JsonProcessingException;
7
import com.fasterxml.jackson.databind.ObjectMapper;
8
import com.github.jsonldjava.core.JsonLdConsts;
9
import com.github.jsonldjava.core.JsonLdProcessor;
10
import com.github.jsonldjava.utils.JsonUtils;
11
import io.micronaut.cache.annotation.CacheConfig;
12
import io.micronaut.cache.annotation.Cacheable;
13
import io.micronaut.context.annotation.Context;
14
import lombok.RequiredArgsConstructor;
15
import lombok.extern.slf4j.Slf4j;
16
import org.fiware.mintaka.exception.ContextRetrievalException;
17
import org.fiware.mintaka.exception.StringExpansionException;
18

19
import javax.annotation.PostConstruct;
20
import java.io.ByteArrayInputStream;
21
import java.io.IOException;
22
import java.net.MalformedURLException;
23
import java.net.URI;
24
import java.net.URISyntaxException;
25
import java.net.URL;
26
import java.nio.charset.StandardCharsets;
27
import java.util.List;
28
import java.util.Map;
29
import java.util.Optional;
30
import java.util.Set;
31
import java.util.stream.Collectors;
32

33
/**
34
 * Cache for ld context. Provides additional functionality to work with the context.
35
 */
36
@Slf4j
1✔
37
@Context
38
@CacheConfig("contexts")
39
@RequiredArgsConstructor
40
public class LdContextCache {
41

42
    private final ContextProperties contextProperties;
43

44
    private URL coreContextUrl;
45
    private Object coreContext;
46

47
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
1✔
48

49
    @PostConstruct
50
    public void initDefaultContext() {
51
        try {
52
            coreContextUrl = new URL(contextProperties.getDefaultUrl());
1✔
53
            coreContext = JsonUtils.fromURLJavaNet(coreContextUrl);
1✔
54
        } catch (IOException e) {
×
55
            throw new ContextRetrievalException("Invalid core context configured.", e, contextProperties.getDefaultUrl());
×
56
        }
1✔
57
    }
1✔
58

59
    /**
60
     * Get context from the given url. Will be cached.
61
     *
62
     * @param url - url to get the context from
63
     * @return the context
64
     */
65
    @Cacheable
66
    public Object getContextFromURL(URL url) {
67
        try {
68
            if (url.toURI().equals(coreContextUrl.toURI())) {
1✔
69
                return coreContext;
1✔
70
            }
71
            return JsonUtils.fromURLJavaNet(url);
1✔
72
        } catch (IOException e) {
×
73
            throw new ContextRetrievalException(String.format("Was not able to retrieve context from %s.", url), e, url.toString());
×
74
        } catch (URISyntaxException uriSyntaxException) {
×
75
            throw new IllegalArgumentException(String.format("Received an invalid url: %s", url), uriSyntaxException);
×
76
        }
77
    }
78

79
    /**
80
     * Expand all given attributes with the given contexts.
81
     *
82
     * @param stringsToExpand - strings to be expanded
83
     * @param contextUrls     - urls of contexts to be used for expansion
84
     * @return list of expanded attribute-ids
85
     */
86
    public List<String> expandStrings(List<String> stringsToExpand, List<URL> contextUrls) {
87
        Map contextMap = (Map) getContext(contextUrls);
1✔
88

89
        return stringsToExpand.stream()
1✔
90
                .map(stringToExpand -> expandString(stringToExpand, contextMap))
1✔
91
                .collect(Collectors.toList());
1✔
92
    }
93

94
    /**
95
     * Expand the given string with the provided contexts.
96
     *
97
     * @param stringToExpand - string to be expanded
98
     * @param contextUrls    - urls of contexts to be used for expansion
99
     * @return the expanded attribute-id
100
     */
101
    public String expandString(String stringToExpand, List<URL> contextUrls) {
102
        return expandString(stringToExpand, (Map) getContext(contextUrls));
1✔
103
    }
104

105
    private String expandString(String stringToExpand, Map contextMap) {
106
        String jsonLdString = getJsonLdString(stringToExpand);
1✔
107
        try {
108
            Map jsonLdObject = (Map) JsonUtils.fromString(jsonLdString);
1✔
109
            jsonLdObject.put(JsonLdConsts.CONTEXT, contextMap.get(JsonLdConsts.CONTEXT));
1✔
110
            return getIdFromJsonLDObject(jsonLdObject);
1✔
111
        } catch (IOException e) {
×
112
            throw new StringExpansionException(String.format("Was not able expand %s.", jsonLdString), e);
×
113
        }
114
    }
115

116
    /**
117
     * Retrieve the context as a JsonDocument
118
     *
119
     * @param contextURLs - either be a (URL)String, a URL or a list of urls/urlstrings.
120
     * @return the context
121
     */
122
    public Document getContextDocument(Object contextURLs) {
123
        try {
124
            Object context = getContext(contextURLs);
1✔
125
            return JsonDocument.of(new ByteArrayInputStream(OBJECT_MAPPER.writeValueAsString(context).getBytes(StandardCharsets.UTF_8)));
1✔
126
        } catch (JsonLdError | JsonProcessingException e) {
×
127
            throw new IllegalArgumentException(String.format("No valid context available via %s", contextURLs), e);
×
128
        }
129
    }
130

131
    /**
132
     * Get the context from the given object. Should either be a (URL)String, a URL or a list of urls/urlstrings.
133
     * We use the Json-ld-java lib for retrieval, since the titanium lib is not able to combine context objects.
134
     *
135
     * @param contextURLs - either be a (URL)String, a URL or a list of urls/urlstrings.
136
     * @return the context
137
     */
138
    private Object getContext(Object contextURLs) {
139
        if (contextURLs instanceof List) {
1✔
140
            var m = Map.of(JsonLdConsts.CONTEXT, ((List) contextURLs).stream()
1✔
141
                    .map(url -> getContext(url))
1✔
142
                    .map(contextMap -> ((Map<String, Object>) contextMap).get(JsonLdConsts.CONTEXT))
1✔
143
                    .map(contextObject -> {
1✔
144
                        // follow potential list-contexts
145
                        if (contextObject instanceof List) {
1✔
146
                            return getContext((List) contextObject);
1✔
147
                        }
148
                        return contextObject;
1✔
149
                    })
150
                    .map(co -> {
1✔
151
                        if (co instanceof Map<?, ?> coMap) {
1✔
152
                            if (coMap.containsKey(JsonLdConsts.CONTEXT)) {
1✔
153
                                return coMap.get(JsonLdConsts.CONTEXT);
1✔
154
                            }
155
                        }
156
                        return co;
1✔
157
                    })
158
                    .flatMap(map -> ((Map<String, Object>) map).entrySet().stream())
1✔
159
                    .collect(Collectors.toMap(e -> ((Map.Entry<String, Object>) e).getKey(), e -> ((Map.Entry<String, Object>) e).getValue(), (e1, e2) -> e2)));
1✔
160
            return m;
1✔
161
        } else if (contextURLs instanceof URL) {
1✔
162
            return getContextFromURL((URL) contextURLs);
1✔
163
        } else if (contextURLs instanceof String) {
1✔
164
            return getContextFromURL((String) contextURLs);
1✔
165
        } else if (contextURLs instanceof URI) {
1✔
166
            return getContextFromURL(contextURLs.toString());
1✔
167
        }
168
        throw new ContextRetrievalException(String.format("Did not receive a valid context: %s.", contextURLs), contextURLs.toString());
×
169
    }
170

171

172
    /**
173
     * Get the context from the given url
174
     *
175
     * @param urlString - string containing the url
176
     * @return the context
177
     */
178
    private Object getContextFromURL(String urlString) {
179
        try {
180
            return getContextFromURL(new URL(urlString));
1✔
181
        } catch (MalformedURLException e) {
×
182
            throw new ContextRetrievalException(String.format("Was not able to convert %s to URL.", urlString), e, urlString);
×
183
        }
184
    }
185

186

187
    /**
188
     * Extract the context urls from the link header. CORE_CONTEXT will be automatically added.
189
     *
190
     * @param headerString - content of the link header
191
     * @return list of context urls, will either be only the core context or the core-context + the header context
192
     */
193
    public List<URL> getContextURLsFromLinkHeader(String headerString) {
194

195
        Optional<String> linkedContextString = Optional.empty();
1✔
196

197
        if (headerString != null && !headerString.isEmpty() && !headerString.isBlank()) {
1✔
198
            linkedContextString = Optional.of(headerString.split(";")[0].replace("<", "").replace(">", ""));
1✔
199
        }
200

201
        return linkedContextString
1✔
202
                .map(lCS -> {
1✔
203
                    try {
204
                        return new URL(lCS);
1✔
205
                    } catch (MalformedURLException e) {
1✔
206
                        throw new IllegalArgumentException("Context url is invalid.", e);
1✔
207
                    }
208
                })
209
                .map(url -> List.of(url, coreContextUrl)).orElse(List.of(coreContextUrl));
1✔
210
    }
211

212
    // extract the Id from the expanded object
213
    private String getIdFromJsonLDObject(Map<String, Object> jsonLdObject) {
214
        Map<String, Object> expandedObject = (Map<String, Object>) JsonLdProcessor.expand(jsonLdObject)
1✔
215
                .stream()
1✔
216
                .findFirst()
1✔
217
                .orElseThrow(() -> new StringExpansionException(String.format("Was not able to get an expanded object for %s.", jsonLdObject)));
1✔
218
        Set<String> expandedKeys = expandedObject.keySet();
1✔
219
        if (expandedKeys.size() != 1) {
1✔
220
            throw new StringExpansionException(String.format("Was not able to correctly expand key. Got multiple keys: %s", expandedKeys));
×
221
        }
222
        return expandedKeys.iterator().next();
1✔
223
    }
224

225
    // create a json object for json-ld api to be used for extending the key.
226
    private String getJsonLdString(String string) {
227
        return String.format("{\"%s\":\"\"}", string);
1✔
228
    }
229

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