Skip to content

Commit

Permalink
Merge pull request #433 from ScorpioBroker/follow-rel-query
Browse files Browse the repository at this point in the history
Follow rel query
  • Loading branch information
ScorpioBroker committed Sep 2, 2023
2 parents b87710a + 7286e6e commit 095f178
Show file tree
Hide file tree
Showing 19 changed files with 3,425 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,21 @@ public class Constants {
allowedScalars.put(AppConstants.SUBSCRIPTION_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_SCOPE_Q);

allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_HAS_OBJECT);
allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_OBJECT_TYPE);
allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_HAS_VALUE);
allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_COORDINATES);
allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_UNIT_CODE);
allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_DATA_SET_ID);
allowedScalars.put(AppConstants.ENTITY_CREATE_PAYLOAD, NGSIConstants.NGSI_LD_SCOPE);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_HAS_OBJECT);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_OBJECT_TYPE);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_HAS_VALUE);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_COORDINATES);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_UNIT_CODE);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_DATA_SET_ID);
allowedScalars.put(AppConstants.ENTITY_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_SCOPE);
allowedScalars.put(AppConstants.ENTITY_ATTRS_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_HAS_OBJECT);
allowedScalars.put(AppConstants.ENTITY_ATTRS_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_OBJECT_TYPE);
allowedScalars.put(AppConstants.ENTITY_ATTRS_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_HAS_VALUE);
allowedScalars.put(AppConstants.ENTITY_ATTRS_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_COORDINATES);
allowedScalars.put(AppConstants.ENTITY_ATTRS_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_UNIT_CODE);
Expand Down Expand Up @@ -129,6 +132,7 @@ public class Constants {
allowedScalars.put(AppConstants.CSOURCE_REG_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_COORDINATES);
allowedScalars.put(AppConstants.CSOURCE_REG_UPDATE_PAYLOAD, NGSIConstants.NGSI_LD_SCOPE);
allowedScalars.put(AppConstants.MERGE_PATCH_PAYLOAD, NGSIConstants.NGSI_LD_HAS_OBJECT);
allowedScalars.put(AppConstants.MERGE_PATCH_PAYLOAD, NGSIConstants.NGSI_LD_OBJECT_TYPE);
allowedScalars.put(AppConstants.MERGE_PATCH_PAYLOAD, NGSIConstants.NGSI_LD_HAS_VALUE);
allowedScalars.put(AppConstants.MERGE_PATCH_PAYLOAD, NGSIConstants.NGSI_LD_COORDINATES);
allowedScalars.put(AppConstants.MERGE_PATCH_PAYLOAD, NGSIConstants.NGSI_LD_UNIT_CODE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
Expand All @@ -33,7 +32,6 @@
import com.github.jsonldjava.core.JsonLdApi;
import com.github.jsonldjava.core.JsonLdProcessor;
import com.google.common.net.HttpHeaders;

import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.core.buffer.Buffer;
import io.vertx.mutiny.ext.web.client.HttpResponse;
Expand Down Expand Up @@ -347,8 +345,9 @@ private static Uni<Object> fromJsonLdViaHttpUri(final URL url, WebClient webClie
}).onItem().transformToUni(result -> {
final int status = result.statusCode();
if (status != 200 && status != 203) {
String finalUrl = URLDecoder.decode(url.getPath().split("createcache/")[1],StandardCharsets.UTF_8);
return Uni.createFrom()
.failure(new IOException("Can't retrieve " + url + ", status code: " + status));
.failure(new IOException("Can't retrieve " + finalUrl + ", status code: " + status));
}
URL alternateLink;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public interface NGSIConstants {
public final static String CSOURCE_TYPE = "type";
public final static String CSOURCE_TIMESTAMP = "timestamp";
public final static String CSOURCE_COORDINATES = "coordinates";
public final static String FLAT = "flat";
public final static String INLINE = "inline";
public final static String NGSI_LD_SUBSCRIPTION_NAME = "https://uri.etsi.org/ngsi-ld/subscriptionName";
public final static String CSOURCEREGISTRATION_NAME = "registrationName";
public final static String OBJECT = "object";
Expand All @@ -52,6 +54,7 @@ public interface NGSIConstants {
public final static String NGSI_LD_PROPERTY = "https://uri.etsi.org/ngsi-ld/Property";
public final static String NGSI_LD_HAS_VALUE = "https://uri.etsi.org/ngsi-ld/hasValue";
public final static String NGSI_LD_HAS_OBJECT = "https://uri.etsi.org/ngsi-ld/hasObject";
public final static String NGSI_LD_OBJECT_TYPE = "https://uri.etsi.org/ngsi-ld/default-context/objectType";
public final static String NGSI_LD_COORDINATES = "https://purl.org/geojson/vocab#coordinates"; // "https://uri.etsi.org/ngsi-ld/coordinates";
public final static String NGSI_LD_GEOPROPERTY = "https://uri.etsi.org/ngsi-ld/GeoProperty";
public final static String NGSI_LD_LANGPROPERTY = "https://uri.etsi.org/ngsi-ld/LanguageProperty";
Expand Down Expand Up @@ -438,12 +441,8 @@ public interface NGSIConstants {
public static final String HAS_OBJECT_NULL = "[{https://uri.etsi.org/ngsi-ld/hasObject=[{@id=urn:ngsi-ld:null}]";
public static final String LANGUAGE_PROPERTY = "LanguageProperty";
public static final String LANGUAGE_MAP = "languageMap";


public static final Set<String> ENTITY_BASE_PROPS = Sets.newHashSet(JSON_LD_ID, JSON_LD_TYPE, NGSI_LD_CREATED_AT, NGSI_LD_MODIFIED_AT, NGSI_LD_SCOPE);


public final static String NGSI_LD_HAS_KEY ="https://uri.etsi.org/ngsi-ld/hasKey";

public static final String OBJECT_TYPE = "objectType";
}

Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,13 @@ public static RestResponse<Object> handleControllerExceptions(Throwable e) {
.header(HttpHeaders.CONTENT_TYPE, AppConstants.NGB_APPLICATION_JSON)
.entity(responseException.getJson()).build();
}
if(e instanceof IOException ioException){
logger.debug("Exception :: ", ioException);
return RestResponseBuilderImpl.create(ErrorType.LdContextNotAvailable.getCode())
.header(HttpHeaders.CONTENT_TYPE, AppConstants.NGB_APPLICATION_JSON)
.entity(new ResponseException(ErrorType.LdContextNotAvailable)
.getJson()).build();
}
if (e instanceof DateTimeParseException) {
logger.debug("Exception :: ", e);
return RestResponseBuilderImpl.create(HttpStatus.SC_BAD_REQUEST)
Expand Down Expand Up @@ -691,8 +698,12 @@ public static RestResponse<Object> generateBatchResult(List<NGSILDOperationResul
String type = (String) result.get(0).get("type");
if (type.equalsIgnoreCase("Delete") || type.equalsIgnoreCase("Append"))
return RestResponse.status(RestResponse.Status.NOT_FOUND, result);
else
else if(result.get(0).get("failure").toString().contains("503")){
return RestResponse.status(RestResponse.Status.SERVICE_UNAVAILABLE, result);
}
else {
return RestResponse.status(RestResponse.Status.BAD_REQUEST, result);
}
}
if (!isHavingError && isHavingSuccess) {
String type = (String) result.get(0).get("type");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import java.net.URLDecoder;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PrimitiveIterator.OfInt;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -203,7 +206,7 @@ public static GeoQueryTerm parseGeoQuery(String georel, String coordinates, Stri
}

public static AttrsQueryTerm parseAttrs(String attrs, Context context) throws ResponseException {
if (attrs == null) {
if (attrs == null || attrs.isEmpty()) {
return null;
}
AttrsQueryTerm result = new AttrsQueryTerm(context);
Expand Down Expand Up @@ -461,4 +464,39 @@ public static LanguageQueryTerm parseLangQuery(String langString) throws Respons
return result;
}

public static Map<String, Object> parseInput(String input) {
if(input==null || input.isEmpty()){
return new HashMap<>();
}
Stack<Map<String, Object>> stack = new Stack<>();
Map<String, Object> resultMap = new HashMap<>();
stack.push(resultMap);

StringBuilder keyBuilder = new StringBuilder();
for (char c : input.toCharArray()) {
if (c == '{') {
String key = keyBuilder.toString();
Map<String, Object> childMap = new HashMap<>();
stack.peek().put(key, childMap);
stack.push(childMap);
keyBuilder.setLength(0);
} else if (c == '}') {
if (keyBuilder.length() > 0) {
stack.peek().put(keyBuilder.toString(), null);
keyBuilder.setLength(0);
}
stack.pop();
} else if (c == ',') {
if (keyBuilder.length() > 0) {
stack.peek().put(keyBuilder.toString(), null);
keyBuilder.setLength(0);
}
} else {
keyBuilder.append(c);
}
}

return resultMap;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.neclab.ngsildbroker.entityhandler.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Random;
Expand Down Expand Up @@ -78,7 +79,12 @@ public Uni<RestResponse<Object>> createMultiple(HttpServerRequest request,
entityId);
if (obj2 instanceof ResponseException) {
failureResults.addFailure((ResponseException) obj2);
} else {
}
else if(obj2 instanceof IOException){
failureResults.addFailure(
new ResponseException(ErrorType.LdContextNotAvailable, ((Exception) obj2).getMessage()));
}
else {
failureResults.addFailure(
new ResponseException(ErrorType.InvalidRequest, ((Exception) obj2).getMessage()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ private void noConcise(Object object, Map<String, Object> parentMap, String keyO
// Map have object but not type
if (map.containsKey(NGSIConstants.OBJECT)) {
((Map<String, Object>) map).put(NGSIConstants.TYPE, NGSIConstants.RELATIONSHIP);

}
// Map have value but not type
if (map.containsKey(NGSIConstants.VALUE) && !map.containsKey(NGSIConstants.TYPE)) {
Expand All @@ -251,7 +252,7 @@ private void noConcise(Object object, Map<String, Object> parentMap, String keyO
if (map.containsKey(NGSIConstants.LANGUAGE_MAP)) {
((Map<String, Object>) map).put(NGSIConstants.TYPE, NGSIConstants.LANGUAGE_PROPERTY);
}

// Iterate through every element of Map
Object[] mapKeys = map.keySet().toArray();
for (Object key : mapKeys) {
Expand All @@ -263,7 +264,8 @@ private void noConcise(Object object, Map<String, Object> parentMap, String keyO
&& !key.equals(NGSIConstants.QUERY_PARAMETER_DATA_SET_ID) && !key.equals(NGSIConstants.OBJECT)
&& !key.equals(NGSIConstants.VALUE) && !key.equals(NGSIConstants.SCOPE)
&& !key.equals(NGSIConstants.QUERY_PARAMETER_UNIT_CODE)
&& !key.equals(NGSIConstants.LANGUAGE_MAP)) {
&& !key.equals(NGSIConstants.LANGUAGE_MAP)
&& !key.equals(NGSIConstants.OBJECT_TYPE)) {
noConcise(map.get(key), (Map<String, Object>) map, key.toString());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@

import java.io.IOException;
import java.util.List;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;

import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.resteasy.reactive.RestResponse;
import org.jboss.resteasy.reactive.server.jaxrs.RestResponseBuilderImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.github.jsonldjava.core.JsonLDService;
import com.github.jsonldjava.utils.JsonUtils;
import com.google.common.base.Objects;
import com.google.common.net.HttpHeaders;

import eu.neclab.ngsildbroker.commons.constants.NGSIConstants;
import eu.neclab.ngsildbroker.commons.datatypes.terms.AttrsQueryTerm;
import eu.neclab.ngsildbroker.commons.datatypes.terms.CSFQueryTerm;
Expand Down Expand Up @@ -69,10 +74,14 @@ public class QueryController {
@Path("/entities/{entityId}")
@GET
public Uni<RestResponse<Object>> getEntity(HttpServerRequest request, @QueryParam(value = "attrs") String attrs,
@QueryParam(value = "options") String options, @QueryParam(value = "lang") String lang,
@QueryParam(value = "geometryProperty") String geometryProperty,
@QueryParam(value = "localOnly") boolean localOnly, @PathParam("entityId") String entityId,
@QueryParam(value = "doNotCompact") boolean doNotCompact) {
@QueryParam(value = "options") String options, @QueryParam(value = "lang") String lang,
@QueryParam(value = "geometryProperty") String geometryProperty,
@QueryParam(value = "localOnly") boolean localOnly, @PathParam("entityId") String entityId,
@QueryParam(value = "doNotCompact") boolean doNotCompact,
@QueryParam("containedBy")@DefaultValue("") String containedBy,
@QueryParam("join")String join,
@QueryParam("idsOnly")boolean idsOnly,
@QueryParam("joinLevel")@DefaultValue("1")int joinLevel) {
int acceptHeader = HttpUtils.parseAcceptHeader(request.headers().getAll("Accept"));
if (acceptHeader == -1) {
return HttpUtils.getInvalidHeader();
Expand All @@ -82,17 +91,18 @@ public Uni<RestResponse<Object>> getEntity(HttpServerRequest request, @QueryPara
headerContext = HttpUtils.getAtContext(request);
logger.debug("retrieve called: " + request.path());
return HttpUtils.getContext(headerContext, ldService).onItem().transformToUni(context -> {
AttrsQueryTerm attrsQuery;
// AttrsQueryTerm attrsQuery;
LanguageQueryTerm langQuery;
try {
HttpUtils.validateUri(entityId);
attrsQuery = QueryParser.parseAttrs(attrs, context);
// attrsQuery = QueryParser.parseAttrs(attrs, context);
langQuery = QueryParser.parseLangQuery(lang);
} catch (Exception e) {
return Uni.createFrom().item(HttpUtils.handleControllerExceptions(e));
}
return queryService
.retrieveEntity(context, HttpUtils.getTenant(request), entityId, attrsQuery, langQuery, localOnly)
.retrieveEntity(context, HttpUtils.getTenant(request), entityId, attrs, langQuery,
localOnly,containedBy,join,idsOnly,joinLevel)
.onItem().transformToUni(entity -> {
if (doNotCompact) {
return Uni.createFrom().item(RestResponse.ok((Object) entity));
Expand Down Expand Up @@ -123,7 +133,9 @@ public Uni<RestResponse<Object>> query(HttpServerRequest request, @QueryParam("i
@QueryParam("geometryProperty") String geometryProperty, @QueryParam("lang") String lang,
@QueryParam("scopeQ") String scopeQ, @QueryParam("localOnly") boolean localOnly,
@QueryParam("options") String options, @QueryParam("limit") Integer limit, @QueryParam("offset") int offset,
@QueryParam("count") boolean count, @QueryParam("idsOnly") boolean idsOnly,
@QueryParam("count") boolean count, @QueryParam("containedBy")@DefaultValue("") String containedBy,
@QueryParam("join")String join, @QueryParam("idsOnly")boolean idsOnly,
@QueryParam("joinLevel")@DefaultValue("1")int joinLevel,
@QueryParam("doNotCompact") boolean doNotCompact, @QueryParam("entityMap") String entityMapToken) {
int acceptHeader = HttpUtils.parseAcceptHeader(request.headers().getAll("Accept"));
if (acceptHeader == -1) {
Expand Down Expand Up @@ -207,7 +219,7 @@ public Uni<RestResponse<Object>> query(HttpServerRequest request, @QueryParam("i
if (idsOnly) {
return queryService
.queryForEntityIds(HttpUtils.getTenant(request), ids, typeQueryTerm, idPattern, attrsQuery,
qQueryTerm, geoQueryTerm, scopeQueryTerm, langQuery, context, request.headers())
qQueryTerm, geoQueryTerm, scopeQueryTerm, langQuery, context, request.headers(), true,join,containedBy,joinLevel)
.onItem().transform(list -> {
String body;
Object result = "[]";
Expand Down

0 comments on commit 095f178

Please sign in to comment.