Skip to content

Commit

Permalink
Merge pull request #1561 from FIWARE/hosted/contexts
Browse files Browse the repository at this point in the history
Details of hosted contexts
  • Loading branch information
kzangeli authored Feb 21, 2024
2 parents 575328f + 51dc690 commit 94a722b
Show file tree
Hide file tree
Showing 30 changed files with 1,221 additions and 889 deletions.
3 changes: 2 additions & 1 deletion CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
* #1542: Array Reduction (arrays of one single element are "flattened" to that very element)
* SOF: https://stackoverflow.com/questions/77911109/fiware-to-payload-too-large
* #1551: format=simplified for distribute GET /entities gave Normalized for entities from other brokers

## New Features:
* Support for attributes of type VocabularyProperty
* Support for attributes of type JsonProperty
* Support for the new URL parameter "format" for output formats (normalized, concise, simplified)
* Fixed a possible crash for TRoE and attributes of type Vocab/Json/Language
* Modified the @context hosting feature to be according to API spec
1 change: 0 additions & 1 deletion src/lib/orionld/context/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ SET (SOURCES
orionldContextItemAlreadyExpanded.cpp
orionldAttributeExpand.cpp
orionldSubAttributeExpand.cpp
orionldContextOriginName.cpp
orionldEntityExpand.cpp
orionldEntityCompact.cpp
)
Expand Down
43 changes: 1 addition & 42 deletions src/lib/orionld/context/orionldContextCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,48 +37,6 @@ extern "C"



// -----------------------------------------------------------------------------
//
// orionldOriginFromString - FIXME: move to its own module
//
OrionldContextOrigin orionldOriginFromString(const char* s)
{
if (strcmp(s, "UnknownOrigin") == 0) return OrionldContextUnknownOrigin;
else if (strcmp(s, "Inline") == 0) return OrionldContextFromInline;
else if (strcmp(s, "Downloaded") == 0) return OrionldContextDownloaded;
else if (strcmp(s, "FileCached") == 0) return OrionldContextFileCached;
else if (strcmp(s, "ForNotifications") == 0) return OrionldContextForNotifications;
else if (strcmp(s, "ForForwarding") == 0) return OrionldContextForForwarding;
else if (strcmp(s, "UserCreated") == 0) return OrionldContextUserCreated;

return OrionldContextUnknownOrigin;
}



// -----------------------------------------------------------------------------
//
// orionldOriginToString - FIXME: move to its own module
//
const char* orionldOriginToString(OrionldContextOrigin origin)
{
switch (origin)
{
case OrionldContextUnknownOrigin: return "UnknownOrigin";
case OrionldContextFromInline: return "FromInline";
case OrionldContextDownloaded: return "Downloaded";
case OrionldContextFileCached: return "FileCached";
case OrionldContextForNotifications: return "ForNotifications";
case OrionldContextForForwarding: return "ForForwarding";
case OrionldContextUserCreated: return "UserCreated";
case OrionldContextBuiltinCoreContext: return "BuiltinCoreContext";
}

return "InvalidOrigin";
}



// -----------------------------------------------------------------------------
//
// orionldContextCreate -
Expand All @@ -95,6 +53,7 @@ OrionldContext* orionldContextCreate(const char* url, OrionldContextOrigin origi
LM_X(1, ("out of memory - trying to allocate a OrionldContext of %d bytes", sizeof(OrionldContext)));

contextP->origin = origin;
contextP->kind = OrionldContextCached; // By defaukt. Changed later to Hosted/Implicit if needed
contextP->parent = NULL;

// NULL URL means NOT to be saved - will live just inside the request-thread
Expand Down
181 changes: 104 additions & 77 deletions src/lib/orionld/contextCache/orionldContextCacheGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,114 +32,141 @@ extern "C"
#include "logMsg/logMsg.h" // LM_*
#include "logMsg/traceLevels.h" // Lmt*

#include "orionld/types/OrionldContext.h" // OrionldContext
#include "orionld/types/OrionldContext.h" // OrionldContext, orionldOriginToString
#include "orionld/types/OrionldContextItem.h" // OrionldContextItem
#include "orionld/common/orionldState.h" // orionldState
#include "orionld/common/numberToDate.h" // numberToDate
#include "orionld/context/orionldCoreContext.h" // orionldCoreContextP
#include "orionld/context/orionldContextOriginName.h" // orionldContextOriginName
#include "orionld/contextCache/orionldContextCache.h" // Context Cache Internals
#include "orionld/contextCache/orionldContextCacheGet.h" // Own interface



// -----------------------------------------------------------------------------
//
// orionldContextCacheGet -
// orionldContextWithDetails - FIXME: rename and put in separate module
//
KjNode* orionldContextCacheGet(KjNode* arrayP, bool details)
KjNode* orionldContextWithDetails(OrionldContext* contextP)
{
for (int ix = 0; ix < orionldContextCacheSlotIx; ix++)
char createdAtString[64];
char lastUseString[64];

numberToDate(contextP->createdAt, createdAtString, sizeof(createdAtString));
numberToDate(contextP->usedAt, lastUseString, sizeof(lastUseString));

//
// Details, according to spec:
// URL
// localId
// kind (Hosted, Cached, ImplicitlyCreated)
// createdAt
// lastUsage (optional)
// numberOfHits (optional)
// extraInfo (object with broker specific fields, like "type", "origin")
//

KjNode* contextObjP = kjObject(orionldState.kjsonP, NULL);

KjNode* urlStringP = kjString(orionldState.kjsonP, "URL", contextP->url);
KjNode* idStringP = kjString(orionldState.kjsonP, "localId", (contextP->id == NULL)? "None" : contextP->id);
KjNode* kindP = kjString(orionldState.kjsonP, "kind", orionldKindToString(contextP->kind));
KjNode* createdAtP = kjString(orionldState.kjsonP, "createdAt", createdAtString);
KjNode* extraInfoP = kjObject(orionldState.kjsonP, "extraInfo");
KjNode* typeStringP = kjString(orionldState.kjsonP, "type", contextP->keyValues? "hash-table" : "array");
KjNode* originP = kjString(orionldState.kjsonP, "origin", orionldOriginToString(contextP->origin));

kjChildAdd(contextObjP, urlStringP);
kjChildAdd(contextObjP, idStringP);
kjChildAdd(contextObjP, kindP);
kjChildAdd(contextObjP, createdAtP);
kjChildAdd(contextObjP, extraInfoP);
kjChildAdd(extraInfoP, typeStringP);
kjChildAdd(extraInfoP, originP);

if (contextP != orionldCoreContextP)
{
OrionldContext* contextP = orionldContextCacheArray[ix];
KjNode* usedAtP = kjString(orionldState.kjsonP, "lastUsage", lastUseString);
KjNode* lookupsP = kjInteger(orionldState.kjsonP, "numberOfHits", contextP->lookups);

if (contextP == NULL)
continue;
kjChildAdd(contextObjP, usedAtP);
kjChildAdd(contextObjP, lookupsP);
}

if (details == true)
if (contextP->parent != NULL)
{
KjNode* parentP = kjString(orionldState.kjsonP, "parent", contextP->parent);

kjChildAdd(extraInfoP, parentP);
}

if (contextP->keyValues)
{
// Show a maximum of 5 items from the hash-table
KjNode* hashTableObjectP = kjObject(orionldState.kjsonP, "hash-table");
KHashTable* htP = contextP->context.hash.nameHashTable;
int noOfItems = 0;

for (int slot = 0; slot < ORIONLD_CONTEXT_CACHE_HASH_ARRAY_SIZE; ++slot)
{
char createdAtString[64];
char lastUseString[64];

numberToDate(contextP->createdAt, createdAtString, sizeof(createdAtString));
numberToDate(contextP->usedAt, lastUseString, sizeof(lastUseString));

KjNode* contextObjP = kjObject(orionldState.kjsonP, NULL);
KjNode* urlStringP = kjString(orionldState.kjsonP, "url", contextP->url);
KjNode* idStringP = kjString(orionldState.kjsonP, "id", (contextP->id == NULL)? "None" : contextP->id);
KjNode* typeStringP = kjString(orionldState.kjsonP, "type", contextP->keyValues? "hash-table" : "array");
KjNode* originP = kjString(orionldState.kjsonP, "origin", orionldContextOriginName(contextP->origin));
KjNode* createdAtP = kjString(orionldState.kjsonP, "createdAt", createdAtString);

kjChildAdd(contextObjP, urlStringP);
kjChildAdd(contextObjP, idStringP);
kjChildAdd(contextObjP, typeStringP);
kjChildAdd(contextObjP, originP);
kjChildAdd(contextObjP, createdAtP);

if (contextP != orionldCoreContextP)
KHashListItem* itemP = htP->array[slot];

while (itemP != 0)
{
KjNode* usedAtP = kjString(orionldState.kjsonP, "lastUse", lastUseString);
KjNode* lookupsP = kjInteger(orionldState.kjsonP, "lookups", contextP->lookups);
OrionldContextItem* hashItemP = (OrionldContextItem*) itemP->data;
KjNode* hashItemStringP = kjString(orionldState.kjsonP, hashItemP->name, hashItemP->id);

kjChildAdd(contextObjP, usedAtP);
kjChildAdd(contextObjP, lookupsP);
}
kjChildAdd(hashTableObjectP, hashItemStringP);

if (contextP->parent != NULL)
{
KjNode* parentP = kjString(orionldState.kjsonP, "parent", contextP->parent);
++noOfItems;
if (noOfItems >= 5)
break;

kjChildAdd(contextObjP, parentP);
itemP = itemP->next;
}

if (contextP->keyValues)
{
// Show a maximum of 5 items from the hash-table
KjNode* hashTableObjectP = kjObject(orionldState.kjsonP, "hash-table");
KHashTable* htP = contextP->context.hash.nameHashTable;
int noOfItems = 0;
if (noOfItems >= 5)
break;
}

kjChildAdd(extraInfoP, hashTableObjectP);
}
else
{
//
// If ARRAY - show all the URLs in the array
//
KjNode* urlArrayP = kjArray(orionldState.kjsonP, "URLs");

for (int slot = 0; slot < ORIONLD_CONTEXT_CACHE_HASH_ARRAY_SIZE; ++slot)
{
KHashListItem* itemP = htP->array[slot];
for (int aIx = 0; aIx < contextP->context.array.items; ++aIx)
{
KjNode* urlStringP = kjString(orionldState.kjsonP, NULL, contextP->context.array.vector[aIx]->url);

while (itemP != 0)
{
OrionldContextItem* hashItemP = (OrionldContextItem*) itemP->data;
KjNode* hashItemStringP = kjString(orionldState.kjsonP, hashItemP->name, hashItemP->id);
kjChildAdd(urlArrayP, urlStringP);
}
kjChildAdd(extraInfoP, urlArrayP);
}

kjChildAdd(hashTableObjectP, hashItemStringP);
return contextObjP;
}

++noOfItems;
if (noOfItems >= 5)
break;

itemP = itemP->next;
}

if (noOfItems >= 5)
break;
}
// -----------------------------------------------------------------------------
//
// orionldContextCacheGet -
//
KjNode* orionldContextCacheGet(KjNode* arrayP, bool details)
{
for (int ix = 0; ix < orionldContextCacheSlotIx; ix++)
{
OrionldContext* contextP = orionldContextCacheArray[ix];

kjChildAdd(contextObjP, hashTableObjectP);
}
else
{
//
// If ARRAY - show all the URLs in the array
//
KjNode* urlArrayP = kjArray(orionldState.kjsonP, "URLs");

for (int aIx = 0; aIx < contextP->context.array.items; ++aIx)
{
KjNode* urlStringP = kjString(orionldState.kjsonP, NULL, contextP->context.array.vector[aIx]->url);

kjChildAdd(urlArrayP, urlStringP);
}
kjChildAdd(contextObjP, urlArrayP);
}
if (contextP == NULL)
continue;

if (details == true)
{
KjNode* contextObjP = orionldContextWithDetails(contextP);
kjChildAdd(arrayP, contextObjP);
}
else
Expand Down
9 changes: 6 additions & 3 deletions src/lib/orionld/contextCache/orionldContextCachePersist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ extern "C"
#include "logMsg/logMsg.h" // LM_*
#include "logMsg/traceLevels.h" // Lmt*

#include "orionld/types/OrionldContext.h" // OrionldContext
#include "orionld/types/OrionldContext.h" // OrionldContext, orionldOriginToString, orionldKindToString
#include "orionld/common/orionldState.h" // orionldState
#include "orionld/common/uuidGenerate.h" // uuidGenerate
#include "orionld/context/orionldContextUrlGenerate.h" // orionldContextUrlGenerate
#include "orionld/context/orionldContextOriginName.h" // orionldContextOriginName
#include "orionld/mongoc/mongocContextCachePersist.h" // mongocContextCachePersist - FIXME: Use dbContextCachePersist
#include "orionld/contextCache/orionldContextCachePersist.h" // Own interface

Expand All @@ -61,7 +60,8 @@ void orionldContextCachePersist(OrionldContext* contextP)
KjNode* idP;
KjNode* urlP = kjString(orionldState.kjsonP, "url", contextP->url);
KjNode* parentP;
KjNode* originP = kjString(orionldState.kjsonP, "origin", orionldContextOriginName(contextP->origin));
KjNode* originP = kjString(orionldState.kjsonP, "origin", orionldOriginToString(contextP->origin));
KjNode* kindP = kjString(orionldState.kjsonP, "kind", orionldKindToString(contextP->kind));
KjNode* createdAtP = kjFloat(orionldState.kjsonP, "createdAt", orionldState.requestTime); // FIXME: make sure it's not overwritten if already exists
KjNode* valueP = contextP->tree;

Expand All @@ -88,6 +88,9 @@ void orionldContextCachePersist(OrionldContext* contextP)
// Field: "origin"
kjChildAdd(contextObjP, originP);

// Field: "kind"
kjChildAdd(contextObjP, kindP);

// Field: "createdAt"
kjChildAdd(contextObjP, createdAtP);

Expand Down
24 changes: 9 additions & 15 deletions src/lib/orionld/serviceRoutines/orionldGetContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ extern "C"



extern KjNode* orionldContextWithDetails(OrionldContext* contextP);
// ----------------------------------------------------------------------------
//
// orionldGetContext -
Expand All @@ -54,25 +55,18 @@ bool orionldGetContext(void)
return false;
}

orionldState.responseTree = kjObject(orionldState.kjsonP, NULL);
if (orionldState.responseTree == NULL)
{
orionldError(OrionldBadRequestData, "kjObject failed", "out of memory?", 500);
return false;
}

if (orionldState.uriParams.details == true)
{
KjNode* urlNodeP = kjString(orionldState.kjsonP, "URL", contextP->url);
KjNode* idNodeP = kjString(orionldState.kjsonP, "localId", contextP->id);
KjNode* kindNodeP = kjString(orionldState.kjsonP, "kind", orionldOriginToString(contextP->origin));

kjChildAdd(orionldState.responseTree, urlNodeP);
kjChildAdd(orionldState.responseTree, idNodeP);
kjChildAdd(orionldState.responseTree, kindNodeP);
}
orionldState.responseTree = orionldContextWithDetails(contextP);
else
{
orionldState.responseTree = kjObject(orionldState.kjsonP, NULL);
if (orionldState.responseTree == NULL)
{
orionldError(OrionldBadRequestData, "kjObject failed", "out of memory?", 500);
return false;
}

contextP->tree->name = (char*) "@context";
kjChildAdd(orionldState.responseTree, contextP->tree);
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/serviceRoutines/orionldPostContexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ bool orionldPostContexts(void)

contextP->createdAt = orionldState.requestTime;
contextP->usedAt = orionldState.requestTime;
contextP->kind = OrionldContextHosted;

httpHeaderLocationAdd(contextP->url, NULL, NULL);

Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ SET (SOURCES
DistOpType.cpp
TroeMode.cpp
Verb.cpp
OrionldContext.cpp
)

# Include directories
Expand Down
Loading

0 comments on commit 94a722b

Please sign in to comment.