GcmReceiver cannot get any messages with payload having the field "message_type" - google-cloud-messaging

It's my understanding that the payload can have any field names, but look like that is not the case. In the following code, if jData has a field "message_type", the android app will not receive a push notification for the message even sending the message to GCM succeeds (receiving a response: {"message_id":xxx}). I guess somehow "message_type" is used internally by GCM, so we should never use that field?
jGcmData.put("to", "/topics/global");
// What to send in GCM message.
jGcmData.put("data", jData);
// Create connection to send GCM Message request.
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty(
"Authorization", "key=" + mContext.getString(R.string.google_server_api_key));
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);

As talked about on GCM Reference
data Optional, JSON object
.......
The key should not be a reserved word ("from" or any word starting
with "google" or "gcm"). Do not use any of the words defined in this
table (such as collapse_key).
On reference for Downstream message XMPP message response body
message_type Required, string
This parameter specifies an 'ack' or
'nack' message from the XMPP connection server to the app server.
If the value is set to nack, the app server should look at error and
error_description to get failure information.
message_type is defined in reference table so it is a reserved word.
So
Do not use it.

Related

Get messages by property or header in RabbitMQ

I'm new in to RabbitMQ and I've faced a problem. I'm trying to get messages from queue by API method. I've made that by now I want to get messages from queue by header or property if it is possible. I read the documentation about HTTP API. I have not found such an API for filtering messages by some headers or properties.
I use that kind of API to get messages from queue:
/api/queues/vhost/name/get
and in the body:
{"count":20,"ackmode":"ack_requeue_true","encoding":"auto"}
I was thinking, maybe it is possible to somehow pass some filter in the body so it could filter and return the message what I want.
This is how my message looks like :
I have tried to pass in the body type = "myType" or header = "myHeader"
I've made that by now I want to get messages from queue by header or
property if it is possible.
RabbitMQ only delivers messages in order from a queue. There is no way to filter once a message is in a queue.
You can filter messages as they are published to an exchange, however. Use a headers exchange and bind queues based on header values. Then, each queue will contain the messages you expect and you can then consume from them.
The RabbitMQ tutorials have a section that use a "headers exchange". Use that as a guide.
Finally, only use the HTTP API for testing. It is a very inefficient way to retrieve messages.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
A bit late to the party, but I think you can achieve the same like this
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(hostname);
Connection conn = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueBind(queueName, exchangeName, "");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
Map<String, Object> headers = delivery.getProperties().getHeaders();
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "', with header : " + headers.get("TestHeader") );
};
channel.basicConsume(queue, true, deliverCallback, consumerTag -> { });

How to extract sessionId from Citrus HttpRequest

I tried to test the a set of REST services using Citrus Java DSL. After authentication the services expect the same, valid session id of the first request.
On the server side I can see, that there exists a random session-id, but at the second request, the session-id is null.
I've tried to set handleCookies to true in the endpoint configuration and tried to extract some header information (set-cookie) but without success. The EndpointConfiguration is reused during the different requests.
CitrusEndpoints.http()
.client()
.handleCookies(true)
How can I force the Endpoint to reuse the negotiated session-id or how can I extract it from the request / response?
Thanks in advance for any ideas and hints.
The response to your 1st request should have a header set
Set-Cookie: JSESSIONID=ABCDEFG;path=/api/foo
You can extract this information in your receive operation
http()
.client(todoClient)
.receive()
.response(HttpStatus.OK)
.extractFromHeader("Set-Cookie", "cookie")
.payload("{ \"foo\": \"bar\" }");
After that we have to post process the new ${cookie} value in order to extract the actual session id name and value into a new variable ${sessionId}.
createVariable("sessionId", "citrus:substringBefore(${cookie}, ';')");
Now we have a variable ${sessionId} that only contains the name and value of the session id - in our example this is JSESSIONID=ABCDEFG.
In further requests you can use the variable in order to set proper Cookie header information
http()
.client(todoClient)
.send()
.get("/api/foo")
.header("Cookie", "${sessionId}")
.accept(ContentType.APPLICATION_JSON.getMimeType());

WSO2 Send Recovery Notification

In our current WSO2 setup, after a user performs a self creation, we place his account into a locked state, and send a confirmation email to the address specified during creation. This email has a link which allows the user to verify his account.
For development purposes, we are attempting to get the workflow down using the UserInformationRecoveryService wsdl in SOAP UI. The service which we seem to want is called sendRecoveryNotification. Here is the signature of this service:
sendRecoveryNotification(String username, String key, String notificationType)
The username parameter is simply the username of the WSO2 user in question, which we have. For the notificationType we have been using email, which presumably would trigger an email to be sent to the user. The problem is with the key parameter. It is not clear what value should be used as key, and all our guesses always lead to this error response:
18001 invalid confirmation code for user : tbiegeleisen#abc.com#tenant.com
We also noticed that several other services also expect a key, and it is not clear how to get this value.
Can someone shed light on the workflow for user recovery in WSO2? It seems to be a Catch-22 with regard of requiring a token in order to generate a new token to be sent to a user.
The WSO2 documentation clearly spells out the workflow for recovery with notification. The key which needs to be used is the return value from a call to the verifyUser() SOAP web service. This service itself expects a Captcha which normally would be sent from the UI. Here is a code snippet showing how a recovery notification can be sent:
String cookies = client.login("admin#tenant.com#tenant.com", "admin");
UserInformationRecoveryUtil userInfoutil = new UserInformationRecoveryUtil(webserviceUrl, cookies);
CaptchaInfoBean captchaInfo = new CaptchaInfoBean();
captchaInfo.setImagePath(captchaPath);
captchaInfo.setSecretKey(captchaKey);
captchaInfo.setUserAnswer(captcha);
String username = emailId + "#" + tenantDomain;
String key = userInfoutil.verifyUser(username, captchaInfo);
// now pass the key based on the Captcha along with the type of recovery action
userInfoutil.sendRecoveryNotification(username, key, "accountUnLock");

Passbook update tag: if-modified-since (null)

I am using Restlet2.0 (java) to build passbook server. When I send a Push Notification to APNs with PushToken, I got message 'if-modified-since (null)' from the server log:
entity.getText() : {"logs":["[2013-03-31 00:18:29 +1100] Get pass task
(pass type pass.xxxxxx.freehug, serial number ABC, if-modified-since
(null); with web service url
http://192.168.1.43:8080/passbook/restlet) encountered error:
Server response was malformed (Missing response data)"]}
This responding URL matches the router defined for the LoggingResource class (Line 4), but not the SerialNumbersPassWithDeviceResource class (Line 2) which defines the passUpdatedSince={tag} parameter to be captured for the latest pkpass comparison:
router.attach("/v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}", DeviceRegistrationResource.class); //1/4. Registration - POST/DELETE
router.attach("/v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}?passUpdatedSince={tag}", SerialNumbersPassWithDeviceResource.class); //2. SerialNumbers - GET
router.attach("/v1/passes/{passTypeIdentifier}/{serialNumber}", LatestVersionPassResource.class); //3. LatestVersion - GET
router.attach("/v1/log", LoggingResource.class); //5. Logging - POST
So where can I set the Update Tag (passUpdatedSince={tag}) and how can I get it under the router in above Line 2? Is my router setup for getting Update tag correct?
The passUpdatedSince={tag} value is set from the last successful response that your web service gave to the requsest:
https://{webServiceURL}/v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}
You set it by providing a key of lastUpdated in the JSON dictionary response to the above request. The value can be anything you like, but the simplest approach would be to use a timestamp.
The if-modified-since value is set by the Last-Modified HTTP header sent with the last .pkpass bundle received matching the passTypeIdentifier and serialNumber. Again, you can choose what value to send in this header.
The specific error that you mention above is not due to either of these. It is caused by your web service not providing a .pkpass bundle in response to the request to:
https://{webServiceURL}/v1/passes/{passTypeIdentifier}/{serialNumber}
You may want to try hooking your device up to Xcode, turning on PassKit logging (Settings -> Developer), then monitoring the device's console log as you send the push. This may give you more detail as to why the device sent the message to your web service log.

Upload file to Solr with HttpClient and MultipartEntity

httpclient, httpmime 4.1.3
I am trying to upload a file through http to a remote server with no success.
Here's my code:
HttpPost method;
method = new HttpPost(solrUrl + "/extract");
method.getParams().setParameter("literal.id", fileId);
method.getParams().setBooleanParameter("commit", true);
MultipartEntity me = new MultipartEntity();
me.addPart("myfile", new InputStreamBody(doubleInput, contentType, fileId));
method.setEntity(me);
//method.setHeader("Content-Type", "multipart/form-data");
HttpClient httpClient = new DefaultHttpClient();
HttpResponse hr = httpClient.execute(method);
The server is Solr.
This is to replace a working bash script that calls curl like this,
curl http://localhost:8080/solr/update/extract?literal.id=bububu&commit=true -F myfile=#bububu.doc
If I try to set "Content-Type" "multipart/form-data", the receiving part says that there's no boundary (which is true):
HTTP Status 500 - the request was rejected because no multipart boundary was found
If I omit this header setting, the server issues an error description that, as far as I discovered, indicates that the content type was not multipart [2]:
HTTP Status 400. The request sent by the client was syntactically incorrect ([doc=null] missing required field: id).
This is related to [1] but I couldn't determine the answer from it. I was wondering,
I am in the same situation but didn't understand what to do. I was hoping that the MultipartEntity would tell the HttpPost object that it is multipart, form data and have some boundary, and I wouldnt set content type by myself. I didn't quite get how to provide boundaries to the entities - the MultipartEntity doesn't have a method like setBoundary. Or, how to get that randomly generated boundary to specify it in addHeader by myself - no getBoundary methor either...
[1] Problem with setting header "Content-Type" in uploading file with HttpClient4
[2] http://lucene.472066.n3.nabble.com/Updating-the-index-with-a-csv-file-td490013.html
I am suspicious of
method.getParams().setParameter("literal.id", fileId);
method.getParams().setBooleanParameter("commit", true);
In the first line, is fileId a string or file pointer (or something else)? I hope it is a string. As for the second line, you can rather set a normal parameter.
I am trying to tackle the HTTP Status 400. I dont know much Java (or is that .Net?)
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error