Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Review] feat: Publishing of DataSetMetaData via mqtt json #5118

Open
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

wlkrm
Copy link

@wlkrm wlkrm commented May 9, 2022

This PR enables the server to publish DataSetMetaData via mqtt and json encoding. If enabled, DataSetMetaData are published, whenever a new PublishedDataSet is added. In addition, it introduces a new function for the server API (UA_Server_updateDataSetField()) which allows the server to inform the pubsub layer that FieldMetaData were changed. The pubsub layer will then publish the updated version of the DataSetMetaData. This enables the user to make multiple changes to the FieldMetaData in an transactional style. The tutorial_pubsub_mqtt_publish was extended to publish the DataSetMetaData via json mqtt, if UA_ENABLE_PUBSUB, UA_ENABLE_PUBSUB_MQTT, UA_ENABLE_PUBSUB_MQTT_METADATA and UA_ENABLE_JSON_ENCODING are set. The binary encoding is not supported. As stated in the draft for UA Specification Part 14 - MQTT Enhancements, a DataSetMetaDataType message is an instance of a DataSetMetaDataType encoded using the JSON encoding defined in OPC 10000-6.

@CLAassistant
Copy link

CLAassistant commented May 9, 2022

CLA assistant check
All committers have signed the CLA.

@wlkrm wlkrm changed the title [WIP] feat: Üublishing of DataSetMetaData via mqtt json [WIP] feat: Publishing of DataSetMetaData via mqtt json May 9, 2022
@wlkrm wlkrm force-pushed the mqtt-metadata-rebase branch 3 times, most recently from 08409a9 to d9afcd5 Compare May 16, 2022 14:42
@wlkrm wlkrm changed the title [WIP] feat: Publishing of DataSetMetaData via mqtt json feat: Publishing of DataSetMetaData via mqtt json May 16, 2022
@wlkrm wlkrm changed the title feat: Publishing of DataSetMetaData via mqtt json [Review] feat: Publishing of DataSetMetaData via mqtt json May 16, 2022
@andreasebner
Copy link
Contributor

Thank you for the contribution @wlkrm! Currently the appveyor build is failing: 5>Compiling...
6>..\src\pubsub\ua_pubsub_networkmessage_json.c(246) : error C2361: initialization of 'count' is skipped by 'default' label
6> ..\src\pubsub\ua_pubsub_networkmessage_json.c(217) : see declaration of 'count'
6>..\src\pubsub\ua_pubsub_networkmessage_json.c(246) : error C2361: initialization of 's' is skipped by 'default' label
6> ..\src\pubsub\ua_pubsub_networkmessage_json.c(171) : see declaration of 's

It would be great if you could rebase your changes and search for a solution. I’m looking forward to merge your changes, but currently the coverage will decrease significantly because your changes do not contain test cases.
@NoelGraf could you please review this PR?

@wlkrm
Copy link
Author

wlkrm commented May 20, 2022

I will add the missing test cases.

@NoelGraf
Copy link
Member

@wlkrm
The changes look good overall. First, I would suggest doing a rebase since some changes have been made to MQTT.

src/server/ua_server.c Outdated Show resolved Hide resolved
@@ -287,6 +288,7 @@ typedef struct {
typedef struct {
UA_String name;
UA_PublishedDataSetType publishedDataSetType;
UA_Boolean sendViaWriterGroupTopic;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the insertion of the field necessary?
And what's the field for?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The field allows for selective batching. DataSetMessages of DataSetWriters can be batched by their common WriterGroup using the UA_BrokerDataSetWriterTransportDataType of the WriterGroup according to Part 14. PublishedDataSets of Writers grouped by a common WriterGroup with this flag set will be sent out batched under the Data-Topic-Queue defined in the transportSettings (UA_BrokerDataSetWriterTransportDataType.queueName) of the WriterGroup. The reason for the implementation is, that my use-case gets simplified, if I receive DataSetMessages of multiple DataSetWriter grouped together through batching. Example JSONs and Topics of this can be found here (https://github.com/umati/Showcase/blob/pubsub/PubSub.md#topic-structure).

@wlkrm wlkrm force-pushed the mqtt-metadata-rebase branch 2 times, most recently from 87bf0f8 to d552dd3 Compare August 1, 2022 14:02
@wlkrm
Copy link
Author

wlkrm commented Aug 1, 2022

@NoelGraf, thank you for your comments. I rebased the PR and tests for the encoding. I was not really sure how to properly test the MQTT-Part, as the tests would have to spin up a broker? Please review again.

Copy link
Member

@jpfr jpfr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really good overall.
Please make this configurable with a configuration flag, not a build flag.

MQTT+JSON is not used in environments where every kilobyte counts.
So we can afford to have this compiled in and keep the complexity of the build options low.

CMakeLists.txt Outdated Show resolved Hide resolved
@wlkrm
Copy link
Author

wlkrm commented Aug 2, 2022

@jpfr I removed the compile time switches and replaced them by a per DataSetWriter config field. A DataSetWriter can now be configured (https://github.com/wlkrm/open62541/blob/34156d549bab3e00d9d71b715e99dec81ffa6f81/include/open62541/server_pubsub.h#L599) to publish the DataSetMetaData using the corresponding transport layer (e.g. JSON-MQTT, which is the only metadata transport implemented in this PR).

@jpfr
Copy link
Member

jpfr commented Aug 3, 2022

I removed the compile time switches and replaced them by a per DataSetWriter config field. A DataSetWriter can now be configured (https://github.com/wlkrm/open62541/blob/34156d549bab3e00d9d71b715e99dec81ffa6f81/include/open62541/server_pubsub.h#L599

If this is the place where the feature is enabled, add a comment that the feature requires JSON+MQTT.
Otherwise people will not understand what it does without looking at the code.

We can also log a warning if the feature is enabled without JSON+MQTT.

If there is a canonical section in the PubSub spec, also refer to that in the comment.

examples/pubsub/tutorial_pubsub_mqtt_publish.c Outdated Show resolved Hide resolved
examples/pubsub/tutorial_pubsub_mqtt_publish.c Outdated Show resolved Hide resolved
examples/pubsub/tutorial_pubsub_mqtt_publish.c Outdated Show resolved Hide resolved
examples/pubsub/tutorial_pubsub_mqtt_publish.c Outdated Show resolved Hide resolved
@@ -314,6 +315,7 @@ typedef struct {
typedef struct {
UA_String name;
UA_PublishedDataSetType publishedDataSetType;
UA_Boolean sendViaWriterGroupTopic;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a more precise name of this flag would help to understand it. In addition add a short inline comment.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed it to batchMessagesViaWriterGroupTopic and added the coment.

src/pubsub/ua_pubsub_datasetmetadata_json.c Outdated Show resolved Hide resolved
src/pubsub/ua_pubsub_datasetmetadata_json.c Outdated Show resolved Hide resolved
src/pubsub/ua_pubsub_writer.c Outdated Show resolved Hide resolved
Comment on lines 490 to 522
void
UA_Server_updateDataSetField(UA_Server *server, const UA_NodeId dsf, UA_Boolean minor, UA_Boolean major) {
UA_DataSetField *currentField = UA_DataSetField_findDSFbyId(server, dsf);
if(!currentField) {
return;
}

if(currentField->configurationFrozen) {
UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER,
"Update DataSetField failed. DataSetField is frozen.");
return;
}

UA_PublishedDataSet *pds =
UA_PublishedDataSet_findPDSbyId(server, currentField->publishedDataSet);
if(!pds) {
return;
}

if(pds->configurationFrozen) {
UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER,
"Update DataSetField failed. PublishedDataSet is frozen.");
return;
}

/* Update minor version of PublishedDataSet */
UA_UInt32 timeDifference = UA_PubSubConfigurationVersionTimeDifference();
if(minor)
pds->dataSetMetaData.configurationVersion.minorVersion = timeDifference;
if(major)
pds->dataSetMetaData.configurationVersion.majorVersion = timeDifference;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code does not match the logic implied by the function name. In addition the user can change the minor/major version directly. I would preffer to have only implicit changes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the flags.

break;
}
#ifdef UA_ENABLE_JSON_ENCODING
res = sendNetworkMessageMetadataJson(connection, &dataSetMetaData, &newDataSetWriter->config.dataSetWriterId, 1, &newDataSetWriter->config.transportSettings);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we send out the Metadata during the WG creation. Not sure if this is allowed if the state is not operational.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MetaData are now published for the first time, when the transport is ready.
63ab001

@wlkrm
Copy link
Author

wlkrm commented Aug 5, 2022

I removed the compile time switches and replaced them by a per DataSetWriter config field. A DataSetWriter can now be configured (https://github.com/wlkrm/open62541/blob/34156d549bab3e00d9d71b715e99dec81ffa6f81/include/open62541/server_pubsub.h#L599

If this is the place where the feature is enabled, add a comment that the feature requires JSON+MQTT. Otherwise people will not understand what it does without looking at the code.

We can also log a warning if the feature is enabled without JSON+MQTT.

If there is a canonical section in the PubSub spec, also refer to that in the comment.

I added the comment. And a warning: https://github.com/wlkrm/open62541/blob/63ab001e387136a30925936656b9e60aa3c113fb/src/pubsub/ua_pubsub_writer.c#L891

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants