CDAP Common provides core common utilities and abstractions for the CDAP (Cask Data Application Platform) ecosystem including exception handling, service management, configuration, HTTP utilities, metadata management, security abstractions, discovery services, and various utility classes that are shared across CDAP components.
—
Network utilities for address resolution, port management, and service discovery integration with comprehensive tools for distributed service coordination.
Core network utilities for address resolution, port management, and service discovery integration.
/**
* Network utility functions for CDAP services
*/
public final class Networks {
/**
* Resolve hostname to InetAddress with fallback
* @param hostname The hostname to resolve
* @param onErrorAddress Fallback address if resolution fails
* @return Resolved InetAddress or fallback address
*/
public static InetAddress resolve(String hostname, InetAddress onErrorAddress);
/**
* Find a random free port
* @return Available port number
*/
public static int getRandomPort();
/**
* Extract IP address from socket address
* @param address The socket address
* @return IP address as string
*/
public static String getIP(SocketAddress address);
/**
* Add discoverable service to configuration
* @param cConf Configuration object
* @param key Configuration key
* @param discoverable Service to add
*/
public static void addDiscoverable(CConfiguration cConf, String key, Discoverable discoverable);
/**
* Remove discoverable service from configuration
* @param cConf Configuration object
* @param key Configuration key
* @param discoverable Service to remove
*/
public static void removeDiscoverable(CConfiguration cConf, String key, Discoverable discoverable);
/**
* Get discoverable services from configuration
* @param cConf Configuration object
* @param key Configuration key
* @return Set of discoverable services
*/
public static Set<Discoverable> getDiscoverables(CConfiguration cConf, String key);
/**
* Set network address in configuration
* @param cConf Configuration object
* @param key Configuration key
* @param addr Socket address to set
*/
public static void setAddress(CConfiguration cConf, String key, InetSocketAddress addr);
/**
* Get network address from configuration
* @param cConf Configuration object
* @param key Configuration key
* @return Socket address from configuration
*/
public static InetSocketAddress getAddress(CConfiguration cConf, String key);
}Usage Examples:
import io.cdap.cdap.common.utils.Networks;
import io.cdap.cdap.common.conf.CConfiguration;
import org.apache.twill.discovery.Discoverable;
// Resolve hostnames with fallback
InetAddress localhost = InetAddress.getLoopbackAddress();
InetAddress resolved = Networks.resolve("my-server.com", localhost);
System.out.println("Resolved address: " + resolved.getHostAddress());
// Find available ports
int port1 = Networks.getRandomPort();
int port2 = Networks.getRandomPort();
System.out.println("Available ports: " + port1 + ", " + port2);
// Extract IP from socket address
SocketAddress socketAddr = new InetSocketAddress("192.168.1.100", 8080);
String ip = Networks.getIP(socketAddr);
System.out.println("IP: " + ip); // "192.168.1.100"
// Service discovery integration
CConfiguration cConf = CConfiguration.create();
// Add discoverable service
Discoverable webService = new Discoverable() {
@Override
public String getName() { return "web-service"; }
@Override
public InetSocketAddress getSocketAddress() {
return new InetSocketAddress("localhost", 8080);
}
@Override
public byte[] getPayload() { return new byte[0]; }
};
Networks.addDiscoverable(cConf, "services.web", webService);
// Remove discoverable service
Networks.removeDiscoverable(cConf, "services.web", webService);
// Retrieve discoverable services
Set<Discoverable> services = Networks.getDiscoverables(cConf, "services.web");
for (Discoverable service : services) {
System.out.println("Service: " + service.getName() +
" at " + service.getSocketAddress());
}
// Address configuration management
InetSocketAddress bindAddr = new InetSocketAddress("0.0.0.0", 9090);
Networks.setAddress(cConf, "my.service.bind.address", bindAddr);
InetSocketAddress configuredAddr = Networks.getAddress(cConf, "my.service.bind.address");
System.out.println("Configured to bind on: " + configuredAddr);Components for service discovery and endpoint selection strategies.
/**
* Strategy for selecting endpoints from discovered services
*/
public interface EndpointStrategy {
/**
* Pick an endpoint from available discoverables
* @param discoverables Available service endpoints
* @return Selected endpoint or null if none available
*/
Discoverable pick(Iterable<Discoverable> discoverables);
}
/**
* Base implementation of endpoint strategy
*/
public abstract class AbstractEndpointStrategy implements EndpointStrategy {
protected AbstractEndpointStrategy();
/**
* Pick an endpoint, with null handling
*/
@Override
public final Discoverable pick(Iterable<Discoverable> discoverables);
/**
* Subclasses implement the actual picking logic
*/
protected abstract Discoverable doPick(Iterable<Discoverable> discoverables);
}
/**
* Random endpoint selection strategy
*/
public class RandomEndpointStrategy extends AbstractEndpointStrategy {
public RandomEndpointStrategy();
@Override
protected Discoverable doPick(Iterable<Discoverable> discoverables);
}
/**
* Sticky endpoint selection strategy that prefers the same endpoint
*/
public class StickyEndpointStrategy extends AbstractEndpointStrategy {
public StickyEndpointStrategy();
@Override
protected Discoverable doPick(Iterable<Discoverable> discoverables);
}Utilities for URI handling and address resolution.
/**
* URI scheme constants
*/
public enum URIScheme {
HTTP("http"),
HTTPS("https"),
FILE("file");
private final String scheme;
URIScheme(String scheme);
public String getScheme();
/**
* Create URI with this scheme
*/
public URI createURI(String host, int port, String path);
}
/**
* Discoverable with address resolution capabilities
*/
public class ResolvingDiscoverable implements Discoverable {
public ResolvingDiscoverable(Discoverable discoverable);
@Override
public String getName();
@Override
public InetSocketAddress getSocketAddress();
@Override
public byte[] getPayload();
/**
* Get resolved socket address (resolves hostname to IP)
*/
public InetSocketAddress getResolvedSocketAddress();
}Advanced Usage Examples:
import io.cdap.cdap.common.discovery.*;
import org.apache.twill.discovery.DiscoveryServiceClient;
// Endpoint selection strategies
public class LoadBalancedClient {
private final DiscoveryServiceClient discoveryClient;
private final EndpointStrategy strategy;
public LoadBalancedClient(DiscoveryServiceClient discoveryClient) {
this.discoveryClient = discoveryClient;
// Use random strategy for load balancing
this.strategy = new RandomEndpointStrategy();
}
public String makeRequest(String serviceName, String path) throws IOException {
Iterable<Discoverable> endpoints = discoveryClient.discover(serviceName);
Discoverable endpoint = strategy.pick(endpoints);
if (endpoint == null) {
throw new IOException("No available endpoints for service: " + serviceName);
}
InetSocketAddress addr = endpoint.getSocketAddress();
// Make HTTP request to selected endpoint
return httpClient.get("http://" + addr.getHostString() + ":" +
addr.getPort() + path);
}
}
// Sticky client that prefers the same endpoint
public class StickyClient {
private final EndpointStrategy stickyStrategy = new StickyEndpointStrategy();
public void processWorkflow(String serviceName, List<String> requests) {
Iterable<Discoverable> endpoints = discoveryClient.discover(serviceName);
// All requests in this workflow will prefer the same endpoint
for (String request : requests) {
Discoverable endpoint = stickyStrategy.pick(endpoints);
if (endpoint != null) {
processRequest(endpoint, request);
}
}
}
}
// URI building utilities
public class ServiceUrlBuilder {
public static URI buildServiceUrl(URIScheme scheme, Discoverable service, String path) {
InetSocketAddress addr = service.getSocketAddress();
return scheme.createURI(addr.getHostString(), addr.getPort(), path);
}
public static List<URI> buildServiceUrls(String serviceName, String path,
DiscoveryServiceClient discoveryClient) {
List<URI> urls = new ArrayList<>();
for (Discoverable service : discoveryClient.discover(serviceName)) {
URI httpUrl = URIScheme.HTTP.createURI(
service.getSocketAddress().getHostString(),
service.getSocketAddress().getPort(),
path
);
urls.add(httpUrl);
}
return urls;
}
}
// Address resolution with fallback
public class NetworkConfig {
public static InetSocketAddress getBindAddress(CConfiguration cConf,
String hostKey, String portKey,
String defaultHost, int defaultPort) {
String host = cConf.get(hostKey, defaultHost);
int port = cConf.getInt(portKey, defaultPort);
// Resolve hostname with localhost fallback
InetAddress addr = Networks.resolve(host, InetAddress.getLoopbackAddress());
return new InetSocketAddress(addr, port);
}
public static void configureService(CConfiguration cConf, String serviceName,
InetSocketAddress bindAddress) {
// Store the actual bind address after service starts
Networks.setAddress(cConf, serviceName + ".bind.address", bindAddress);
// Make it discoverable
Discoverable discoverable = new SimpleDiscoverable(serviceName, bindAddress);
Networks.addDiscoverable(cConf, serviceName + ".discoverable", discoverable);
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-cdap-cdap--cdap-common