Java: Generating CIDR InetAddress

Una pequeña chuleta para generar una “NetMask” desde un CIDR en Java:

import java.net.InetAddress;

public static InetAddress getAddressByCIDR(final int bits, final boolean ipv6) {
	final int totalBits = (ipv6 ? 128 : 32);
	if (bits < 0 || bits > totalBits)
		throw new IllegalArgumentException("Illegal CIDR prefix");
	final byte[] bytes = new byte[totalBits >> 3];
	for (int offset = 0; offset < bits; offset++) {
		bytes[offset >> 3] |= (1 << (7 - (offset & 7)));
	}
	try {
		return InetAddress.getByAddress(bytes);
	} catch (UnknownHostException e) {
		throw new RuntimeException(e);
	}
}

Referencias:
CIDR

Apache: PROXY protocol for Amazon ELB (Elastic Load Balancing)

If you want to use Apache 2.2 / 2.4 behind a Amazon ELB (Elastic Load Balancing), HAproxy, Stunnel, Stud o anything similar, you will have seen that in the logs appears IP of ELB instead of the remote client, and filter by IP is a double problem.

The module “remoteip” does not solve the problem. Amazon ELB, HAProxy and others support “PROXY protocol”, that helps to fix this issues working behind proxys.

The protocol look similar to:

PROXY TCP4 10.1.2.3 192.168.0.11 56324 443\r\n
GET / HTTP/1.1\r\n
Host: www.acme.com\r\n
Accept: */*\r\n
Connection: close\r\n
\r\n

But Apache currently does not support out-of-the-box. So following the philosophy of Do-It-Yourself, here is the source code (beta):

mod_myfixip.c in Github (for Apache 2.4)
mod_myfixip.c in Github (for Apache 2.2)

References:
ElasticLoadBalancing: Enable Proxy Protocol
PROXY protocol

Java: Could not generate DH keypair

Si te aparece este error, sigue leyendo…

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1762)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1723)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1706)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1237)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)

Leer más de esta entrada

Linux: Convert OGM to AVI

Una simple chuleta para convertir video en formato .ogm a formato .avi en Ubuntu 14.04:

avconv -i "input.ogm" -vcodec copy -acodec libmp3lame -ac 2 -ar 44100 "output.avi"

Si tu reproductor no soporta el formato del stream de video de original y necesitas cambiar el codec puedes usar “-vcodec mpeg4″, aunque el proceso será mucho más lento.

Para ver la lista de codecs soportados:

avconv -codecs

El paquete Ubuntu es libav-tools.

Referencia:
avconv.1

Network: Latency benchmark

Las pruebas han sido muy basicas (pero dan una idea/orden de magnitud), las maquinas dst tienen un Servidor ECHO-TCP y las maquinas src tiene un Cliente ECHO-TCP. El cliente se conecta al servidor, envia un byte, lee el byte de vuelta, asi una y otra vez en un bucle de 10mil iteraciones, calcula la latencia minima, maxima y la media de las 10mil iteraciones.

Los resultados:

+--------+--------+------------+-------------+------------+----------+
| src    | dst    |    min     |     max     |    avg     | medium   |
+--------+--------+------------+-------------+------------+----------+
| linux1 | win7   | 2137.421µs | 24779.393µs | 3471.736µs | plc      |
| linux2 | win7   | 2035.887µs | 36111.414µs | 3040.004µs | plc      |
| linux3 | win7   | 1889.267µs | 10737.868µs | 2689.145µs | plc      |
| linux1 | win7   | 1031.974µs |  6943.338µs | 1371.043µs | wifi-11n |
| linux2 | win7   |  786.553µs |  4445.808µs | 1153.319µs | wifi-11n |
| linux3 | win7   |  621.457µs | 40078.223µs |  964.037µs | wifi-11n |
| linux1 | win7   |  380.495µs | 69546.800µs |  732.009µs | gbe      |
| linux1 | linux3 |  101.130µs | 10486.523µs |  314.863µs | vm       |
| linux2 | linux1 |  159.140µs |  9334.732µs |  308.808µs | vm       |
| linux2 | win7   |  165.534µs | 11921.050µs |  307.096µs | gbe      |
| linux3 | win7   |   79.133µs |  2289.499µs |  150.973µs | gbe      |
| linux2 | linux3 |   54.764µs |  5447.378µs |   86.460µs | vm       |
| linux1 | linux1 |   54.197µs |   299.199µs |   85.713µs | loopback |
| linux2 | linux2 |   41.505µs |   372.127µs |   72.765µs | loopback |
| linux3 | linux3 |   15.805µs |   500.069µs |   48.219µs | loopback |
| win7   | win7   |   17.675µs |    76.399µs |   22.927µs | loopback |
+--------+--------+------------+-------------+------------+----------+

Las maquinas son:

  • linux1: Ubuntu 14.04 32bits (virtual)
  • linux2: Ubuntu 14.04 64bits (virtual)
  • linux3: Ubuntu 12.04 64bits (fisica)
  • win7: Windows 7 Pro 64bits (fisica)

Los medios de transmision son:

  • plc: enlace PLC HomePlug-AV (aunque el PLC se conecta a la red por Ethernet a 100Mb)
  • wifi: enlace wifi 802.11n (aunque el AP-Wifi se conecta a la red por Ethernet a 100Mb)
  • vm: comunicacion entre dos maquinas dentro de un mismo hypervisor/host (linux3)
  • gbe: enlace Ethernet a 1Gb
  • loopback: comunicacion dentro de la misma maquina (127.0.0.1)

Sourcecode on GitHub:
EchoServer.java
EchoClient.java

Java: Agnostic Cache with Dynamic Proxies and Reflection

Hace tiempo usé un modulo de Perl muy interesante, Memoize. La idea era muy sencilla, tienes una funcion X, si para una entrada A, hay una salida B constantes y ese cálculo es lento, puede usar un caché.

La idea es esa, calcular una vez, usar muchas; sin tener que tener una implementación con cache de cada implementación original.

Aquí está la implementación en Java usando Reflexión:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

public class ReflectMemoizer implements InvocationHandler {
  private final Object object;
  private final HashMap<Method, ConcurrentHashMap<List<Object>, Object>> caches;

  /**
   * Memoize object
   * @param object source
   * @return proxied object
   */
  public static Object memoize(final Object object) 
        throws InstantiationException, IllegalAccessException {
    final Class<?> clazz = object.getClass();
    final ReflectMemoizer memoizer = new ReflectMemoizer(object);
    return Proxy.newProxyInstance(clazz.getClassLoader(), 
        clazz.getInterfaces(), memoizer);
  }

  private ReflectMemoizer(final Object object) {
    this.object = object;
    this.caches = new HashMap<Method, ConcurrentHashMap<List<Object>, Object>>();
  }

  public Object invoke(final Object proxy, final Method method, 
        final Object[] args) throws Throwable {
    if (method.getReturnType().equals(Void.TYPE)) {
      // Don't cache void methods
      return invoke(method, args);
    } else {
      final Map<List<Object>, Object> cache = getCache(method);
      final List<Object> key = Arrays.asList(args);
      Object value = cache.get(key);
      if ((value == null) && !cache.containsKey(key)) {
        value = invoke(method, args);
        cache.put(key, value);
      }
      return value;
    }
  }

  private synchronized Map<List<Object>, Object> getCache(final Method m) {
    ConcurrentHashMap<List<Object>, Object> cache = caches.get(m);
    if (cache == null) {
      cache = new ConcurrentHashMap<List<Object>, Object>();
      caches.put(m, cache);
    }
    return cache;
  }

  private Object invoke(final Method method, final Object[] args) 
        throws Throwable {
    try {
      return method.invoke(object, args);
    } catch (InvocationTargetException e) {
      throw e.getTargetException();
    }
  }
}

Leer más de esta entrada

Java: ServiceLoader decouple API and Implementation

Un sencillo ejemplo del uso de ServiceLoader, muy útil para para crear aplicaciones extensibles a la vez que separamos las interfaces de sus implementaciones en diferentes empaquetados (jar).

La factoría que usa el ServiceLoader y la interface común (ambos ficheros en storage-api.jar):

package com.acme;

import java.util.ServiceLoader;

public class StorageFactory {
  public static Storage getInstance() {
    for (Storage storage : ServiceLoader.load(Storage.class)) {
      return storage;
    }
    throw new UnsupportedOperationException("No implementation found");
  }
}

La interface que deben implementar todos los servicios:

package com.acme;

public interface Storage {
  void put(String key, String value);

  String get(String key);
}

Un ejemplo de implementación en memoria (ambos ficheros en storage-memory.jar):

package com.acme;

import java.util.concurrent.ConcurrentHashMap;

public class MemoryStorage implements Storage {
  private final ConcurrentHashMap<String, String> map;

  public MemoryStorage() {
    map = new ConcurrentHashMap<String, String>();
  }

  @Override
  public void put(final String key, final String value) {
    map.put(key, value);
  }

  @Override
  public String get(final String key) {
    return map.get(key);
  }
}

El fichero META-INF/services/com.acme.Storage

com.acme.MemoryStorage

Otra implementación estilo /dev/null (ambos ficheros en storage-null.jar):

package com.acme;

public class NullStorage implements Storage {
  @Override
  public void put(final String key, final String value) {
  }

  @Override
  public String get(final String key) {
    return null;
  }
}

El fichero META-INF/services/com.acme.Storage

com.acme.NullStorage

Y para acabar, el código de prueba:

package com.acme;

public class TestStorage {
  public static void main(final String[] args) throws Throwable {
    final Storage storage = StorageFactory.getInstance();
    storage.put("data", "hello world");
    System.out.println(storage.get("data"));
  }
}

Referencias:
java.util.ServiceLoader

Java: Get Current Method Name from a Class

Una cosa que suele mejorar mucho las trazas o el profiling es saber “donde estás”, no solo en que clase, si no en que método. Por desgracia actualmente en Java no existe un simple Thread.currentThread().getCurrentMethod() o similar.

La información se puede sacar del StackTrace (también hay un método oscuro sun.reflect.Reflection.getCallerClass(int), pero en Java 8 ha desaparecido y como dicen los de Oracle: sun.* is private api, is not supported).

Lo malo del StackTrace es que es relativamente pesado, tanto si usas Thread.currentThread().getStackTrace() o new Throwable().getStackTrace()

Se puede acelerar la ejecución usando los metodos internos de Throwable mediante reflexión (no suelo ser muy partidario, pero hablamos de 10 veces más rápido). Para asegurar que si los métodos privados cambian el código siga funcionando, aquí un método mixto:
Leer más de esta entrada

Java: Configuration and Preferences API

Lidiar con la configuración siempre es un tema complejo, históricamente los Properties y los XML siempre han salido al rescate.
La problemática viene cuando empiezan a crecer el número de parámetros, de ficheros de configuración y el número de entornos donde debes desplegar (desarrollo, test, producción), ya sean urls de conexión, configuraciones de bbdd o directorios de almacenamiento. Lo peor es cuando esos parametros van empaquetados dentro del jar o el war, entonces tienes q hacer modificaciones manuales, usar profiles de maven o cosas similares.

Si estas cosas te suenan… Una alternativa es usar el API de Preferences de Java (usando las systemRoot); un ejemplo de uso:

Leer más de esta entrada

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

A %d blogueros les gusta esto: