microsoft - porta azure
Conexión del bus de servicio Azure con Android (1)
Escribí un programa simplemente Java (jdk 1.7) que enumera todos mis temas de bus de servicio e imprime el nombre de cada tema en stdout:
try {
String namespace = "myservicebus"; // from azure portal
String issuer = "owner"; // from azure portal
String key = "asdjklasdjklasdjklasdjklasdjk"; // from azure portal
Configuration config = ServiceBusConfiguration.configureWithWrapAuthentication(
namespace,
issuer,
key,
".servicebus.windows.net",
"-sb.accesscontrol.windows.net/WRAPv0.9");
ServiceBusContract service = ServiceBusService.create(config);
ListTopicsResult result = service.listTopics();
List<TopicInfo> infoList = result.getItems();
for(TopicInfo info : infoList){
System.out.println( info.getPath());
}
} catch (Exception e) {
e.printStackTrace();
}
Ahora, estoy tratando de ejecutar este ejemplo en un proyecto simple de Android (Android 4.2) pero no funcionará. El tiempo de ejecución siempre arroja el siguiente error:
java.lang.RuntimeException: Service or property not registered: com.microsoft.windowsazure.services.serviceBus.ServiceBusContract
¿Alguien ha establecido con éxito una conexión desde un dispositivo Android (o emulador) a un bus de servicio azul?
¿Microsoft Azure-Java-SDK no es compatible con los proyectos de Android?
Gracias por adelantado
Este error se debe al hecho de que los apk generados no incluyen (eliminan) la información de ServiceLoader (bajo META-INF / services). Puede probarse borrándolo del jar generado y ver que aparezca el mismo error. En la documentación se dice que ahora es compatible, pero encontré problemas para usarlo.
http://developer.android.com/reference/java/util/ServiceLoader.html
Puede incluir manualmente los datos en el apk usando hormiga
Mantenga los archivos ''META-INF / services'' en apk
Después de 10 horas de depuración, eliminación de clases manualmente, incluidos META-INF / services, etc., descubrí que Azure SDK usa algunas clases que no son compatibles con Android (javax.ws. *) Y cualquier woraround me funciona.
Así que recomendaría usar la API REST en entornos Android, busque debajo el código fuente que utilicé para separar los mensajes al tema.
private static String generateSasToken(URI uri) {
String targetUri;
try {
targetUri = URLEncoder
.encode(uri.toString().toLowerCase(), "UTF-8")
.toLowerCase();
long expiresOnDate = System.currentTimeMillis();
int expiresInMins = 20; // 1 hour
expiresOnDate += expiresInMins * 60 * 1000;
long expires = expiresOnDate / 1000;
String toSign = targetUri + "/n" + expires;
// Get an hmac_sha1 key from the raw key bytes
byte[] keyBytes = sasKey.getBytes("UTF-8");
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256");
// Get an hmac_sha1 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
// Compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal(toSign.getBytes("UTF-8"));
// using Apache commons codec for base64
// String signature = URLEncoder.encode(
// Base64.encodeBase64String(rawHmac), "UTF-8");
String rawHmacStr = new String(Base64.encodeBase64(rawHmac, false),"UTF-8");
String signature = URLEncoder.encode(rawHmacStr, "UTF-8");
// construct authorization string
String token = "SharedAccessSignature sr=" + targetUri + "&sig="
+ signature + "&se=" + expires + "&skn=" + sasKeyName;
return token;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void Send(String topic, String subscription, String msgToSend) throws Exception {
String url = uri+topic+"/messages";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
// Add header
String token = generateSasToken(new URI(uri));
post.setHeader("Authorization", token);
post.setHeader("Content-Type", "text/plain");
post.setHeader(subscription, subscription);
StringEntity input = new StringEntity(msgToSend);
post.setEntity(input);
System.out.println("Llamando al post");
HttpResponse response = client.execute(post);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() != 201)
throw new Exception(response.getStatusLine().getReasonPhrase());
}
Más información en REST API Azure information.