Skip to content

Commit

Permalink
Merge pull request #1656 from FIWARE/feature/orderByIfLocal
Browse files Browse the repository at this point in the history
Support for the URL parameter 'orderBy'
  • Loading branch information
kzangeli authored Aug 19, 2024
2 parents 9f18e94 + 0bf0367 commit 5d3c511
Show file tree
Hide file tree
Showing 18 changed files with 303 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
## New Features:
* Distributed subscriptions: subordinate subscriptions are DELETED when their "father" is deleted
* Support for the URL parameter 'csf' in GET /ngsi-ld/v1/csourceRegistrations
* Support for the URL parameter 'orderBy' (must be an attribute) in GET //ngsi-ld/v1/entities, but only if 'local' is set. (This is not NGSI-LD standard. Yet ...)

## Notes
36 changes: 19 additions & 17 deletions src/lib/orionld/context/orionldAttributeExpand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,23 @@
char* orionldAttributeExpand
(
OrionldContext* contextP,
char* shortName,
const char* shortName,
bool useDefaultUrlIfNotFound,
OrionldContextItem** contextItemPP
)
{
if (strcmp(shortName, "id") == 0) return shortName;
else if (strcmp(shortName, "@id") == 0) return shortName;
else if (strcmp(shortName, "type") == 0) return shortName;
else if (strcmp(shortName, "@type") == 0) return shortName;
else if (strcmp(shortName, "scope") == 0) return shortName;
else if (strcmp(shortName, "location") == 0) return shortName;
else if (strcmp(shortName, "createdAt") == 0) return shortName;
else if (strcmp(shortName, "modifiedAt") == 0) return shortName;
else if (strcmp(shortName, "observationSpace") == 0) return shortName;
else if (strcmp(shortName, "operationSpace") == 0) return shortName;
char* sName = (char*) shortName; // just to avoid a warning for strcmp

if (strcmp(sName, "id") == 0) return sName;
else if (strcmp(sName, "@id") == 0) return sName;
else if (strcmp(sName, "type") == 0) return sName;
else if (strcmp(sName, "@type") == 0) return sName;
else if (strcmp(sName, "scope") == 0) return sName;
else if (strcmp(sName, "location") == 0) return sName;
else if (strcmp(sName, "createdAt") == 0) return sName;
else if (strcmp(sName, "modifiedAt") == 0) return sName;
else if (strcmp(sName, "observationSpace") == 0) return sName;
else if (strcmp(sName, "operationSpace") == 0) return sName;

#if 1
// FIXME: 'observedAt' as an attribute is not a thing - special treatment only if sub-attribute
Expand All @@ -70,15 +72,15 @@ char* orionldAttributeExpand
//
// We should probably forbid an attribute to have the name 'observedAt'
//
else if (strcmp(shortName, "observedAt") == 0)
else if (strcmp(sName, "observedAt") == 0)
{
orionldContextItemExpand(contextP, shortName, false, contextItemPP);
return shortName;
orionldContextItemExpand(contextP, sName, false, contextItemPP);
return sName;
}
#endif

if (orionldContextItemAlreadyExpanded(shortName) == true)
return shortName;
if (orionldContextItemAlreadyExpanded(sName) == true)
return sName;

return orionldContextItemExpand(contextP, shortName, useDefaultUrlIfNotFound, contextItemPP);
return orionldContextItemExpand(contextP, sName, useDefaultUrlIfNotFound, contextItemPP);
}
2 changes: 1 addition & 1 deletion src/lib/orionld/context/orionldAttributeExpand.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
extern char* orionldAttributeExpand
(
OrionldContext* contextP,
char* shortName,
const char* shortName,
bool useDefaultUrlIfNotFound,
OrionldContextItem** contextItemPP
);
Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/entityMaps/entityMapCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ EntityMap* entityMapCreate(DistOp* distOpList, char* idPattern, QNode* qNode, Or
geoInfoP,
NULL,
geojsonGeometryLongName,
orionldState.uriParams.orderBy,
true,
false);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/mhd/mhdConnectionInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ MHD_Result mhdConnectionInit
// 2. NGSI-LD requests don't support the broker to be started with -noCache
if (noCache == true)
{
orionldError(OrionldBadRequestData, "Not Implemented", "Running without Subscription Cache is not implemented for NGSI-LD requests", 501);
orionldError(OrionldOperationNotSupported, "Not Implemented", "Running without Subscription Cache is not implemented for NGSI-LD requests", 501);
return MHD_YES;
}

Expand Down
10 changes: 10 additions & 0 deletions src/lib/orionld/mhd/mhdConnectionTreat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ char* pCheckLinkHeader(char* link)



// -----------------------------------------------------------------------------
//
// linkGet -
//
static bool linkGet(const char* link)
{
//
Expand Down Expand Up @@ -1095,6 +1099,12 @@ MHD_Result mhdConnectionTreat(void)
orionldError(OrionldBadRequestData, "Unsupported URI parameter", detail, 400);
goto respond;
}

if ((orionldState.uriParams.orderBy != NULL) && (orionldState.uriParams.local == false))
{
orionldError(OrionldOperationNotSupported, "Not supported URL parameter", "The URL parameter 'orderBy' only works if also 'local' is set", 501);
goto respond;
}
}

//
Expand Down
23 changes: 22 additions & 1 deletion src/lib/orionld/mongoc/mongocEntitiesQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern "C"
#include "orionld/common/orionldError.h" // orionldError
#include "orionld/common/dotForEq.h" // dotForEq
#include "orionld/q/qTreeToBson.h" // qTreeToBson
#include "orionld/context/orionldAttributeExpand.h" // orionldAttributeExpand
#include "orionld/mongoc/mongocWriteLog.h" // MONGOC_RLOG - FIXME: change name to mongocLog.h
#include "orionld/mongoc/mongocConnectionGet.h" // mongocConnectionGet
#include "orionld/mongoc/mongocKjTreeToBson.h" // mongocKjTreeToBson
Expand Down Expand Up @@ -661,6 +662,7 @@ KjNode* mongocEntitiesQuery
OrionldGeoInfo* geoInfoP,
int64_t* countP,
const char* geojsonGeometry,
const char* orderBy,
bool onlyIds,
bool onlyIdAndType
)
Expand Down Expand Up @@ -696,7 +698,26 @@ KjNode* mongocEntitiesQuery

bson_init(&sortDoc);

bson_append_int32(&sortDoc, "creDate", 7, 1);
if (orderBy == NULL)
bson_append_int32(&sortDoc, "creDate", 7, 1);
else
{
char* longName = orionldAttributeExpand(orionldState.contextP, orderBy, true, NULL);
int len = strlen(longName) + 14;
char* path = kaAlloc(&orionldState.kalloc, len);

len = snprintf(path, len - 1, "attrs.%s.value", longName);

// Replacing dots for '=' - including the last one (should not be replaced)
dotForEq(&path[6]);

// Reversing the '=' of ".value" to a dot
path[len - 6] = '.';

LM_T(LmtMongoc, ("Ordering by '%s' (%d letters)", path, len));
bson_append_int32(&sortDoc, path, len, 1);
}

bson_append_int32(&sortDoc, "_id.id", 6, 1);
bson_append_document(&options, "sort", 4, &sortDoc);
bson_destroy(&sortDoc);
Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/mongoc/mongocEntitiesQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern KjNode* mongocEntitiesQuery
OrionldGeoInfo* geoInfoP,
int64_t* countP,
const char* geojsonGeometry,
const char* orderBy,
bool onlyIds,
bool onlyIdAndType
);
Expand Down
4 changes: 2 additions & 2 deletions src/lib/orionld/payloadCheck/pcheckInformationItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ bool pCheckOverlappingEntities(KjNode* entitiesP, KjNode* propertiesP, KjNode* r

if (entitiesP == NULL)
{
KjNode* entityArray = mongocEntitiesQuery(NULL, NULL, NULL, &attrsV, NULL, NULL, NULL, NULL, false, false);
KjNode* entityArray = mongocEntitiesQuery(NULL, NULL, NULL, &attrsV, NULL, NULL, NULL, NULL, orionldState.uriParams.orderBy, false, false);
if ((entityArray != NULL) && (entityArray->value.firstChildP != NULL))
{
KjNode* _idP = kjLookup(entityArray->value.firstChildP, "_id");
Expand Down Expand Up @@ -350,7 +350,7 @@ bool pCheckOverlappingEntities(KjNode* entitiesP, KjNode* propertiesP, KjNode* r
entityTypeList.array = entityTypeArray;
entityTypeArray[0] = entityType;

KjNode* entityArray = mongocEntitiesQuery(&entityTypeList, NULL, entityIdPattern, &attrsV, NULL, NULL, NULL, NULL, false, false);
KjNode* entityArray = mongocEntitiesQuery(&entityTypeList, NULL, entityIdPattern, &attrsV, NULL, NULL, NULL, NULL, NULL, false, false);
if ((entityArray != NULL) && (entityArray->value.firstChildP != NULL))
{
KjNode* _idP = kjLookup(entityArray->value.firstChildP, "_id");
Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/service/orionldServiceInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ static void restServicePrepare(OrionLdRestService* serviceP, OrionLdRestServiceS
serviceP->uriParams |= ORIONLD_URIPARAM_LOCAL;
serviceP->uriParams |= ORIONLD_URIPARAM_ONLYIDS;
serviceP->uriParams |= ORIONLD_URIPARAM_ENTITYMAP;
serviceP->uriParams |= ORIONLD_URIPARAM_ORDERBY;
}
else if (serviceP->serviceRoutine == orionldGetEntity)
{
Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/serviceRoutines/orionldDeleteEntities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ bool orionldDeleteEntities(void)
&geoInfo,
&count,
geojsonGeometryLongName,
NULL,
false,
true);
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ bool orionldGetEntitiesLocal
geoInfoP,
&count,
geojsonGeometryLongName,
orionldState.uriParams.orderBy,
onlyIds,
false);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/serviceRoutines/orionldPostBatchCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ bool orionldPostBatchCreate(void)
//
// FIXME: Use simpler mongoc function - we only need to know whether the entities exist or not
//
KjNode* dbEntityArray = mongocEntitiesQuery(NULL, &eIdArray, NULL, NULL, NULL, NULL, NULL, NULL, false, false);
KjNode* dbEntityArray = mongocEntitiesQuery(NULL, &eIdArray, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false);
if (dbEntityArray == NULL)
{
orionldError(OrionldInternalError, "Database Error", "error querying the database for entities", 500);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/serviceRoutines/orionldPostBatchUpdate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ bool orionldPostBatchUpdate(void)
//
// The entity id array is ready - time to query mongo
//
KjNode* dbEntityArray = mongocEntitiesQuery(NULL, &eIdArray, NULL, NULL, NULL, NULL, NULL, NULL, false, false);
KjNode* dbEntityArray = mongocEntitiesQuery(NULL, &eIdArray, NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false);
if (dbEntityArray == NULL)
{
orionldError(OrionldInternalError, "Database Error", "error querying the database for entities", 500);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/serviceRoutines/orionldPostBatchUpsert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ bool orionldPostBatchUpsert(void)
//
orionldState.uriParams.limit = noOfEntities;
orionldState.uriParams.offset = 0;
KjNode* dbEntityArray = mongocEntitiesQuery(NULL, &eIdArray, NULL, NULL, NULL, NULL, NULL, NULL, false, false);
KjNode* dbEntityArray = mongocEntitiesQuery(NULL, &eIdArray, NULL, NULL, NULL, NULL, NULL, NULL, orionldState.uriParams.orderBy, false, false);
if (dbEntityArray == NULL)
{
orionldError(OrionldInternalError, "Database Error", "error querying the database for entities", 500);
Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/types/OrionLdRestService.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ typedef struct OrionLdRestServiceSimplifiedVector
#define ORIONLD_URIPARAM_FORMAT (UINT64_C(1) << 40)
#define ORIONLD_URIPARAM_EXPAND_VALUES (UINT64_C(1) << 41)
#define ORIONLD_URIPARAM_KIND (UINT64_C(1) << 42)
#define ORIONLD_URIPARAM_ORDERBY (UINT64_C(1) << 43)



Expand Down
Loading

0 comments on commit 5d3c511

Please sign in to comment.