Skip to content

V.2 Migration Guide

Thorben Kuck edited this page Sep 20, 2018 · 11 revisions

In version 2 of NetCom2 a lot has changed.

The key focus of this Version was, to introduce a more NIO friendly environment. This lead to more modularity within the framework. Also, there are some packages and classes, that have been relocated or out right been deleted.

Rule of Thumb:

Most of the important features are still where they are. If you encounter any issue with a wrong import (either the class or the package cannot be found) whilst using a sophisticated IDE (like IntelliJ for example) , try to delete that import and let the IDE find the corresponding class. This should fix most of those issues.

Backwards Compatibility

The backwards compatibility cannot be maintained! V.1.* and V.2.* cannot be used together (i.e. ClientStart of V.1.* and ServerStart of V.2.*).

The reason for that is, that the handshake protocol for the Communication establishment was changed quit a bit. The positive result of that is, that you now may establish Connections from within ClientConnectedHandlers at the ServerStart.

Adapt your existing Code

OnReceiveFamily

First of, before we can handle the deprecated entries, we have to make sure that the existing Code can be compiled. If you used custom implementations of the OnReceiveFamily (OnReceiveSingle, OnReceive and OnReceiveTriple), you will have to alter them.

Take this OnReceiveTriple as an example:

package example;

import com.github.thorbenkuck.netcom2.network.shared.session.Session;
import com.github.thorbenkuck.netcom2.network.shared.comm.OnReceiveTripple;
import com.github.thorbenkuck.netcom2.network.shared.clients.Connection;

class TestHandler implements OnReceiveTriple<TestObject> {

    @Override
    public void accept(Connection connection, Session session, TestObject testObject) {
	// ...
    }
}

This class cannot be compiled for 3 reasons: We implemented the wrong method, Session cannot be found, Connection cannot be found. Why is that?

With V.2 we changed the OnReceiveTriple to no longer except a Connection, but to accept a ConnectionContext. This ConnectionContext gives you more options, to work with your Connections, since it unites the Connection and the Client this Connection is associated with. Note: This gives you the power to not only close the Connection (by calling ConnectionContext#close), but to also close the Connection and invalidate the Client (by calling ConnectionContext#kill). This comes in handy, to kill off malicious Clients, but can also mess up your program, if used in the wrong scenario.

For the other two issues, all we have to do, is to change the imports. The corresponding "correct" handler will look like this:

package example;

import com.github.thorbenkuck.netcom2.network.shared.Session;
import com.github.thorbenkuck.netcom2.network.shared.comm.OnReceiveTriple;
import com.github.thorbenkuck.netcom2.network.shared.connections.ConnectionContext;

public class TestHandler implements OnReceiveTriple<TestObject> {
    @Override
    public void accept(ConnectionContext connectionContext, Session session, TestObject testObject) {
        // ....
    }
}

"Main" Class.

To explain the next difference, let's take a look at this little example:

package example;

import com.github.thorbenkuck.netcom2.network.client.ClientStart;
import com.github.thorbenkuck.netcom2.exceptions.StartFailedException;

class Example {
    public void example() {
        ClientStart clientStart = ClientStart.at("localhost", 8888);

        clientStart.getCommunicationRegistration()
               .register(TestObject.class)
               .addFirst((testObject -> System.out.println("Server send: " + testObject.getHello())));

        try {
            clientStart.launch();
        } catch (StartFailedException e) {
            e.printStackTrace();
            System.exit(1);
        }

        clientStart.send()
               .objectToServer(new TestObject("Hello!"));
    }
}

The method call clientStart.send(), with returns a Sender interface, is now deprecated. Why is that exactly?

With V.2 we wanted to provide a way, to introduce "outside-modules", which basically are an extension to the existing Network-Interfaces, but do not need to be implemented into those. We introduced the interface: com.github.thorbenkuck.netcom2.interfaces.Module

This interface allows you to create Extensions, that may be opened on network interfaces. This is also done, to reduce the "overhead" of the Network-Classes (since they do not have to maintain this Objects instance) and allow for better scalability. The Sender is one of these. You would use it the following way:

package example;

import com.github.thorbenkuck.netcom2.network.client.ClientStart;
import com.github.thorbenkuck.netcom2.exceptions.StartFailedException;

class Example {
    public void example() {
        ClientStart clientStart = ClientStart.at("localhost", 8888);

        clientStart.getCommunicationRegistration()
               .register(TestObject.class)
               .addFirst((testObject -> System.out.println("Server send: " + testObject.getHello())));

        try {
            clientStart.launch();
        } catch (StartFailedException e) {
            e.printStackTrace();
            System.exit(1);
        }

        Sender sender = Sender.open(clientStart);

        sender.objectToServer(new TestObject("Hello!"));
    }
}

On that note: The following statements are not longer possible in V.2:

sender.objectToServer(/* ... */).andWaitForReceiving(Type.class);
sender.objectToServer(/* ... */).andWaitForSendFinished(Type.class);

The scenarios in which this kind of synchronized Communication is required is so extremely rare, that the introduced overhead was not worth it. For every Object, we had to latch 2 callbacks onto the Connection. If you do not call those Methods, they are discarded fast, but for scalibility, this is a pure nightmare. This is the reason they are removed without deprecation.

Other modularized components are:

ServerStart serverStart = ...
ClientStart clientStart = ...

serverStart.distribute(); // deprecated
Distributor distributor = Distributor.open(serverStart); // will now be used

clientStart.getRemoteObject(Test.class); // deprecated (was a shortcut for the next line)
clientStart.getRemoteObjectFactory(); // deprecated
RemoteObjectFactory factory = RemoteObjectFactory.open(clientStart); // will now be used

serverStart.remoteObjects(); // deprecated
RemoteObjectRegistration registration = RemoteObjectRegistration.open(serverStart) // will now be used

To adapt to this change, you will have to store this Module Implementations by yourself.

Connection changes

The Connections have been overhauled the most in this change. The Connection interface changed quit a bit and a NIO-Connection was introduced. Because of the somewhat strange design in NIO, there are changes to the internal mechanisms. They won't effect you in your daily programming-session, but provide you with more choices:

Previously, the following was possible:

int port = ...;
String hostName = ...;
ServerStart.at(port);
ClientStart.at(hostName, port);

And now, you can do the following:

int port = ...;
String hostName = ...;
InetSocketAddress serverAddress = ...;
InetSocketAddress clientAddress = ...;

ServerStart.at(port);
ServerStart.at(serverAddress);
ServerStart.nio(port);
ServerStart.nio(serverAddress);
ServerStart.tcp(port);
ServerStart.tcp(serverAddress);
ServerStart.raw(port);
ServerStart.raw(serverAddress);

ClientStart.at(hostName, port);
ClientStart.at(clientAddress);
ClientStart.nio(hostName, port);
ClientStart.nio(clientAddress);
ClientStart.tcp(hostName, port);
ClientStart.tcp(clientAddress);
ClientStart.as(clientAddress, /* ... */);
ClientStart.findLocalServer(port);

calling .at is now a synonymy for .nio, which is the java NIO-Driven design. TCP is old IO and uses a custom Thread for reading. Previously each Connection had a custom Thread for writing as well. This has been replaced with the NetComThreadPool, which allows for Runnables to be run by Worker-Processes.

For the ServerStart: calling .raw will give you a ServerStart with no ConnectorCore. You can provide your own via setter-injection (if needed).

For the ClientStart: calling .as with a custom ClientCore is nearly similia to the ConnectorCore within the ServerStart. You can provide your own ClientCore, to define the way Connections are established or blocking until finished should be handled.

On the other hand, calling .findLocalServer will use the new ServiceDiscoverer, to find a ServerStart that can be located using the provided port. Any established ServerStart can simply call .allowLocalAreaNetworkFind with the port and ServiceDiscovery is done. You can also provide your own ServiceDiscoveryHub if you want to

Raw informations

Relocations

The following Classes have been relocated:

CommunicationRegistration

The CommunicationRegistration was previously found within the package com.github.thorbenkuck.netcom2.network.shared.comm and is now found within the package com.github.thorbenkuck.netcom2.network.shared..

The comm package is meant for the actual communications. The CommunicationRegistration is only meant to aggregate said Communications. This is a bit of a kontroverse change, but we fell like this is the right thing.

Session

The Session is no longer found within the package import com.github.thorbenkuck.netcom2.network.shared.session, but in com.github.thorbenkuck.netcom2.network.shared. The session package was not needed and only introduced complexity, that was unnecessary. The Session is a part of both the Client and the Server and can be found in the shared package.

This is a big issue with most Programms! The Session is a very central element of the NetCom2 Communication. All of your Handlers and classes, that require the Session will be effected by this change! We apologize for the inconvenience.

Connection

The Connection was changed from the location com.github.thorbenkuck.netcom2.network.shared.clients to com.github.thorbenkuck.netcom2.network.shared.connections. Since the Connection is so central and got expanded pretty impressively with this update, we felt like giving it a new package.

NOTE! The change effecting the OnReceiveFamily also makes your Handlers, which implement those broken! This might be the biggest piece of work for you. If you used lambadas, all you have to do, is to check the imports and the calls on Connection.

Logging

The Logging interface (and all default implementations) where previously found in the package com.github.thorbenkuck.netcom2.network.interfaces. It is now deprecated and routes alle calls to the new Logging location, which is: com.github.thorbenkuck.netcom2.logging. It makes way more sense to have a package for the logging itself, which may be extracted into a separate maven-project itself.

NOTE! It would be a bad idea, to keep using this deprecated version. The whole package might be relocated.

com.github.thorbenkuck.netcom2.network.interfaces

Since NetCom2 is interface driven, it makes no sense to have a interface package. The following interfaces are still present, but deprecated and not used anymore:

  • ClientConnectedHandler The ClientConnectedHandler is connected to the Clients. Therefor it has been relocated to the com.github.thorbenkuck.netcom2.network.shared.clients package. The old one is no longer used and your code may be broken. (If you used a lambda instead of an implementations of this interface, you do not need to do anything)
  • Connector
    This interface is no longer needed, because of the redesign, to introduce NIO.
  • DecrytionAdapter
    This interface has been relocated to the package com.github.thorbenkuck.netcom2.network.shared
  • EncrytionAdapter
    This interface has been relocated to the package com.github.thorbenkuck.netcom2.network.shared
  • Launch
    This interface, which is used by both the ServerStart and the ClientStart, has been relocated from
  • DecrytionAdapter
    This interface has been relocated to the package com.github.thorbenkuck.netcom2.network.interfaces to com.github.thorbenkuck.netcom2.interfaces. This Interface may be associated with more than just Network stuff.
  • Logging
    See above.
  • NetworkInterface
    This interface represents an entry point for a network communication. This does not mean, that only things within the network package can establish network communication. More specific, with the introduction of the com.github.thorbenkuck.netcom2.services, there is another package, that does allow network communication. Therefor it has been relocated to com.github.thorbenkuck.netcom2.interfaces.
  • ReceivingService
    Is no longer needed, because of the redesign.
  • SendingService
    Is no longer needed, because of the redesign.
Clone this wiki locally