I've got a requirement to log message from the Android client. Is there any sumo logic API to log message from the Android application?
You can post your log message/ any message from your Android application to Summo Logic cloud-based log management.
Summo Logic provides Web Services/ REST to perform POST, GET Request.
You just need to post your data on the request body and mention your
Sumo collection endpoint as well as UniqueHTTPCollectorCode.
REST Service/ Web Service : https://[SumoEndpoint]/receiver/v1/http/[UniqueHTTPCollectorCode]
For Instance:
"https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/SanTC12dhaV1oma90Vvb..."
You can use Retorfit / Volley library for REST Communication .
I have given a below pseudo code which conveys the basic REST Communication in background through Android Async Task.
I strictly recommend to use the above mentioned libraries.
public static String performPostRequest(String summoUrl, String payload,
Context context) throws IOException {
URL url = new URL(summoUrl);
HttpURLConnection uc = (HttpURLConnection) url.openConnection();
String line;
StringBuffer jsonString = new StringBuffer();
uc.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
uc.setRequestMethod("POST");
uc.setDoInput(true);
uc.setInstanceFollowRedirects(false);
uc.connect();
OutputStreamWriter writer = new OutputStreamWriter(uc.getOutputStream(), "UTF-8");
writer.write(payload);
writer.close();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while((line = br.readLine()) != null){
jsonString.append(line);
}
br.close();
} catch (Exception ex) {
ex.printStackTrace();
}
uc.disconnect();
return jsonString.toString();
}
Async task
new AsyncTask<String, String, String>() {
#Override
protected String doInBackground(String... params) {
try {
String response = makePostRequest(""https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/ZaVnC4dhaV1oma90Vvb..."",
// Sample JSON Data "
{ \"organization": \"organization.name\",
\"environment": \"environment.name\",
\"apiProduct": \("apiproduct.name"),
\"proxyName": \("apiproxy.name"),
\"appName": \("developer.app.name"),
\"verb": \("request.verb"),
\"url": '' + \("client.scheme") + '://' + \("request.header.host") + \("request.uri"),
\"responseCode": \("message.status.code"),
\"responseReason": \("message.reason.phrase"),
\"clientLatency": total_client_time,
\"targetLatency": total_target_time,
\"totalLatency": total_request_time
}", getApplicationContext());
// Hard coded Success as response from Server, replace with this as per your need
return "Success";
} catch (IOException exception) {
exception.printStackTrace();
return exception.getMessage();
}
}
}.execute("");
For more information, Please refer the documentation from Official Sumo Webpage
https://help.sumologic.com/Send-Data/Sources/02Sources-for-Hosted-Collectors/HTTP-Source/Upload-Data-to-an-HTTP-Source
Related
I'm trying to implement Firebase Topic Messaging in an Android application, and I'm attempting to build a HTTP post request, and I'm receiving a response code of 400. I have looked at various solutions but none of them have seemed to help.
Here is where I call the subclass of AsyncTask:
try{new FirebaseSendMessage().execute("Hello world");}
catch (Exception e) {
Log.d("Exception", e.toString());
}
Here is my Async Task class's subclass.
class FirebaseSendMessage extends AsyncTask<String, Integer, Double> {
private final static String USER_AGENT = "Mozilla/5.0";
private final static String AUTH_KEY = "<My firebase authorization key obtained from firebase>";
private Exception exception;
protected Double doInBackground(String... params) {
try {
sendRequest(params);
} catch (Exception e) {
this.exception = e;
}
return null;
}
protected void onPostExecute(Long l) {
// TODO: check this.exception
// TODO: do something with the feed
}
public void sendRequest(String... params) {
try {
String urlString = "https://fcm.googleapis.com/fcm/send";
URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Authorization", "key=" + AUTH_KEY);
String postJsonData = "{\"to\": \"/topics/news\"\"data\": {\"message\": \"This is a Firebase Cloud Messaging Topic Message!\"}";
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postJsonData);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK){
System.out.println("succeeded");
}
/*InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//con.disconnect();*/
}
catch(IOException e){
Log.d("exception thrown: ", e.toString());
}
}
}
Error: I/System.out: POST Response Code :: 400
Please let me know if there are additional code snippets required to help me debug. Thanks in advance!
Error 400 means an Invalid JSON in your request:
Check that the JSON message is properly formatted and contains valid fields (for instance, making sure the right data type is passed in).
In your sendRequest, you missed a comma (,) between "news\" and \"data\" and a closing bracket (}):
String postJsonData = "{\"to\": \"/topics/news\"\"data\": {\"message\": \"This is a Firebase Cloud Messaging Topic Message!\"}";
which looks like this:
{"to": "/topics/news/""data":{"message":"...."}
Should be:
String postJsonData = "{\"to\": \"/topics/news\", \"data\": {\"message\": \"This is a Firebase Cloud Messaging Topic Message!\"}}";
So that the JSON structure would be correct:
{"to": "/topics/news/",
"data":{"message":"..."}
}
For those who are willing to use the authentication key in your application.
I suggest to encrypt the key manually by the SHA-1 of your application and the decrypt it at the time of runtime with the SHA-1 code.
I want to implement a basic authentication using an Android Client and a Glassfish 4.1.1 Server (communicating through REST-Service).
The Service is working quite well (proven by POSTMAN and another C#-Client) but on Android, it's driven me crazy by now.
It also appears that the object-to-send is received as 'null' on the server side, also an annoying "EOFException" is thrown on the Android Side.
Server side (works fine)
#POST
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
public Account validate(Account acc)
{
Account a = null;
a = Database.getInstance().getAccountByUserPw(acc);
return a;
}
Android Client:
public Account postData(String JSONtoSend)
{
URL url;
Account get = new Account();
try {
url = new URL("http://192.xxx.xxx.x:18080/HolidayOutServer/webresources/validateacc");
HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
urlCon.setRequestMethod("POST");
urlCon.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlCon.setRequestProperty("Accept", "application/json; charset=UTF-8");
urlCon.setDoOutput(true); // to be able to write.
urlCon.setDoInput(true); // to be able to read.
OutputStreamWriter out = new OutputStreamWriter(urlCon.getOutputStream());
out.write(JSONtoSend);
ObjectInputStream ois = new ObjectInputStream(urlCon.getInputStream());
get = (Account) ois.readObject();
return get;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return get;
}
which is called within this:
class help extends AsyncTask<String, Void, Account>
{
#Override
protected Account doInBackground(String... params) {
return postData(new Gson().toJson(new Account("aleqs", "lexx", -2)));
}
}
Problems in a nutshell:
Jersey Server receives null
Android throws this ridiculous EOFException.
Can somebody help ?
Thanks in advance,
John.
Ok, I managed to find a solution here after hours.
This code works for me:
try( DataOutputStream wr = new DataOutputStream( urlCon.getOutputStream())) {
wr.write(new Gson().toJson(new Account("aleqs", "lexx", -2)).getBytes());
}
Reader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
response = sb.toString();
return response;
} catch (IOException e) {
e.printStackTrace();
}
return response;
Change the return type of "donInBackGround" to String and let the helper class extend -String, Void, String-.
MOST IMPORTANT: CHECK IF YOUR ATTRIBUTES ON CLIENT SIDE (eg. id, name, ..) match with those from SERVER SIDE.
Consider cap locks and so on..
Cheers !
I have a question about the proper syntax and order of code in regards to accessing a REST API.
I am trying to access a database that I made on an mBaas called backendless.com. (The following data information is specific to this mBaas but my question is more about the general process of accessing REST API's in Android)
According to their tutorial to bulk delete (https://backendless.com/documentation/data/rest/data_deleting_data_objects.htm) I need a URL that queries my database for a specific value and then deletes it. I have that value. They also need 3 request headers (application-id, secret key, application type).I have those as well.
I utilized all of this information in an ASyncTask class that technically should open the url, set the request headers, and make the call to the REST API. My only issue is, I have no idea if I'm missing some kind of code here? Is my current code in proper order? Every time my class is executed, nothing happens.
I also get a log cat exception in regards to my URL: java.io.FileNotFoundException: api.backendless.com/v1/data/bulk/...
The URL does not lead to anything when I place it in my browser but I'm told that it shouldn't since the browser sends it as a GET request.
Anyway, here is my ASyncTask Class with all of the info. Does anyone know if this code looks correct or am I missing something here? I'm new to making these type of calls and don't really understand the roll that request-headers play in accessing REST APIs. Please let me know. Thank you!
class DeleteBulkFromBackEnd extends AsyncTask<Void,Void,String>{
final String API_URL = "https://api.backendless.com/v1/data/bulk/LocalPhoneNum?where%3DuserEmailID%3Dmark#gmail.com";
#Override
protected String doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(API_URL);
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty( "application-id","12345678" );
urlConnection.setRequestProperty( "secret-key","12345678" );
urlConnection.setRequestProperty( "application-type", "REST" );
urlConnection.connect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
Log.d("Contact","ERROR " + e.toString() );//IO Exception Prints in log cat not recognizing URL
e.printStackTrace();
}finally {
urlConnection.disconnect();
}
return null;
}
}
I recommend you to use okhttp for easy network access.
And check the response code and response body.
In your build.gradle:
compile 'com.squareup.okhttp3:okhttp:3.4.1'
Your AsyncTask will be like this:
class DeleteBulkFromBackEnd extends AsyncTask<Void, Void, String> {
final String API_URL = "https://api.backendless.com/v1/data/bulk/LocalPhoneNum?where%3DuserEmailID%3Dmark#gmail.com";
final OkHttpClient mClient;
public DeleteBulkFromBackEnd(OkHttpClient client) {
mClient = client;
}
#Override
protected String doInBackground(Void... params) {
try {
Request request = new Request.Builder()
.url(API_URL)
.delete()
.header("application-id", "12345678")
.header("secret-key", "12345678")
.header("application-type", "REST")
.build();
Response response = mClient.newCall(request).execute();
Log.d("DeleteBulkFromBackEnd", "Code: " + response.code());
Log.d("DeleteBulkFromBackEnd", "Body: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Execute the AsyncTask like this:
OkHttpClient client = new OkHttpClient();
void someMethod() {
...
new DeleteBulkFromBackEnd(client).execute();
...
}
As I've commented, here's the solution:
class DeleteBulkFromBackEnd extends AsyncTask<Void,Void,String>{
final String API_URL = "https://api.backendless.com/v1/data/bulk/LocalPhoneNum?where%3DuserEmailID%3Dmark#gmail.com";
#Override
protected String doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(API_URL);
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty( "application-id","12345678" );
urlConnection.setRequestProperty( "secret-key","12345678" );
urlConnection.setRequestProperty( "application-type", "REST" );
urlConnection.setRequestMethod("DELETE");
urlConnection.connect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
Log.d("Contact","ERROR " + e.toString() );//IO Exception Prints in log cat not recognizing URL
e.printStackTrace();
}finally {
urlConnection.disconnect();
}
return null;
}
}
I'm looking forward to implement an app which connects to Spotify. To use Spotify services, I need a token, which I can get with the Spotify SDK, however this token is intended for quick expiring not for long term use. In the web API I can make calls from within my server to get new access tokens via refresh_token. I know this must be done in a call server to server. But, I don't know how should I manage the info provided by the Android Spotify SDK to get the refresh_token from the server. I don't even know if this can be achieved via the Spotify SDK or will I have to implement the whole authorization. I've searched info in the web but I can't find info related to this subject. Hope someone can help.
A few months ago I have developed an app which also uses Spotify's services. Since I wanted to query audio features of a song, I had to use Spotify's Web API instead as Spotify's Android SDK hasn't provided such thing yet. When I implemented the app I didn't think about it too much so every time when I need to do queries I'd get the access token again. You can get the token using the following code, inside the json string also comes with a expires_in property that tells you how many seconds the token will expire, therefore it should be easy to achieve what you want with some slight modification.
private String getAccessTokenFromJsonStr(String spotifyJsonStr) throws JSONException {
final String OWM_ACCESS_TOKEN = "access_token";
String accessToken;
try {
JSONObject spotifyJson = new JSONObject(spotifyJsonStr);
accessToken = spotifyJson.getString(OWM_ACCESS_TOKEN);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return accessToken;
}
private String getSpotifyAccessToken(){
String response;
String accessToken;
try {
String serviceURL = "https://accounts.spotify.com/api/token";
URL myURL = new URL(serviceURL);
HttpsURLConnection myURLConnection = (HttpsURLConnection) myURL.openConnection();
String userCredentials = "YOUR_USER_CREDENTIALS:YOUR_USER_CREDENTIALS";
int flags = Base64.NO_WRAP | Base64.URL_SAFE;
byte[] encodedString = Base64.encode(userCredentials.getBytes(), flags);
String basicAuth = "Basic " + new String(encodedString);
myURLConnection.setRequestProperty("Authorization", basicAuth);
myURLConnection.setRequestMethod("POST");
myURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
myURLConnection.setUseCaches(false);
myURLConnection.setDoInput(true);
myURLConnection.setDoOutput(true);
System.setProperty("http.agent", "");
HashMap postDataParams = new HashMap<String, String>();
postDataParams.put("grant_type", "client_credentials");
OutputStream os = myURLConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
response = "";
int responseCode=myURLConnection.getResponseCode();
Log.d(LOG_TAG, "response code is " + responseCode);
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(myURLConnection.getInputStream()));
while ((line=br.readLine()) != null) {
response+=line;
}
}
else {
response="";
String errLine;
String errResponse = "";
BufferedReader br=new BufferedReader(new InputStreamReader(myURLConnection.getErrorStream()));
while ((errLine=br.readLine()) != null) {
errResponse += errLine;
}
Log.d(LOG_TAG, "error response is " + errResponse);
}
Log.d(LOG_TAG, "response is " + response);
} catch (Exception e){
e.printStackTrace();
}
String accessTokenJsonStr = response.toString();
try {
accessToken = getAccessTokenFromJsonStr(accessTokenJsonStr);
return accessToken;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
Authorization-guide
Basically if you need a refresh token (the token provided by SDK lasts for one hour, and then you have to request another one) you need to use the web api to fetch this token. In this case you would not use the SDK for any part of the authentication process. Technically you don't have to use a server↔server component for the passing secret to Spotify server auth step, it's just best practice (security wise) to avoid hard coding the secret into your app, but technically there is nothing preventing you from doing all the authentication steps app↔spotify server utilizing the pertinent web api calls.
I have set up the Asterisk Server properly for allowing GUI interface, to check this I have tried & tested an already available Application for Android & tested the same with my browser.
I am able to login & view the files.
eg.
http://192.168.8.x:8088/asterisk/rawman?action=getconfig&filename=users.conf
this commands shows me the user.conf file.
However the same commands does not works from my Android Application. It results in
Response: Error
Message: Permission denied
my code:
1st button click:
try{
new mygoogleSearch().execute(http://192.168.8.x:8088/asterisk/rawman?action=login&username=tismo&secret=tismo123);
}
catch(Exception e) {
Log.v("Exception google search","Exception:"+e.getMessage());
}
this returns:
03-27 17:27:09.468: E/GoogleSearch(21686): Response: SuccessMessage: Authentication accepted
On 2nd Button click:
try{
new Execute().execute("http://192.168.8.4:8088/asterisk/rawman?action=getconfig&filename=test.conf");
} catch(Exception e) {
Log.v("Exception google search","Exception:"+e.getMessage());
}
class mygoogleSearch extends AsyncTask {
protected String doInBackground(String... searchKey) {
;
String cmd = searchKey[0];
try {
return action(cmd);
} catch(Exception e) {
Log.v("Exception ",
"Exception:"+e.getMessage());
return "";
}
}
private String action(String uRL)
throws MalformedURLException, IOException {
String newFeed= uRL;
StringBuilder response = new StringBuilder();
URL url = new URL(newFeed);
HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
httpconn.setUseCaches(false);
//httpconn.setRequestProperty("Cache", "false");
if(httpconn.getResponseCode()==HttpURLConnection.HTTP_OK) {
BufferedReader input = new BufferedReader(
new InputStreamReader(httpconn.getInputStream()),
8192);
String strLine = null;
while ((strLine = input.readLine()) != null) {
response.append(strLine);
}
input.close();
}
return response.toString();
}
this returns:
03-27 17:28:31.808: E/GoogleSearch(21800): Response: ErrorMessage: Permission denied
You need a CookieManager to connect to the same session.
Quote from the asteriskbook "the definitive Guide"
"The LOGIN command authenticates credentials for the Manager interface’s HTML view.
Once you are logged in, Asterisk stores a cookie on your browser (valid for the length of the httptimeout setting). This cookie is used to connect to the same session."
Update: Examples of a CookieManager Storage to mimic the Browser:
How to use Cookies with HttpUrlConnection, persist Cookies using HttpUrlConnection