diff --git a/endpoints/citrus-camel/src/main/java/org/citrusframework/camel/actions/CreateCamelRouteAction.java b/endpoints/citrus-camel/src/main/java/org/citrusframework/camel/actions/CreateCamelRouteAction.java index 57b6a32885..e7e9f0b437 100644 --- a/endpoints/citrus-camel/src/main/java/org/citrusframework/camel/actions/CreateCamelRouteAction.java +++ b/endpoints/citrus-camel/src/main/java/org/citrusframework/camel/actions/CreateCamelRouteAction.java @@ -62,7 +62,7 @@ public void doExecute(TestContext context) { final List routesToUse; if (StringUtils.hasText(routeContext)) { - // now lets parse the routes with JAXB + // now let's parse the routes with JAXB try { Object value = CamelUtils.getJaxbContext().createUnmarshaller().unmarshal(new StringSource(context.replaceDynamicContentInString(routeContext))); if (value instanceof CamelRouteContextFactoryBean) { diff --git a/src/manual/actions-purge-endpoints.adoc b/src/manual/actions-purge-endpoints.adoc index 34a36ac7f8..b70eee8fd0 100644 --- a/src/manual/actions-purge-endpoints.adoc +++ b/src/manual/actions-purge-endpoints.adoc @@ -188,4 +188,4 @@ public SequenceBeforeTest beforeTest() { Just use this before-test bean in the Spring bean application context and the purge endpoint action is active. Obsolete messages that are waiting on the message endpoints for consumption are purged before the next test in line is executed. -TIP: Purging message endpoints becomes also very interesting when working with server instances in Citrus. Each server component automatically has an inbound message endpoint where incoming messages are stored to internally. Citrus will automatically use this incoming message endpoint as target for the purge action so you can just use the server instance as you know it from your configuration in any purge action. +TIP: Purging message endpoints becomes also very interesting when working with server instances in Citrus. Each server component automatically has an inbound message endpoint where incoming messages are stored too internally. Citrus will automatically use this incoming message endpoint as target for the purge action so you can just use the server instance as you know it from your configuration in any purge action. diff --git a/src/manual/actions-purge-jms.adoc b/src/manual/actions-purge-jms.adoc index 02f324e5e1..c9584630bc 100644 --- a/src/manual/actions-purge-jms.adoc +++ b/src/manual/actions-purge-jms.adoc @@ -91,7 +91,7 @@ NOTE: Citrus provides special support for JMS related features when using the Sp Notice that we have referenced the *jms* namespace when using the *purge-jms-queues* test action. -Purging the JMS queues in every test case is quite exhausting because every test case needs to define a purging action at the very beginning of the test. Fortunately the test suite definition offers tasks to run before, between and after the test cases which should ease up this tasks a lot. The test suite offers a very simple way to purge the destinations between the tests. See link:#before-suite[testsuite-before-test]for more information about this. +Purging the JMS queues in every test case is quite exhausting because every test case needs to define a purging action at the very beginning of the test. Fortunately the test suite definition offers tasks to run before, between and after the test cases which should ease up these tasks a lot. The test suite offers a very simple way to purge the destinations between the tests. See link:#before-suite[testsuite-before-test] for more information about this. As you can see in the next example it is quite easy to specify a group of destinations in the Spring configuration that get purged before a test is executed. diff --git a/src/manual/actions-receive.adoc b/src/manual/actions-receive.adoc index a6bcb91bb1..8a71773760 100644 --- a/src/manual/actions-receive.adoc +++ b/src/manual/actions-receive.adoc @@ -492,7 +492,7 @@ actions: ---- In addition to that you can ignore some elements that are skipped in comparison. We will describe this later on in this section. -Now lets continue with message header validation. +Now let's continue with message header validation. [[receive-message-headers]] === Validate message headers @@ -903,10 +903,10 @@ In messaging applications the header information often holds message ids, correl With this information given you can explicitly listen for messages that belong to your test case. This is very helpful to avoid receiving messages that are still available on the message destination. -Lets say the tested software application keeps sending messages that belong to previous test cases. This could happen in +Let's say the tested software application keeps sending messages that belong to previous test cases. This could happen in retry situations where the application error handling automatically tries to solve a communication problem that occurred during previous test cases. As a result a message destination (e.g. a JMS message queue) contains messages that are not -valid any more for the currently running test case. The test case might fail because the received message does not apply +valid anymore for the currently running test case. The test case might fail because the received message does not apply to the actual use case. So we will definitely run into validation errors as the expected message control values do not match. Now we have to find a way to avoid these problems. The test could filter the messages on a destination to only receive messages diff --git a/src/manual/actions-send.adoc b/src/manual/actions-send.adoc index e933321602..54fb633e5a 100644 --- a/src/manual/actions-send.adoc +++ b/src/manual/actions-send.adoc @@ -129,7 +129,7 @@ variable by the expression *_${variable-name}_* . TIP: Use variables wherever you can! At least the important entities of a test should be defined as variables at the beginning. The test case improves maintainability and flexibility when using variables. -Now lets have a closer look at the sending action. The *'endpoint'* attribute might catch your attention first. This attribute +Now let's have a closer look at the sending action. The *'endpoint'* attribute might catch your attention first. This attribute references a message endpoint in Citrus configuration by name. As previously mentioned the message endpoint definition lives in a separate configuration file and contains the actual message transport settings. In this example the *"helloService"* is referenced which is a message endpoint for sending out messages via JMS or HTTP for instance. diff --git a/src/manual/changes-new.adoc b/src/manual/changes-new.adoc index 8e933f6243..982b65de71 100644 --- a/src/manual/changes-new.adoc +++ b/src/manual/changes-new.adoc @@ -540,7 +540,7 @@ Also following _org.springframework.beans.factory.xml.BeanDefinitionParser_ add |_**SchemaRepositoryParser**_ | `META-INF/citrus/schema-repository/parser` |=== -The bean definition parsers mentioned above are now able to dynamically lookup element parsers that live in other modules. For instance the `SchemaParser` loads and delegates the bean definition parsing to `.xsd` or `.json` related schema parser implementations that live in `citrus-validation-xml` or `citrus-validation-json` modules. The user needs to add these modules to the classpath when using a XML or Json schema in a schema repository. +The bean definition parsers mentioned above are now able to dynamically lookup element parsers that live in other modules. For instance the `SchemaParser` loads and delegates the bean definition parsing to `.xsd` or `.json` related schema parser implementations that live in `citrus-validation-xml` or `citrus-validation-json` modules. The user needs to add these modules to the classpath when using an XML or Json schema in a schema repository. Also the test action registry is now able to load parser implementation from other modules using the resource lookup mechanism. This way we can delegate to data dictionary parser implementations for `XML` or `Json` when they are present on the classpath. diff --git a/src/manual/data-dictionary.adoc b/src/manual/data-dictionary.adoc index f3b5d32b7b..1be1c8de51 100644 --- a/src/manual/data-dictionary.adoc +++ b/src/manual/data-dictionary.adoc @@ -79,7 +79,7 @@ For more complex XML payloads where more flexibility is required the XPath data As expected XPath mapping expressions are more powerful and can better handle complex scenarios with XML namespaces, attributes and node lists. Just like the node mapping dictionary the XPath mapping dictionary also supports variables, functions and an external mapping file. -XPath works fine with namespaces. In general it is good practice to define a namespace context where you map namespace URI values with prefix values. So your XPath expression is more precise and evaluation is strict. In Citrus the *NamespaceContextBuilder* which is also added as a normal Spring bean to the application context manages namespaces used in your XPath expressions. See our XML and XPath chapters in this documentation for detailed description how to accomplish fail safe XPath expressions with namespaces. +XPath works fine with namespaces. In general it is good practice to define a namespace context where you map namespace URI values with prefix values. So your XPath expression is more precise and evaluation is strict. In Citrus the *NamespaceContextBuilder* which is also added as a normal Spring bean to the application context manages namespaces used in your XPath expressions. See our XML and XPath chapters in this documentation for detailed description how to accomplish fail-safe XPath expressions with namespaces. This completes the XML data dictionary usage in Citrus. Later on we will see some more advanced data dictionary scenarios where we will discuss the usage of dictionary scopes and mapping strategies. But before that let us have a look at other message formats like JSON messages. diff --git a/src/manual/endpoint-adapter.adoc b/src/manual/endpoint-adapter.adoc index d6a27deb58..1dd989dcf0 100644 --- a/src/manual/endpoint-adapter.adoc +++ b/src/manual/endpoint-adapter.adoc @@ -1,7 +1,7 @@ [[endpoint-adapter]] = Endpoint adapter -Endpoint adapter help to customize the behavior of a Citrus server such as HTTP or SOAP web servers. As the servers get started with the Citrus context they are ready to receive incoming client requests. Now there are different ways to process these incoming requests and to provide a proper response message. By default the server will forward the incoming request to a in memory message channel where a test can receive the message and provide a synchronous response. This message channel handling is done automatically behind the scenes so the tester does not care about these things. The tester just uses the server directly as endpoint reference in the test case. This is the default behaviour. In addition to that you can define custom endpoint adapters on the Citrus server in order to change this default behavior. +Endpoint adapter help to customize the behavior of a Citrus server such as HTTP or SOAP web servers. As the servers get started with the Citrus context they are ready to receive incoming client requests. Now there are different ways to process these incoming requests and to provide a proper response message. By default the server will forward the incoming request to an in-memory message channel where a test can receive the message and provide a synchronous response. This message channel handling is done automatically behind the scenes so the tester does not care about these things. The tester just uses the server directly as endpoint reference in the test case. This is the default behaviour. In addition to that you can define custom endpoint adapters on the Citrus server in order to change this default behavior. You set the custom endpoint adapter directly on the server configuration as follows: diff --git a/src/manual/endpoint-arquillian.adoc b/src/manual/endpoint-arquillian.adoc index c00304d5df..e85bdc48d8 100644 --- a/src/manual/endpoint-arquillian.adoc +++ b/src/manual/endpoint-arquillian.adoc @@ -1,14 +1,14 @@ [[arquillian]] = Arquillian support -Arquillian is a well known integration test framework that comes with a great feature set when it comes to Java EE testing inside of a full qualified application server. With Arquiliian you can deploy your Java EE services in a real application server of your choice and execute the tests inside the application server boundaries. This makes it very easy to test your Java EE services in scope with proper JNDI resource allocation and other resources provided by the application server. Citrus is able to connect with the Arquillian test case. Speaking in more detail your Arquillian test is able to use a Citrus extension in order to use the Citrus feature set inside the Arquillian boundaries. +Arquillian is a well known integration test framework that comes with a great feature set when it comes to Java EE testing inside a full qualified application server. With Arquillian you can deploy your Java EE services in a real application server of your choice and execute the tests inside the application server boundaries. This makes it very easy to test your Java EE services in scope with proper JNDI resource allocation and other resources provided by the application server. Citrus is able to connect with the Arquillian test case. Speaking in more detail your Arquillian test is able to use a Citrus extension in order to use the Citrus feature set inside the Arquillian boundaries. Read the next section in order to find out more about the Citrus Arquillian extension. [[citrus-arquillian-extension]] == Citrus Arquillian extension -Arquillian offers a fine mechanism for extensions adding features to the Arquillian test setup and test execution. The Citrus extension respectively adds Citrus framework instance creation and Citrus test execution to the Arquillian world. First of all lets have a look at the extension descriptor properties settable via *arquillian.xml* : +Arquillian offers a fine mechanism for extensions adding features to the Arquillian test setup and test execution. The Citrus extension respectively adds Citrus framework instance creation and Citrus test execution to the Arquillian world. First of all let's have a look at the extension descriptor properties settable via *arquillian.xml* : [source,xml] ---- @@ -42,12 +42,12 @@ Now that we have added the extension descriptor with all properties we need to a ---- -Now everything is set up to use Citrus within Arquillian. Lets use Citrus functionality in a Arquillian test case. +Now everything is set up to use Citrus within Arquillian. Let's use Citrus functionality in an Arquillian test case. [[client-side-testing]] == Client side testing -Arquillian separates client and container side testing. When using client side testing the test case is executed outside of the application container deployment. This means that your test case has no direct access to container managed resources such as JNDI resources. On the plus side it is not necessary to include your test in the container deployment. The test case interacts with the container deployment as a normal client would do. Lets have a look at a first example: +Arquillian separates client and container side testing. When using client side testing the test case is executed outside the application container deployment. This means that your test case has no direct access to container managed resources such as JNDI resources. On the plus side it is not necessary to include your test in the container deployment. The test case interacts with the container deployment as a normal client would do. Let's have a look at a first example: [source,java] ---- @@ -116,12 +116,12 @@ The Citrus test designer provides Java DSL methods for building the test logic. When the Citrus test case is executed the messages are sent over the wire. The respective response message is received with well known Citrus receive message logic. We can validate the response messages accordingly and make sure the client call was done right. In case something goes wrong within Citrus test execution the framework will raise exceptions accordingly. As a result the JUnit test method is successful or failed with errors coming from Citrus test execution. -This is how Citrus and Arquillian can interact in a test scenario where the test deployment is managed by Arquillian and the client side actions take place within Citrus. This is a great way to combine both frameworks with Citrus being able to call different service API endpoints in addition with validating the outcome. This was a client side test case where the test logic was executed outside of the application container. Arquillian also supports container remote test cases where we have direct access to container managed resources. The following section describes how this works with Citrus. +This is how Citrus and Arquillian can interact in a test scenario where the test deployment is managed by Arquillian and the client side actions take place within Citrus. This is a great way to combine both frameworks with Citrus being able to call different service API endpoints in addition with validating the outcome. This was a client side test case where the test logic was executed outside the application container. Arquillian also supports container remote test cases where we have direct access to container managed resources. The following section describes how this works with Citrus. [[container-side-testing]] == Container side testing -In previous sections we have seen how to combine Citrus with Arquillian in a client side test case. This is the way to go for all test cases that do not need to have access on container managed resources. Lets have a look at a sample where we want to gain access to a JMS queue and connection managed by the application container. +In previous sections we have seen how to combine Citrus with Arquillian in a client side test case. This is the way to go for all test cases that do not need to have access on container managed resources. Let's have a look at a sample where we want to gain access to a JMS queue and connection managed by the application container. [source,java] ---- @@ -190,7 +190,7 @@ This is how to combine Citrus and Arquillian in order to build integration tests [[test-runners]] == Test runners -In the previous sections we have used the Citrus *TestDesigner* in order to construct a Citrus test case to execute within the Arquillian boundaries. The nature of the test designer is to aggregate all Java DSL method calls in order to build a complete Citrus test case before execution is done via the Citrus framework. This approach can cause some unexpected behavior when mixing the Citrus Java DSL method calls with Arquillian test logic. Lets describe this by having a look at an example where th mixture of test designer and pure Java test logic causes unseen problems. +In the previous sections we have used the Citrus *TestDesigner* in order to construct a Citrus test case to execute within the Arquillian boundaries. The nature of the test designer is to aggregate all Java DSL method calls in order to build a complete Citrus test case before execution is done via the Citrus framework. This approach can cause some unexpected behavior when mixing the Citrus Java DSL method calls with Arquillian test logic. Let's describe this by having a look at an example where th mixture of test designer and pure Java test logic causes unseen problems. [source,java] ---- @@ -272,7 +272,7 @@ public void testDesignRuntimeMixture(@CitrusResource TestRunner runner) throws E } ---- -The test logic has not changed significantly. We use the Citrus *TestRunner* as method injected parameter instead of the *TestDesigner* . And this is pretty much the trick. Now the Java DSL methods do execute the Citrus test logic immediately. This is why the syntax of the Citrus Java DSL methods have changed a little bit. We now use a anonymous interface implementation for constructing the send/receive test action logic. As a result we can use the Citrus Java DSL as normal code and we can mix the runtime Java logic as each statement is executed immediately. +The test logic has not changed significantly. We use the Citrus *TestRunner* as method injected parameter instead of the *TestDesigner* . And this is pretty much the trick. Now the Java DSL methods do execute the Citrus test logic immediately. This is why the syntax of the Citrus Java DSL methods have changed a little bit. We now use an anonymous interface implementation for constructing the send/receive test action logic. As a result we can use the Citrus Java DSL as normal code and we can mix the runtime Java logic as each statement is executed immediately. With Java lambda expressions our code looks even more straight forward and less verbose as we can skip the anonymous interface implementations. With Java 8 you can write the same test like this: diff --git a/src/manual/endpoint-camel.adoc b/src/manual/endpoint-camel.adoc index 576c8553f5..1e283e59b8 100644 --- a/src/manual/endpoint-camel.adoc +++ b/src/manual/endpoint-camel.adoc @@ -436,7 +436,7 @@ public CamelContext camelContext() { ---- The route has an exception handling block defined that is called as soon as the exchange processing ends up in some error or exception. -With Citrus you can also simulate a exchange exception when sending back a synchronous response to a calling route. +With Citrus you can also simulate an exchange exception when sending back a synchronous response to a calling route. .Java [source,java,indent=0,role="primary"] diff --git a/src/manual/endpoint-channel.adoc b/src/manual/endpoint-channel.adoc index f78bf5f05b..f8461ecb9d 100644 --- a/src/manual/endpoint-channel.adoc +++ b/src/manual/endpoint-channel.adoc @@ -148,8 +148,7 @@ reply to that channel. The basic configuration for a synchronous channel endpoin public ChannelSyncEndpoint helloEndpoint() { return new ChannelSyncEndpointBuilder() .channel("helloChannel") - .replyTimeout(1000L) - .pollingInterval(1000L) + .pollingInterval(1000) .build(); } ---- @@ -159,7 +158,6 @@ public ChannelSyncEndpoint helloEndpoint() { ---- ---- @@ -459,7 +457,7 @@ when(receive("orderChannelEndpoint") == Xpath selector It is also possible to evaluate some XPath expression on the message payload in order to select a message from a message -channel. The XPath expression outcome must match an expected value and only then the message is consumed form the channel. +channel. The XPath expression outcome must match an expected value and only then the message is consumed from the channel. The syntax for the XPath expression is to be defined as the element name like this: @@ -544,7 +542,7 @@ This will match all incoming messages regardless the XML namespace prefix that i == JsonPath selector It is also possible to evaluate some JsonPath expression on the message payload in order to select a message from a message -channel. The JsonPath expression outcome must match an expected value and only then the message is consumed form the channel. +channel. The JsonPath expression outcome must match an expected value and only then the message is consumed from the channel. The syntax for the JsonPath expression is to be defined as the element name like this: diff --git a/src/manual/endpoint-component.adoc b/src/manual/endpoint-component.adoc index 437956d996..423f73c331 100644 --- a/src/manual/endpoint-component.adoc +++ b/src/manual/endpoint-component.adoc @@ -35,11 +35,11 @@ Of course this mechanism is not limited to JMS endpoints. We can use all default [horizontal] jms:: Creates a JMS endpoint for sending and receiving message to a queue or topic channel:: Creates a channel endpoint for sending and receiving messages using an in memory Spring Integration message channel -http:: Creates a HTTP client for sending a request to some server URL synchronously waiting for the response message +http:: Creates an HTTP client for sending a request to some server URL synchronously waiting for the response message ws:: Creates a Web Socket client for sending messages to or receiving messages from a Web Socket server soap:: Creates a SOAP WebService client that send a proper SOAP message to the server URL and waits for the synchronous response to arrive ssh:: Creates a new ssh client for publishing a command to the server -mail:: or smtp: Creates a new mail client for sending a mail mime message to a SMTP server +mail:: or smtp: Creates a new mail client for sending a mail mime message to an SMTP server camel:: Creates a new Apache Camel endpoint for sending and receiving Camel exchanges both to and from Camel routes. vertx:: or eventbus: Creates a new Vert.x instance sending and receiving messages with the network event bus rmi:: Creates a new RMI client instance sending and receiving messages for method invocation on remote interfaces diff --git a/src/manual/endpoint-direct.adoc b/src/manual/endpoint-direct.adoc index 7bce10abe6..68a608ada2 100644 --- a/src/manual/endpoint-direct.adoc +++ b/src/manual/endpoint-direct.adoc @@ -122,8 +122,7 @@ reply to that queue. The basic configuration for a synchronous direct endpoint c public ChannelSyncEndpoint helloEndpoint() { return new ChannelSyncEndpointBuilder() .queue("helloChannel") - .replyTimeout(1000L) - .pollingInterval(1000L) + .pollingInterval(1000) .build(); } ---- @@ -133,7 +132,6 @@ public ChannelSyncEndpoint helloEndpoint() { ---- ---- @@ -246,7 +244,7 @@ then(send("helloSyncEndpoint") A queue can hold multiple messages at the same time. Usually you receive messages using first-in-first-out pattern. Message selectors enable you to select messages form that queue so you can pick messages form a queue based on a selector evaluation. -Citrus introduces a special queue message queue implementation that support message selectors. +Citrus introduces a special message queue implementation that supports message selectors. .Java [source,java,indent=0,role="primary"] @@ -432,7 +430,7 @@ when(receive("orderChannelEndpoint") == Xpath selector It is also possible to evaluate some XPath expression on the message payload in order to select a message from a message -queue. The XPath expression outcome must match an expected value and only then the message is consumed form the queue. +queue. The XPath expression outcome must match an expected value and only then the message is consumed from the queue. The syntax for the XPath expression is to be defined as the element name like this: @@ -517,7 +515,7 @@ This will match all incoming messages regardless the XML namespace prefix that i == JsonPath selector It is also possible to evaluate some JsonPath expression on the message payload in order to select a message from a message -queue. The JsonPath expression outcome must match an expected value and only then the message is consumed form the queue. +queue. The JsonPath expression outcome must match an expected value and only then the message is consumed from the queue. The syntax for the JsonPath expression is to be defined as the element name like this: diff --git a/src/manual/endpoint-docker.adoc b/src/manual/endpoint-docker.adoc index dbe5d77fc1..8df7ad29ca 100644 --- a/src/manual/endpoint-docker.adoc +++ b/src/manual/endpoint-docker.adoc @@ -3,7 +3,7 @@ Citrus provides configuration components and test actions for interaction with a Docker daemon. The Citrus docker client component will execute Docker commands for container management such as start, stop, build, inspect and so on. The Docker client by default uses the Docker remote REST API. As a user you can execute Docker commands as part of a Citrus test and validate possible command results. -NOTE: The Docker test components in Citrus are kept in a separate Maven module. If not already done so you have to include the module as Maven dependency to your project +NOTE: The Docker test components in Citrus are kept in a separate Maven module. If not already done, you have to include the module as Maven dependency to your project [source,xml] ---- @@ -120,7 +120,7 @@ We added a special docker namespace with prefix *docker:* so now we can start to ---- -In this very simple example we first ping the Docker daemon to make sure we have connectivity up and running. After that we get the Docker version information. The second action shows an important concept when executing Docker commands in Citrus. As a tester we might be interested in validating the command result. So wen can specify an optional *docker:result* which is usually in JSON data format. As usual we can use test variables here and ignore some values explicitly such as the *GitCommit* value. +In this very simple example we first ping the Docker daemon to make sure we have connectivity up and running. After that we get the Docker version information. The second action shows an important concept when executing Docker commands in Citrus. As a tester we might be interested in validating the command result. So we can specify an optional *docker:result* which is usually in JSON data format. As usual we can use test variables here and ignore some values explicitly such as the *GitCommit* value. Based on that we can execute several Docker commands in a test case: diff --git a/src/manual/endpoint-ftp.adoc b/src/manual/endpoint-ftp.adoc index c93c68804e..e264c174fb 100644 --- a/src/manual/endpoint-ftp.adoc +++ b/src/manual/endpoint-ftp.adoc @@ -1,7 +1,7 @@ [[ftp]] = FTP support -With Citrus it is possible to start your own ftp server for accepting incoming client requests. You can also use Citrus as a FTP client to send FTP commands. The next sections deal with FTP connectivity. +With Citrus it is possible to start your own ftp server for accepting incoming client requests. You can also use Citrus as an FTP client to send FTP commands. The next sections deal with FTP connectivity. NOTE: The FTP components in Citrus are maintained in their own Maven module. So you should add the module as Maven dependency to your project accordingly. @@ -314,7 +314,7 @@ When the file is stored on server side we receive a success result message with [[ftp-client-retrieve]] === Retrieve files -We are able to retrieve files from a FTP server. We need to specify the target file path that we want to get on the server user home directory. +We are able to retrieve files from an FTP server. We need to specify the target file path that we want to get on the server user home directory. .Java [source,java,indent=0,role="primary"] diff --git a/src/manual/endpoint-http.adoc b/src/manual/endpoint-http.adoc index 0ab370bfdb..f1d49ad3ee 100644 --- a/src/manual/endpoint-http.adoc +++ b/src/manual/endpoint-http.adoc @@ -396,7 +396,7 @@ public HttpClient httpClient() { Of course, you can set the *Accept* header on each send operation in order to tell the server what kind of content types are supported in response messages. -Now we can send and receive messages as Http client with specific test actions. Now lets move on to the Http server. +Now we can send and receive messages as Http client with specific test actions. Now let's move on to the Http server. [[http-client-interceptors]] == Http client interceptors @@ -436,7 +436,7 @@ component. You can add custom interceptor implementations here in order to parti [[http-rest-server]] == Http REST server -Receiving Http requests requires a Http server listening on a port on your local machine. Citrus offers an embedded Http +Receiving Http requests requires an Http server listening on a port on your local machine. Citrus offers an embedded Http server which is capable of handling incoming Http requests. The server accepts client connections and must provide a proper Http response. In the next section you will see how to simulate server side Http REST service with Citrus. @@ -445,7 +445,7 @@ Http response. In the next section you will see how to simulate server side Http ---- @Bean public HttpServer httpServer() { - return new HttpClientBuilder() + return new HttpServerBuilder() .port(8080) .autoStart(true) .build(); @@ -469,7 +469,7 @@ response message as reply which will be automatically sent back to the Http clie image:figure_008.jpg[figure_008.jpg] The figure above shows the basic setup with inbound channel and reply channel. You as a tester should not worry about this -to much. By default, you as a tester just use the server as synchronous endpoint in your test case. This means that you +too much. By default, you as a tester just use the server as synchronous endpoint in your test case. This means that you simply receive a message from the server and send a response back. .Java @@ -508,18 +508,18 @@ send("httpServer") As you can see we reference the server id in both receive and send actions. The Citrus server instance will automatically send the response back to the calling Http client. In most cases this is exactly what we want to do - send back a response message that is specified inside the test. The Http server component by default uses a channel endpoint adapter in order to -forward all incoming requests to an in memory message channel. This is done completely behind the scenes. The Http server +forward all incoming requests to an in-memory message channel. This is done completely behind the scenes. The Http server component provides some more customization possibilities when it comes to endpoint adapter implementations. This topic is discussed in a separate section link:#endpoint-adapter[endpoint-adapter]. Up to now we keep it simple by synchronously receiving and sending messages in the test case. TIP: The default channel endpoint adapter automatically creates an inbound message channel where incoming messages are stored -to internally. So if you need to clean up a server that has already stored some incoming messages you can do this easily by +too internally. So if you need to clean up a server that has already stored some incoming messages you can do this easily by purging the internal message channel. The message channel follows a naming convention *{serverName}.inbound* where *{serverName}* is the Spring bean name of the Citrus server endpoint component. If you purge this internal channel in a before test nature you are sure that obsolete messages on a server instance get purged before each test is executed. -So lets get back to our mission of providing response messages as server to connected clients. As you might know Http REST +So let's get back to our mission of providing response messages as server to connected clients. As you might know Http REST works with some characteristic properties when it comes to send and receive messages. For instance a client can send different request methods GET, POST, PUT, DELETE, HEAD and so on. The Citrus server may verify this method when receiving client requests. Therefore we have introduced special Http test actions for server communication. Have a look at a simple example: @@ -601,11 +601,11 @@ headers. As usual the optional message body is compared to an expected message t is saved to a test variable *message_id* for later usage in the response. The response message defines Http typical entities such as *status* and *reason-phrase*. Here the tester can simulate -*404 NOT_FOUND* errors or similar other status codes that get send back to the client. In our example everything is *OK* +*404 NOT_FOUND* errors or similar other status codes that get sent back to the client. In our example everything is *OK* and we send back a response body and some custom header entries. That is basically how Citrus simulates Http server operations. We receive the client request and validate the request properties. -Then we send back a response with a Http status code. +Then we send back a response with an Http status code. This completes the server actions on Http message transport. Now we continue with some more Http specific settings and features. @@ -752,7 +752,7 @@ http().server("httpServer") ---- -Once more we set the custom header entry (*X-CustomHeaderId*) and a Http reserved header (*Content-Type*) for the response +Once more we set the custom header entry (*X-CustomHeaderId*) and an Http reserved header (*Content-Type*) for the response message. On top of this we are able to set the response status for the Http response. We use the reserved header names *status* in order to mark the success of the server operation. With this mechanism we can easily simulate different server behaviour such as Http error response codes (e.g. 404 - Not found, 500 - Internal error). Let us have a closer look at the generated @@ -824,7 +824,7 @@ services some other header names are essential for validation. These are request path and request URI. The Citrus server side REST message controller will automatically add all this information to the message header for you. So all you need to do is validate the header entries in your test. -The next example receives a Http GET method request on server side. Here the GET request does not have any message payload, +The next example receives an Http GET method request on server side. Here the GET request does not have any message payload, so the validation just works on the information given in the message header. We assume the client to call `http://localhost:8080/app/users?id=123456789`. As a tester we need to validate the request method, request URI, context path and the query parameters. @@ -894,7 +894,7 @@ http() ---- -The parameter are automatically added to the request URL that is configured on the `httpClient` component. +The parameters are automatically added to the request URL that is configured on the `httpClient` component. [[http-server-interceptors]] == Http server interceptors @@ -946,7 +946,7 @@ Form urlencoded form data content could look like this: password=s%21cr%21t&username=foo ---- -A you can see the form data is automatically encoded. In the example above we transmit two form controls *password* and +As you can see the form data is automatically encoded. In the example above we transmit two form controls *password* and *username* with respective values *s$cr$t* and *foo* . In case we would validate this form data in Citrus we are able to do this with plaintext message validation. @@ -996,7 +996,7 @@ send("httpServer") Obviously validating these key-value pair character sequences can be hard especially when having HTML forms with lots of form controls. This is why Citrus provides a special message validator for *x-www-form-urlencoded* contents. First of all -we have to add *citrus-http* module as dependency to our project if not done so yet. After that we can add the validator +we have to add *citrus-http* module as dependency to our project if we have not done so yet. After that we can add the validator implementation to the list of message validators used in Citrus. .Java @@ -1248,10 +1248,10 @@ public BasicAuthClientHttpRequestFactory basicAuthFactory() { BasicAuthClientHttpRequestFactory factory = new BasicAuthClientHttpRequestFactory(); AuthScope scope = new AuthScope("localhost", "8080", "", "basic"); - factory.setAuthScope(); + factory.setAuthScope(scope); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("someUsername", "somePassword"); - factory.setCredentials(); + factory.setCredentials(credentials); return factory; } @@ -1285,7 +1285,7 @@ The advantages of this method is obvious. Now all sending test actions that refe add the basic authentication header. The above configuration results in Http client requests with authentication headers properly set for basic authentication. -The client request factory takes care on adding the proper basic authentication header to each request that is sent with this +The client request factory takes care of adding the proper basic authentication header to each request that is sent with this Citrus message sender. Citrus uses preemptive authentication. The message sender only sends a single request to the server with all authentication information set in the message header. The request which determines the authentication scheme on the server is skipped. This is why you have to add some auth scope in the client request factory so Citrus can setup an authentication @@ -1455,9 +1455,9 @@ http().server("httpServer") ---- -The sample above receives a Http request with method POST and some request data. The server response is specified with _Http 200 OK_ +The sample above receives an Http request with method POST and some request data. The server response is specified with _Http 200 OK_ and some additional cookie information. The cookie is part of the message header specification and gets a name and value -as well as several other attributes. This response will result in a Http response with the _"Set-Cookie"_ header set: +as well as several other attributes. This response will result in an Http response with the _"Set-Cookie"_ header set: .Set cookie header [source,text] @@ -1599,9 +1599,9 @@ client and server components support gzip compression out of the box. This means encoding headers in your http request/response message. Accept-Encoding=gzip:: Setting for clients when requesting gzip compressed response content. The Http server must support gzip compression then in order to provide the response as zipped byte stream. The Citrus http server component automatically recognizes this header in a request and applies gzip compression to the response. -Content-Encoding=gzip:: When a http server sends compressed message content to the client this header is set to *gzip* in order to mark the compression. The Http client must support gzip compression then in order to unzip the message content. The Citrus http client component automatically recognizes this header in a response and applies gzip unzip logic before passing the message to the test case. +Content-Encoding=gzip:: When an http server sends compressed message content to the client this header is set to *gzip* in order to mark the compression. The Http client must support gzip compression then in order to unzip the message content. The Citrus http client component automatically recognizes this header in a response and applies gzip unzip logic before passing the message to the test case. -The Citrus client and server automatically take care on gzip compression when those headers are set. In the test case you +The Citrus client and server automatically take care of gzip compression when those headers are set. In the test case you do not need to zip or unzip the content then as it is automatically done before. This means that you can request gzipped content from a server with just adding the message header *Accept-Encoding* in @@ -1774,7 +1774,7 @@ Citrus provides several default servlet implementations that are automatically a implementations are: org.citrusframework.http.servlet.RequestCachingServletFilter:: caches incoming request data so input streams can be read multiple times during request processing (important when request logging is enabled) -org.citrusframework.http.servlet.GzipServletFilter:: applies Gzip compressing when according headers are set and client explicitly asks for compressed request/response communication +org.citrusframework.http.servlet.GzipServletFilter:: applies Gzip compression when according headers are set and client explicitly asks for compressed request/response communication By the time you define some custom servlet filters or mappings to the server component Citrus will not apply default servlet filters. This means you always need to construct the whole servlet filter chain including default servlet filters mentioned above. diff --git a/src/manual/endpoint-jdbc.adoc b/src/manual/endpoint-jdbc.adoc index bd5d629902..5110df5620 100644 --- a/src/manual/endpoint-jdbc.adoc +++ b/src/manual/endpoint-jdbc.adoc @@ -370,7 +370,7 @@ In addition, there are advanced configuration possibilities to customize the beh | endpoint adapter | No | JdbcEndpointAdapterController -| A Endpoint adapter implementation creating the messages for validation. +| An Endpoint adapter implementation creating the messages for validation. |=== @@ -443,7 +443,7 @@ via the endpoint configuration. | `JdbcMessage.exception(String exceptionText)` | send -| Sends a exception to the system under test. Regarding to the driver documentation, the error will be an SQLException. +| Sends an exception to the system under test. Regarding the driver documentation, the error will be an SQLException. | `JdbcMessage.rowsUpdated(int number)` | send @@ -470,7 +470,7 @@ To use this, you have to specify the format of the dataSet String. Please refer | `JdbcMessage.error()` | send -| Sends a empty error result to the system under test. +| Sends an empty error result to the system under test. |=== diff --git a/src/manual/endpoint-jms.adoc b/src/manual/endpoint-jms.adoc index fcafd7395e..3f4a03dfe1 100644 --- a/src/manual/endpoint-jms.adoc +++ b/src/manual/endpoint-jms.adoc @@ -144,7 +144,7 @@ bean names. public JmsEndpoint helloServiceEndpoint() { return new JmsEndpointBuilder() .destination("Citrus.HelloService.Request.Queue") - .connectionFactory("myConnectionFactory") + .connectionFactory(myConnectionFactory()) .build(); } ---- @@ -157,7 +157,7 @@ public JmsEndpoint helloServiceEndpoint() { connection-factory="myConnectionFactory"/> ---- -As an alternative to that you may want to use a special Spring jms template implementation as custom bean in your endpoint. +As an alternative to that you may want to use a special Spring JMS template implementation as custom bean in your endpoint. .Java [source,java,indent=0,role="primary"] @@ -166,7 +166,7 @@ As an alternative to that you may want to use a special Spring jms template impl public JmsEndpoint helloServiceEndpoint() { return new JmsEndpointBuilder() .destination("Citrus.HelloService.Request.Queue") - .jmsTemplate("myJmsTemplate") + .jmsTemplate(myJmsTemplate()) .build(); } ---- @@ -241,7 +241,7 @@ a JMS connection factory in the configuration as the component needs to connect ---- @Bean public JmsSyncEndpoint helloServiceSyncEndpoint() { - return new JmsEndpointBuilder() + return new JmsSyncEndpointBuilder() .destination("Citrus.HelloService.InOut.Queue") .build(); } @@ -313,7 +313,7 @@ component as follows. ---- @Bean public JmsSyncEndpoint helloServiceSyncEndpoint() { - return new JmsEndpointBuilder() + return new JmsSyncEndpointBuilder() .destination("Citrus.HelloService.InOut.Queue") .replyDestination("Citrus.HelloService.Reply.Queue") .build(); @@ -459,10 +459,10 @@ were sent in advance to the subscription. By default Citrus will use a subscript in the test cases. This means that the topic subscription is started and stopped per receive action when the action is performed inside a test case. -In order to solve racing conditions for messages that are sent prior to the subscription you can also use a `auto-start` +In order to solve racing conditions for messages that are sent prior to the subscription you can also use an `auto-start` setting on the JMS endpoint component. This causes Citrus to start/stop the subscription based on the endpoint lifecycle instead of linking the subscription to the receive action. When the endpoint is ready the subscription is started and all -incoming message events are cached and stored to a internal in memory message channel for later consumption in the tests. +incoming message events are cached and stored to an internal in-memory message channel for later consumption in the tests. Here is the endpoint configuration with `auto-start` enabled. @@ -496,7 +496,7 @@ is loaded in the project. The internal message channel name is derived from the `{citrus-jms:endpoint@id}":subscriber.inbound"` -The in memory channel id is the combined result of the JMS endpoint id and the prefix `:subscriber.inbound`. In our example +The in-memory channel id is the combined result of the JMS endpoint id and the postfix `:subscriber.inbound`. In our example this would be `helloServiceTopicEndpoint:subscriber.inbound`. Now all messages sent to the topic in advance to the tests are cached and ready for consumption and verification in the test. @@ -527,6 +527,7 @@ public JmsSyncEndpoint helloServiceSyncEndpoint() { return new JmsEndpointBuilder() .destination("Citrus.HelloService.Topic") .pubSubDomain(true) + .durableSubscription(true) .autoStart(true) .build(); } diff --git a/src/manual/endpoint-jmx.adoc b/src/manual/endpoint-jmx.adoc index 7570c62cf2..4029e9e092 100644 --- a/src/manual/endpoint-jmx.adoc +++ b/src/manual/endpoint-jmx.adoc @@ -140,7 +140,7 @@ actions: ---- -As you can see we just used a normal send action referencing the jmx client component that we have just added. The message payload is a XML representation of the managed bean access. This is a special Citrus XML representation. Citrus will convert this XML payload to the actuel managed bean access. In the example above we try to access a managed bean with object name *java.lang:type=Memory* . The object name is defined in JMX specification and consists of a key *java.lang:type* and a value *Memory* . So we identify the managed bean on the server by its type. +As you can see we just used a normal send action referencing the jmx client component that we have just added. The message payload is an XML representation of the managed bean access. This is a special Citrus XML representation. Citrus will convert this XML payload to the actuel managed bean access. In the example above we try to access a managed bean with object name *java.lang:type=Memory* . The object name is defined in JMX specification and consists of a key *java.lang:type* and a value *Memory* . So we identify the managed bean on the server by its type. Now that we have access to the managed bean we can read its managed attributes such as *Verbose* . This is a boolean type attribute so the mbean invocation result will be a respective Boolean object. We can validate the managed bean attribute access in a receive action. @@ -212,7 +212,7 @@ actions: In the sample above we receive the mbean result and expect a *java.lang.Boolean* object return value. The return value content is also validated within the mbean result payload. -Some managed bean attributes might also be settable for us. So wen can define the attribute access as write operation by specifying a value in the send action payload. +Some managed bean attributes might also be settable for us. So we can define the attribute access as write operation by specifying a value in the send action payload. .Java [source,java,indent=0,role="primary"] @@ -378,7 +378,7 @@ This completes the basic JMX managed bean access as client. Now we also want to [[jmx-server]] == JMX server -The server side is always a little bit more tricky because we need to simulate custom managed bean access as a server. First of all Citrus provides a server component that specifies the connection properties for clients such as transport protocols, ports and mbean object names. Lets create a new server that accepts incoming requests via RMI on a remote registry *localhost:1099* . +The server side is always a little bit more tricky because we need to simulate custom managed bean access as a server. First of all Citrus provides a server component that specifies the connection properties for clients such as transport protocols, ports and mbean object names. Let's create a new server that accepts incoming requests via RMI on a remote registry *localhost:1099* . [source,xml] ---- @@ -413,11 +413,11 @@ On last thing to mention is that we could have also used *platform* as server-ur Now that we clarified the connectivity we need to talk about how to define the managed beans that are available on our JMX mbean server. This is done as nested *mbean* configuration elements. Here the managed bean definitions describe the managed bean with its objectDomain, objectName, operations and attributes. The most convenient way of defining such managed bean definitions is to give a bean type which is the fully qualified class name of the managed bean. Citrus will use the package name and class name for proper objectDomain and objectName construction. -Lets have a closer look at the first mbean definition in the example above. So the first managed bean is defined by its class name *org.citrusframework.jmx.mbean.HelloBean* and therefore is accessible using the objectName *org.citrusframework.jmx.mbean:type=HelloBean* . In addition to that Citrus will read the class information such as available methods, getters and setters for constructing a proper MBeanInfo. In the second managed bean definition in our example we have used additional custom objectDomain and objectName values. So the *NewsBean* will be accessible with *org.citrusframework.news:name=News* on the managed bean server. +Let's have a closer look at the first mbean definition in the example above. So the first managed bean is defined by its class name *org.citrusframework.jmx.mbean.HelloBean* and therefore is accessible using the objectName *org.citrusframework.jmx.mbean:type=HelloBean* . In addition to that Citrus will read the class information such as available methods, getters and setters for constructing a proper MBeanInfo. In the second managed bean definition in our example we have used additional custom objectDomain and objectName values. So the *NewsBean* will be accessible with *org.citrusframework.news:name=News* on the managed bean server. This is how we can define the bindings of managed beans and what clients need to search for when finding and accessing the managed beans on the server. When clients try to find the managed beans they have to use proper objectNames accordingly. ObjectNames that are not defined on the server will be rejected with managed bean not found error. -Right now we have to use the qualified class name of the managed bean in the definition. What happens if we do not have access to that mbean class or if there is not managed bean interface available at all? Citrus provides a generic managed bean that is able to handle any managed bean interaction. The generic bean implementation needs to know the managed operations and attributes though. So lets define a new generic managed bean on our server: +Right now we have to use the qualified class name of the managed bean in the definition. What happens if we do not have access to that mbean class or if there is not managed bean interface available at all? Citrus provides a generic managed bean that is able to handle any managed bean interaction. The generic bean implementation needs to know the managed operations and attributes though. So let's define a new generic managed bean on our server: [source,xml] ---- @@ -702,6 +702,6 @@ actions: ---- -The receive action expects read access to the *NewsBean* attribute *newsCount* and returns a result object of type *java.lang.Integer* . This way we can expect all attribute access to our managed beans. Write operations will have a attribute value specified. +The receive action expects read access to the *NewsBean* attribute *newsCount* and returns a result object of type *java.lang.Integer* . This way we can expect all attribute access to our managed beans. Write operations will have an attribute value specified. This completes the JMX server capabilities with managed bean access on operations and attributes. diff --git a/src/manual/endpoint-kafka.adoc b/src/manual/endpoint-kafka.adoc index 56e59cddaf..60daafd48e 100644 --- a/src/manual/endpoint-kafka.adoc +++ b/src/manual/endpoint-kafka.adoc @@ -156,7 +156,7 @@ The following table shows all available settings on a Kafka endpoint in Citrus: | No | `org.citrusframework.kafka.message.KafkaMessageConverter` | Converter maps internal Citrus message objects to ProducerRecord/ConsumerRecord objects. The converter implementation takes - care on message key, value, timestamp and special message headers. + care of message key, value, timestamp and special message headers. | header-mapper | No @@ -179,7 +179,7 @@ The following table shows all available settings on a Kafka endpoint in Citrus: | No | earliest | When consuming records from a topic partition and the current offset does not exist on that partition Kafka will automatically - seek to a valid offset position on that partition. The `offset-reset` setting where to find the new position (latest, earliest, + seek to a valid offset position on that partition. The `offset-reset` setting sets where to find the new position (latest, earliest, none). If `none` is set the consumer will receive an exception instead of resetting the offset to a valid position. | partition @@ -303,9 +303,9 @@ can set or verify those headers in send and receive actions as follows: ---- send(helloKafkaEndpoint) .message() - .header("KafkaMessageHeaders.TOPIC", "my.very.special.topic") - .header("KafkaMessageHeaders.MESSAGE_KEY", "myKey") - .header("KafkaMessageHeaders.PARTITION", 1); + .header(KafkaMessageHeaders.TOPIC, "my.very.special.topic") + .header(KafkaMessageHeaders.MESSAGE_KEY, "myKey") + .header(KafkaMessageHeaders.PARTITION, 1); ---- .XML @@ -323,7 +323,7 @@ and to specify the target partition of the producer record. These settings do on Default values on the Kafka endpoint are overwritten respectively. TIP: Typing of message header entries may also be of interest in order to meet the Kafka standards. For instance the following -message key is of type `java.lang.Integer` and is therefore transferred via Kafka's key-serializer as a integer value. You need +message key is of type `java.lang.Integer` and is therefore transferred via Kafka's key-serializer as an integer value. You need to set the header type to `integer` and use a `org.apache.kafka.common.serialization.IntegerSerializer` as key-serializer on the Kafka endpoint configuration. @@ -332,7 +332,7 @@ the Kafka endpoint configuration. ---- send(helloKafkaEndpoint) .message() - .header("KafkaMessageHeaders.MESSAGE_KEY", 1L); + .header(KafkaMessageHeaders.MESSAGE_KEY, 1L); ---- .XML @@ -351,11 +351,11 @@ an expected behavior. ---- receive(helloKafkaEndpoint) .message() - .header("KafkaMessageHeaders.TIMESTAMP", Matchers.greaterThan(0)) - .header("KafkaMessageHeaders.TOPIC", "my.expected.topic") - .header("KafkaMessageHeaders.MESSAGE_KEY", "myKey") - .header("KafkaMessageHeaders.PARTITION", 1) - .header("KafkaMessageHeaders.OFFSET", Matchers.greaterThanOrEqualTo(0)); + .header(KafkaMessageHeaders.TIMESTAMP, Matchers.greaterThan(0)) + .header(KafkaMessageHeaders.TOPIC, "my.expected.topic") + .header(KafkaMessageHeaders.MESSAGE_KEY, "myKey") + .header(KafkaMessageHeaders.PARTITION, 1) + .header(KafkaMessageHeaders.OFFSET, Matchers.greaterThanOrEqualTo(0)); ---- .XML @@ -436,7 +436,7 @@ test as follows: send("kafka:hello") .message() .body("foo") - .header("KafkaMessageHeaders.MESSAGE_KEY", 1); + .header(KafkaMessageHeaders.MESSAGE_KEY, 1); ---- .XML @@ -454,7 +454,7 @@ send("kafka:hello") This action above will create a dynamic Kafka endpoint and publish the message to the `hello` topic. The dynamic endpoint url uses the `kafka:` scheme and gives the topic name as resource path. In addition to that the dynamic endpoint url is able -to set multiple parameters such as `server`. Lets have a look at this in a small example. +to set multiple parameters such as `server`. Let's have a look at this in a small example. .Java [source,java,indent=0,role="primary"] diff --git a/src/manual/endpoint-kubernetes.adoc b/src/manual/endpoint-kubernetes.adoc index eb35dc4364..1eb9cf1768 100644 --- a/src/manual/endpoint-kubernetes.adoc +++ b/src/manual/endpoint-kubernetes.adoc @@ -4,7 +4,7 @@ http://kubernetes.io/[Kubernetes] is one of the hottest management platforms for containerized applications these days. Kubernetes lets you deploy, scale and manage your containers on the platform so you get features like auto-scaling, self-healing, service discovery and load balancing. Citrus provides interaction with the Kubernetes REST API so you can access the Kubernetes platform and its resources within a Citrus test case. -NOTE: The Kubernetes test components in Citrus are kept in a separate Maven module. If not already done so you have to include the module as Maven dependency to your project +NOTE: The Kubernetes test components in Citrus are kept in a separate Maven module. If not already done, you have to include the module as Maven dependency to your project [source,xml] ---- @@ -94,7 +94,7 @@ Citrus supports the following Kubernetes API commands with respective test actio * *k8s:watch-nodes* * *k8s:watch-replication-controllers* -We will discuss these commands in detail later on in this chapter. For now lets have a closer look on how to use the commands inside of a Citrus test. +We will discuss these commands in detail later on in this chapter. For now let's have a closer look on how to use the commands inside a Citrus test. [[kubernetes-commands-in-xml]] == Kubernetes commands in XML @@ -157,7 +157,7 @@ We added a special kubernetes namespace with prefix *k8s:* so now we can start t ---- In this very simple example we first ping the Kubernetes REST API to make sure we have connectivity up and running. The info command connects the REST API and returns a list of status information of the Kubernetes client. -After that we get the list of available Kubernetes pods. As a tester we might be interested in validating the command results. So wen can specify an optional *k8s:result* which is usually in Json format. With that we can apply the full +After that we get the list of available Kubernetes pods. As a tester we might be interested in validating the command results. So we can specify an optional *k8s:result* which is usually in Json format. With that we can apply the full Citrus Json validation power to the Kubernetes results. As usual we can use test variables here and ignore some values explicitly such as the *metadata* value. Also JsonPath expression validation and Json test message validation features in Citrus come in here to validate the results. @@ -436,7 +436,7 @@ public void getPodsTest() { } ---- -As you can see we are able get the complete pod information from Kubernetes. The result is validated with Json message validator in Citrus. This means we can use _@ignore@_ as well as test variables and +As you can see we are able to get the complete pod information from Kubernetes. The result is validated with Json message validator in Citrus. This means we can use _@ignore@_ as well as test variables and JsonPath expressions. [[create-resources]] diff --git a/src/manual/endpoint-mail.adoc b/src/manual/endpoint-mail.adoc index 71ffe2af1e..2ab87c52a1 100644 --- a/src/manual/endpoint-mail.adoc +++ b/src/manual/endpoint-mail.adoc @@ -3,7 +3,7 @@ Sending and receiving mails is the next interest we are going to talk about. When dealing with mail communication you most certainly need to interact with some sort of IMAP or POP mail server. But in Citrus we do not want to manage mails in a personal inbox. We just need to be able to exchange mail messages the persisting in a user inbox is not part of our business. -This is why Citrus provides *just* a SMTP mail server which accepts mail messages from clients. Once the SMTP server has accepted an incoming mail it forwards those data to the running test case. In the test case you can receive the incoming mail message and perform message validation as usual. The mail sending part is easy as Citrus offers a mail client that connects to some SMTP server for sending mails to the outside world. +This is why Citrus provides *just* an SMTP mail server which accepts mail messages from clients. Once the SMTP server has accepted an incoming mail it forwards those data to the running test case. In the test case you can receive the incoming mail message and perform message validation as usual. The mail sending part is easy as Citrus offers a mail client that connects to some SMTP server for sending mails to the outside world. NOTE: The mail components in Citrus are kept in a separate Maven module. So you should check that the module is available as Maven dependency in your project @@ -62,9 +62,9 @@ from:: The message sender mail address to:: The message recipient mail address. You can add multiple recipients by using a comma separated list. cc:: Copy recipient mail address. You can add multiple recipients by using a comma separated list. bcc:: Blind copy recipient mail address. You can add multiple recipients by using a comma separated list. -subject:: Some subject used as mail head line. +subject:: Some subject used as mail headline. -As a tester you are able to set these properties in your test case. Citrus defines a XML mail message representation that you can use inside your send action. Let us have a look at this: +As a tester you are able to set these properties in your test case. Citrus defines an XML mail message representation that you can use inside your send action. Let us have a look at this: [source,xml] ---- @@ -145,7 +145,7 @@ We assert the *_MailSendException_* from Spring to be thrown while sending the m [[mail-server]] == Mail server -Consuming mail messages is a more complicated task as we need to have some sort of server that clients can connect to. In your mail client software you typically point to some IMAP or POP inbox and receive mails from that endpoint. In Citrus we do not want to manage a whole personal mail inbox such as IMAP or POP would provide. We just need a SMTP server endpoint for clients to send mails to. The SMTP server accepts mail messages and forwards those to a running test case for further validation. +Consuming mail messages is a more complicated task as we need to have some sort of server that clients can connect to. In your mail client software you typically point to some IMAP or POP inbox and receive mails from that endpoint. In Citrus we do not want to manage a whole personal mail inbox such as IMAP or POP would provide. We just need an SMTP server endpoint for clients to send mails to. The SMTP server accepts mail messages and forwards those to a running test case for further validation. NOTE: We have no user inbox where incoming mails are stored. The mail server just forwards incoming mails to the running test for validation. After the test the incoming mail message is gone. @@ -160,7 +160,7 @@ Let us have a look at the Citrus mail server component and how you can add it to auto-start="true"/> ---- -The mail server component receives several properties such as *port* or *auto-start* . Citrus starts a in memory SMTP server that clients can connect to. +The mail server component receives several properties such as *port* or *auto-start* . Citrus starts an in-memory SMTP server that clients can connect to. In your test case you can then receive the incoming mail messages on the server in order to perform the well known XML validation mechanisms within Citrus. The message header and the payload contain all mail information so you can verify the content with expected templates as usual: @@ -287,4 +287,4 @@ Now besides not accepting a mail message in the first place you can als simulate As you can see from the example above we first accept the connection and receive the mail content as usual. Now the test returns a negative mail response with some error code reason set. The Citrus SMTP communication will then fail and the calling mail client receives the respective error. -If you skip the negative mail response the server will automatically response with positive SMTP response codes to the calling client. +If you skip the negative mail response the server will automatically respond with positive SMTP response codes to the calling client. diff --git a/src/manual/endpoint-restdocs.adoc b/src/manual/endpoint-restdocs.adoc index 7563724fd6..f28d021e75 100644 --- a/src/manual/endpoint-restdocs.adoc +++ b/src/manual/endpoint-restdocs.adoc @@ -3,7 +3,7 @@ Spring Restdocs project helps to easily generate API documentation for RESTful services. While messages are exchanged the Restdocs library generates request/response snippets and API documentation. You can add the Spring Restdocs documentation to the Citrus client components for Http *and* SOAP endpoints. -NOTE: The Spring Restdocs support components in Citrus are kept in a separate Maven module. If not already done so you have to include the module as Maven dependency to your project +NOTE: The Spring Restdocs support components in Citrus are kept in a separate Maven module. If not already done, you have to include the module as Maven dependency to your project [source,xml] ---- diff --git a/src/manual/endpoint-rmi.adoc b/src/manual/endpoint-rmi.adoc index 8170e66426..bcfc6202b8 100644 --- a/src/manual/endpoint-rmi.adoc +++ b/src/manual/endpoint-rmi.adoc @@ -3,7 +3,7 @@ RMI stands for Remote Method Invocation and is a standard way of calling Java method interfaces where caller and callee (client and server) are not located within the same JVM. So the object passed to the method as argument as well as the method return value are transmitted over the wire. -As a client Citrus is able to connect to some RMI registry that exposes some remote interfaces. As a server Citrus implements such a RMI registry and handles incoming method calls with providing the respective return value. +As a client Citrus is able to connect to some RMI registry that exposes some remote interfaces. As a server Citrus implements such an RMI registry and handles incoming method calls with providing the respective return value. NOTE: The RMI components in Citrus are kept in a separate Maven module. So you should check that the module is available as Maven dependency in your project diff --git a/src/manual/endpoint-selenium.adoc b/src/manual/endpoint-selenium.adoc index 2ff2310782..e8019a0137 100644 --- a/src/manual/endpoint-selenium.adoc +++ b/src/manual/endpoint-selenium.adoc @@ -3,7 +3,7 @@ http://www.seleniumhq.org/[Selenium] is a very popular tool for testing user interfaces with browser automation. Citrus is able to integrate with the Selenium Java API in order to execute Selenium commands. -NOTE: The Selenium test components in Citrus are kept in a separate Maven module. If not already done so you have to include the module as Maven dependency to your project +NOTE: The Selenium test components in Citrus are kept in a separate Maven module. If not already done, you have to include the module as Maven dependency to your project [source,xml] ---- @@ -196,7 +196,7 @@ public void seleniumTest() { } ---- -Now lets have a closer look at the different Selenium test actions supported in Citrus. +Now let's have a closer look at the different Selenium test actions supported in Citrus. [[start-stop-browser]] == Start/stop browser @@ -362,8 +362,8 @@ ids, names or xpath expressions. == Page actions Page objects are a well known pattern when using Selenium. The page objects define elements that the page is working with. In addition to that the -page objects define actions that can be executed from outside. This object oriented approach for accessing pages and their elements is a very good idea. -Lets have a look at a sample page object. +page objects define actions that can be executed from outside. This object-oriented approach for accessing pages and their elements is a very good idea. +Let's have a look at a sample page object. [source,java] ---- @@ -429,7 +429,7 @@ should always be the last parameter. == Page validation We can also use page object for validation purpose. The page object is loaded and instantiated as described in previous section. Then the page validator -is called. The validator performs assertions and validation operations with the page object. Lets see a sample page validator: +is called. The validator performs assertions and validation operations with the page object. Let's see a sample page validator: [source,java] ---- diff --git a/src/manual/endpoint-soap.adoc b/src/manual/endpoint-soap.adoc index 7a76379d6b..c09acfd41f 100644 --- a/src/manual/endpoint-soap.adoc +++ b/src/manual/endpoint-soap.adoc @@ -171,11 +171,11 @@ The figure above shows the basic setup with inbound channel and reply channel. Y ---- -As you can see we reference the server id in both receive and send actions. The Citrus server instance will automatically send the response back to the calling client. In most cases this is what you need to simulate a SOAP server instance in Citrus. Of course we have some more customization possibilities that we will go over later on. This customizations are optional so you can also skip the next description on endpoint adapters if you are happy with just what you have learned about the SOAP server component in Citrus. +As you can see we reference the server id in both receive and send actions. The Citrus server instance will automatically send the response back to the calling client. In most cases this is what you need to simulate a SOAP server instance in Citrus. Of course we have some more customization possibilities that we will go over later on. These customizations are optional so you can also skip the next description on endpoint adapters if you are happy with just what you have learned about the SOAP server component in Citrus. Just like the HTTP server component the SOAP server component by default uses the channel endpoint adapter in order to forward all incoming requests to an in memory message channel. This is done completely behind the scenes. The Citrus configuration has become a lot easier here so you do not have to configure this by default. When nothing else is set the test case does not worry about that settings on the server and just uses the server id reference as synchronous endpoint. -TIP: The default channel endpoint adapter automatically creates an inbound message channel where incoming messages are stored to internally. So if you need to clean up a server that has already stored some incoming messages you can do this easily by purging the internal message channel. The message channel follows a naming convention *{serverName}.inbound* where *{serverName}* is the Spring bean name of the Citrus server endpoint component. If you purge this internal channel in a before test nature you are sure that obsolete messages on a server instance get purged before each test is executed. +TIP: The default channel endpoint adapter automatically creates an inbound message channel where incoming messages are stored too internally. So if you need to clean up a server that has already stored some incoming messages you can do this easily by purging the internal message channel. The message channel follows a naming convention *{serverName}.inbound* where *{serverName}* is the Spring bean name of the Citrus server endpoint component. If you purge this internal channel in a before test nature you are sure that obsolete messages on a server instance get purged before each test is executed. However we do not want to loose the great extendability and customizing capabilities of the Citrus server component. This is why you can optionally define the endpoint adapter implementation used by the Citrus SOAP server. We provide several message endpoint adapter implementations for different simulation strategies. With these endpoint adapters you should be able to generate proper SOAP response messages for the client in various ways. Before we have a closer look at the different adapter implementations we want to show how you can set a custom endpoint adapter on the server component. @@ -195,7 +195,7 @@ With this endpoint adapter configuration above we change the Citrus server behav [[soap-send-and-receive]] == SOAP send and receive -Citrus provides test actions for sending and receiving messages of all kind. Different message content and different message transports are available to these send and receive actions. When using SOAP message transport we might need to set special information on that messages. These are special SOAP headers, SOAP faults and so on. So we have created a special SOAP namespace for all your SOAP related send and receive operations in a XML DSL test: +Citrus provides test actions for sending and receiving messages of all kind. Different message content and different message transports are available to these send and receive actions. When using SOAP message transport we might need to set special information on that messages. These are special SOAP headers, SOAP faults and so on. So we have created a special SOAP namespace for all your SOAP related send and receive operations in an XML DSL test: [source,xml] ---- @@ -236,7 +236,7 @@ receive:: Special receive operation for validating SOAP message content. send-fault:: Special send operation for sending out SOAP fault message content. assert-fault:: Special assertion operation for expecting a SOAP fault message as response. -The special SOAP related send and receive actions can coexist with normal Citrus actions. In fact you can mix those action types as you want inside of a test case. All test actions that work with SOAP message content on client and server side should use this special namespace. +The special SOAP related send and receive actions can coexist with normal Citrus actions. In fact you can mix those action types as you want inside a test case. All test actions that work with SOAP message content on client and server side should use this special namespace. In Java DSL we have something similar to that. The Java DSL provides special SOAP related features when calling the *soap()* method. With a fluent API you are able to then send and receive SOAP message content as client and server. @@ -262,7 +262,7 @@ In the following sections the SOAP related capabilities are discussed in more de [[soap-headers]] == SOAP headers -SOAP defines several header variations that we discuss in the following sections. First of all we deal with the special *SOAP action* header. In case we need to set this SOAP action header we simply need to use the special *_soap-action_* attribute in our test. The special header key in combination with a underlying SOAP client endpoint component constructs the SOAP action in the SOAP message. +SOAP defines several header variations that we discuss in the following sections. First of all we deal with the special *SOAP action* header. In case we need to set this SOAP action header we simply need to use the special *_soap-action_* attribute in our test. The special header key in combination with an underlying SOAP client endpoint component constructs the SOAP action in the SOAP message. .XML DSL [source,xml] @@ -386,7 +386,7 @@ As you can see the SOAP XML header validation can combine header element and XML [[soap-http-mime-headers]] == SOAP HTTP mime headers -Besides the SOAP specific header elements the HTTP mime headers (e.g. Content-Type, Content-Length, Authorization) might be candidates for validation, too. When using HTTP as transport layer the SOAP message may define those mime headers. The tester is able to send and validate these headers inside the test case, although these HTTP headers are located outside of the SOAP envelope. Let us first of all speak about validating the HTTP mime headers. This feature is not enabled by default. We have enable this in our SOAP server configuration. +Besides the SOAP specific header elements the HTTP mime headers (e.g. Content-Type, Content-Length, Authorization) might be candidates for validation, too. When using HTTP as transport layer the SOAP message may define those mime headers. The tester is able to send and validate these headers inside the test case, although these HTTP headers are located outside the SOAP envelope. Let us first of all speak about validating the HTTP mime headers. This feature is not enabled by default. We have enabled this in our SOAP server configuration. [source,xml] ---- @@ -430,7 +430,7 @@ So much for receiving and validating HTTP mime message headers with SOAP communi ---- -The listing above defines a HTTP mime header *operation* . The header prefix *_citrus_http__* is cut off before the header goes into the HTTP header section. With this feature we can decide where exactly our header information is located in our resulting client message. +The listing above defines an HTTP mime header *operation* . The header prefix *_citrus_http__* is cut off before the header goes into the HTTP header section. With this feature we can decide where exactly our header information is located in our resulting client message. [[soap-envelope-handling]] == SOAP Envelope handling @@ -985,7 +985,7 @@ The mechanism on HTTP error code simulation is not different to the usual SOAP r ---- -The SOAP response must be empty and the HTTP status code is set to a value other than 200, like 500. This results in a HTTP error sent to the calling client with error 500 "Internal server error". +The SOAP response must be empty and the HTTP status code is set to a value other than 200, like 500. This results in an HTTP error sent to the calling client with error 500 "Internal server error". [[soap-attachment]] == SOAP attachment support diff --git a/src/manual/endpoint-ssh.adoc b/src/manual/endpoint-ssh.adoc index bfc4686a97..5691dcd61b 100644 --- a/src/manual/endpoint-ssh.adoc +++ b/src/manual/endpoint-ssh.adoc @@ -5,7 +5,7 @@ In the spirit of other Citrus mock services, there is support for simulating an This means that the Citrus test case does not deal with pure SSH protocol commands. Instead of this we use the powerful XML validation capabilities in Citrus when dealing with the simple XML documents that represent the SSH request/response data. -Let us clarify this with a little example. Once the real SSH server daemon is fired up within Citrus we accept a SSH EXEC request for instance. The request is translated into a XML message of the following format: +Let us clarify this with a little example. Once the real SSH server daemon is fired up within Citrus we accept an SSH EXEC request for instance. The request is translated into an XML message of the following format: [source,xml] ---- @@ -26,7 +26,7 @@ This message can be validated with the usual Citrus mechanism in a receive test ---- -Besides simulating a full featured SSH server, Citrus also provides SSH client functionality. This client uses the same request message pattern, which is translated into a real SSH call to an SSH server. The SSH response received is also translated into a XML message as shown above so we can validate it with known validation mechanisms in Citrus. +Besides simulating a full-featured SSH server, Citrus also provides SSH client functionality. This client uses the same request message pattern, which is translated into a real SSH call to an SSH server. The SSH response received is also translated into an XML message as shown above so we can validate it with known validation mechanisms in Citrus. Similar to the other Citrus modules (http, soap), a Citrus SSH server and client is configured in Citrus Spring application context. There is a dedicated *ssh* namespace available for all ssh Citrus components. The namespace declaration goes into the context top-level element as usual: @@ -70,7 +70,7 @@ The SSH client receives several attributes, these are: id:: Id identifying the bean and used as reference from with test descriptions. (e.g. id="sshClient") host:: Host to connect to for sending an SSH Exec request. Default is 'localhost' (e.g. host="localhost") port: Port to use. Default is 2222 (e.g. port="9072") -private-key-path:: Path to a private key, which can be either a plain file path or an class resource if prefixed with 'classpath' (e.g. private-key-path="classpath:test_user.priv") +private-key-path:: Path to a private key, which can be either a plain file path or a class resource if prefixed with 'classpath' (e.g. private-key-path="classpath:test_user.priv") private-key-password:: Optional password for the private key (e.g. password="s!cr!t") user:: User used for connecting to the SSH server (e.g. user="roland") password:: Password used for password based authentication. Might be combined with "private-key-path" in which case both authentication mechanism are tried (e.g. password="ps!st) @@ -134,15 +134,15 @@ The `<citrus-ssh:server>` supports the following attributes: .SSH Server Attributes: [horizontal] id:: Name of the SSH server which identifies it unique within the Citrus Spring context (e.g. id="sshServer") -host-key-path:: Path to PEM encoded key pair (public and private key) which is used as host key. By default, a standard, pre-generate, fixed keypair is used. The path can be specified either as an file path, or, if prefixed with *classpath:* is looked up from within the classpath. The path the is relative from to the top-level package, so no leading slash should be used (e.g. hist-key-path="/etc/citrus_ssh_server.pem) +host-key-path:: Path to PEM encoded key pair (public and private key) which is used as host key. By default, a standard, pre-generate, fixed keypair is used. The path can be specified either as a file path, or, if prefixed with *classpath:* is looked up from within the classpath. The path the is relative from to the top-level package, so no leading slash should be used (e.g. hist-key-path="/etc/citrus_ssh_server.pem) user-home-path:: Path to user home directory. If not set ${user.dir}/target/{serverName}/home/{user} is used by default. user:: User which is allowed to connect (e.g. user="roland") -allowed-key-path:: Path to a SSH public key stored in PEM format. These are the keys, which are allowed to connect to the SSH server when publickey authentication is used. It seves the same purpose as authorized_keys for standard SSH installations. The path can be specified either as an file path, or, if prefixed with *classpath:* is looked up from within the classpath. The path the is relative from to the top-level package, so no leading slash should be used (e.g. allowed-key-path="classpath:test_user_pub.pem) +allowed-key-path:: Path to an SSH public key stored in PEM format. These are the keys, which are allowed to connect to the SSH server when publickey authentication is used. It seves the same purpose as authorized_keys for standard SSH installations. The path can be specified either as a file path, or, if prefixed with *classpath:* is looked up from within the classpath. The path the is relative from to the top-level package, so no leading slash should be used (e.g. allowed-key-path="classpath:test_user_pub.pem) password:: Password which should be used when password authentication is used. Both publickey authentication and password based authentication can be used together in which case both methods are tried in turn (e.g. password="s!cr!t") host:: Host address (e.g. localhost) port:: Port on which to listen. The SSH server will bind on localhost to this port (e.g. port="9072") auto-start:: Whether to start this SSH server automatically. Default is *true* . If set to *false*, a test action is responsible for starting/stopping the server (e.g. auto-start="true") -endpoint-adapter:: Bean reference to a endpoint adapter which processes the incoming SSH request. The message format for the request and response are described above (e.g. endpoint-adapter="sshEndpointAdapter") +endpoint-adapter:: Bean reference to an endpoint adapter which processes the incoming SSH request. The message format for the request and response are described above (e.g. endpoint-adapter="sshEndpointAdapter") Once the SSH server component is added to the Spring application context with a proper endpoint adapter like the MessageChannel forwarding adapter we can receive incoming requests in a test case and provide a respone message for the client. diff --git a/src/manual/endpoint-vertx.adoc b/src/manual/endpoint-vertx.adoc index 53fde5ccf3..b726f0eed6 100644 --- a/src/manual/endpoint-vertx.adoc +++ b/src/manual/endpoint-vertx.adoc @@ -72,7 +72,7 @@ one single consumer on the event bus address will receive the message. If there wins and receives the message. In contrary to that the publish-subscribe scenario would deliver the message to all available consumers on the event bus address simultaneously. You can enable the *pubSubDomain* on the Vert.x endpoint component for this communication pattern. -The Vert.x endpoint needs a instance factory implementation in order to create the embedded Vert.x instance. By default the bean name +The Vert.x endpoint needs an instance factory implementation in order to create the embedded Vert.x instance. By default the bean name *vertxInstanceFactory* is recognized by all Vert.x endpoint components. We will talk about Vert.x instance factories in more detail later on in this chapter. @@ -103,7 +103,7 @@ As the Vert.x Citrus endpoint is bidirectional you can also receive messages fro ---- Citrus automatically adds some special message headers to the message, so you can validate the Vert.x event bus address. This completes -the simple send and receive operations on a Vert.x event bus. Now lets move on to synchronous endpoints where Citrus waits for a reply on the event bus. +the simple send and receive operations on a Vert.x event bus. Now let's move on to synchronous endpoints where Citrus waits for a reply on the event bus. [[synchronous-vert-x-endpoint]] == Synchronous Vert.x endpoint @@ -180,7 +180,7 @@ Citrus starts an embedded Vert.x instance at runtime in order to participate in instances are connected via the event bus. For starting the Vert.x event bus Citrus uses a cluster hostname and port definition. You can customize this cluster host in order to connect to a very special cluster in your network. -Now Citrus needs to manage the Vert.x instances created during the test run. By default Citrus will look for a instance factory bean +Now Citrus needs to manage the Vert.x instances created during the test run. By default Citrus will look for an instance factory bean named *vertxInstanceFactory* . You can choose the factory implementation to use in your project. By default you can use the caching factory implementation that caches the Vert.x instances so we do not connect more than one Vert.x instance to the same cluster host. Citrus offers following instance factory implementations: diff --git a/src/manual/endpoint-websocket.adoc b/src/manual/endpoint-websocket.adoc index 6217bed883..5e7e455261 100644 --- a/src/manual/endpoint-websocket.adoc +++ b/src/manual/endpoint-websocket.adoc @@ -51,7 +51,7 @@ On the client side Citrus offers a client component that goes directly to the Sp The *url* defines the endpoint to send messages to. The server has to be a WebSocket ready web server that supports Http connection upgrade for WebSocket protocols. WebSocket by its nature is an asynchronous bidirectional protocol. This means that the connection between client and server remains open and both server and client can send and receive messages. So when the Citrus client is waiting for a message we need a timeout that stops the asynchronous waiting. The receiving test action and the test case will fail when such a timeout is raised. -The WebSocket client will automatically open a connection to the server and ask for a connection upgrade to WebSocket protocol. This handshake is done once when the connection to the server is established. After that the client can push messages to the server and on the other side the server can push messages to the client. Now lets first push some messages to the server: +The WebSocket client will automatically open a connection to the server and ask for a connection upgrade to WebSocket protocol. This handshake is done once when the connection to the server is established. After that the client can push messages to the server and on the other side the server can push messages to the client. Now let's first push some messages to the server: [source,xml] ---- @@ -99,7 +99,7 @@ The specific send action above will send its message to the dynamic endpoint (ws [[websocket-server-endpoints]] == WebSocket server endpoints -On the server side Citrus has a Http server implementation that we can easily start during test runtime. The Http server accepts connections from clients and also supports WebSocket upgrade strategies. This means clients can ask for a upgrade to the WebSocket standard. In this handshake the server will upgrade the connection to WebSocket and afterwards client and server can exchange messages over this connection. This means the connection is kept alive and multiple messages can be exchanged. Lets see how WebSocket endpoints are added to a Http server component in Citrus. +On the server side Citrus has a Http server implementation that we can easily start during test runtime. The Http server accepts connections from clients and also supports WebSocket upgrade strategies. This means clients can ask for an upgrade to the WebSocket standard. In this handshake the server will upgrade the connection to WebSocket and afterwards client and server can exchange messages over this connection. This means the connection is kept alive and multiple messages can be exchanged. Let's see how WebSocket endpoints are added to a Http server component in Citrus. [source,xml] ---- diff --git a/src/manual/endpoint-zookeeper.adoc b/src/manual/endpoint-zookeeper.adoc index 1869d7947d..e439291234 100644 --- a/src/manual/endpoint-zookeeper.adoc +++ b/src/manual/endpoint-zookeeper.adoc @@ -3,7 +3,7 @@ Citrus provides configuration components and test actions for interacting with Zookeeper. The Citrus Zookeeper client component executes commands like create-node, check node-exists, delete-node, get node-data or set node-data. As a user you can execute Zookeeper commands as part of a Citrus test and validate possible command results. -NOTE: The Zookeeper test components in Citrus are kept in a separate Maven module. If not already done so you have to include the module as Maven dependency to your project +NOTE: The Zookeeper test components in Citrus are kept in a separate Maven module. If not already done, you have to include the module as Maven dependency to your project [source,xml] ---- diff --git a/src/manual/endpoints.adoc b/src/manual/endpoints.adoc index 7ce2668636..d4ef57841c 100644 --- a/src/manual/endpoints.adoc +++ b/src/manual/endpoints.adoc @@ -93,7 +93,7 @@ XML. Finally let us have a look at a first example how a sending action is defin ---- -Now lets have a closer look at the sending action. The *'endpoint'* attribute might catch your attention first. This attribute +Now let's have a closer look at the sending action. The *'endpoint'* attribute might catch your attention first. This attribute references the message endpoint in Citrus configuration by its identifier. As previously mentioned the message endpoint definition lives in a separate configuration file and contains the actual message transport settings. In this example the *"helloServiceEndpoint"* is referenced which is a JMS endpoint for sending out messages to a JMS queue for instance. @@ -200,7 +200,7 @@ will only wait a given amount of time before raising a timeout error. Following fails as the message did not arrive in time. Citrus defines default timeout settings for all message receiving tasks. At this point you know the two most important test actions in Citrus. Sending and receiving actions will become the main -components of your integration tests when dealing with loosely coupled message based components in a enterprise application +components of your integration tests when dealing with loosely coupled message based components in an enterprise application environment. It is very easy to create complex message flows, meaning a sequence of sending and receiving actions in your test case. You can replicate use cases and test your message exchange with extended message validation capabilities. See link:#actions-receive[actions-receive] for a more detailed description on how to validate incoming messages and how to expect diff --git a/src/manual/functions.adoc b/src/manual/functions.adoc index c969286b51..1e5a07139b 100644 --- a/src/manual/functions.adoc +++ b/src/manual/functions.adoc @@ -17,7 +17,7 @@ The library is built in the Spring configuration and contains a set of functions ---- -As you can see the library defines one to many functions either referenced as normal Spring bean or by its implementing Java class name. Citrus constructs the library and you are able to use the functions in your test case with the leading library prefix just like this: +As you can see the library defines one-to-many functions either referenced as normal Spring bean or by its implementing Java class name. Citrus constructs the library and you are able to use the functions in your test case with the leading library prefix just like this: [source,xml] ---- @@ -183,7 +183,7 @@ Function output: [[functions-round]] == round() -This is a simple mathematic function that will round decimal numbers representations to their nearest non decimal number. +This is a simple mathematical function that will round decimal numbers representations to their nearest non-decimal number. [source,xml] ---- @@ -774,7 +774,7 @@ becomes very easy then. [[functions-url-encode]] == urlEncode()/urlDecode() -The *urlEncode* function takes a String and performs proper URL encoding. The result is an URL encoded String that is using proper character escaping for Http. +The *urlEncode* function takes a String and performs proper URL encoding. The result is a URL encoded String that is using proper character escaping for Http. [source,xml] ---- diff --git a/src/manual/message-tracing.adoc b/src/manual/message-tracing.adoc index 0000a2ca10..cb9a0c5aa4 100644 --- a/src/manual/message-tracing.adoc +++ b/src/manual/message-tracing.adoc @@ -32,7 +32,7 @@ Each Citrus test writes a *.msgs* file containing all messages that went over th NOTE: As the file names do not change with each test run message tracing files may be overwritten. So you eventually need to save the generated message debug files before running another group of test cases. -Lets see some sample output for a test case with message communication over SOAP Http: +Let's see some sample output for a test case with message communication over SOAP Http: [source,xml] ---- diff --git a/src/manual/reporting.adoc b/src/manual/reporting.adoc index 79c804e3e3..20cfb8c8c2 100644 --- a/src/manual/reporting.adoc +++ b/src/manual/reporting.adoc @@ -98,6 +98,6 @@ citrus.html.report.directory:: Output directory path (default= *_${project.build citrus.html.report.file:: File name for the report file (default= *_citrus-test-results.html_*). citrus.html.report.template:: Template HTML file with placeholders for report results. citrus.html.report.detail.template:: Template file for detailed test results. -citrus.html.report.logo:: File resource path pointing to a image that is added to top of HTML report. +citrus.html.report.logo:: File resource path pointing to an image that is added to top of HTML report. The HTML report is based on a template file that is customizable to your special needs. The default templates can be found in https://github.com/citrusframework/citrus/tree/master/modules/citrus-core/src/main/resources/org/citrusframework/report[report-templates sources]. diff --git a/src/manual/run-xml.adoc b/src/manual/run-xml.adoc index 0669f205c8..a30a6a4496 100644 --- a/src/manual/run-xml.adoc +++ b/src/manual/run-xml.adoc @@ -117,7 +117,7 @@ that the Java class is able to find and load the XML file when running the test. Each XML test in Citrus defines the `@CitrusTestSource` annotation in the Java class. This annotation makes Citrus search for the XML file that represents the Citrus test within your classpath. -In the basic example above this means that Citrus searches for a XML test file in *org/citrusframework/MyFirstCitrus_IT.xml* . +In the basic example above this means that Citrus searches for an XML test file in *org/citrusframework/MyFirstCitrus_IT.xml* . You can customize this path and tell Citrus to search for another XML file by using the `@CitrusTestSource` annotation properties. @@ -434,7 +434,7 @@ idea how that works: Just use the script code right inside the variable value definition. The value of the variable is the result of the last operation performed within the script. For longer script code the use of `<![CDATA[ ]]>` sections is recommended. -Citrus uses the Java script engine mechanism to evaluate the script code. By default, Groovy is supported as a script +Citrus uses the JavaScript engine mechanism to evaluate the script code. By default, Groovy is supported as a script engine implementation. You can add additional engine implementations to your project and support other script types, too. [[xml-templates]] diff --git a/src/manual/runtimes-cucumber.adoc b/src/manual/runtimes-cucumber.adoc index f8ca071acd..e136c5e58d 100644 --- a/src/manual/runtimes-cucumber.adoc +++ b/src/manual/runtimes-cucumber.adoc @@ -93,7 +93,7 @@ extends the default Cucumber reporter so the default Cucumber report summary is That completes the JUnit class configuration. Now we are able to add feature stories and step definitions to the package of our test *MyFeatureIT* . Cucumber and Citrus will automatically pick up step definitions and glue code in that test -package. So lets write a feature story *echo.feature* right next to the *MyFeatureIT* test class. +package. So let's write a feature story *echo.feature* right next to the *MyFeatureIT* test class. .echo.feature [source,gherkin] @@ -112,7 +112,7 @@ Feature: Echo service ---- As you can see this story defines two scenarios with the Gherkin *Given-When-Then* syntax. Now we need to add step definitions -that glue the story description to Citrus test actions. Lets do this in a new class *EchoSteps* . +that glue the story description to Citrus test actions. Let's do this in a new class *EchoSteps* . .EchoSteps.java [source,java] diff --git a/src/manual/setup.adoc b/src/manual/setup.adoc index dab0c88d9f..02deb71728 100644 --- a/src/manual/setup.adoc +++ b/src/manual/setup.adoc @@ -180,7 +180,7 @@ repositories { } ---- -Citrus stable release versions are available on Maven central. Now lets move on with adding the Citrus libraries to the project. +Citrus stable release versions are available on Maven central. Now let's move on with adding the Citrus libraries to the project. .Add Citrus test scoped dependencies [source,groovy] diff --git a/src/manual/test-actors.adoc b/src/manual/test-actors.adoc index 21323eaac4..59a52ad89c 100644 --- a/src/manual/test-actors.adoc +++ b/src/manual/test-actors.adoc @@ -5,7 +5,7 @@ The concept of test actors came to our mind when reusing Citrus test cases in en It would be great if we could reuse the Citrus integration tests in this test setup as we have the complete test flow of messages available in the Citrus tests. We only have to remove the simulated send/receive actions for those real interface partner applications which are available in our end-to-end test setup. -With test actors we have the opportunity to link test actions, in particular send/receive message actions, to a test actor. The test actor can be disabled in configuration very easy and following from that all linked send/receive actions are disabled, too. One Citrus test case is runnable with different test setup scenarios where different partner applications on the one hand are available as real life applications and on the other hand my require simulation. +With test actors we have the opportunity to link test actions, in particular send/receive message actions, to a test actor. The test actor can be disabled in configuration very easy and following from that all linked send/receive actions are disabled, too. One Citrus test case is runnable with different test setup scenarios where different partner applications on the one hand are available as real life applications and on the other hand require simulation. [[define-test-actors]] == Define test actors @@ -55,7 +55,7 @@ This explicitly links test actors to test actions so you can decide which link s [[disable-test-actors]] == Disable test actors -Usually both airline applications are simulated in our integration tests. But this time we want to change this by introducing a royal airline application which is online as a real application instance. So we need to skip all simulated message interactions for the royal airline application in our Citrus tests. This is easy as we have linked all send/receive actions to one of our test actors. So wen can disable the royal airline test actor in our configuration: +Usually both airline applications are simulated in our integration tests. But this time we want to change this by introducing a royal airline application which is online as a real application instance. So we need to skip all simulated message interactions for the royal airline application in our Citrus tests. This is easy as we have linked all send/receive actions to one of our test actors. So we can disable the royal airline test actor in our configuration: [source,xml] ---- diff --git a/src/manual/test-suite.adoc b/src/manual/test-suite.adoc index d572e75506..d66182e6a4 100644 --- a/src/manual/test-suite.adoc +++ b/src/manual/test-suite.adoc @@ -248,7 +248,7 @@ When using the Java DSL before suite support you can set suite names and test gr ---- -Environment or system properties are defined as list of key-value pairs. When specified the properties have to be present with respective value. In case the property value is left out in configuration the property must simply exists on the system +Environment or system properties are defined as list of key-value pairs. When specified the properties have to be present with respective value. In case the property value is left out in configuration the property must simply exist on the system in order to enable the before suite sequence in that test run. .XML Config diff --git a/src/manual/validation-json.adoc b/src/manual/validation-json.adoc index 78915c5de4..bc62d84c82 100644 --- a/src/manual/validation-json.adoc +++ b/src/manual/validation-json.adoc @@ -123,7 +123,7 @@ As you can see you can use test variables as well as ignore element syntax here, different Json element orders when comparing received and expected Json object. We can also use Json arrays and nested objects. The default Json message validator implementation in Citrus is very powerful in comparing Json objects. -Instead of defining an expected message body template we can also use Groovy validation scripts. Lets have a look at +Instead of defining an expected message body template we can also use Groovy validation scripts. Let's have a look at the Groovy Json message validator example. As usual the default Groovy Json message validator is active by default. But the special Groovy message validator implementation will only jump in when we used a validation script in our receive message definition. Let's have an example for that. @@ -205,7 +205,7 @@ The listing above shows some power of the validation script. We can access the m header. With test context access we can also save the whole message body as a new test variable for later usage in the test. In general Groovy code inside the XML test case definition or as part of the Java DSL code is not very comfortable to maintain. -Neither you do have code syntax assist or code completion when using inline Groovy scripts. +Neither you do have code syntax assist nor code completion when using inline Groovy scripts. Also, in case the validation script gets more complex you might want to load the script from an external file resource. @@ -416,7 +416,7 @@ format. By default, Citrus is working with XML message data and therefore the XM With the message type attribute set to *json* we make sure that Citrus enables Json specific features on the message validation such as JsonPath support. -Now lets get a bit more complex with validation matchers and Json object functions. Citrus tries to give you the most comfortable +Now let's get a bit more complex with validation matchers and Json object functions. Citrus tries to give you the most comfortable validation capabilities when comparing Json object values and Json arrays. One first thing you can use is object functions like *keySet()* or *size()* . This functionality is not covered by JsonPath out of the box but added by Citrus. See the following example on how to use it: @@ -448,7 +448,7 @@ receive(someEndpoint) The object functions do return special Json object related properties such as the set of *keys* for an object or the size of a Json array. -Now lets get even more comfortable validation capabilities with matchers. Citrus supports Hamcrest matchers which gives +Now let's get even more comfortable validation capabilities with matchers. Citrus supports Hamcrest matchers which gives us a very powerful way of validating Json object elements and arrays. See the following examples that demonstrate how this works: .Java @@ -585,7 +585,7 @@ The following table assumes that the Json schema validation is activated for the |The message of the test action must be valid regarding at least one of the available schemas within the context. |A schema overruling is configured in the test case. -|The configured schema must exist and the message must be valid regarding to the specified schema. +|The configured schema must exist and the message must be valid regarding the specified schema. |A schema repository overruling is configured in the test case. |The configured schema repository must exist and the message must be valid regarding at least one of the schemas within diff --git a/src/manual/validation-matchers.adoc b/src/manual/validation-matchers.adoc index ccf2aab91a..cfd1faa5e4 100644 --- a/src/manual/validation-matchers.adoc +++ b/src/manual/validation-matchers.adoc @@ -31,7 +31,7 @@ TIP: You can use validation matcher with all validation mechanisms - not only wi A set of validation matcher implementations is usually combined to a validation matcher library. The library has a prefix that will identify the validation matcher inside the test case. The default test framework validation matcher library uses a default prefix (citrus). You can write your own validation matcher library using your own prefix in order to extend the test framework functionality whenever you want. -The library is built in the Spring configuration and contains a set of validation matcher that are of public use. +The library is built in the Spring configuration and contains a set of validation matchers that are of public use. [source,xml] ---- @@ -48,11 +48,11 @@ As you can see the library defines one to many validation matcher members either [source,xml] ---- @foo:isNumber()@ - @foo:contains()@ - @foo:customMatcher()@ +@foo:contains()@ +@foo:customMatcher()@ ---- -TIP: You can add custom validation matcher implementations and custom validation matcher libraries. Just use a custom prefix for your library. The default Citrus validation matcher library uses no prefix.See now the following sections describing the default validation validation matcher in Citrus. +TIP: You can add custom validation matcher implementations and custom validation matcher libraries. Just use a custom prefix for your library. The default Citrus validation matcher library uses no prefix. See now the following sections describing the default validation matcher in Citrus. [[matcher-ignore]] == ignore() @@ -81,7 +81,7 @@ NOTE: The ignore validation matcher is the only validation matcher that is able [[matcher-matches-xml]] == matchesXml() -The XML validation matcher implementation is the possibly most exciting one, as we can validate nested XML with full validation power (e.g. ignoring elements, variable support). The matcher checks a nested XML fragment to compare against expected XML. For instance we receive following XML message payload for validation: +The XML validation matcher implementation is the possibly most exciting one, as we can validate nested XML with full validation power (e.g. ignoring elements, variable support). The matcher checks a nested XML fragment to compare against expected XML. For instance we receive the following XML message payload for validation: [source,xml] ---- @@ -145,7 +145,7 @@ This matcher searches for a character sequence inside the actual value. If the c @contains('foo')@ ---- -The validation matcher also exist in a case insensitive variant. +The validation matcher also exists in a case-insensitive variant. [source,xml] ---- @@ -192,7 +192,7 @@ Date values are always difficult to check for equality. Especially when you have @matchesDatePattern('yyyy-MM-dd')@ ---- -The example listing uses a date format pattern that is expected. The actual date value is parsed according to this pattern and may cause errors in case the value is no valid date matching the desired format. +The example listing uses a date format pattern that is expected. The actual date value is parsed according to this pattern and may cause errors in case the value is not a valid date matching the desired format. [[matcher-isnumber]] == isNumber() @@ -276,7 +276,7 @@ The matcher works on date values and checks that a given date is within the expe Possible valid values would be 'some date' >= '01-12-2015' and 'some date' <= '31-12-2015' -The date-format is optional and when omitted it is assumed that all dates match the default date format *yyyy-MM-dd* . When specifying a custom date format use java's date format as a reference for valid date formats. Only dates were used in the example above but we could just as easily used date and time as shown in the example below +The date-format is optional and when omitted it is assumed that all dates match the default date format *yyyy-MM-dd* . When specifying a custom date format use Java's date format as a reference for valid date formats. Only dates were used in the example above but we could just as easily used date and time as shown in the example below [source,xml] ---- @@ -286,14 +286,14 @@ The date-format is optional and when omitted it is assumed that all dates match [[matcher-assert-that]] == assertThat() -Hamcrest is a very powerful matcher library with extraordinary matcher implementations. You can use Hamcrest matchers also as Citrus validation matcher. +Hamcrest is a very powerful matcher library with extraordinary matcher implementations. You can use Hamcrest matchers also as Citrus validation matchers. [source,xml] ---- @assertThat(equalTo(foo))@ ---- -In the listing above we are using the *equalTo()* matcher. All Hamcrest matchers are surrounded by a *assertThat* expression. You are able to combine several Hamcrest matchers then in order to construct very powerful validation logic. See the following examples on what is possible then: +In the listing above we are using the *equalTo()* matcher. All Hamcrest matchers are surrounded by an *assertThat* expression. You are able to combine several Hamcrest matchers then in order to construct very powerful validation logic. See the following examples on what is possible then: [source,xml] ---- @@ -337,7 +337,7 @@ Citrus will automatically perform validation matchers on the element value. Only This matcher implementation checks for equality with prior normalization of all new line characters. This includes new line types CR, LF and CRLF as well as multiple new lines in value and control value. So when using this validation matcher all new line characters are removed prior to checking for equality. -Lets assume that we have a value with new lines that we want to validate using the matcher implementation: +Let's assume that we have a value with new lines that we want to validate using the matcher implementation: [source,text] ---- @@ -348,7 +348,7 @@ value with lots of new lines ---- -You can now skip all new line characters in your control value using the `ignoreNewLine matcher`. +You can now skip all new line characters in your control value using the `ignoreNewLine` matcher. [source,xml] ---- @@ -362,7 +362,7 @@ As you can see the new line characters are not breaking the validation. The othe This trim matcher will remove leading and trailing whitespaces before checking for equality. -Lets assume that we have a value with leading and trailing whitespaces: +Let's assume that we have a value with leading and trailing whitespaces: [source,text] ---- diff --git a/src/manual/validation-xml.adoc b/src/manual/validation-xml.adoc index b4f445029e..0bbcd03b38 100644 --- a/src/manual/validation-xml.adoc +++ b/src/manual/validation-xml.adoc @@ -315,7 +315,7 @@ in the XML tree is represented with a simple dot - for example: `TestRequest.VersionId` The expression will search the XML tree for the respective `` element. Attributes are supported too. -In case the last element in the dot-notated expression is a XML attribute the framework will automatically find it. +In case the last element in the dot-notated expression is an XML attribute the framework will automatically find it. Of course this dot-notated syntax is very simple and might not be applicable for more complex tree navigation. XPath is much more powerful - no doubt. The dot-notated syntax might help those of you that are not familiar with XPath. @@ -388,7 +388,7 @@ module. NOTE: XPath uses decimal number type *Double* by default when evaluating expressions with *number* result type. This means we have to use Double typed expected values, too. Citrus also provides the result type *integer* that automatically converts -the XPath expression result to a *Integer* type. +the XPath expression result to an *Integer* type. When using the XML DSL we have to use the *assertThat* validation matcher syntax for defining the Hamcrest matcher. You can combine matcher implementation as seen in the *anyOf(empty(), nullValue())* expression. When using the Java DSL you can just @@ -470,7 +470,7 @@ receive("someEndpoint") ---- -Now the expressions works fine, and the validation is successful. Relying on the namespace prefix `ns1` is quite error prone though. +Now the expressions works fine, and the validation is successful. Relying on the namespace prefix `ns1` is quite error-prone though. This is because the test depends on the very specific namespace prefix. As soon as the message is sent with a different namespace prefix (e.g. ns2) the validation will fail again. @@ -531,7 +531,7 @@ test cases from namespace prefix bindings that might be broken with time. You ca XPath expressions are valid inside a test case (validation, ignore, extract). In the previous section we have seen that XML namespaces can get tricky with XPath validation. Default namespaces can do -even more! So lets look at the example with default namespaces: +even more! So let's look at the example with default namespaces: .Sample XML body with default namespaces [source,xml] @@ -903,7 +903,7 @@ schema definitions to the schema repository and you will be fine. [[wsdl-schemas]] ==== WSDL schemas -In SOAP WebServices world the WSDL (WebService Schema Definition Language) defines the structure an nature of the XML +In SOAP WebServices world the WSDL (WebService Schema Definition Language) defines the structure and nature of the XML messages exchanged across the interface. Often the WSDL files do hold the XML schema definitions as nested elements. In Citrus you can directly set the WSDL file as location of a schema definition like this: @@ -1135,7 +1135,7 @@ public SimpleXsdSchema goodbyeSchema() { The listing above defines two root qname mappings - one for *HelloRequest* and one for *GoodbyeRequest* message types. An incoming message of type is then mapped to the respective schema and so on. With these dedicated -mappings you are able to control which schema is used on a XML request, regardless of target namespace definitions. +mappings you are able to control which schema is used on an XML request, regardless of target namespace definitions. [[schema-mapping-strategy-chain]] ==== Schema mapping strategy chain @@ -1207,8 +1207,8 @@ comes in and tries to find a proper schema. [[dtd-validation]] ==== DTD validation -XML DTD (document type definition) is another way to validate the structure of a XML document. Many people say that -DTD is deprecated and XML schema is the much more efficient way to describe the rules of a XML structure. We do not +XML DTD (document type definition) is another way to validate the structure of an XML document. Many people say that +DTD is deprecated and XML schema is the much more efficient way to describe the rules of an XML structure. We do not disagree with that, but we also know that legacy systems might still use DTD. So in order to avoid validation errors we have to deal with DTD validation as well.