Skip to content

Commit

Permalink
Merge pull request #1681 from FIWARE/dds/legacyReadMode
Browse files Browse the repository at this point in the history
The rest of the tasks for read-only legacy mode
  • Loading branch information
kzangeli authored Oct 3, 2024
2 parents f2a6201 + 442e9e5 commit c59d55e
Show file tree
Hide file tree
Showing 16 changed files with 435 additions and 139 deletions.
4 changes: 3 additions & 1 deletion src/lib/orionld/common/orionldState.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,13 @@ typedef struct OrionldConnectionState
DistOp* distOpList;
uint32_t acceptMask; // "1 << MimeType" mask for all accepted Mime Types, regardless of which is chosen and of weight
bool ddsSample; // Are we treating a sample from DDS?
char* ddsType; // type of DDS Sample
double ddsPublishTime; // time of DDS publication

//
// TRoE
//
bool noDbUpdate; // If nothing changed in DB - troe is not invoked
bool noDbUpdate; // If nothing changed in DB - troe is not invoked
bool troeError;
KjNode* duplicateArray;
KjNode* troeIgnoreV[20];
Expand Down
10 changes: 6 additions & 4 deletions src/lib/orionld/common/traceLevels.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@
typedef enum OrionldTraceLevels
{
StMhdInit = 100,
StSR = 101,

StRequest = 200,
StDds = 201,
StDdsPublish = 202,
StDdsNotification = 203,
StDdsLibInfo = 204,
StDdsLibDebug = 205,
StDump = 206,
StDdsDump = 207,
StDdsConfig = 208,
StSR = 209
StDdsConfig = 206,

StDump = 300,
StDdsDump = 301
} OrionldTraceLevels;

#endif // SRC_LIB_ORIONLD_COMMON_TRACELEVELS_H_
1 change: 1 addition & 0 deletions src/lib/orionld/dbModel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ SET (SOURCES
dbModelAttributeCreatedAtSet.cpp
dbModelAttributeLookup.cpp
dbModelToEntityIdAndTypeObject.cpp
dbModelAttributePublishedAtLookup.cpp
)

# Include directories
Expand Down
53 changes: 53 additions & 0 deletions src/lib/orionld/dbModel/dbModelAttributePublishedAtLookup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
*
* Copyright 2024 FIWARE Foundation e.V.
*
* This file is part of Orion-LD Context Broker.
*
* Orion-LD Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion-LD Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion-LD Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* orionld at fiware dot org
*
* Author: Ken Zangelin
*/
#include <unistd.h> // NULL

extern "C"
{
#include "kjson/KjNode.h" // KjNode
#include "kjson/kjLookup.h" // kjLookup
#include "ktrace/kTrace.h" // trace messages - ktrace library
}

#include "orionld/common/traceLevels.h" // KT_T trace levels
#include "orionld/dds/kjTreeLog.h" // kjTreeLog2



// -----------------------------------------------------------------------------
//
// dbModelAttributePublishedAtLookup -
//
double dbModelAttributePublishedAtLookup(KjNode* dbAttrP)
{
kjTreeLog2(dbAttrP, "dbAttr", StDds);

KjNode* publishedAtP = kjLookup(dbAttrP, "publishedAt");

if (publishedAtP != NULL)
return publishedAtP->value.f;

return 0;
}
41 changes: 41 additions & 0 deletions src/lib/orionld/dbModel/dbModelAttributePublishedAtLookup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef SRC_LIB_ORIONLD_DBMODEL_DBMODELATTRIBUTEPUBLISHEDATLOOKUP_H_
#define SRC_LIB_ORIONLD_DBMODEL_DBMODELATTRIBUTEPUBLISHEDATLOOKUP_H_

/*
*
* Copyright 2024 FIWARE Foundation e.V.
*
* This file is part of Orion-LD Context Broker.
*
* Orion-LD Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion-LD Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion-LD Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* orionld at fiware dot org
*
* Author: Ken Zangelin
*/
extern "C"
{
#include "kjson/KjNode.h" // KjNode
}



// -----------------------------------------------------------------------------
//
// dbModelAttributePublishedAtLookup -
//
extern double dbModelAttributePublishedAtLookup(KjNode* dbAttrP);

#endif // SRC_LIB_ORIONLD_DBMODEL_DBMODELATTRIBUTEPUBLISHEDATLOOKUP_H_
2 changes: 2 additions & 0 deletions src/lib/orionld/dds/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ SET (SOURCES
ddsCategoryToKlogSeverity.cpp
ddsNotification.cpp
ddsEntityCreateFromAttribute.cpp
ddsConfigTopicToAttribute.cpp
ddsAttributeCreate.cpp
)

# Include directories
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ extern "C"
}

#include "orionld/common/orionldState.h" // ddsConfigTree
#include "orionld/common/traceLevels.h" // KT_T trace levels
#include "orionld/kjTree/kjNavigate.h" // kjNavigate
#include "orionld/dds/kjTreeLog.h" // kjTreeLog2
#include "orionld/dds/ddsConfigTopicToAttribute.h" // Own interface


Expand Down
25 changes: 2 additions & 23 deletions src/lib/orionld/dds/ddsEntityCreateFromAttribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,9 @@ extern "C"
//
int ddsEntityCreateFromAttribute(KjNode* attrNodeP, const char* entityId, const char* attrName)
{
char* entityType = NULL;

kjTreeLog2(orionldState.requestTree, "Attribute", StDds);

// Create entity and continue
// What do I do if there is no entity type?
//
KjNode* entityTypeNodeP = (orionldState.requestTree->type == KjObject)? kjLookup(orionldState.requestTree, "entityType") : NULL;
if (entityTypeNodeP != NULL)
{
kjChildRemove(orionldState.requestTree, entityTypeNodeP);
entityType = entityTypeNodeP->value.s;
}
else
entityType = (char*) "T"; // FIXME: find the antity type in the config file, if not present as node "entityType" in orionldState.requestTree

orionldState.payloadIdNode = kjString(orionldState.kjsonP, "id", entityId);
orionldState.payloadTypeNode = kjString(orionldState.kjsonP, "type", entityType);

KT_T(StDds, "Entity doesn't exist - calling orionldPostEntities");
KT_T(StDds, "But first, need to transform the incoming request tree into a JSON object");

KjNode* attributeP = orionldState.requestTree;
attributeP->name = (char*) attrName;

attributeP->name = (char*) attrName;
orionldState.requestTree = kjObject(orionldState.kjsonP, NULL);

kjChildAdd(orionldState.requestTree, attributeP);
Expand Down
6 changes: 4 additions & 2 deletions src/lib/orionld/dds/ddsInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern "C"
#include "orionld/common/traceLevels.h" // kjTreeLog2
#include "orionld/common/orionldState.h" // ddsEnablerConfigFile, ddsConfigFile
#include "orionld/kjTree/kjNavigate.h" // kjNavigate
#include "orionld/dds/ddsConfigTopicToAttribute.h" // ddsConfigTopicToAttribute - for debugging only
#include "orionld/dds/ddsCategoryToKlogSeverity.h" // ddsCategoryToKlogSeverity
#include "orionld/dds/ddsConfigLoad.h" // ddsConfigLoad
#include "orionld/dds/kjTreeLog.h" // kjTreeLog2
Expand Down Expand Up @@ -92,8 +93,6 @@ int ddsInit(Kjson* kjP, DdsOperationMode _ddsOpMode)
{
ddsOpMode = _ddsOpMode; // Not yet in use ... invent usage or remove !

eprosima::ddsenabler::init_dds_enabler(ddsEnablerConfigFile, ddsNotification, ddsTypeNotification, ddsLog);

//
// DDS Configuration File
//
Expand Down Expand Up @@ -127,5 +126,8 @@ int ddsInit(Kjson* kjP, DdsOperationMode _ddsOpMode)
#endif
}

KT_T(StDds, "Calling init_dds_enabler");
eprosima::ddsenabler::init_dds_enabler(ddsEnablerConfigFile, ddsNotification, ddsTypeNotification, ddsLog);

return 0;
}
131 changes: 40 additions & 91 deletions src/lib/orionld/dds/ddsNotification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ extern "C"
#include "orionld/common/orionldState.h" // orionldState, kjTreeLog
#include "orionld/common/traceLevels.h" // KT_T trace levels
#include "orionld/common/tenantList.h" // tenant0
#include "orionld/context/orionldContextItemExpand.h" // orionldContextItemExpand
#include "orionld/serviceRoutines/orionldPutAttribute.h" // orionldPutAttribute
#include "orionld/dds/kjTreeLog.h" // kjTreeLog2
#include "orionld/dds/ddsConfigTopicToAttribute.h" // ddsConfigTopicToAttribute
#include "orionld/dds/ddsNotification.h" // Own interface


Expand All @@ -46,36 +48,50 @@ extern "C"
//
void ddsNotification(const char* typeName, const char* topicName, const char* json, double publishTime)
{
KT_T(StDds, "Got a notification on %s:%s (json: %s)", typeName, topicName, json);
KT_T(StDdsNotification, "Got a notification on %s:%s (json: %s)", typeName, topicName, json);

orionldStateInit(NULL);

KjNode* kTree = kjParse(orionldState.kjsonP, (char*) json);
if (kTree == NULL)
KT_RVE("Error parsing json payload from DDS: '%s'", json);

KjNode* idNodeP = kjLookup(kTree, "id");
KjNode* typeNodeP = kjLookup(kTree, "type");
KjNode* attrValueNodeP = kjLookup(kTree, topicName);
char* entityId = NULL;
char* entityType = NULL;
char* attrShortName = ddsConfigTopicToAttribute(topicName, &entityId, &entityType);

if (idNodeP == NULL) KT_RVE("No 'id' field in DDS payload ");
if (typeNodeP == NULL) KT_RVE("No 'type' field in DDS payload ");
if (attrValueNodeP == NULL) KT_RVE("No attribute field ('%s') in DDS payload", topicName);
if (attrShortName == NULL)
{
KT_W("Topic '%s' not found in the config file - redirect to default DDS entity", topicName);
entityId = (char*) "urn:ngsi-ld:dds:default";
entityType = (char*) "DDS";
attrShortName = (char*) topicName;
}

orionldState.payloadIdNode = idNodeP;
orionldState.payloadTypeNode = typeNodeP;
KT_T(StDds, "orionldState.payloadIdNode: %p", orionldState.payloadIdNode);
KT_T(StDds, "orionldState.payloadTypeNode: %p", orionldState.payloadTypeNode);
KjNode* participantIdNodeP = kjLookup(kTree, "id");
if (participantIdNodeP != NULL)
{
char* pipe = strchr(participantIdNodeP->value.s, '|');
if (pipe != NULL)
*pipe = 0;
participantIdNodeP->name = (char*) "participantId";
}

KjNode* idNodeP = kjString(orionldState.kjsonP, "id", entityId);
KjNode* typeNodeP = kjLookup(kTree, "type");

// char* attributeLongName = orionldAttributeExpand(coreContextP, topicName, true, NULL);
if (typeNodeP != NULL)
orionldState.ddsType = typeNodeP->value.s;

char* pipe = strchr(idNodeP->value.s, '|');
if (pipe != NULL)
*pipe = 0;
char* expandedType = orionldContextItemExpand(orionldState.contextP, entityType, true, NULL);
typeNodeP = kjString(orionldState.kjsonP, "type", expandedType);

KjNode* attrValueNodeP = kjLookup(kTree, topicName);
if (attrValueNodeP == NULL)
KT_RVE("No attribute field ('%s') in DDS payload", topicName);

char id[256];
snprintf(id, sizeof(id) - 1, "urn:%s", idNodeP->value.s);
KT_T(StDds, "New entity id: %s", id);
orionldState.payloadIdNode = idNodeP;
orionldState.payloadTypeNode = typeNodeP;

KjNode* attrNodeP = kjObject(orionldState.kjsonP, NULL);
kjChildAdd(attrNodeP, attrValueNodeP);
Expand All @@ -84,89 +100,22 @@ void ddsNotification(const char* typeName, const char* topicName, const char* js
orionldState.requestTree = attrNodeP;
orionldState.uriParams.format = (char*) "simplified";
orionldState.uriParams.type = typeNodeP->value.s;
orionldState.wildcard[0] = id;
orionldState.wildcard[1] = (char*) topicName;
orionldState.wildcard[0] = entityId;
orionldState.wildcard[1] = (char*) attrShortName;

orionldState.tenantP = &tenant0; // FIXME ... Use tenants?
orionldState.in.pathAttrExpanded = (char*) topicName;
orionldState.ddsSample = true;
orionldState.ddsPublishTime = publishTime;

//
// If the entity does not exist, it needs to be created
// Except of course, if it is registered and exists elsewhere
//
KT_T(StDds, "Calling orionldPutAttribute");
orionldPutAttribute();
}

#if 0
#include "orionld/dds/ddsConfigTopicToAttribute.h" // ddsConfigTopicToAttribute
void ddsNotification(const char* entityType, const char* entityId, const char* topicName, KjNode* notificationP)
{
KT_V("Got a notification from DDS");
kjTreeLog2(notificationP, "notification", StDds);

//
// We receive entire NGSI-LD Attributes
//
KjNode* aValueNodeP = kjLookup(notificationP, "attributeValue");

if (entityId == NULL)
{
KT_W("Entity without id from DDS");
return;
}

//
// Criteria for obtaining the necessary attribute info (Entity ID+Type + Attribute long name):
//
// 1. Set the attribute long name to the topic name
// 2. Take all three from the DDS config file (depending on the topic name)
// 3. Override entity id+type with entityType+entityId from the parameters of this function
//

//
// GET the attribute long name (and entity id+type) from the DDS config file
//
char* eId = NULL;
char* eType = NULL;
char* attributeLongName = ddsConfigTopicToAttribute(topicName, &eId, &eType);

if (attributeLongName == NULL) // Topic name NOT found in DDS config file
attributeLongName = (char*) topicName;

// Take entity id+type from config file unless given as parameters to this function (which would override)
if (entityType == NULL)
entityType = eType;
if (entityId == NULL)
entityId = eId;

// What to do if we have no entity id+type ?
// - The entity id is MANDATORY - cannot continue if we don't know the entity ID
// - The entity type is onbly needed when creating the entity - and we don't know right now whether the entity already exists.
// So, we let it pass and get an error later (404 Not Found)
if (entityId == NULL)
{
KT_E(("Got a DDS sample for an entity whose ID cannot be obtained"));
return;
}

orionldState.uriParams.type = (char*) entityType;

orionldState.wildcard[0] = (char*) entityId;
orionldState.wildcard[1] = (char*) attributeLongName; // The topic is the attribute long name

orionldState.requestTree = aValueNodeP;
orionldState.tenantP = &tenant0; // FIXME ... Use tenants?
orionldState.in.pathAttrExpanded = (char*) topicName;
orionldState.ddsSample = true;
kjChildAdd(attrNodeP, participantIdNodeP);

KT_T(StDds, "Calling orionldPutAttribute");
KjNode* publishedAt = kjFloat(orionldState.kjsonP, "publishedAt", publishTime);
kjChildAdd(attrNodeP, publishedAt);

//
// If the entity does not exist, it needs to be created
// Except of course, if it is registered and exists elsewhere
//
orionldPutAttribute();
}
#endif
Loading

0 comments on commit c59d55e

Please sign in to comment.