Streaming REST API - rest

We are currently using SpringBoot to implement REST services where the response is sent in the form of JSON. I am exploring the ways to "stream" the response.
Could somebody please suggest different ways/approaches to stream the response.
Regards,
Rohit

Below is the code snippet to stream data from a rest endpoint.
#RequestMapping(value = "/streams", method = RequestMethod.GET)
public StreamingResponseBody getStreamingResponse () {
return new StreamingResponseBody() {
#Override
public void writeTo (OutputStream out) throws IOException {
for (int i = 0; i < 1000; i++) {
out.write((Integer.toString(i) + " - ")
.getBytes());
out.flush();
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}

Related

xmpp file upload using smack

i am unable to upload file on xmpp using smack client android. slot.puturl() returns "https://localhost:7443/httpfileupload/27c97df7-dbbf-47ff-b19a-3ac624e51cf0/1.jpg"
HttpFileUploadManager manager = HttpFileUploadManager.getInstanceFor(mConnection);
try {
Slot slot = manager.requestSlot(path, 10000);
uploadFileToSlot(new File(path), slot);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
I got solution for after very deep research.
That HttpFileUploadManager is only for requesting slot from server.
Once you got slot request url upload file using httpclient or okhttpclient.
For okhttpclient:
You need to configure sslSocketFactory by mtm or certificatepinning.
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient().newBuilder();
SSLContext sslContext = JavaPinning.forPin(<PINNING_VALUE>);
okHttpClientBuilder.writeTimeout(5, TimeUnit.MINUTES)
.connectTimeout(5, TimeUnit.MINUTES)
.readTimeout(5, TimeUnit.MINUTES);
okHttpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), JavaPinning.trustManagerForPin(<PINNING_VALUE>));
OkHttpClient client = okHttpClientBuilder.build();
initiate okhttpclient and add file like.
Request request = new Request.Builder()
.url(slot.getPutUrl())
.put(RequestBody.create(MediaType.parse("application/octet-stream"), files))
.build();
Now lets begin to upload.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(final Call call, final IOException e) {
// Handle the error
Log.i(log, "error " + e);
}
#Override
public void onResponse(final Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
// Handle the error
Log.i(log, "errored " + response);
}
Log.i(log, "success " + response);
// Upload successful
}
});
Hope it helps you.

Call facebook graphrequest multiple times

i'm developpig an app in which i need to call the fb graphrequest multiple times , but those calls needs to be one after the other, the first one will get me the user friends, and the other calls will be done in a loop (for each friend ) get the "likes" that that friend made, now with the code that i made, the first one gives me the friends but the second one (the loop instruction) won't work, i guess it has somehing to do with the async calls but i don't know how to make them serial calls, here's my code :
GraphRequest request = GraphRequest.newMyFriendsRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONArrayCallback() {
#Override
public void onCompleted(JSONArray array, GraphResponse response) {
JSONObject jsonArray = response.getJSONObject();
try {
length = jsonArray.getJSONArray("data").length();
for (int i = 0; i < length; i++) {
AlertDialog a = new AlertDialog.Builder(liste_peronalisee.this).create();
a.setTitle("Erreur");
id[i] = jsonArray.getJSONArray("data").getJSONObject(i).getString("id");
a.setMessage(id[i]);
a.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
request.executeAsync();
for(int i=0;i<id.length;i++)
request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/".concat(id[i]).concat("/likes"),
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
JSONObject jsonArray = response.getJSONObject();
try {
length = jsonArray.getJSONArray("data").length();
for (int i = 0; i < length; i++) {
AlertDialog a = new AlertDialog.Builder(liste_peronalisee.this).create();
a.setTitle("Erreur");
id[i] = jsonArray.getJSONArray("data").getJSONObject(i).getString("name");
a.setMessage(id[i]);
a.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
request.executeAsync();
i need a quick answer, thanks in advance

What is the proper way of enabling Stream Management in smack 4.1.1

I have search every for the method used in enabling stream management in smack and nothing is working for me
This function isSmAvailable() always return false, am using prosody as the XMPP server in which the smacks[mod_smacks] is installed and enabled below is my code
XMPPTCPConnectionConfiguration.Builder configureBuilder = XMPPTCPConnectionConfiguration.builder();
configureBuilder.setServiceName(Config.XMPP_HOST);
configureBuilder.setHost(HOST);
//configureBuilder.allowEmptyOrNullUsernames();
configureBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
//configureBuilder.setDebuggerEnabled(true);
SmackConfiguration.DEBUG = true;
xmppConnection = new XMPPTCPConnection(configureBuilder.build());
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
//PingManager
xmppConnection.setUseStreamManagement(true);
xmppConnection.setUseStreamManagementResumption(true);
ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(xmppConnection);
reconnectionManager.enableAutomaticReconnection();
try {
MyLog.w("Connecting to xmpp server");
xmppConnection.setPacketReplyTimeout(100000);
xmppConnection.connect();
//xmppConnection.sendSmAcknowledgement();
if (xmppConnection.isSmEnabled()) {
MyLog.w("stream M is enabled");
} else {
MyLog.w("stream M is not enabled");
}
if (xmppConnection.isSmAvailable()) {
MyLog.w("stream M available");
} else {
MyLog.w("stream M is not available");
}
//xmppConnection.
xmppConnection.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection xmppConnection) {
//logger.warning("Connected to server successfully");
MyLog.w("Connected to server");
}
#Override
public void authenticated(XMPPConnection xmppConnect, boolean b) {
//logger.warning("Nice it is authenticated too");
MyLog.w("Finally logged into the server");
}
#Override
public void connectionClosed() {
//logger.warning("Connected to server failed");
}
#Override
public void connectionClosedOnError(Exception e) {
//logger.warning(e.getMessage());
MyLog.w("Connection close on error" + e.getMessage());
}
#Override
public void reconnectionSuccessful() {
//I think here we need to relogin the user
MyLog.w("Reconnected successfully ....thanks to RC");
}
#Override
public void reconnectingIn(int i) {
}
#Override
public void reconnectionFailed(Exception e) {
MyLog.w("Reconnection Failed " + e.getMessage());
}
});
} catch (Exception e) {
MyLog.w("connected-error" + e.getMessage());
}
I tried adding streamFeature for stream management using
xmppConnection.addStreamFeature() but it tells me that the function is private
and also through ProviderManager.addStreamFeature(element, namespace, provider) is also not working
Can you please help me to figure this out or there is something am doing wrong here
Thanks
Check your ejabbered config file for stream management is enable or not.
stream_management: true
resend_on_timeout: true
resume_timeout: 300
In android code you just add to below line to enable stream management in your app.
static{
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
}
This piece of code is working for me having ejabbered on server side--
XMPPTCPConnectionConfiguration connConfig = XMPPTCPConnectionConfiguration.builder()
.setHost(HOST)
.setPort(PORT)
.setDebuggerEnabled(true)
.setSecurityMode(SecurityMode.disabled)
.setUsernameAndPassword(USERNAME, PASSWORD)
.setServiceName(SERVICE).build();
XMPPTCPConnection connection = new XMPPTCPConnection(connConfig);
connection.setUseStreamManagement(true);
connection.setPacketReplyTimeout(TIME_OUT);
connection.connect();
connection.login();

I get the following error: "message": "Malformed access token

I have an app in facebook and I am trying to obtain long term token,
for that I call the following link:
https://graph.facebook.com/oauth/authorize?client_id=xxxxxx&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Faccesstokforfacebook%2Ffbaccess&scope=read_stream,read_insights,user_religion_politics,user_relationship_details,user_hometown,user_location,user_likes,user_activities,user_interests,user_education_history,user_work_history,user_website,user_groups,user_events,user_photos,user_videos,user_about_me,user_status,user_games_activity,user_tagged_places,user_actions.books,user_actions.video,user_actions.news
and the return url is a servlet with following codes:
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String accessCode = request.getParameter("code");
System.out.println("dddd "+accessCode);
//print SUCCESS if code is found
/*if (accessCode!=null){*/
out.print("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\"><html><head><title>Facebook Access Granted</title></head><body>");
out.print("<p>SUCCESS!</p><p>"+accessCode+"</p></body></html>");
and this servlet receives the very long code like this:
AQCY244eMOhxEVu3e6UEIl-qK974wTh-p0Il1ZdG9VEAYl5GdrjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQcJeUmeXFU56cbWbmXJdLQvEyIT7JWCxxu6tChkr9oCL1DVYxxv4v-j4Y_vaWGD7dYcxxxxxxxxxxxxxxxxxxTvZPHLU-tU5ySHrQrVgpo_i8minM73cyWxxxxxxxxxxxxxxdZvnrIhQXQ-B_3LAFzDcWe2NbCW7WSgmQ-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMkJ55M0wHHbLmL4D-g_wLIwhpz4W_8Hz0h7v_ZL
Now when I use this token to get the all info for a page I get an error:
this is a link that I use:
https://graph.facebook.com/v2.0/khalatbari.hooman/feed?access_token=THE ABOVE CODE
and the error is:
Now I think the code that I get is not access token but I have no idea how to use this code to get access token!!!
can anyone help
Finally found solution for Facebook SDK 4.6.0 to getting limited comment's list for feed :
1> Calling commentInfo() firstly Inside Activity's oncreate()
:
private boolean isLoadMoreCalled;
commentInfo("", "true");
2> Putting load more method also there like:
listViewCommentList.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.d("scrollState", ""+scrollState);
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int last_visible_in_screen = firstVisibleItem + visibleItemCount;
if(last_visible_in_screen == totalItemCount && isLoadMoreCalled) {
Toast.makeText(getApplicationContext(), "Loading more Items 10", Toast.LENGTH_SHORT).show();
commentInfo(nextFeedUrl, "false");
isLoadMoreCalled = false;
}
}
});
3> create commentInfo() of outside onCreate() :
public void commentInfo (String fields, final String isFirst) {
/** Festival Feed Comments Details #Facebook */
Bundle params = new Bundle();
params.putString("fields", "message,created_time,from");
params.putString("limit", "10");
if(isFirst.equals("false")) {
params.putString("after", fields);
}
showProgressBar();
/* make the API call */
//refreshCurrentAccessTokenAsync();
System.out.println("Acees Token Comment>>>"+ AccessToken.getCurrentAccessToken());
new GraphRequest(AccessToken.getCurrentAccessToken(), "/"+ feedId +"/comments", params, HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
/* handle the result */
System.out.println("Festival feed Comments response::" + String.valueOf(response.getJSONObject()));
try {
JSONObject jObjResponse = new JSONObject(String.valueOf(response.getJSONObject()));
JSONObject jObjPaging = jObjResponse.getJSONObject("paging");
JSONObject jObjCursor = jObjPaging.getJSONObject("cursors");
nextFeedUrl = "";
nextFeedUrl = jObjCursor.getString("after");
System.out.println("nextFeedUrl>>"+ nextFeedUrl);
JSONArray jArrayData = jObjResponse.getJSONArray("data");
for(int i = 0; i< jArrayData.length(); i++) {
Getting comments info & store into Data-Structure(Array-List)
}
if(isFirst.equals("true")) {
fbFeedCommentAdapter = new FbFeedCommentAdapter();
listViewCommentList.setAdapter(fbFeedCommentAdapter);
}
else {
fbFeedCommentAdapter.notifyDataSetChanged();
}
if(!jObjPaging.has("next")) {
isLoadMoreCalled = false;
}
else {
isLoadMoreCalled = true;
}
dismissProgressBar();
}
catch (Exception e) {
e.printStackTrace();
dismissProgressBar();
}
}
}
).executeAsync();
}
Here,
fbFeedCommentAdapter -> BaseAdapter
listViewCommentList -> Listview
Also refer How to use the Facebook Graph Api Cursor-based Pagination

RequestFactory and offline clients

I'm trying to create an application which is able to work even when network is down.
The idea is to store data returned from RequestFactory on the localStorage, and to use localStorage when network isn't available.
My problem - I'm not sure exactly how to differentiate between server errors(5XX, 4XX, ...) and network errors.
(I assume that on both cases my Receiver.onFailure() would be called, but I still don't know how to identify this situation)
Any help would be appreciated,
Thanks,
Gilad.
The response code when there is no internet connection is 0.
With RequestFactory to identify that the request was unsuccessful because of the network the response code has to be accessed. The RequestTransport seems like the best place.
Here is a rough implementation of an OfflineAwareRequestTransport.
public class OfflineAwareRequestTransport extends DefaultRequestTransport {
private final EventBus eventBus;
private boolean online = true;
public OfflineAwareRequestTransport(EventBus eventBus) {
this.eventBus = eventBus;
}
#Override
public void send(final String payload, final TransportReceiver receiver) {
// super.send(payload, proxy);
RequestBuilder builder = createRequestBuilder();
configureRequestBuilder(builder);
builder.setRequestData(payload);
builder.setCallback(createRequestCallback(receiver, payload));
try {
builder.send();
} catch (RequestException e) {
}
}
protected static final int SC_OFFLINE = 0;
protected RequestCallback createRequestCallback(final TransportReceiver receiver,
final String payload) {
return new RequestCallback() {
public void onError(Request request, Throwable exception) {
receiver.onTransportFailure(new ServerFailure(exception.getMessage()));
}
public void onResponseReceived(Request request, Response response) {
if (Response.SC_OK == response.getStatusCode()) {
String text = response.getText();
setOnline(true);
receiver.onTransportSuccess(text);
} else if (response.getStatusCode() == SC_OFFLINE) {
setOnline(false);
boolean processedOk = processPayload(payload);
receiver.onTransportFailure(new ServerFailure("You are offline!", OfflineReceiver.name,
"", !processedOk));
} else {
setOnline(true);
String message = "Server Error " + response.getStatusCode() + " " + response.getText();
receiver.onTransportFailure(new ServerFailure(message));
}
}
};
}