Skip to content
Thomas Schwotzer edited this page Jan 5, 2022 · 4 revisions

Shark Messenger Component

This project was implemented as a SharkComponent. A few things a worth to be discussed, namely interface definition and component start up.

Format definition

Have look in the source. We discuss just a few things on that page.

@ASAPFormats(formats = {SharkMessengerComponent.SHARK_MESSENGER_FORMAT})
public interface SharkMessengerComponent extends SharkComponent {
    // ...
    String SHARK_MESSENGER_FORMAT = "shark/messenger";
    // ...

Our component is a Shark component. We make that explicit by declaring extends SharkComponent

We define a format SHARK_MESSENGER_FORMAT and make clear that this format is meant to be our ASAP format and we want the peer to exchange message tagged with that string ( @ASAPFormats).

Factory / start up

A Shark component needs a factory. Our factory is called SharkMessengerComponentFactory.

public class SharkMessengerComponentFactory implements SharkComponentFactory {
    private final SharkPKIComponent pkiComponent;
    //..
    public SharkMessengerComponentFactory(SharkPKIComponent pkiComponent) {
        this.pkiComponent = pkiComponent;
    }

    @Override
    public SharkComponent getComponent() {
        return new SharkMessengerComponentImpl(pkiComponent);
    }
}

Our component requires a SharkPKI component. We make this relationship explicit be declaring a parameter of type SharkPKIComponent in our constructor. We simply remember this object. We need this object for encrypting and signing messages.

Let’s have a look in the construction of our Shark messenger component.

class SharkMessengerComponentImpl extends SharkMessagesReceivedListenerManager
        implements SharkMessengerComponent, ASAPMessageReceivedListener {

    private final SharkPKIComponent sharkPKIComponent;
    private ASAPPeer asapPeer;

    public SharkMessengerComponentImpl(SharkPKIComponent sharkPKIComponent) {
        this.sharkPKIComponent = sharkPKIComponent;
    }
    // ..
}

This construtor only keeps a reference to our PKI in a member. Other methods need it, see previous section. A Shark peer starts its components during is own start process. It calls onStart():

@Override
public void onStart(ASAPPeer asapPeer) throws SharkException {
    this.asapPeer = asapPeer;
    this.asapPeer.addASAPMessageReceivedListener(
                SharkMessengerComponent.SHARK_MESSENGER_FORMAT,
                this);

There is not much to be done. We remember our ASAP peer. We need it to send message. We also add a message received listener. That is more for illustrational purpose. As discussed, there is no need for an immediate reaction on an incoming ASAP message.

Have a look into the sources. Use it as a template if it fits to your needs. Some details shall be mentioned:

Each API method implemention checks if the system is already up and running by calling this.checkComponentRunning(); That method is simple.

private void checkComponentRunning() throws SharkMessengerException {
    if(this.asapPeer == null || this.sharkPKIComponent == null)
        throw new SharkMessengerException("peer not started an/or pki not initialized");
}

An exception is thrown if we do not have a pki object or an ASAP peer. Both are required to perform any API method. Each API call will fail until the system is properly initialized.

Built in five steps

Related projects

User Guide

CLI - User Guide

  • TODO

Distributed Tests

Clone this wiki locally