DS-Lab / src / main / java / dslab / rmi / stub / dmtp / DmtpClientStubImpl.java
DmtpClientStubImpl.java
Raw
package dslab.rmi.stub.dmtp;

import dslab.protocol.ProtocolException;
import dslab.protocol.dmtp.Dmtp;
import dslab.rmi.channel.SocketChannel;
import dslab.rmi.serialize.dmtp.DmtpClientSerializer;
import dslab.rmi.serialize.dmtp.DmtpServerSerializer.DmtpCommand;
import dslab.rmi.stub.ClientStub;
import dslab.routing.Address;
import dslab.routing.AddressResolutionException;
import dslab.routing.Domain;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import static dslab.rmi.serialize.dmtp.DmtpServerSerializer.DmtpCommand.to;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;

public class DmtpClientStubImpl extends ClientStub<Dmtp> implements DmtpClientStubFragment {


    /**
     * Do not instantiate this class directly. Use {@link dslab.ComponentFactory#newDmtpInstance} instead.
     */
    public DmtpClientStubImpl(SocketChannel channel) {
        super(channel, new DmtpClientSerializer());
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (asList(Dmtp.class.getMethods()).contains(method)) {
            var dmtpCommand = DmtpCommand.valueOf(method.getName());
            var arg = args == null ? null : args[0];
            var result = call(dmtpCommand, arg).get();
            return result;
        } else if (asList(DmtpClientStub.class.getMethods()).contains(method))
            return method.invoke(this, args);

        throw new NoSuchMethodError(method.toString());
    }

    /**
     * Walks through the message recipients and checks which are valid and which aren't
     */
    public AddressValidationResult validate(List<Address> addresses, Domain domain) {
        var bad = new ArrayList<Address>();
        var good = new ArrayList<Address>();
        var ignored = new ArrayList<Address>();

        for (var address : addresses) {
            if (!address.getDomain().equals(domain)) {
                ignored.add(address);
                continue;
            }

            try {
                call(to, singletonList(address)).get();
                good.add(address);
            } catch (ProtocolException e) {
                if (e instanceof AddressResolutionException) {
                    bad.add(address);
                    continue;
                }
                throw new RuntimeException(e); //never happens
            }
        }
        return new AddressValidationResult(good, bad, ignored);
    }

    @Override protected String getProtocolName() {
        return "DMTP2.0";
    }
}