Table of Contents
In real systems, messages may be modified before they are sent, e.g. they may be
signed or encrypted, messages have to be transformed to other formats, because the real
system can not handle XML messages but has its own message format. In the tutorial
example, client messages can be protected from changes by a calculated checksum. Of
course, this simple modification could be handled by a plug-in and a substitution or
composition in a template, other manipulations like encrypting are more complex and
can not be handled with plug-ins. This manipulation often should be performed without
being explicitly noted in the test case, because the manipulation is not in the scope of
the tests. Therefore,
PETA offers the extension mechanism of filters to manipulate messages. A filter gets
a message as input and transforms this message to output. It is realized as a java class
that implements the
de.verit.peta.engine.filter.Filter interface. A filter may be
explicitly called in the test case, which will be done in the tutorial example or they may
be referenced in the PETA
configuration and implicitly used for all operations of the related actors.
![]() | Further information |
|---|---|
|
Detailed information about PETA filters can be found in the PETA-Core Reference Manual. |
To create a new filter, press the New filter
button in the toolbar. In the wizard, set the source folder of the
filter's java file to
TutorialProject/src and enter a package name. Enter
Checksum as the class name and press the Next
button. On the second page, enter a description for this filter. As the filter does not
need an argument, press the Finish button to create a java
file in the specified package and open it in the editor.
The following code example shows the implementation of the Checksum filter. If an outgoing message does not have a checksum, the filter adds a calculated checksum to it. Otherwise, the message is not changed. While acting as an input filter, the checksum is extracted and removed from the incoming message and validated against a calculated checksum. In case of a mismatch, the context value _peta/filterChecksum_Result is set to failed , otherwise, the context value is set to ok.
Context values starting with _peta/ are special read only context values which will not be checked during the test case validation (validation of references to context values). Therefore, references to such a context value can be used in test cases without the need to define the context value. To set the value of such a context value in a filter, the method setForced has to be used instead of the method set, otherwise, the test case using the filter would fail.
Example 11.1. Implementation of the Checksum filter
package de.verit.peta.tutorial.filter;
import java.util.zip.CRC32;
import de.verit.peta.common.PetaErrorException;
import de.verit.peta.engine.context.Constants;
import de.verit.peta.engine.context.ContextCache;
import de.verit.peta.engine.document.Message;
import de.verit.peta.engine.filter.Filter;
import de.verit.peta.engine.filter.FilterBase;
public class Checksum extends FilterBase implements Filter {
/**
* @see Filter#filter(de.verit.peta.engine.document.Message,
* de.verit.peta.engine.context.ContextCache)
*/
public Message filter(Message inputMessage,
ContextCache context)
throws PetaErrorException {
Message filteredMessage = null;
final String me = context.get(Constants.ACTOR);
final String sender = context.get(Constants.SENDER);
if (me.equals(sender)) {
// sending the message
// insert checksum into message
long checksum = getChecksum(inputMessage);
String messageString = inputMessage.getAsString();
messageString =
messageString.replaceAll("(<request *)>", "$1"
+ " checksum=\"" + checksum + "\">");
filteredMessage = new Message(messageString);
} else {
// receiving the message
// extract checksum from message
String messageString = inputMessage.getAsString();
long receivedChecksum = Long.parseLong(
messageString.replaceAll("\n", "").replaceAll(
"<request.*? checksum=\"(.*)\".*", "$1"));
// remove checksum from message
messageString = messageString.replaceAll(
"(<request.*?) checksum=\".*\">",
"$1>");
filteredMessage = new Message(messageString);
// validate checksum
long calculatedChecksum = getChecksum(filteredMessage);
if (calculatedChecksum == receivedChecksum) {
context.setForced("_peta/filterChecksum_Result",
"ok");
} else {
context.setForced("_peta/filterChecksum_Result",
"failed");
}
}
return filteredMessage;
}
/**
* Get checksum for given message.
*
* @param message The message.
* @return The message's checksum.
*/
private long getChecksum(final Message message) {
CRC32 crc32 = new CRC32();
crc32.update(message.getAsBinary());
return crc32.getValue();
}
}
Now the new filter can be used in the test cases. In this example, it will be used when the client sends the message to the server. Therefore, the filter has to be added as the output filter of the client's operation and as the input filter of the server's check request event.
To add the output filter, drag'n'drop the Add
Outputfilter symbol to the first operation. In the wizard, select
Checksum from the list of available filters and press the
OK button.
To add the input filter, the module checkRequest has to
be opened in a PETA editor. Expand its event and drag'n'drop the Add
Inputfilter symbol to this event. In the wizard, select
Checksum from the list of available filters and press the
OK button.
To assert the successful checksum validation, drag'n'drop the Add
Assertion symbol from the palette to a place in the event above the
existing assertions. Add
checksum validation ok as the name of the assertion, set the operator
to
== and the data type to
String. As a context value (set by the filter) shall be asserted, press
the left Add Reference button and enter the key
_peta/filterChecksum_Result. Then, press the right Add
Constant button and enter the expected constant value
ok. Finish adding the new assertion by pressing the
OK button.