I try to upload multiple images to the server and before that, I want to compress my images. for compressing part I use AdvancedLuban Library in my project to compress selected images of users and then for uploading part I use Retrofit in RxJava way. I do all in my presenter class and all of this works properly. My problem is I want to do all of this in my UploadWorker class which is inherited from RxWorker and while doing uploading show progress in the notification.
The code I wrote does not work properly and notification progress did not update correctly.
Here is my UploadWorker.class
public class UploadWorker extends RxWorker {
private static final String TAG = UploadWorker.class.getSimpleName();
public static final String KEY_STRING_DATA = "string_data";
private static final int COMPRESS_MAX_SIZE = 200;
private static final int PROGRESS_MAX = 100;
private Context context;
private FileUploader uploader;
public UploadWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
ApiService apiService = ServiceBuilder.buildService(ApiService.class);
uploader = new FileUploader(apiService);
}
#NonNull
#Override
public Single<Result> createWork() {
Data data = getInputData();
String strData = data.getString(KEY_STRING_DATA);
List<String> stringList = deserializeFromJson(strData);
List<File> files = new ArrayList<>();
for (String path : stringList) {
File f = new File(path);
files.add(f);
}
return Single.fromObservable(Luban.compress(context,files)
.setMaxSize(COMPRESS_MAX_SIZE)
.putGear(Luban.CUSTOM_GEAR)
.setCompressFormat(Bitmap.CompressFormat.JPEG)
.asListObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<List<File>, ArrayList<String>>() {
#Override
public ArrayList<String> apply(List<File> files) throws Exception {
ArrayList<String> filListPath = new ArrayList<>();
for (File file:files) {
filListPath.add(file.getAbsolutePath());
}
return filListPath ;
}
})
.map(new Function<ArrayList<String>, Disposable>() {
#Override
public Disposable apply(ArrayList<String> strings) throws Exception {
HashMap<String, RequestBody> map = new HashMap<>();
return getUploadObserver(map,strings);
}
}).map(new Function<Disposable, Result>() {
#Override
public Result apply(Disposable disposable) throws Exception {
return Result.success();
}
})
);
}
private Disposable getUploadObserver(HashMap<String, RequestBody> map, ArrayList<String> files) {
return uploader.uploadMultiImage(map, files)
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Double>() {
#Override
public void accept(Double progress) throws Exception {
notifyUpload((int) (100 * progress));
Log.d(TAG, "accept: " + (int) (100 * progress));
}
});
}
public void notifyUpload(int progress) {
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, Config.NOTIFICATION_CHANNEL);
builder.setSmallIcon(R.drawable.ic_notification_icon)
.setContentTitle("Upload")
.setContentText("Uploading in progress")
.setPriority(NotificationCompat.PRIORITY_LOW)
.setAutoCancel(true);
if (progress < PROGRESS_MAX) {
builder.setProgress(PROGRESS_MAX, progress, false);
}else {
builder.setContentText("Upload complete")
.setProgress(0,0,false);
}
notificationManagerCompat.notify(200, builder.build());
}
public static List<String> deserializeFromJson(String jsonString){
Gson gson = new Gson();
Type listOf = new TypeToken<ArrayList<String>>() {}.getType();
return gson.fromJson(jsonString,listOf);
}
}
FileUploader.class
public class FileUploader implements FileUploaderContract{
private final ApiService service;
private static final String TAG = FileUploaderModel.class.getSimpleName();
public FileUploaderModel(ApiService service) {
this.service = service;
}
#Override
public Flowable<Double> uploadMultiImage(HashMap<String,RequestBody> map, ArrayList<String> filePaths) {
return Flowable.create(new FlowableOnSubscribe<Double>() {
#Override
public void subscribe(FlowableEmitter<Double> emitter) throws Exception {
try {
List<MultipartBody.Part> myPart = new ArrayList<>();
for (String path:filePaths) {
myPart.add(createMultipartBody(path, emitter));
}
ResponseBody response = service.postMultipleImage(map,myPart).blockingGet();
Log.d(TAG, "subscribe: " + response);
emitter.onComplete();
} catch (Exception e) {
emitter.tryOnError(e);
}
}
}, BackpressureStrategy.LATEST);
}
#NonNull
private RequestBody createPartFromString(String descriptionString) {
return RequestBody.create(MultipartBody.FORM, descriptionString);
}
private MultipartBody.Part createMultipartBody(String filePath, FlowableEmitter<Double> emitter) {
File file = new File(filePath);
return MultipartBody.Part.createFormData("image", file.getName(), createCountingRequestBody(file, emitter));
}
private RequestBody createCountingRequestBody(File file, FlowableEmitter<Double> emitter) {
RequestBody requestBody = createRequestBody(file);
return new CountingRequestBody(requestBody, (bytesWritten, contentLength) -> {
double progress = (1.0 * bytesWritten) / contentLength;
emitter.onNext(progress);
});
}
}
And call my UploadWorker in my MainActivity like below
String strData = serializeToJson(mAdapter.getImageList());
Data data = new Data.Builder()
.putString(UploadWorker.KEY_STRING_DATA,strData)
.build();
WorkRequest mRequestWork = new OneTimeWorkRequest.Builder(UploadWorker.class)
.setInitialDelay(1, TimeUnit.SECONDS)
.setInputData(data)
.build();
WorkManager.getInstance(getContext()).enqueue(mRequestWork)
Related
This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Using GSON to parse a JSON with dynamic "key" and "value" in android
(2 answers)
Closed 5 years ago.
This is my JsonResponse , and since its not in array i am facing some difficulties , can any one help me out ? in android
{
"errorno": "0",
"responsemsg": "Login Success.",
"busid": "1234",
"returnmobileno": "1234567890"
}
try this
try {
JSONObject lJsonObject = new JSONObject(response);
String errorno = lJsonObject .getString("errorno");
String responsemsg = lJsonObject .getString("responsemsg");
String busid = response.lJsonObject ("busid");
String returnmobileno = lJsonObject .getString("returnmobileno");
} catch (JSONException e) {
e.printStackTrace();
}
Try this,
try {
String errorno = response.getString("errorno");
String responsemsg = response.getString("responsemsg");
String busid = response.getString("busid");
String returnmobileno = response.getString("returnmobileno");
Log.d(TAG, "errorno:" + errorno+" responsemsg:"+responsemsg+" busid:"+busid+" returnmobileno:"+returnmobileno);
} catch (JSONException e) {
e.printStackTrace();
}
use below code to pass your strong
serverData = gson.fromJson(response, ServerData.class);
in build.gradle -> dependencies
// retrofit, gson
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
public class ApiClient {
public static final String SERVER_BASE_URL = "http://example.com/abc/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(SERVER_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public interface ApiInterface {
#POST("appServices/getData.php")
#FormUrlEncoded
Call<ResponseBody> getAllDataJSONFromServer(#Field("vcode") String vcode);
}
public class ServerData implements Parcelable {
public static final Creator<ServerData> CREATOR = new Creator<ServerData>() {
#Override
public ServerData createFromParcel(Parcel in) {
return new ServerData(in);
}
#Override
public ServerData[] newArray(int size) {
return new ServerData[size];
}
};
private static final int VERSION = 1;
#SerializedName("errorno")
private String errorno;
#SerializedName(responsemsg)
private String responsemsg;
#SerializedName("busid")
private String busid;
#SerializedName("returnmobileno")
private String returnmobileno;
private void readFromParcel(Parcel in) {
if (in.readInt() == VERSION) {
errorno = in.readString();
responsemsg = in.readString();
busid = in.readString();
returnmobileno = in.readString();
}
}
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(VERSION);
parcel.writeString(errorno);
parcel.writeString(responsemsg);
parcel.writeString(busid);
parcel.writeString(returnmobileno);
}
#Override
public int describeContents() {
return 0;
}
public String getErrorno() {
return errorno;
}
public void setErrorno(String errorno) {
this.errorno = errorno;
}
public String getResponsemsg() {
return responsemsg;
}
public void setResponsemsg(String responsemsg) {
this.responsemsg = responsemsg;
}
public String getBusid() {
return busid;
}
public void setBusid(String busid) {
this.busid = busid;
}
public String getReturnmobileno() {
return returnmobileno;
}
public void setReturnmobileno(String returnmobileno) {
this.returnmobileno = returnmobileno;
}
}
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
// get and save all data from server
Call<ResponseBody> call = apiService.getAllDataJSONFromServer(local_vcode, local_cvcode, pckgName);
call.enqueue(new Callback<ResponseBody>() {
#SuppressWarnings("ConstantConditions")
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> responsebody) {
try {
String response = responsebody.body().string();
serverData = gson.fromJson(response, ServerData.class); // this will fetch data to model class ServerData
if (serverData != null) {
// do the rest here...
String vcode = serverData.getVcode();
Log.e("~~~ vode = ", vcode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
progressDialog.dismiss();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
try {
t.printStackTrace();
progressDialog.dismiss();
} catch (Exception ignored) {
}
}
});
I have a retrofit 2 response by which i gets data from server. my code is working fine.
But i want cache this response using SharedPreferences and keep it till that activity is running and after activity is destroyed. i want to delete this response from SharedPreferences.
This is my Code:
public class SampleClass {
private DataInterface mListener;
public SampleClass() {
super();
}
public void getDataForId(final String id) {
ApiInterface apiInterface = APIClient.getApiInterface();
Call<MyResponse> call = apiInterface.getResponse();
call.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response!=null && response.body() != null && mListener != null) {
mListener.responseData(response.body());
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
}
});
}
public void setOnDataListener(DataInterface listener) {
mListener = listener;
}
public interface DataInterface {
void responseData( MyResponse myResponse );
}
}
SecondData class file
sampleClass.setOnDataListener(new SampleClass.DataInterface() {
#Override
public void responseData(MyResponse myResponse) {
// i wanna store this response into SharedPreferences for temp and delete after activity is destroyed.
List<Detail> details = myResponse.getDetails();
for (Detail d : details) {
if (d.getId().equals(id)) {
reqDetail = d;
name.setText(reqDetail.getName());
Picasso.with(SecondData.this)
.load(reqDetail.getName())
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(image);
}
}
}
});
ApiInterface
public interface ApiInterfaceNew {
#GET("/display.php")
Call<MyResponse> getResponse();//imp to include MyResponse as a call
}
Api class
private static final String ROOT_URL = "";
private static Retrofit retrofit1 = null;
private static final String CACHE_CONTROL = "Cache-Control";
public static Retrofit getClient() {
if (retrofit1 == null) {
retrofit1 = new Retrofit.Builder()
.baseUrl(ROOT_URL)
.client(provideOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit1;
}
public static ApiInterfaceNew getApiInterface() {
return getClient().create(ApiInterfaceNew.class);
}
private static OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(provideHttpLoggingInterceptor())
.addInterceptor(provideOfflineCacheInterceptor())
.addNetworkInterceptor(provideCacheInterceptor())
.cache(provideCache())
.build();
}
private static Cache provideCache() {
Cache cache = null;
try {
cache = new Cache(new File(AppControler.getInstance().getCacheDir(), "http-cache"),
10 * 1024 * 1024); // 10 MB
} catch (Exception e) {
Timber.e("Could not create Cache!");
}
return cache;
}
private static HttpLoggingInterceptor provideHttpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor =
new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Timber.e(message);
}
});
httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? HEADERS : NONE);
return httpLoggingInterceptor;
}
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
public static Interceptor provideOfflineCacheInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!AppControler.hasNetwork()) {
CacheControl cacheControl = new CacheControl.Builder()
.maxStale(7, TimeUnit.DAYS)
.build();
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
return chain.proceed(request);
}
};
}
AppControler class
public class AppControler extends Application {
private static AppControler instance;
#Override
public void onCreate()
{
super.onCreate();
instance = this;
if (BuildConfig.DEBUG)
{
Timber.plant(new Timber.DebugTree());
}
Timber.i("Creating our Application");
}
public static AppControler getInstance ()
{
return instance;
}
public static boolean hasNetwork ()
{
return instance.checkIfHasNetwork();
}
public boolean checkIfHasNetwork()
{
ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
Add below code in your Retrofit response when a response is success.
First convert JSON to string and store.
Gson gson = new Gson();
String favData = gson.toJson(response.body());
save strings to prefrance.
preferenceManager is my SharedPref class
preferenceManager.setStringPreference(Global.OFFLINE_WORD, favData);
now when you want to get pref data call below method.
public ArrayList<MyResponse> getData(String key) {
String data = getStringPreference(key);
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<MyResponse>>() {
}.getType();
return gson.fromJson(data, type);
}
You can use either ObjectMapper or Gson.
For ObjectMapper you can refer the below code
public static void updateUserInfo(UserInfo userInfo, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Crashlytics.log("updating User Info "+(userInfo!=null?userInfo.toString():"UserInfo is null"));
final SharedPreferences.Editor edit = preferences.edit();
ObjectMapper objectMapper = new ObjectMapper();
try {
String value = objectMapper.writeValueAsString(userInfo);
edit.putString("USER_INFO_MODEL", value);
edit.commit();
} catch (JsonProcessingException e) {
Exceptions.propagate(e);
}
}
you can also get the stored response from shared preferences
public static UserInfo getUserInfo(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String userDetatails = preferences.getString(AppConstants.USER_INFO_MODEL, "");
Crashlytics.log("get UserInfo "+userDetatails);
ObjectMapper mapper = new ObjectMapper();
if (StringUtils.isEmpty(userDetatails)) {
return null;
}
UserInfo userInfo = null;
try {
userInfo = mapper.readValue(userDetatails, UserInfo.class);
} catch (IOException e) {
Exceptions.propagate(e);
}
return userInfo;
}
I know there are some identical questions but I just couldn't figure out what I'm doing wrong.
public class MainActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
new JsonHandler().execute(this, collection, gridArray, customGridAdapter);
...
}
}
So in my main activity I need to query an API which gives back JSON and I have to process that to build my database.
Then in doInBackground() I call getAllCards() which gets the first JSON. Because the JSON includes URLs for more JSON requests, I have a few methods each querying a more detailed JSON.
public final class JsonHandler extends AsyncTask {
private final String urlCards = "https://api.gwentapi.com/v0/cards/";
private final String urlSpecificCard = "https://api.gwentapi.com/v0/cards/:id";
private Context context;
private Collection collection;
private ArrayList<Card> gridArray;
private CustomGridViewAdapter customGridAdapter;
public JsonHandler(Context context, Collection collection, ArrayList<Card> gridArray, CustomGridViewAdapter customGridAdapter){
this.context = context;
this.collection = collection;
this.gridArray = gridArray;
this.customGridAdapter = customGridAdapter;
}
public JsonHandler(){
this.context = null;
this.collection = null;
this.gridArray = null;
this.customGridAdapter = null;
}
private void getAllCards() throws RuntimeException {
JsonObjectRequest arrayRequest = new JsonObjectRequest(Request.Method.GET, urlCards, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
generateCollection(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
throw new RuntimeException(e.getMessage());
}
});
Volley.newRequestQueue(context).add(arrayRequest);
}
private void getSpecificCard(final String cardURL) throws RuntimeException {
JsonObjectRequest arrayRequest = new JsonObjectRequest(Request.Method.GET, cardURL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
processCard(response, collection);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
throw new RuntimeException(e.getMessage());
}
});
Volley.newRequestQueue(context).add(arrayRequest);
}
private void generateCollection(JSONObject response) throws RuntimeException {
try {
JSONArray array = response.getJSONArray("results");
for(int i = 0; i < array.length();i++){
JSONObject object = array.getJSONObject(i);
String cardURL = object.getString("href");
getSpecificCard(cardURL);
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private void processCard(JSONObject response, Collection collection){
try {
String id = response.getString("id");
EnumFaction faction = EnumFaction.valueOf(response.getJSONObject("faction").getString("name").toUpperCase());
EnumType type = null;
EnumRarity rarity = null;
EnumLane lane = null;
EnumLoyalty loyalty = null;
String name = response.getString("name");
String text = response.getString("text");
String imagePath = "https://api.gwentapi.com/media/\" + id + \"_small.png";
URL url = new URL(imagePath);
InputStream inputStream = url.openConnection().getInputStream();
Bitmap image = BitmapFactory.decodeStream(inputStream);
Card card = new Card(id, faction, type, rarity, lane, loyalty, name, text, null, imagePath, 0);
collection.addCard(card);
gridArray.add(card);
customGridAdapter.notifyDataSetChanged();
} catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
#Override
protected Object doInBackground(Object[] params) {
context = (Context) params[0];
collection = (Collection) params[1];
gridArray = (ArrayList<Card>) params[2];
customGridAdapter = (CustomGridViewAdapter) params[3];
getAllCards();
return null;
}
}
So now on to the problem:
When the programm reaches processCard() when I've gathered enough information, I get a NetworkOnMainThreadException when I create the InputStream.
I've tried so many different methods to get a Bitmap from my URL and different methods to do an asynchronous task - all leading to the same result.
If you could show me how to resolve this issue, I'd be sooo happy.
Edit: Since it got marked as duplicate: I AM USING ASYNCTASK! I have looked at many questions and tried what they did there, it doesn't work!
Not really familiar with how volley works but onResponse but be on the main thread so you need to start a new thread to make that call too
A NullPointerException occurs on the indicated line of my endpoint api method when called by the android client but not when called from the api explorer:
#ApiMethod(name = "publishReview", path = "publish-review", httpMethod = ApiMethod.HttpMethod.POST)
public Review publishReview(#Named("userId") final String id, ReviewForm reviewForm) {
Key<Profile> profileKey = Key.create(Profile.class, id);
final Key<Review> reviewKey = factory().allocateId(profileKey, Review.class);
final Long reviewId = reviewKey.getId();
Profile user = ofy().load().key(profileKey).now();
Review review = new Review(reviewId, id, reviewForm);
user.addToMyReviews(reviewId); // NULLPOINTER HERE
ofy().save().entities(review, user).now();
return review;
}
Here is addToMyReviews(Long reviewId):
public void addToMyReviews(final Long reviewId) {
if (!myReviews.contains(reviewId))
myReviews.add(reviewId);
}
Here is the android client side call of the endpoint method:
public static class PublishReview extends AsyncTask<Void, Void, String> {
private static MyApi myApiService = null;
private ReviewForm mReview;
private final String mUserId;
private Context mContext;
public PublishReview(final String userId, ReviewForm review, Context context) {
mReview = review;
mUserId = userId;
mContext = context;
}
#Override
protected String doInBackground(Void... params) {
if (myApiService == null) { // Only do this once
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
myApiService = builder.build();
}
try {
return myApiService.publishReview(mUserId, mReview).execute().getTitle();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String title) {
Toast.makeText(mContext, title + " published", Toast.LENGTH_LONG).show();
}
}
The mUserId and mReview variables on the client side are not null when passed into the endpoint method as params.
How do I fix this error?
I have some old playframework 2.2 java webservice that interacts with akka, and now I should port them to playframework 2.3.
However, async has been deprecated and even after reading the doc about the async porting (http://www.playframework.com/documentation/2.3.x/JavaAsync) I wasn't able to understand how to apply it to my case (code below):
I must make the await for a timeout/akka server reply before starting the construction of my reply (ok()), otherwise I will block the thread.
I should make the actorselection async too.
I should make the akka server reply parsing/reply construction async too
I looked around and I wasn't able to find an example of such interactions, even in typesafe templates.
How could I do that?
/* playframework 2.2 code */
public class Resolve extends Controller {
private final static String RESOLVER_ACTOR = play.Play.application().configuration().getString("actor.resolve");
#CorsRest
#VerboseRest
#RequireAuthentication
#BodyParser.Of(BodyParser.Json.class)
public static Result getJsonTree() {
JsonNode json = request().body().asJson();
ProtoBufMessages.ResolveRequest msg;
ResolveRequestInput input;
try {
input = new ResolveRequestInput(json);
} catch (rest.exceptions.MalformedInputException mie) {
return badRequest(mie.getMessage());
}
msg = ((ProtoBufMessages.ResolveRequest)input.getMessage());
ActorSelection resolver = Akka.system().actorSelection(RESOLVER_ACTOR);
Timeout tim = new Timeout(Duration.create(4, "seconds"));
Future<Object> fut = Patterns.ask(resolver, input.getMessage(), tim);
return async (
F.Promise.wrap(fut).map(
new F.Function<Object, Result>() {
public Result apply(Object response) {
ProtoBufMessages.ResolveReply rsp = ((ProtoBufMessages.ResolveReply)response);
ResolveOutput output = new ResolveOutput(rsp);
return ok(output.getJsonReply());
}
}
)
);
}
}
I came out with the code below
public class Resolve extends Controller {
private final static String RESOLVER_ACTOR = play.Play.application().configuration().getString("actor.resolve");
private final static BrainProtoMessages.ResolveReply request_error = BrainProtoMessages.ResolveReply.newBuilder()
.setReturnCode(BResults.REQUEST_FAILED)
.build();
#CorsRest
#VerboseRest
#RequireAuthentication
#BodyParser.Of(BodyParser.Json.class)
public static Result resolve_map() {
final ResolveRequestInput input;
final F.Promise<ActorSelection> selected_target;
final F.Promise<Future<Object>> backend_request;
final F.Promise<BrainProtoMessages.ResolveReply> backend_reply;
final F.Promise<ObjectNode> decode_json;
final F.Promise<Result> ok_result;
final JsonNode json = request().body().asJson();
try {
input = new ResolveRequestInput(json);
} catch (rest.exceptions.MalformedInputException mie) {
return badRequest(mie.getMessage());
}
selected_target = F.Promise.promise(
new F.Function0<ActorSelection>() {
#Override
public ActorSelection apply() throws Throwable {
return Akka.system().actorSelection(RESOLVER_ACTOR);
}
}
);
backend_request =
selected_target.map(
new F.Function<ActorSelection, Future<Object>>() {
#Override
public Future<Object> apply(ActorSelection actorSelection) throws Throwable {
return Patterns.ask(actorSelection, input.getMessage(),new Timeout(Duration.create(4, "seconds")));
}
}
);
backend_reply = backend_request.map(
new F.Function<Future<Object>, BrainProtoMessages.ResolveReply>() {
#Override
public BrainProtoMessages.ResolveReply apply(Future<Object> akka_reply) throws Throwable {
try {
return (BrainProtoMessages.ResolveReply) Await.result(akka_reply, Duration.create(4, "seconds"));
}catch(Exception error)
{
return request_error;
}
}
}
);
decode_json = backend_reply.map(
new F.Function<BrainProtoMessages.ResolveReply, ObjectNode>() {
#Override
public ObjectNode apply(BrainProtoMessages.ResolveReply response) throws Throwable {
return new ResolveOutput(response).getJsonReply();
}
}
);
ok_result = decode_json.map(
new F.Function<ObjectNode, Result>() {
#Override
public Result apply(ObjectNode reply) {
return ok(reply);
}
}
);
try {
return ok_result.get(8000);
}catch(Exception error)
{
return internalServerError();
}
}
}