blob: fb33231c5e54d489443206833db9f4c035da4a3b [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.v23.rpc;
import io.v.v23.verror.VException;
import java.util.Arrays;
/**
* Stores the information required to create a listening network endpoint for a server
* and, optionally, the name of a proxy to use in conjunction with that listener.
*/
public class ListenSpec {
/**
* A pair of (network protocol, address) that the server should listen on.
* For TCP, the address must be in {@code ip:port} format. The {@code ip} may be omitted, but
* the {@code port} can not (choose a port of {@code 0} to have the system allocate one).
*/
public static class Address {
private final String protocol;
private final String address;
/**
* Creates a new {@link Address} with the given protocol and address.
*
* @param protocol network protocol (e.g., {@code "tcp"})
* @param address network address (e.g., {@code "localhost:32786"})
*/
public Address(String protocol, String address) {
this.protocol = protocol;
this.address = address;
}
/**
* Returns the network protocol.
*/
public String getProtocol() { return this.protocol; }
/**
* Returns the network address.
*/
public String getAddress() { return this.address; }
@Override
public String toString() {
return this.protocol + ":" + this.address;
}
}
private final Address[] addrs; // non-null
private final String proxy; // non-null
private final AddressChooser chooser; // non-null
/**
* Creates a new {@link ListenSpec} with the given addresses, proxy,
* and {@link AddressChooser}.
*
* @param addrs {@link Address}es that the server should listen on
* @param proxy proxy that the server should use to proxy the connection
* @param chooser {@link AddressChooser} used for selecting addresses to publish with the
* mount table from a candidate set of addresses; if {@code null}, a default
* {@link AddressChooser} that chooses all the addresses will be used.
*/
public ListenSpec(Address[] addrs, String proxy, AddressChooser chooser) {
this.addrs = addrs == null ? new Address[0] : Arrays.copyOf(addrs, addrs.length);
this.proxy = proxy == null ? "" : proxy;
this.chooser = chooser != null ? chooser : new AddressChooser() {
@Override
public NetworkAddress[] choose(String protocol, NetworkAddress[] candidates)
throws VException {
return candidates;
}
};
}
/**
* Same as {@link #ListenSpec(Address[],String,AddressChooser)}, only with a
* single listening {@link Address}.
*/
public ListenSpec(Address addr, String proxy, AddressChooser chooser) {
this(new Address[]{ addr }, proxy, chooser);
}
/**
* Returns a new copy of this {@link ListenSpec} with the {@link AddressChooser} replaced with
* the given address chooser.
*/
public ListenSpec withAddressChooser(AddressChooser newChooser) {
return new ListenSpec(getAddresses(), proxy, newChooser);
}
/**
* Returns a new copy of this {@link ListenSpec} whose {@link #getProxy} method will return the
* given proxy.
*/
public ListenSpec withProxy(String newProxy) {
return new ListenSpec(getAddresses(), newProxy, chooser);
}
/**
* Returns a new copy of this {@link ListenSpec} whose {@link #getAddresses} method will return
* an array containing only the given address.
*/
public ListenSpec withAddress(Address address) {
return new ListenSpec(new Address[]{address}, proxy, chooser);
}
/**
* Returns the addresses the server should listen on.
*/
public Address[] getAddresses() {
return Arrays.copyOf(this.addrs, this.addrs.length);
}
/**
* Returns the name of the proxy. If empty, the server isn't proxied.
*/
public String getProxy() { return this.proxy; }
/**
* Returns the address chooser that is used to choose the preferred address
* to publish with the mount table when one is not otherwise specified.
*/
public AddressChooser getChooser() { return this.chooser; }
@Override
public String toString() {
return Arrays.toString(this.addrs) +
(this.proxy.isEmpty() ? "" : "proxy(" + this.proxy + ")");
}
}