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.

Clone this wiki locally