You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2023/08/03 14:18:51 UTC

[plc4x] branch develop updated: feat(opcua): add support for OpcuaMessageError

This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new b88d4eb300 feat(opcua): add support for OpcuaMessageError
b88d4eb300 is described below

commit b88d4eb3002f898b264bebc1cfed081980d64ce5
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Aug 3 16:18:43 2023 +0200

    feat(opcua): add support for OpcuaMessageError
---
 .../protocols/opcua/readwrite/model/MessagePDU.go  |   2 +
 .../opcua/readwrite/model/OpcuaMessageError.go     | 303 +++++++++++++++++++++
 .../plc4x/java/opcua/readwrite/MessagePDU.java     |   3 +
 protocols/opcua/src/main/xslt/opc-manual.xsl       |   6 +
 4 files changed, 314 insertions(+)

diff --git a/plc4go/protocols/opcua/readwrite/model/MessagePDU.go b/plc4go/protocols/opcua/readwrite/model/MessagePDU.go
index e5dfe130ff..8ff90105bb 100644
--- a/plc4go/protocols/opcua/readwrite/model/MessagePDU.go
+++ b/plc4go/protocols/opcua/readwrite/model/MessagePDU.go
@@ -150,6 +150,8 @@ func MessagePDUParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer,
 		_childTemp, typeSwitchError = OpcuaMessageRequestParseWithBuffer(ctx, readBuffer, response)
 	case messageType == "MSG" && response == bool(true): // OpcuaMessageResponse
 		_childTemp, typeSwitchError = OpcuaMessageResponseParseWithBuffer(ctx, readBuffer, response)
+	case messageType == "ERR" && response == bool(true): // OpcuaMessageError
+		_childTemp, typeSwitchError = OpcuaMessageErrorParseWithBuffer(ctx, readBuffer, response)
 	default:
 		typeSwitchError = errors.Errorf("Unmapped type for parameters [messageType=%v, response=%v]", messageType, response)
 	}
diff --git a/plc4go/protocols/opcua/readwrite/model/OpcuaMessageError.go b/plc4go/protocols/opcua/readwrite/model/OpcuaMessageError.go
new file mode 100644
index 0000000000..4a2dba0ba3
--- /dev/null
+++ b/plc4go/protocols/opcua/readwrite/model/OpcuaMessageError.go
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package model
+
+import (
+	"context"
+	"fmt"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// OpcuaMessageError is the corresponding interface of OpcuaMessageError
+type OpcuaMessageError interface {
+	fmt.Stringer
+	utils.LengthAware
+	utils.Serializable
+	MessagePDU
+	// GetChunk returns Chunk (property field)
+	GetChunk() string
+	// GetError returns Error (property field)
+	GetError() OpcuaStatusCode
+	// GetReason returns Reason (property field)
+	GetReason() PascalString
+}
+
+// OpcuaMessageErrorExactly can be used when we want exactly this type and not a type which fulfills OpcuaMessageError.
+// This is useful for switch cases.
+type OpcuaMessageErrorExactly interface {
+	OpcuaMessageError
+	isOpcuaMessageError() bool
+}
+
+// _OpcuaMessageError is the data-structure of this message
+type _OpcuaMessageError struct {
+	*_MessagePDU
+	Chunk  string
+	Error  OpcuaStatusCode
+	Reason PascalString
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_OpcuaMessageError) GetMessageType() string {
+	return "ERR"
+}
+
+func (m *_OpcuaMessageError) GetResponse() bool {
+	return bool(true)
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_OpcuaMessageError) InitializeParent(parent MessagePDU) {}
+
+func (m *_OpcuaMessageError) GetParent() MessagePDU {
+	return m._MessagePDU
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_OpcuaMessageError) GetChunk() string {
+	return m.Chunk
+}
+
+func (m *_OpcuaMessageError) GetError() OpcuaStatusCode {
+	return m.Error
+}
+
+func (m *_OpcuaMessageError) GetReason() PascalString {
+	return m.Reason
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewOpcuaMessageError factory function for _OpcuaMessageError
+func NewOpcuaMessageError(chunk string, error OpcuaStatusCode, reason PascalString) *_OpcuaMessageError {
+	_result := &_OpcuaMessageError{
+		Chunk:       chunk,
+		Error:       error,
+		Reason:      reason,
+		_MessagePDU: NewMessagePDU(),
+	}
+	_result._MessagePDU._MessagePDUChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastOpcuaMessageError(structType any) OpcuaMessageError {
+	if casted, ok := structType.(OpcuaMessageError); ok {
+		return casted
+	}
+	if casted, ok := structType.(*OpcuaMessageError); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_OpcuaMessageError) GetTypeName() string {
+	return "OpcuaMessageError"
+}
+
+func (m *_OpcuaMessageError) GetLengthInBits(ctx context.Context) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits(ctx))
+
+	// Simple field (chunk)
+	lengthInBits += 8
+
+	// Implicit Field (messageSize)
+	lengthInBits += 32
+
+	// Simple field (error)
+	lengthInBits += 32
+
+	// Simple field (reason)
+	lengthInBits += m.Reason.GetLengthInBits(ctx)
+
+	return lengthInBits
+}
+
+func (m *_OpcuaMessageError) GetLengthInBytes(ctx context.Context) uint16 {
+	return m.GetLengthInBits(ctx) / 8
+}
+
+func OpcuaMessageErrorParse(ctx context.Context, theBytes []byte, response bool) (OpcuaMessageError, error) {
+	return OpcuaMessageErrorParseWithBuffer(ctx, utils.NewReadBufferByteBased(theBytes), response)
+}
+
+func OpcuaMessageErrorParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, response bool) (OpcuaMessageError, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	log := zerolog.Ctx(ctx)
+	_ = log
+	if pullErr := readBuffer.PullContext("OpcuaMessageError"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for OpcuaMessageError")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (chunk)
+	_chunk, _chunkErr := readBuffer.ReadString("chunk", uint32(8), "UTF-8")
+	if _chunkErr != nil {
+		return nil, errors.Wrap(_chunkErr, "Error parsing 'chunk' field of OpcuaMessageError")
+	}
+	chunk := _chunk
+
+	// Implicit Field (messageSize) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
+	messageSize, _messageSizeErr := readBuffer.ReadInt32("messageSize", 32)
+	_ = messageSize
+	if _messageSizeErr != nil {
+		return nil, errors.Wrap(_messageSizeErr, "Error parsing 'messageSize' field of OpcuaMessageError")
+	}
+
+	// Simple Field (error)
+	if pullErr := readBuffer.PullContext("error"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for error")
+	}
+	_error, _errorErr := OpcuaStatusCodeParseWithBuffer(ctx, readBuffer)
+	if _errorErr != nil {
+		return nil, errors.Wrap(_errorErr, "Error parsing 'error' field of OpcuaMessageError")
+	}
+	error := _error
+	if closeErr := readBuffer.CloseContext("error"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for error")
+	}
+
+	// Simple Field (reason)
+	if pullErr := readBuffer.PullContext("reason"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for reason")
+	}
+	_reason, _reasonErr := PascalStringParseWithBuffer(ctx, readBuffer)
+	if _reasonErr != nil {
+		return nil, errors.Wrap(_reasonErr, "Error parsing 'reason' field of OpcuaMessageError")
+	}
+	reason := _reason.(PascalString)
+	if closeErr := readBuffer.CloseContext("reason"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for reason")
+	}
+
+	if closeErr := readBuffer.CloseContext("OpcuaMessageError"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for OpcuaMessageError")
+	}
+
+	// Create a partially initialized instance
+	_child := &_OpcuaMessageError{
+		_MessagePDU: &_MessagePDU{},
+		Chunk:       chunk,
+		Error:       error,
+		Reason:      reason,
+	}
+	_child._MessagePDU._MessagePDUChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_OpcuaMessageError) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes(context.Background()))))
+	if err := m.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_OpcuaMessageError) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	log := zerolog.Ctx(ctx)
+	_ = log
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("OpcuaMessageError"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for OpcuaMessageError")
+		}
+
+		// Simple Field (chunk)
+		chunk := string(m.GetChunk())
+		_chunkErr := writeBuffer.WriteString("chunk", uint32(8), "UTF-8", (chunk))
+		if _chunkErr != nil {
+			return errors.Wrap(_chunkErr, "Error serializing 'chunk' field")
+		}
+
+		// Implicit Field (messageSize) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
+		messageSize := int32(int32(m.GetLengthInBytes(ctx)))
+		_messageSizeErr := writeBuffer.WriteInt32("messageSize", 32, (messageSize))
+		if _messageSizeErr != nil {
+			return errors.Wrap(_messageSizeErr, "Error serializing 'messageSize' field")
+		}
+
+		// Simple Field (error)
+		if pushErr := writeBuffer.PushContext("error"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for error")
+		}
+		_errorErr := writeBuffer.WriteSerializable(ctx, m.GetError())
+		if popErr := writeBuffer.PopContext("error"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for error")
+		}
+		if _errorErr != nil {
+			return errors.Wrap(_errorErr, "Error serializing 'error' field")
+		}
+
+		// Simple Field (reason)
+		if pushErr := writeBuffer.PushContext("reason"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for reason")
+		}
+		_reasonErr := writeBuffer.WriteSerializable(ctx, m.GetReason())
+		if popErr := writeBuffer.PopContext("reason"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for reason")
+		}
+		if _reasonErr != nil {
+			return errors.Wrap(_reasonErr, "Error serializing 'reason' field")
+		}
+
+		if popErr := writeBuffer.PopContext("OpcuaMessageError"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for OpcuaMessageError")
+		}
+		return nil
+	}
+	return m.SerializeParent(ctx, writeBuffer, m, ser)
+}
+
+func (m *_OpcuaMessageError) isOpcuaMessageError() bool {
+	return true
+}
+
+func (m *_OpcuaMessageError) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(context.Background(), m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java
index 628434f0b6..a8a860296d 100644
--- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java
+++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java
@@ -133,6 +133,9 @@ public abstract class MessagePDU implements Message {
     } else if (EvaluationHelper.equals(messageType, (String) "MSG")
         && EvaluationHelper.equals(response, (boolean) true)) {
       builder = OpcuaMessageResponse.staticParseMessagePDUBuilder(readBuffer, response);
+    } else if (EvaluationHelper.equals(messageType, (String) "ERR")
+        && EvaluationHelper.equals(response, (boolean) true)) {
+      builder = OpcuaMessageERR.staticParseMessagePDUBuilder(readBuffer, response);
     }
     if (builder == null) {
       throw new ParseException(
diff --git a/protocols/opcua/src/main/xslt/opc-manual.xsl b/protocols/opcua/src/main/xslt/opc-manual.xsl
index 3bc21d45c5..036648d7d3 100644
--- a/protocols/opcua/src/main/xslt/opc-manual.xsl
+++ b/protocols/opcua/src/main/xslt/opc-manual.xsl
@@ -125,6 +125,12 @@
            [simple          int 32             requestId]
            [array           byte               message count 'messageSize - 24']
        ]
+       ['"ERR"','true'     OpcuaMessageError
+           [simple          string 8           chunk ]
+           [implicit        int 32             messageSize 'lengthInBytes']
+           [simple          OpcuaStatusCode    error ]
+           [simple          PascalString       reason]
+       ]
     ]
 ]