From 7d13055f9fdb7ab92042f786744a8101bf4b90b9 Mon Sep 17 00:00:00 2001 From: Markus Kohlhase Date: Wed, 22 Nov 2023 16:51:49 +0100 Subject: [PATCH] Rename samples folder to examples --- .gitignore | 4 +- .vscode/launch.json | 6 +- Cargo.toml | 16 ++-- README.md | 38 ++++----- docs/client.md | 80 +++++++++--------- docs/compatibility.md | 32 +++---- docs/cross-compile.md | 4 +- docs/design.md | 6 +- docs/developer.md | 5 +- docs/setup.md | 2 +- docs/testing.md | 4 +- {samples => examples}/chess-server/Cargo.toml | 0 {samples => examples}/chess-server/README.md | 0 .../chess-server/chess-server.iml | 0 .../chess-server/src/game.rs | 0 .../chess-server/src/main.rs | 0 {samples => examples}/client.conf | 0 {samples => examples}/demo-server/Cargo.toml | 0 {samples => examples}/demo-server/Dockerfile | 6 +- {samples => examples}/demo-server/README.md | 4 +- {samples => examples}/demo-server/log4rs.yaml | 0 .../demo-server/sample.server.test.conf | 0 .../demo-server/src/control.rs | 0 .../demo-server/src/historical.rs | 0 .../demo-server/src/machine.rs | 0 {samples => examples}/demo-server/src/main.rs | 0 .../demo-server/src/methods.rs | 0 .../demo-server/src/scalar.rs | 0 .../demo-server/users/sample-x509.der | Bin .../discovery-client/Cargo.toml | 0 .../discovery-client/README.md | 0 .../discovery-client/src/main.rs | 0 {samples => examples}/event-client/Cargo.toml | 0 {samples => examples}/event-client/README.md | 0 .../event-client/src/main.rs | 0 {samples => examples}/mqtt-client/Cargo.toml | 0 {samples => examples}/mqtt-client/README.md | 0 {samples => examples}/mqtt-client/src/main.rs | 0 {samples => examples}/server.conf | 0 .../simple-client/Cargo.toml | 0 {samples => examples}/simple-client/README.md | 6 +- .../simple-client/identity/sample-x509.der | Bin .../simple-client/identity/sample-x509.pem | 0 .../simple-client/simple-client.iml | 0 .../simple-client/src/main.rs | 0 .../simple-server/Cargo.toml | 0 {samples => examples}/simple-server/README.md | 0 .../simple-server/simple-server.iml | 0 .../simple-server/src/main.rs | 0 .../simple-server/users/sample-x509.der | Bin {samples => examples}/web-client/Cargo.toml | 0 {samples => examples}/web-client/README.md | 6 +- .../web-client/html/index.html | 0 {samples => examples}/web-client/src/main.rs | 0 lib/src/client/config.rs | 6 +- lib/src/client/mod.rs | 2 +- lib/src/client/tests/mod.rs | 4 +- lib/src/server/config.rs | 4 +- lib/src/server/tests/mod.rs | 2 +- 59 files changed, 119 insertions(+), 118 deletions(-) rename {samples => examples}/chess-server/Cargo.toml (100%) rename {samples => examples}/chess-server/README.md (100%) rename {samples => examples}/chess-server/chess-server.iml (100%) rename {samples => examples}/chess-server/src/game.rs (100%) rename {samples => examples}/chess-server/src/main.rs (100%) rename {samples => examples}/client.conf (100%) rename {samples => examples}/demo-server/Cargo.toml (100%) rename {samples => examples}/demo-server/Dockerfile (79%) rename {samples => examples}/demo-server/README.md (94%) rename {samples => examples}/demo-server/log4rs.yaml (100%) rename {samples => examples}/demo-server/sample.server.test.conf (100%) rename {samples => examples}/demo-server/src/control.rs (100%) rename {samples => examples}/demo-server/src/historical.rs (100%) rename {samples => examples}/demo-server/src/machine.rs (100%) rename {samples => examples}/demo-server/src/main.rs (100%) rename {samples => examples}/demo-server/src/methods.rs (100%) rename {samples => examples}/demo-server/src/scalar.rs (100%) rename {samples => examples}/demo-server/users/sample-x509.der (100%) rename {samples => examples}/discovery-client/Cargo.toml (100%) rename {samples => examples}/discovery-client/README.md (100%) rename {samples => examples}/discovery-client/src/main.rs (100%) rename {samples => examples}/event-client/Cargo.toml (100%) rename {samples => examples}/event-client/README.md (100%) rename {samples => examples}/event-client/src/main.rs (100%) rename {samples => examples}/mqtt-client/Cargo.toml (100%) rename {samples => examples}/mqtt-client/README.md (100%) rename {samples => examples}/mqtt-client/src/main.rs (100%) rename {samples => examples}/server.conf (100%) rename {samples => examples}/simple-client/Cargo.toml (100%) rename {samples => examples}/simple-client/README.md (83%) rename {samples => examples}/simple-client/identity/sample-x509.der (100%) rename {samples => examples}/simple-client/identity/sample-x509.pem (100%) rename {samples => examples}/simple-client/simple-client.iml (100%) rename {samples => examples}/simple-client/src/main.rs (100%) rename {samples => examples}/simple-server/Cargo.toml (100%) rename {samples => examples}/simple-server/README.md (100%) rename {samples => examples}/simple-server/simple-server.iml (100%) rename {samples => examples}/simple-server/src/main.rs (100%) rename {samples => examples}/simple-server/users/sample-x509.der (100%) rename {samples => examples}/web-client/Cargo.toml (100%) rename {samples => examples}/web-client/README.md (94%) rename {samples => examples}/web-client/html/index.html (100%) rename {samples => examples}/web-client/src/main.rs (100%) diff --git a/.gitignore b/.gitignore index 288b089a5..441c4f63f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ target/ pki/ log/ /curl-ca-bundle.crt -/samples/server.test.conf +/examples/server.test.conf /integration/pki-client /integration/pki-server -3rd-party/open62541/build/ \ No newline at end of file +3rd-party/open62541/build/ diff --git a/.vscode/launch.json b/.vscode/launch.json index 0dfc329c0..f27ec29bd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "program": "${workspaceRoot}/target/debug/opcua-simple-client.exe", "args": [], "stopAtEntry": false, - "cwd": "${workspaceRoot}/samples/simple-client", + "cwd": "${workspaceRoot}/exsamples/simple-client", "environment": [], "externalConsole": true, "MIMode": "gdb", @@ -29,7 +29,7 @@ "program": "${workspaceRoot}/target/debug/opcua-simple-server.exe", "args": [], "stopAtEntry": false, - "cwd": "${workspaceRoot}/samples/simple-server", + "cwd": "${workspaceRoot}/exsamples/simple-server", "environment": [], "externalConsole": true, "MIMode": "gdb", @@ -85,4 +85,4 @@ ], "windows": { } -} \ No newline at end of file +} diff --git a/Cargo.toml b/Cargo.toml index 9a1c0a0d3..70b6ae2c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,14 +2,14 @@ members = [ "lib", "integration", - "samples/demo-server", - "samples/simple-client", - "samples/mqtt-client", - "samples/simple-server", - "samples/chess-server", - "samples/discovery-client", - "samples/web-client", - "samples/event-client", + "examples/demo-server", + "examples/simple-client", + "examples/mqtt-client", + "examples/simple-server", + "examples/chess-server", + "examples/discovery-client", + "examples/web-client", + "examples/event-client", "tools/certificate-creator" ] diff --git a/README.md b/README.md index a3d171717..07f4e61ec 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ This is an [OPC UA](https://opcfoundation.org/about/opc-technologies/opc-ua/) se [![Build Status](https://github.com/locka99/opcua/workflows/OPC%20UA%20for%20Rust/badge.svg)](https://github.com/locka99/opcua/actions/workflows/main.yml) OPC UA is an industry standard for monitoring of data. It's used extensively for embedded devices, industrial control, IoT, -etc. - just about anything that has data that something else wants to monitor, control or visualize. +etc. - just about anything that has data that something else wants to monitor, control or visualize. -Rust is a systems programming language and is therefore a natural choice for implementing OPC UA. This implementation +Rust is a systems programming language and is therefore a natural choice for implementing OPC UA. This implementation supports the embedded, micro and nano profiles but may grow to support features in time. Read the [compatibility](./docs/compatibility.md) page for how the implementation conforms with the OPC UA spec. @@ -16,13 +16,13 @@ Read the [change log](./CHANGELOG.md) for changes per version as well as aspirat # License -The code is licenced under [MPL-2.0](https://opensource.org/licenses/MPL-2.0). Like all open source code, you use this code at your own risk. +The code is licenced under [MPL-2.0](https://opensource.org/licenses/MPL-2.0). Like all open source code, you use this code at your own risk. # Setup Read the [setup](./docs/setup.md) for instructions on building OPCUA for Rust. -Read [cross compilation](./docs/cross-compile.md) for hints for cross compiling OPC UA for Rust to other +Read [cross compilation](./docs/cross-compile.md) for hints for cross compiling OPC UA for Rust to other platforms. # Migration notes @@ -35,38 +35,38 @@ Read the [design](./docs/design.md) for more in-depth description of implementat # Tutorial -Tutorials / user guides are still work in progress. +Tutorials / user guides are still work in progress. * [Client Tutorial](docs/client.md) * [Server Tutorial](docs/server.md) # Further Documentation -The API documentation is generated from the latest published crates. This may be some way behind current development. +The API documentation is generated from the latest published crates. This may be some way behind current development. -# Samples +# Examples -If you want to get stuck in, there are a number of samples in the samples/ folder. The `simple-client` and the `simple-server` projects are +If you want to get stuck in, there are a number of examples in the `examples/` folder. The `simple-client` and the `simple-server` projects are minimal client and server programs respectively. ```bash # In one bash -cd opcua/samples/simple-server +cd opcua/examples/simple-server cargo run # In another bash -cd opcua/samples/simple-client +cd opcua/examples/simple-client cargo run ``` -The full list of samples: +The full list of examples: -1. [`simple-server`](samples/simple-server) - an OPC UA server that adds 4 variables v1, v2, v3 and v4 and updates them from a timer via push and pull mechanisms. -2. [`simple-client`](samples/simple-client) - an OPC UA client that connects to a server and subscribes to the values of v1, v2, v3 and v4. -3. [`discovery-client`](samples/discovery-client) - an OPC UA client that connects to a discovery server and lists the servers registered on it. -4. [`chess-server`](samples/chess-server) - an OPC UA server that connects to a chess engine as its back end and updates variables representing the state of the game. -5. [`demo-server`](samples/demo-server) - an OPC UA server that is more complex than the simple server and can be used for compliance testing. -6. [`mqtt-client`](samples/mqtt-client) - an OPC UA client that subscribes to some values and publishes them to an MQTT broker. -7. [`web-client`](samples/web-client) - an OPC UA client that subscribes to some values and streams them over a websocket. -8. [`modbus-server`](samples/modbus-server) - an OPC UA server that translates variables from MODBUS. \ No newline at end of file +1. [`simple-server`](examples/simple-server) - an OPC UA server that adds 4 variables v1, v2, v3 and v4 and updates them from a timer via push and pull mechanisms. +2. [`simple-client`](examples/simple-client) - an OPC UA client that connects to a server and subscribes to the values of v1, v2, v3 and v4. +3. [`discovery-client`](examples/discovery-client) - an OPC UA client that connects to a discovery server and lists the servers registered on it. +4. [`chess-server`](examples/chess-server) - an OPC UA server that connects to a chess engine as its back end and updates variables representing the state of the game. +5. [`demo-server`](examples/demo-server) - an OPC UA server that is more complex than the simple server and can be used for compliance testing. +6. [`mqtt-client`](examples/mqtt-client) - an OPC UA client that subscribes to some values and publishes them to an MQTT broker. +7. [`web-client`](examples/web-client) - an OPC UA client that subscribes to some values and streams them over a websocket. +8. [`modbus-server`](examples/modbus-server) - an OPC UA server that translates variables from MODBUS. diff --git a/docs/client.md b/docs/client.md index 7facc2925..6533937ea 100644 --- a/docs/client.md +++ b/docs/client.md @@ -6,28 +6,28 @@ This is a small tutorial for using the OPC UA client library. It will assume you Rust and tools such as `cargo`. 1. A small overview of OPC UA is [here](./opc_ua_overview.md). -2. Rust OPC UA's compatibility with the standard is described [here](./compatibility.md). +2. Rust OPC UA's compatibility with the standard is described [here](./compatibility.md). ### Introducing the OPC UA Client API The OPC UA for Rust client API supports calls for OPC UA services. Whether the server you are calling implements them is another matter but you can call them. - + For the most part it is synchronous - you call the function and it waits for the server to respond or a timeout to happen. Each function call returns a `Result` either containing the response to the call, or a status code. Data change notifications are asynchronous. When you create a subscription you supply a callback. The client API will automatically begin sending publish requests to the server on your behalf and will call -your callback when a publish response contains notifications. +your callback when a publish response contains notifications. Clients generally require some knowledge of the server you are calling. You need to know its ip address, port, endpoints, security policy and also what services it supports. The client API provides -different ways to connect to servers, by configuration file or ad hoc connections. +different ways to connect to servers, by configuration file or ad hoc connections. -In this sample, we're going to write a simple client that connects to the -`opcua/samples/simple-server`, subscribes to some values and prints them out as they change. +In this example, we're going to write a simple client that connects to the +`opcua/examples/simple-server`, subscribes to some values and prints them out as they change. -If you want to see a finished version of this, look at `opcua/samples/simple-client`. +If you want to see a finished version of this, look at `opcua/examples/simple-client`. ### Life cycle @@ -40,10 +40,10 @@ From a coding perspective a typical use would be this: Most of the housekeeping and detail is handled by the API. You just need to point the client at the server, and set things up before calling stuff on the session. - + ## Create a simple project -We're going to start with a blank project. +We're going to start with a blank project. ``` cargo init --bin test-client @@ -51,7 +51,7 @@ cargo init --bin test-client ## Import the crate -The `opcua-client` is the crate containing the client side API. So first edit your `Cargo.toml` to +The `opcua-client` is the crate containing the client side API. So first edit your `Cargo.toml` to add that dependency: ```toml @@ -63,7 +63,7 @@ opcua = { version = "0.11", features = ["client"] } OPC UA has a *lot* of types and structures and the client has structs representing the client, session and open connection. - + To pull these in, add this to the top of your `main.rs`: ```rust @@ -75,8 +75,8 @@ The `prelude` module contains all of the things a basic client needs. ## Create your client The `Client` object represents a configured client describing its identity and set of behaviours. - -There are three ways we can create one. + +There are three ways we can create one. 1. Via a `ClientBuilder` 2. Externally by loading a a configuration file. @@ -113,8 +113,8 @@ So here we use `ClientBuilder` to construct a `Client` that will: ### Security -Security is an important feature of OPC UA. Because the builder has called `create_sample_keypair(true)` -it will automatically create a self-signed private key and public cert if the files do not already exist. If +Security is an important feature of OPC UA. Because the builder has called `create_sample_keypair(true)` +it will automatically create a self-signed private key and public cert if the files do not already exist. If we did not set this line then something else would have to install a key & cert, e.g. an external script. But as it is set, the first time it starts it will create a directory called `./pki` (relative to @@ -129,7 +129,7 @@ These files are X509 (`cert.der`) and private key (`private.pem`) files respecti containing information about the client "My First Client" and the public key. The private key is just the private key. -For security purposes, clients are required to trust server certificates (and servers are +For security purposes, clients are required to trust server certificates (and servers are required to trust clients), but for demo purposes we've told the client to automatically trust the server by calling `trust_server_certs(true)`. When this setting is true, the client will automatically trust the server regardless of the key it presents. @@ -145,7 +145,7 @@ When we connect to a server for the first you will see some more entries added u The server's .der file was automatically stored in `./pki/trusted` because we told the client to automatically trust the server. The name of this file is derived from information in the certificate and its thumbprint -to make a unique file. +to make a unique file. If we had told the client not to trust the server, the cert would have appeared under `/pki/rejected` and we would need to move it manually into the `/pki/trusted` folder. This @@ -163,14 +163,14 @@ require you do this some other way, e.g. through a web interface or configuratio ### Retry policy -We also set a retry policy, so that if the client cannot connect to the server or is disconnected from the server, +We also set a retry policy, so that if the client cannot connect to the server or is disconnected from the server, it will try to connect up to 3 times before giving up. If a connection succeeds the retry counter is reset so it's 3 tries for any one reconnection attempt, not total. Setting the limit to zero would retry continuously forever. There are also settings to control the retry reconnection rate, i.e. the interval to wait from one failed attempt to the next. It is not advisable to make retries too fast. -### Create the Client +### Create the Client Finally we called `client()` to produce a `Client`. Now we have a client we can start calling it. @@ -186,7 +186,7 @@ We'll go ad hoc. So in your client code you will have some code like this. ```rust fn main() { //... create Client - + // Create an endpoint. The EndpointDescription can be made from a tuple consisting of // the endpoint url, security policy, message security mode and user token policy. let endpoint: EndpointDescription = ( @@ -198,7 +198,7 @@ fn main() { // Create the session let session = client.connect_to_endpoint(endpoint, IdentityToken::Anonymous).unwrap(); - + //... use session } ``` @@ -206,24 +206,24 @@ fn main() { This command asks the API to connect to the server `opc.tcp://localhost:4855/` with a security policy / message mode of None / None, and to connect as an anonymous user. -Assuming the connect success and returns `Ok(session)` then we now have a session to the server. +Assuming the connect success and returns `Ok(session)` then we now have a session to the server. Note you will always get a `session` even if activation failed, i.e. if your identity token was invalid for the endpoint your connection will be open but every call will fail with a `StatusCode::BadSessionNotActivated` service fault until you call `activate_session()` successfully. ## Using the Session object - -Note that the client returns sessions wrapped as a `Arc>`. The `Session` is locked because + +Note that the client returns sessions wrapped as a `Arc>`. The `Session` is locked because the code shares it with the OPC UA for Rust internals. -That means to use a session you must lock it to obtain read or write access to it. e.g, - +That means to use a session you must lock it to obtain read or write access to it. e.g, + ```rust // Obtain a read-write lock to the session let session = session.write().unwrap(); // call it. -``` +``` Since you share the Session with the internals, you MUST relinquish the lock in a timely fashion. i.e. you should never lock it open at the session start because OPC UA will never be able to obtain it and will @@ -248,7 +248,7 @@ Use a scope or a function to release the lock before you hit `Session::run(sessi ```rust { let mut session = session.write().unwrap(); - // ... create some subscriptions, monitored items + // ... create some subscriptions, monitored items } let _ = Session::run(session); ``` @@ -256,26 +256,26 @@ let _ = Session::run(session); ## Calling the server Once we have a session we can ask the server to do things by sending requests to it. Requests correspond to services -implemented by the server. Each request is answered by a response containing the answer, or a service fault if the -service is in error. +implemented by the server. Each request is answered by a response containing the answer, or a service fault if the +service is in error. First a word about synchronous and asynchronous calls. ### Synchronous calls The OPC UA for Rust client API is _mostly_ synchronous by design. i.e. when you call the a function, the request will be -sent to the server and the call will block until the response is received or the call times out. +sent to the server and the call will block until the response is received or the call times out. This makes the client API easy to use. ### Asynchronous calls Under the covers, all calls are asynchronous. Requests are dispatched and responses are handled asynchronously -but the client waits for the response it is expecting or for the call to timeout. +but the client waits for the response it is expecting or for the call to timeout. The only exception to this are publish requests and responses which are always asynchronous. These are handled internally by the API from timers. If a publish response contains changes from a subscription, the subscription's -registered callback will be called asynchronously from another thread. +registered callback will be called asynchronously from another thread. ### Calling a service @@ -293,7 +293,7 @@ Here is code that creates a subscription and adds a monitored item to the subscr println!("Data change from server:"); changed_monitored_items.iter().for_each(|item| print_value(item)); }))?; - + // Create some monitored items let items_to_create: Vec = ["v1", "v2", "v3", "v4"].iter() .map(|v| NodeId::new(2, *v).into()).collect(); @@ -311,7 +311,7 @@ are trying to achieve. ## Session::run -If all you did is subscribe to some stuff and you have no further work to do then you can just call `Session::run()`. +If all you did is subscribe to some stuff and you have no further work to do then you can just call `Session::run()`. ```rust Session::run(session); @@ -323,25 +323,25 @@ This function synchronously runs forever on the thread, blocking until the clien If you intend writing your own loop then the session's loop needs to run asynchronously on another thread. In this case you call `Session::async_run()`. When you call it, a new thread is spawned to maintain the session and the calling thread is free to do something else. So for example, you could write a polling loop of some kind. The call to `run_async()` returns an `tokio::oneshot::Sender` that allows you to send a message to stop the session running on -the other thread. You must capture that sender returned by the function in a variable or it will drop and the session will +the other thread. You must capture that sender returned by the function in a variable or it will drop and the session will also drop. ```rust let session_tx = Session::run_async(session.clone()); loop { - // My loop + // My loop { // I want to poll a value from OPC UA let session = session.write().unwrap(); let value = session.read(....); //... process value } - + let some_reason_to_quit() { // Terminate the session loop session_tx.send(SessionCommand.stop()); } - + // Maybe I sleep in my loop because it polls std::thread::sleep(Duration::from_millis(2000);) } @@ -349,5 +349,5 @@ loop { ## That's it -Now you have created a simple client application. Look at the client examples under `samples`, +Now you have created a simple client application. Look at the client examples under `examples`, starting with `simple-client` for a very basic client. diff --git a/docs/compatibility.md b/docs/compatibility.md index e184ca58e..1b575ebe9 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -1,4 +1,4 @@ -# OPC UA Feature Support +# OPC UA Feature Support ## OPC UA Binary Transport Protocol @@ -26,7 +26,7 @@ The following services are supported in the server: * Attribute service set * Read * Write - * History Read - 0.8+. The server-side functionality is delegated to callbacks that must be implemented. + * History Read - 0.8+. The server-side functionality is delegated to callbacks that must be implemented. * History Update - 0.8+. The server-side functionality is delegated to callbacks that must be implemented. * Session service set @@ -34,13 +34,13 @@ The following services are supported in the server: * ActivateSession * CloseSession * Cancel - stub implementation - + * Node Management service set * AddNodes * AddReferences * DeleteNodes * DeleteReferences - + * Query service set * QueryFirst - stub that returns BadNotSupported * QueryNext - stub that returns BadNotSupported @@ -51,7 +51,7 @@ The following services are supported in the server: * TranslateBrowsePathsToNodeIds * MonitoredItem service set - * CreateMonitoredItems + * CreateMonitoredItems - Data change filter including dead band filtering. - Event filter * ModifyMonitoredItems @@ -73,38 +73,38 @@ The following services are supported in the server: ### Address Space / Nodeset -The standard OPC UA address space is exposed. OPC UA for Rust uses a script to generate code to create and populate the standard address space. This functionality is controlled by a server build feature -`generated-address-space` that defaults to on but can be disabled if the full address space is not required. When disabled, the address space will be empty apart from some root objects. +The standard OPC UA address space is exposed. OPC UA for Rust uses a script to generate code to create and populate the standard address space. This functionality is controlled by a server build feature +`generated-address-space` that defaults to on but can be disabled if the full address space is not required. When disabled, the address space will be empty apart from some root objects. ### Current limitations Currently the following are not supported * Diagnostic info. OPC UA allows for you to ask for diagnostics with any request. None is supplied at this time -* Session resumption. If your client disconnects, all information is discarded. +* Session resumption. If your client disconnects, all information is discarded. * Default node set is mostly static. Certain fields of server information will contain their default values unless explicitly set. * Access control is limited to setting read/write permissions on nodes that apply to all sessions. * Multiple created sessions in a single transport. ## Client -The client API API is synchronous - i.e. you call a function that makes a request and it returns +The client API API is synchronous - i.e. you call a function that makes a request and it returns when the response is received or a timeout occurs. Under the surface it is asynchronous so that functionality may be exposed at some point. -The client exposes functions that correspond to the current server supported profile, i.e. look above at the server services and there will be client-side functions that are analogous to those services. +The client exposes functions that correspond to the current server supported profile, i.e. look above at the server services and there will be client-side functions that are analogous to those services. In addition to the server services above, the following are also supported. -* FindServers - when connected to a discovery server, to find other servers +* FindServers - when connected to a discovery server, to find other servers * RegisterServer - when connected to a discovery server, to register a server -Potentially the client could have functions to call other services so it could be used to call other +Potentially the client could have functions to call other services so it could be used to call other OPC UA implementation. ## Configuration -Server and client can be configured programmatically via a builder or by configuration file. See -the `samples/` folder for examples of client and server side configuration. +Server and client can be configured programmatically via a builder or by configuration file. See +the `examples/` folder for examples of client and server side configuration. The config files are specified in YAML but this is controlled via serde so the format is not hard-coded. @@ -169,14 +169,14 @@ the trust model. ### Certificate creator tool -The `tools/certificate-creator` tool will create a demo public self-signed cert and private key. +The `tools/certificate-creator` tool will create a demo public self-signed cert and private key. It can be built from source, or the crate: ```bash $ cargo install --force opcua-certificate-creator ``` -A minimal usage might be something like this inside samples/simple-client and/or samples/simple-server: +A minimal usage might be something like this inside examples/simple-client and/or examples/simple-server: ```bash $ opcua-certificate-creator --pkipath ./pki diff --git a/docs/cross-compile.md b/docs/cross-compile.md index b59cced02..31dd2b458 100644 --- a/docs/cross-compile.md +++ b/docs/cross-compile.md @@ -138,7 +138,7 @@ So now we can test if the build works: ``` $ source .opcuaSSLenv -$ cd samples/simple-client +$ cd examples/simple-client $ qemu-arm-static ../../target/armv7-unknown-linux-gnueabihf/debug/opcua-simple-client ``` @@ -146,6 +146,6 @@ or ``` $ source .opcuaSSLenv -$ cd samples/demo-server +$ cd examples/demo-server $ qemu-arm-static ../../target/armv7-unknown-linux-gnueabihf/debug/opcua-demo-server ``` diff --git a/docs/design.md b/docs/design.md index ba96050c3..759b8c2f4 100644 --- a/docs/design.md +++ b/docs/design.md @@ -30,7 +30,7 @@ These are all published on [crates.io](https://crates.io). Generally speaking th The workspace also contains some other folders: -* [`samples`](../samples) - containing various client and server examples. +* [`examples`](../examples) - containing various client and server examples. * [`tools`](../tools) - various scripts and tools including scripts that machine generate OPC UA status codes, structs and node ids. * [`integration`](../integration) - integration tests @@ -59,7 +59,7 @@ fn main() { This server will accept connections, allow you to browse the address space and subscribe to variables. -Refer to the [`samples/simple-server/`](../samples/simple-server) and [`samples/simple-client/`](../samples/simple-client) examples +Refer to the [`examples/simple-server/`](../examples/simple-server) and [`examples/simple-client/`](../examples/simple-client) examples for something that adds variables to the address space and changes their values. ## Types @@ -318,7 +318,7 @@ This [OPC UA link](http://opcfoundation-onlineapplications.org/ProfileReporting/ * log - for logging / auditing * openssl - cryptographic functions for signing, certifications and encryption/decryption * serde, server_yaml - for processing config files -* clap - used by sample apps & certificate creator for command line argument processing +* clap - used by example apps & certificate creator for command line argument processing * byteorder - for serializing values with the proper endian-ness * tokio - for asynchronous IO and timers * futures - for futures used by tokio diff --git a/docs/developer.md b/docs/developer.md index 052989382..45229e399 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -34,7 +34,8 @@ CLion has very good Rust support. Install the `rust` and `toml` plugins and choo 1. Enable "Use rustfmt instead of built-in formatter" 2. Enable "Run rustfmt on save" -If you are using RustRover then you get Rust out of the box but you need to ensure you use Rustfmt as your formatter. Using RustRover also prevents you from using some of the 3rd party samples and might also impact on some debugging scenarios, e.g. into OpenSSL code. +If you are using RustRover then you get Rust out of the box but you need to ensure you use Rustfmt as your formatter. +Using RustRover also prevents you from using some of the 3rd party examples and might also impact on some debugging scenarios, e.g. into OpenSSL code. ## Visual Studio Code @@ -50,4 +51,4 @@ It would be very nice if OpenSSL could be replaced by a native Rust crypto libra This is a useful link to follow about setting up [Wireshark for OPC UA](https://opcconnect.opcfoundation.org/2017/02/analyzing-opc-ua-communications-with-wireshark/). This allows you to capture network traffic and see how clients and servers are talking to each other. Wireshark has an OPC UA filter that decodes the binary traffic and tells you what requests and responses were being sent. -The only thing to add to the article is that most of the samples run on port 4855, so you should edit the settings for OPC UA and add port `4855` so that when you capture traffic and filter on `opcua` you see the port. \ No newline at end of file +The only thing to add to the article is that most of the examples run on port 4855, so you should edit the settings for OPC UA and add port `4855` so that when you capture traffic and filter on `opcua` you see the port. diff --git a/docs/setup.md b/docs/setup.md index a02a97b6c..4b6393183 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -82,7 +82,7 @@ The OPC UA server crate also provides some other features that you may or may no OPC UA for Rust follows the normal Rust conventions. There is a `Cargo.toml` per module that you may use to build the module and all dependencies. e.g. ```bash -$ cd opcua/samples/demo-server +$ cd opcua/examples/demo-server $ cargo build ``` diff --git a/docs/testing.md b/docs/testing.md index 710b49064..b5428eab9 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -55,13 +55,13 @@ they describe is covered by unit / integration tests and of course interoperabil ## 3rd party interoperability testing -OPC UA for Rust contains a couple of samples built with 3rd party OPC UA open source implementations for +OPC UA for Rust contains a couple of examples built with 3rd party OPC UA open source implementations for interoperability testing. * Node OPC UA - a NodeJS based implementation * Open62541 - a C based implementation -These can be used in place of the `simple-client` and `simple-server` samples as appropriate: +These can be used in place of the `simple-client` and `simple-server` examples as appropriate: ```bash cd opcua/node-opcua diff --git a/samples/chess-server/Cargo.toml b/examples/chess-server/Cargo.toml similarity index 100% rename from samples/chess-server/Cargo.toml rename to examples/chess-server/Cargo.toml diff --git a/samples/chess-server/README.md b/examples/chess-server/README.md similarity index 100% rename from samples/chess-server/README.md rename to examples/chess-server/README.md diff --git a/samples/chess-server/chess-server.iml b/examples/chess-server/chess-server.iml similarity index 100% rename from samples/chess-server/chess-server.iml rename to examples/chess-server/chess-server.iml diff --git a/samples/chess-server/src/game.rs b/examples/chess-server/src/game.rs similarity index 100% rename from samples/chess-server/src/game.rs rename to examples/chess-server/src/game.rs diff --git a/samples/chess-server/src/main.rs b/examples/chess-server/src/main.rs similarity index 100% rename from samples/chess-server/src/main.rs rename to examples/chess-server/src/main.rs diff --git a/samples/client.conf b/examples/client.conf similarity index 100% rename from samples/client.conf rename to examples/client.conf diff --git a/samples/demo-server/Cargo.toml b/examples/demo-server/Cargo.toml similarity index 100% rename from samples/demo-server/Cargo.toml rename to examples/demo-server/Cargo.toml diff --git a/samples/demo-server/Dockerfile b/examples/demo-server/Dockerfile similarity index 79% rename from samples/demo-server/Dockerfile rename to examples/demo-server/Dockerfile index 7696bcdbf..f94deee5c 100644 --- a/samples/demo-server/Dockerfile +++ b/examples/demo-server/Dockerfile @@ -4,7 +4,7 @@ FROM rust:latest AS builder RUN apt-get install -y libssl-dev WORKDIR /build COPY . . -WORKDIR samples/demo-server +WORKDIR examples/demo-server RUN cargo install --path . # Repackage the binary in a standalone container @@ -12,8 +12,8 @@ FROM debian:bullseye-slim AS dist RUN apt-get update && apt-get install -y openssl && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=builder /usr/local/cargo/bin/opcua-demo-server ./ -COPY --from=builder /build/samples/server.conf ./ -COPY --from=builder /build/samples/demo-server/log4rs.yaml ./ +COPY --from=builder /build/examples/server.conf ./ +COPY --from=builder /build/examples/demo-server/log4rs.yaml ./ COPY --from=builder /build/lib/src/server/html/index.html ./ EXPOSE 4855 EXPOSE 8585 diff --git a/samples/demo-server/README.md b/examples/demo-server/README.md similarity index 94% rename from samples/demo-server/README.md rename to examples/demo-server/README.md index 1c872a740..58be3de3c 100644 --- a/samples/demo-server/README.md +++ b/examples/demo-server/README.md @@ -14,7 +14,7 @@ from `http://localhost:8585`, however you must start it from the `demo-server` d and other resources. ``` -cd opcua/samples/demo-server +cd opcua/examples/demo-server cargo run ``` @@ -45,7 +45,7 @@ If you want to build the demo server and don't have a development environment th ```sh cd opcua -docker build -t opcua-rs/demo-server:latest . -f samples/demo-server/Dockerfile +docker build -t opcua-rs/demo-server:latest . -f examples/demo-server/Dockerfile ``` And then to run it: diff --git a/samples/demo-server/log4rs.yaml b/examples/demo-server/log4rs.yaml similarity index 100% rename from samples/demo-server/log4rs.yaml rename to examples/demo-server/log4rs.yaml diff --git a/samples/demo-server/sample.server.test.conf b/examples/demo-server/sample.server.test.conf similarity index 100% rename from samples/demo-server/sample.server.test.conf rename to examples/demo-server/sample.server.test.conf diff --git a/samples/demo-server/src/control.rs b/examples/demo-server/src/control.rs similarity index 100% rename from samples/demo-server/src/control.rs rename to examples/demo-server/src/control.rs diff --git a/samples/demo-server/src/historical.rs b/examples/demo-server/src/historical.rs similarity index 100% rename from samples/demo-server/src/historical.rs rename to examples/demo-server/src/historical.rs diff --git a/samples/demo-server/src/machine.rs b/examples/demo-server/src/machine.rs similarity index 100% rename from samples/demo-server/src/machine.rs rename to examples/demo-server/src/machine.rs diff --git a/samples/demo-server/src/main.rs b/examples/demo-server/src/main.rs similarity index 100% rename from samples/demo-server/src/main.rs rename to examples/demo-server/src/main.rs diff --git a/samples/demo-server/src/methods.rs b/examples/demo-server/src/methods.rs similarity index 100% rename from samples/demo-server/src/methods.rs rename to examples/demo-server/src/methods.rs diff --git a/samples/demo-server/src/scalar.rs b/examples/demo-server/src/scalar.rs similarity index 100% rename from samples/demo-server/src/scalar.rs rename to examples/demo-server/src/scalar.rs diff --git a/samples/demo-server/users/sample-x509.der b/examples/demo-server/users/sample-x509.der similarity index 100% rename from samples/demo-server/users/sample-x509.der rename to examples/demo-server/users/sample-x509.der diff --git a/samples/discovery-client/Cargo.toml b/examples/discovery-client/Cargo.toml similarity index 100% rename from samples/discovery-client/Cargo.toml rename to examples/discovery-client/Cargo.toml diff --git a/samples/discovery-client/README.md b/examples/discovery-client/README.md similarity index 100% rename from samples/discovery-client/README.md rename to examples/discovery-client/README.md diff --git a/samples/discovery-client/src/main.rs b/examples/discovery-client/src/main.rs similarity index 100% rename from samples/discovery-client/src/main.rs rename to examples/discovery-client/src/main.rs diff --git a/samples/event-client/Cargo.toml b/examples/event-client/Cargo.toml similarity index 100% rename from samples/event-client/Cargo.toml rename to examples/event-client/Cargo.toml diff --git a/samples/event-client/README.md b/examples/event-client/README.md similarity index 100% rename from samples/event-client/README.md rename to examples/event-client/README.md diff --git a/samples/event-client/src/main.rs b/examples/event-client/src/main.rs similarity index 100% rename from samples/event-client/src/main.rs rename to examples/event-client/src/main.rs diff --git a/samples/mqtt-client/Cargo.toml b/examples/mqtt-client/Cargo.toml similarity index 100% rename from samples/mqtt-client/Cargo.toml rename to examples/mqtt-client/Cargo.toml diff --git a/samples/mqtt-client/README.md b/examples/mqtt-client/README.md similarity index 100% rename from samples/mqtt-client/README.md rename to examples/mqtt-client/README.md diff --git a/samples/mqtt-client/src/main.rs b/examples/mqtt-client/src/main.rs similarity index 100% rename from samples/mqtt-client/src/main.rs rename to examples/mqtt-client/src/main.rs diff --git a/samples/server.conf b/examples/server.conf similarity index 100% rename from samples/server.conf rename to examples/server.conf diff --git a/samples/simple-client/Cargo.toml b/examples/simple-client/Cargo.toml similarity index 100% rename from samples/simple-client/Cargo.toml rename to examples/simple-client/Cargo.toml diff --git a/samples/simple-client/README.md b/examples/simple-client/README.md similarity index 83% rename from samples/simple-client/README.md rename to examples/simple-client/README.md index 2f7691e4c..bcfaaf105 100644 --- a/samples/simple-client/README.md +++ b/examples/simple-client/README.md @@ -1,9 +1,9 @@ -To run this sample: +To run this example: -1. Launch either the `samples/simple-server`, or `3rd-party/node-opcua-server`. Both servers expose the same variables. +1. Launch either the `examples/simple-server`, or `3rd-party/node-opcua-server`. Both servers expose the same variables. 2. Run as `cargo run` -The client connects to the server, creates a subscription to variables v1, +The client connects to the server, creates a subscription to variables v1, v2, v3, v4 and continues to print out changes to those values without terminating. ## Crypto diff --git a/samples/simple-client/identity/sample-x509.der b/examples/simple-client/identity/sample-x509.der similarity index 100% rename from samples/simple-client/identity/sample-x509.der rename to examples/simple-client/identity/sample-x509.der diff --git a/samples/simple-client/identity/sample-x509.pem b/examples/simple-client/identity/sample-x509.pem similarity index 100% rename from samples/simple-client/identity/sample-x509.pem rename to examples/simple-client/identity/sample-x509.pem diff --git a/samples/simple-client/simple-client.iml b/examples/simple-client/simple-client.iml similarity index 100% rename from samples/simple-client/simple-client.iml rename to examples/simple-client/simple-client.iml diff --git a/samples/simple-client/src/main.rs b/examples/simple-client/src/main.rs similarity index 100% rename from samples/simple-client/src/main.rs rename to examples/simple-client/src/main.rs diff --git a/samples/simple-server/Cargo.toml b/examples/simple-server/Cargo.toml similarity index 100% rename from samples/simple-server/Cargo.toml rename to examples/simple-server/Cargo.toml diff --git a/samples/simple-server/README.md b/examples/simple-server/README.md similarity index 100% rename from samples/simple-server/README.md rename to examples/simple-server/README.md diff --git a/samples/simple-server/simple-server.iml b/examples/simple-server/simple-server.iml similarity index 100% rename from samples/simple-server/simple-server.iml rename to examples/simple-server/simple-server.iml diff --git a/samples/simple-server/src/main.rs b/examples/simple-server/src/main.rs similarity index 100% rename from samples/simple-server/src/main.rs rename to examples/simple-server/src/main.rs diff --git a/samples/simple-server/users/sample-x509.der b/examples/simple-server/users/sample-x509.der similarity index 100% rename from samples/simple-server/users/sample-x509.der rename to examples/simple-server/users/sample-x509.der diff --git a/samples/web-client/Cargo.toml b/examples/web-client/Cargo.toml similarity index 100% rename from samples/web-client/Cargo.toml rename to examples/web-client/Cargo.toml diff --git a/samples/web-client/README.md b/examples/web-client/README.md similarity index 94% rename from samples/web-client/README.md rename to examples/web-client/README.md index 20fd58581..e8c08ea30 100644 --- a/samples/web-client/README.md +++ b/examples/web-client/README.md @@ -5,14 +5,14 @@ Usage: Run the `demo-server` in one console: ``` -cd opcua/samples/demo-server +cd opcua/examples/demo-server cargo run ``` Then in another console run the `web-client` ``` -cd opcua/samples/web-client +cd opcua/examples/web-client cargo run -- --url opc.tcp://localhost:4855 ``` @@ -32,4 +32,4 @@ OPC UA session will be dropped. Internally, the web-client consists of an `actix-web` server. There is an `OPCUASession` actor which is bound to a websocket context. The actor is created by opening `ws://servername:8686/ws/` which connects to the OPC UA server when it starts. The client session sends messages to the front end over a websocket as JSON and rendered -by the browser. \ No newline at end of file +by the browser. diff --git a/samples/web-client/html/index.html b/examples/web-client/html/index.html similarity index 100% rename from samples/web-client/html/index.html rename to examples/web-client/html/index.html diff --git a/samples/web-client/src/main.rs b/examples/web-client/src/main.rs similarity index 100% rename from samples/web-client/src/main.rs rename to examples/web-client/src/main.rs diff --git a/lib/src/client/config.rs b/lib/src/client/config.rs index ca14c93fc..4e455cc03 100644 --- a/lib/src/client/config.rs +++ b/lib/src/client/config.rs @@ -168,17 +168,17 @@ pub struct ClientConfig { pub application_uri: String, /// Product uri pub product_uri: String, - /// Autocreates public / private keypair if they don't exist. For testing/samples only + /// Autocreates public / private keypair if they don't exist. For testing/examples only /// since you do not have control of the values pub create_sample_keypair: bool, /// Custom certificate path, to be used instead of the default .der certificate path pub certificate_path: Option, /// Custom private key path, to be used instead of the default private key path pub private_key_path: Option, - /// Auto trusts server certificates. For testing/samples only unless you're sure what you're + /// Auto trusts server certificates. For testing/examples only unless you're sure what you're /// doing. pub trust_server_certs: bool, - /// Verify server certificates. For testing/samples only unless you're sure what you're + /// Verify server certificates. For testing/examples only unless you're sure what you're /// doing. pub verify_server_certs: bool, /// PKI folder, either absolute or relative to executable diff --git a/lib/src/client/mod.rs b/lib/src/client/mod.rs index d0ef79618..3ddc03734 100644 --- a/lib/src/client/mod.rs +++ b/lib/src/client/mod.rs @@ -31,7 +31,7 @@ //! //! # Example //! -//! Here is a complete example of a client that connects to the `samples/simple-server`, subscribes +//! Here is a complete example of a client that connects to the `examples/simple-server`, subscribes //! to some values and prints out changes to those values. This example corresponds to the one //! described in the in docs/client.md tutorial. //! diff --git a/lib/src/client/tests/mod.rs b/lib/src/client/tests/mod.rs index 596299810..fb3da5258 100644 --- a/lib/src/client/tests/mod.rs +++ b/lib/src/client/tests/mod.rs @@ -79,12 +79,12 @@ pub fn default_sample_config() -> ClientConfig { #[test] fn client_sample_config() { - // This test exists to create the samples/client.conf file + // This test exists to create the examples/client.conf file // This test only exists to dump a sample config let config = default_sample_config(); let mut path = std::env::current_dir().unwrap(); path.push(".."); - path.push("samples"); + path.push("examples"); path.push("client.conf"); println!("Path is {:?}", path); diff --git a/lib/src/server/config.rs b/lib/src/server/config.rs index bde36c88e..72c9913d2 100644 --- a/lib/src/server/config.rs +++ b/lib/src/server/config.rs @@ -182,7 +182,7 @@ impl Default for Limits { #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct CertificateValidation { - /// Auto trusts client certificates. For testing/samples only unless you're sure what you're + /// Auto trusts client certificates. For testing/examples only unless you're sure what you're /// doing. pub trust_client_certs: bool, /// Check the valid from/to fields of a certificate @@ -533,7 +533,7 @@ pub struct ServerConfig { pub application_uri: String, /// Product url pub product_uri: String, - /// Autocreates public / private keypair if they don't exist. For testing/samples only + /// Autocreates public / private keypair if they don't exist. For testing/examples only /// since you do not have control of the values pub create_sample_keypair: bool, /// Path to a custom certificate, to be used instead of the default .der certificate diff --git a/lib/src/server/tests/mod.rs b/lib/src/server/tests/mod.rs index e19eec7ca..816068083 100644 --- a/lib/src/server/tests/mod.rs +++ b/lib/src/server/tests/mod.rs @@ -63,7 +63,7 @@ pub fn server_config_sample_save() { let config = ServerBuilder::new_sample().config(); let mut path = std::env::current_dir().unwrap(); path.push(".."); - path.push("samples"); + path.push("examples"); path.push("server.conf"); println!("Path is {:?}", path); assert!(config.save(&path).is_ok());