Skip to content

Commit

Permalink
feat(#3112): opc ua multi node selection editor (#3138)
Browse files Browse the repository at this point in the history
* refactor(#3116): Create component for button menu

* refactor(#3116): Move static property utils

* refactor(#3116): Add test to validate tree view of opc ua and buttons

* refactor(#3116): Extract button menu in static-tree-input

* refactor(#3116): Extract component selected-nodes

* refactor(#3116): Fix CSS for component selected-nodes

* refactor(#3116): Fix CSS for component selected-nodes

* refactor(#3116): Harmonized naming of component

* refactor(#3116): Extract static-runtime-resolvable-tree-input component

* refactor(#3116): Add test to show node details

* refactor(#3116): Add component for node details

* refactor(#3116): Add missing headers

* refactor(#3116): Add missing headers

* feat(#3112): Add button to switch editor mode

* feat(#3112): Refactor parameter extractor for tree properties

* feat(#3112): First version of text input works now

* feat(#3112): First version of text input works now

* feat(#3112): First version of text input works now

* feat(#3112):Ensure switch between Tree and text view works as expected

* feat(#3112): Handle broken node ids

* feat(#3112): Add description header to text editor

* feat(#3112): Remove empty lines

* feat(#3112): Fix tree view editor navigation

* feat(#3112): Add exception when node id is invalid

* feat(#3112): fix checkstyle

* Add missing css class

* Fix minor styling issues

* feat(#3112): Fix editing of opc ua adapters

---------

Co-authored-by: Dominik Riemer <[email protected]>
  • Loading branch information
tenthe and dominikriemer authored Aug 15, 2024
1 parent aea863e commit 76a84a3
Show file tree
Hide file tree
Showing 31 changed files with 1,010 additions and 375 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ public interface IParameterExtractor {

<V> List<V> selectedMultiValues(String internalName, Class<V> targetClass);

<V> List<V> selectedTreeNodesInternalNames(String internalName,
Class<V> targetClass);

/**
* @deprecated use {@link #selectedTreeNodesInternalNames(String, Class)} instead
*/
@Deprecated(since = "0.97.0", forRemoval = true)
<V> List<V> selectedTreeNodesInternalNames(String internalName,
Class<V> targetClass,
boolean onlyDataNodes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.eclipse.milo.opcua.sdk.client.nodes.UaVariableNode;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.UaRuntimeException;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
Expand All @@ -49,8 +50,10 @@ public class OpcUaNodeBrowser {

private static final Logger LOG = LoggerFactory.getLogger(OpcUaNodeBrowser.class);

public OpcUaNodeBrowser(OpcUaClient client,
OpcUaConfig spOpcUaClientConfig) {
public OpcUaNodeBrowser(
OpcUaClient client,
OpcUaConfig spOpcUaClientConfig
) {
this.client = client;
this.spOpcConfig = spOpcUaClientConfig;
}
Expand Down Expand Up @@ -85,31 +88,58 @@ public List<TreeInputNode> buildNodeTreeFromOrigin(String nextBaseNodeToResolve)

private OpcNode toOpcNode(String nodeName) throws UaException {
AddressSpace addressSpace = getAddressSpace();
NodeId nodeId = NodeId.parse(nodeName);
UaNode node = addressSpace.getNode(nodeId);

LOG.info("Using node of type {}", node.getNodeClass().toString());
NodeId nodeId;
try {
nodeId = NodeId.parse(nodeName);
} catch (UaRuntimeException e) {
throw new UaException(
StatusCode.BAD.getValue(), "Node ID " + nodeName + " is not in the correct format. "
+ "The correct format is `ns=<namespaceIndex>;<identifierType>=<identifier>`.", e);
}

UaNode node;
try {
node = addressSpace.getNode(nodeId);
} catch (UaException e) {
throw new UaException(
StatusCode.BAD.getValue(),
"Node with ID " + nodeId + " is not present in the OPC UA server.", e
);
}

LOG.info(
"Using node of type {}",
node.getNodeClass()
.toString()
);

if (node instanceof UaVariableNode) {
UInteger value = (UInteger) ((UaVariableNode) node).getDataType().getIdentifier();
return new OpcNode(node.getDisplayName().getText(), OpcUaTypes.getType(value), node.getNodeId());
UInteger value = (UInteger) ((UaVariableNode) node).getDataType()
.getIdentifier();
return new OpcNode(node.getDisplayName()
.getText(), OpcUaTypes.getType(value), node.getNodeId());
}

LOG.warn("Node {} not of type UaVariableNode", node.getDisplayName());

throw new UaException(StatusCode.BAD, "Node is not of type BaseDataVariableTypeNode");
}

private List<TreeInputNode> findChildren(OpcUaClient client,
NodeId nodeId) throws UaException {
private List<TreeInputNode> findChildren(
OpcUaClient client,
NodeId nodeId
) throws UaException {
return client
.getAddressSpace()
.browseNodes(nodeId)
.stream()
.map(node -> {
TreeInputNode childNode = new TreeInputNode();
childNode.setNodeName(node.getDisplayName().getText());
childNode.setInternalNodeName(node.getNodeId().toParseableString());
childNode.setNodeName(node.getDisplayName()
.getText());
childNode.setInternalNodeName(node.getNodeId()
.toParseableString());
childNode.setDataNode(isDataNode(node));
childNode.setNodeMetadata(new OpcUaNodeMetadataExtractor(client, node).extract());
return childNode;
Expand All @@ -118,13 +148,18 @@ private List<TreeInputNode> findChildren(OpcUaClient client,
}



private AddressSpace getAddressSpace() {
return client.getAddressSpace();
}

private boolean isDataNode(UaNode node) {
return (node.getNodeClass().equals(NodeClass.Variable) || (node.getNodeClass().equals(NodeClass.VariableType)))
return (
node.getNodeClass()
.equals(NodeClass.Variable) || (
node.getNodeClass()
.equals(NodeClass.VariableType)
)
)
&& node instanceof UaVariableNode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static <T extends OpcUaConfig> T extractSharedConfig(IParameterExtractor
String selectedAlternativeAuthentication =
extractor.selectedAlternativeInternalId(ACCESS_MODE.name());
List<String> selectedNodeNames =
extractor.selectedTreeNodesInternalNames(AVAILABLE_NODES.name(), String.class, true);
extractor.selectedTreeNodesInternalNames(AVAILABLE_NODES.name(), String.class);

config.setSelectedNodeNames(selectedNodeNames);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;
import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand All @@ -45,8 +46,8 @@ public void testExtractDescription() {
extractor.extractDescription();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("Description"));
Assertions.assertEquals(description, metadata.get("Description"));
assertTrue(metadata.containsKey("Description"));
assertEquals(description, metadata.get("Description"));
}

@Test
Expand All @@ -58,8 +59,8 @@ public void testExtractDescriptionNull() {
extractor.extractDescription();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("Description"));
Assertions.assertEquals("", metadata.get("Description"));
assertTrue(metadata.containsKey("Description"));
assertEquals("", metadata.get("Description"));
}

@Test
Expand All @@ -71,8 +72,8 @@ public void testExtractNamespaceIndex() {
extractor.extractNamespaceIndex();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("NamespaceIndex"));
Assertions.assertEquals("1", metadata.get("NamespaceIndex"));
assertTrue(metadata.containsKey("NamespaceIndex"));
assertEquals("1", metadata.get("NamespaceIndex"));
}

@Test
Expand All @@ -84,8 +85,8 @@ public void testExtractNamespaceIndexNull() {
extractor.extractNamespaceIndex();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("NamespaceIndex"));
Assertions.assertEquals("", metadata.get("NamespaceIndex"));
assertTrue(metadata.containsKey("NamespaceIndex"));
assertEquals("", metadata.get("NamespaceIndex"));
}

@Test
Expand All @@ -97,8 +98,8 @@ public void testExtractNodeClass() {
extractor.extractNodeClass();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("NodeClass"));
Assertions.assertEquals("Variable", metadata.get("NodeClass"));
assertTrue(metadata.containsKey("NodeClass"));
assertEquals("Variable", metadata.get("NodeClass"));
}

@Test
Expand All @@ -110,8 +111,8 @@ public void testExtractNodeClassNull() {
extractor.extractNodeClass();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("NodeClass"));
Assertions.assertEquals("", metadata.get("NodeClass"));
assertTrue(metadata.containsKey("NodeClass"));
assertEquals("", metadata.get("NodeClass"));
}

@Test
Expand All @@ -124,8 +125,8 @@ public void testExtractBrowseName() {
extractor.extractBrowseName();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("BrowseName"));
Assertions.assertEquals(expectedNodeName, metadata.get("BrowseName"));
assertTrue(metadata.containsKey("BrowseName"));
assertEquals(expectedNodeName, metadata.get("BrowseName"));
}

@Test
Expand All @@ -137,8 +138,8 @@ public void testExtractBrowseNameNull() {
extractor.extractBrowseName();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("BrowseName"));
Assertions.assertEquals("", metadata.get("BrowseName"));
assertTrue(metadata.containsKey("BrowseName"));
assertEquals("", metadata.get("BrowseName"));
}

@Test
Expand All @@ -151,8 +152,8 @@ public void testExtractDisplayName() {
extractor.extractDisplayName();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("DisplayName"));
Assertions.assertEquals(expectedName, metadata.get("DisplayName"));
assertTrue(metadata.containsKey("DisplayName"));
assertEquals(expectedName, metadata.get("DisplayName"));
}

@Test
Expand All @@ -164,8 +165,8 @@ public void testExtractDisplayNameNull() {
extractor.extractDisplayName();

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("DisplayName"));
Assertions.assertEquals("", metadata.get("DisplayName"));
assertTrue(metadata.containsKey("DisplayName"));
assertEquals("", metadata.get("DisplayName"));
}

@Test
Expand All @@ -177,8 +178,8 @@ public void testExtractSourceTime() {
extractor.extractSourceTime(value);

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("SourceTime"));
Assertions.assertEquals(date, metadata.get("SourceTime"));
assertTrue(metadata.containsKey("SourceTime"));
assertEquals(date, metadata.get("SourceTime"));
}

@Test
Expand All @@ -190,8 +191,8 @@ public void testExtractSourceTimeNull() {
extractor.extractSourceTime(value);

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("SourceTime"));
Assertions.assertEquals("", metadata.get("SourceTime"));
assertTrue(metadata.containsKey("SourceTime"));
assertEquals("", metadata.get("SourceTime"));
}

@Test
Expand All @@ -203,8 +204,8 @@ public void testExtractServerTime() {
extractor.extractServerTime(value);

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("ServerTime"));
Assertions.assertEquals(date, metadata.get("ServerTime"));
assertTrue(metadata.containsKey("ServerTime"));
assertEquals(date, metadata.get("ServerTime"));
}

@Test
Expand All @@ -216,8 +217,8 @@ public void testExtractServerTimeNull() {
extractor.extractServerTime(value);

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("ServerTime"));
Assertions.assertEquals("", metadata.get("ServerTime"));
assertTrue(metadata.containsKey("ServerTime"));
assertEquals("", metadata.get("ServerTime"));
}

@Test
Expand All @@ -230,8 +231,8 @@ public void testExtractDataType() {
extractor.extractDataType(dataTypeNode);

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("DataType"));
Assertions.assertEquals(expectedName, metadata.get("DataType"));
assertTrue(metadata.containsKey("DataType"));
assertEquals(expectedName, metadata.get("DataType"));
}

@Test
Expand All @@ -243,8 +244,8 @@ public void testExtractDataTypeNull() {
extractor.extractDataType(dataTypeNode);

var metadata = extractor.getMetadata();
Assertions.assertTrue(metadata.containsKey("DataType"));
Assertions.assertEquals("", metadata.get("DataType"));
assertTrue(metadata.containsKey("DataType"));
assertEquals("", metadata.get("DataType"));
}

private OpcUaNodeMetadataExtractor getExtractor(UaNode node) {
Expand Down
Loading

0 comments on commit 76a84a3

Please sign in to comment.