jsonWebClient.DataContent = new System.Net.Http.MultipartFormDataContent();
ByteArrayContent bytes = new ByteArrayContent(File.ReadAllBytes(data.LocalFile));
bytes.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
jsonWebClient.DataContent.Add(bytes, "file", data.FileName);
jsonWebClient.DataContent.Add(bytes, "name", data.FileName);
jsonWebClient.DataContent.Add(new StringContent($"{Connection.UserId}"), "userId");
jsonWebClient.DataContent.Add(new StringContent($"{data.ParentId}"), "parentId");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.CreationTime}"), "created");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.LastWriteTime}"), "modified");
jsonWebClient.DataContent.Add(new StringContent($"{DateTime.Now}"), "clientCreated");
jsonWebClient.DataContent.Add(new StringContent($"{DateTime.Now}"), "clientModified");
jsonWebClient.DataContent.Add(new StringContent($"{fileInfo.Length}"), "size");
So I am trying generate a MultipartFormDataContent to convert to a Byte Array or stream. When I do the stream:
Stream stream = _dataContent.ReadAsStreamAsync().Result;
I get a out of memory exception.
When I try to do:
byte[] bytes = _dataContent.ReadAsByteArrayAsync().Result;
or
byte[] bytes = _dataContent.ReadAsByteArrayAsync().GetAwaiter().GetResult();
It just sits there forever and does nothing. What can I do to make it convert to the proper byte array?
Original source [How would I run an async Task method synchronously?][Rachel]How would I run an async Task<T> method synchronously? method-synchronously
public static class AsyncHelpers
{
/// <summary>
/// Execute's an async Task<T> method which has a void return value synchronously
/// </summary>
/// <param name="task">Task<T> method to execute</param>
public static void RunSync(Func<Task> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
synch.Post(async _ =>
{
try
{
await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
}
/// <summary>
/// Execute's an async Task<T> method which has a T return type synchronously
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="task">Task<T> method to execute</param>
/// <returns></returns>
public static T RunSync<T>(Func<Task<T>> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
T ret = default(T);
synch.Post(async _ =>
{
try
{
ret = await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
return ret;
}
private class ExclusiveSynchronizationContext : SynchronizationContext
{
private bool done;
public Exception InnerException { get; set; }
readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
readonly Queue<Tuple<SendOrPostCallback, object>> items =
new Queue<Tuple<SendOrPostCallback, object>>();
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException("We cannot send to our same thread");
}
public override void Post(SendOrPostCallback d, object state)
{
lock (items)
{
items.Enqueue(Tuple.Create(d, state));
}
workItemsWaiting.Set();
}
public void EndMessageLoop()
{
Post(_ => done = true, null);
}
public void BeginMessageLoop()
{
while (!done)
{
Tuple<SendOrPostCallback, object> task = null;
lock (items)
{
if (items.Count > 0)
{
task = items.Dequeue();
}
}
if (task != null)
{
task.Item1(task.Item2);
if (InnerException != null) // the method threw an exeption
{
throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException);
}
}
else
{
workItemsWaiting.WaitOne();
}
}
}
public override SynchronizationContext CreateCopy()
{
return this;
}
}
}
With this class I was able to convert it right away without waiting and there was no issues with Out of Memory Exception.
Related
I'm new to the quarkus framework where I'm writing rabbitmq-client library based on quarkur framework. I'm using io.quarkiverse.rabbitmqclient.RabbitMQClient.
I need to write JUnit for basic send and consume operations, please help me with how can I write junit and mock RabbitMQClient. I'm using the below code to send and consume message.
#ApplicationScoped
public class RabbitMQProducerAdapterImpl extends RabbitMQCongiguration implements RabbitMQProducerAdapter {
#Override
public void sendMessage(String exchange, String routingKey, String messagePayload) throws IOException {
setUpConnectionAndChannel();
channel.basicPublish(exchange, routingKey, null, messagePayload.getBytes(StandardCharsets.UTF_8));
Log.info("message sent succefully: " + messagePayload);
}
}
Here is the RabbitMQCongiguration
#ApplicationScoped
public class RabbitMQCongiguration {
#Inject
private RabbitMQClient rabbitClient;
protected Channel channel;
protected void setUpConnectionAndChannel() {
try {
// create a connection
Connection connection = rabbitClient.connect();
// create a channel
channel = connection.createChannel();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
protected void setupQueueInDirectExchange(String exchangeName, String routingKey, String queueName,
boolean createExchangeQueues) throws IOException {
setUpConnectionAndChannel();
if (createExchangeQueues) {
this.channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, false, null);
// declaring a queue for this channel. If queue does not exist,
// it will be created on the server. this line not needed if queue already
// present
this.channel.queueDeclare(queueName, true, false, false, null);
}
// Bind Routing Key to Exchange
this.channel.queueBind(queueName, exchangeName, routingKey);
}
}
Below is the class for consumer
#ApplicationScoped
public class RabbitMQConsumerAdapterImpl extends RabbitMQCongiguration implements RabbitMQConsumerAdapter, Runnable {
private String queueName;
private MessageProcessor messageProcessor;
#Override
public void consumeMessage(String exchange, String queueName, String routingKey,
MessageProcessor messageProcessor) throws IOException {
Log.info("starting consumer...");
try {
this.queueName = queueName;
this.messageProcessor = messageProcessor;
Log.info("setting up rabbitMQPrefetchCountConfig");
setupQueueInDirectExchange(exchange, routingKey, queueName, false);
Thread consumerThread = new Thread(this);
consumerThread.start();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
#Override
public void run() {
try {
// start consuming messages. Auto acknowledge messages.
Log.info("Start consuming messages from thread...");
channel.basicConsume(this.queueName, false, (Consumer) new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String msgPayload = null;
if (body == null || body.length == 0) {
Log.warn("Invalid Message Body - Consumer Tag : " + consumerTag + ", Message DeliveryTag : "
+ envelope.getDeliveryTag());
channel.basicReject(envelope.getDeliveryTag(), false);
} else {
msgPayload = new String(body);
try {
JsonParser.parseString(msgPayload);
} catch (JsonSyntaxException ex) {
Log.error(msgPayload + " is not a valid json, Reason - ", ex);
channel.basicReject(envelope.getDeliveryTag(), false);
Log.warn("Rejected the current payload.");
return;
}
messageProcessor.processMessage(msgPayload);
channel.basicAck(envelope.getDeliveryTag(), false);
}
// just print the received message.
Log.info("Received: " + new String(body, StandardCharsets.UTF_8));
}
});
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
#ApplicationScoped
public class MessageProcessorImpl implements MessageProcessor{
#Override
public void processMessage(String messagePayload) {
Log.info("message consumed: " + messagePayload);
}
}
I have created two methods in my BaseViewModel (MVVMLight App) to perform any async code with some logic:
public async Task PerformOperation(Func<Task> action)
{
IsBusy = true;
try
{
await action?.Invoke();
}
catch(Exception ex)
{
// logging is here
}
finally
{
IsBusy = false;
}
}
public async Task PerformOperation(params Operation[] actions)
{
IsBusy = true;
MultipleOperatrions = true;
OperationStatuses = new ObservableCollection<OperationStatus>();
try
{
foreach(var action in actions)
{
var status = new OperationStatus() { StatusText = action.StatusText };
OperationStatuses.Add(status);
try
{
await action?.AsyncAction();
status.Success = true;
}
catch
{
status.Success = false;
}
finally
{
status.IsFinished = true;
}
}
}
catch (Exception ex)
{
// logging is here
}
finally
{
await Task.Delay(1000);
IsBusy = false;
MultipleOperatrions = false;
OperationStatuses = new ObservableCollection<OperationStatus>();
}
}
My models:
public class Operation
{
public Func<Task> AsyncAction { get; private set; }
public string StatusText { get; private set; }
public Operation(Func<Task> action, string statusText)
{
AsyncAction = action;
StatusText = statusText;
}
}
My code of calling the methods in the view model:
...
private IAsyncCommand _buildCommand;
public IAsyncCommand BuildCommand => _buildCommand ?? (_buildCommand = new AsyncCommand(Build));
#endregion
#region Methods
public async Task Build()
{
// IT WORKS
// this method is used for performing only a single operation
// await PerformOperation(async () => { await Task.Delay(3000); });
// IT CRASHES THE APP
// for many tasks
await PerformOperation(new Operation(async () => { await Task.Delay(3000); }, "Preparing..."));
}
...
So, if I call PerformOperation to call just only a single method - it works fine. But it doesn't for the method of performing of several operations - the application just crashes without any exception or messages. I subscribed in App.cs to UnhandledException event to catch it but the app just crashes.
This is my custom middleware class for exception. I want to handle global exceptions.
public class CustomExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public CustomExceptionMiddleware(RequestDelegate next, ILogger<CustomExceptionMiddleware> logger)
{
_logger = logger;
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
try
{
await _next(httpContext);
}catch (Exception e)
{
await HandleExceptionAsync(httpContext, e);
}
}
private Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = HttpStatusCode.InternalServerError;
if(exception is KeyNotFoundException)
{
code = HttpStatusCode.NotFound;
_logger.LogInformation("Exception happend. Exception type: " + exception.GetType().ToString(), new object[0]);
}
else if (exception is UnauthorizedAccessException)
{
code = HttpStatusCode.Unauthorized;
_logger.LogInformation("Exception happend. Exception type: " + exception.GetType().ToString(), new object[0]);
}
else
{
code = HttpStatusCode.BadRequest;
_logger.LogInformation("Exception happend. Bad request ", new object[0]);
}
var result = JsonConvert.SerializeObject(new { error = exception.Message });
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int) code;
//context.ExceptionHandled = true;
return context.Response.WriteAsync(result);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class CustomExceptionMiddlewareExtensions
{
public static IApplicationBuilder UseCustomExceptionMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CustomExceptionMiddleware>();
}
}
I add in my Startup.cs
app.UseCustomExceptionMiddleware();
I don't get logging information that I'm trying to log, and it doesn't throw any exception. What am I missing? Should I throw an exception in a controller class?
I Parse json using volley framework, which every time gets response from the server, does not check the cache, It has taken a whole day, Here is my code. Any of you have used volley for parsing json are expected to help
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Entry entry = cache.get(diag_url);
if(entry != null){
try {
String data = new String(entry.data, "UTF-8");
// handle data, like converting it to xml, json, bitmap etc.,
// Parsing json
JSONArray jsonArray = new JSONArray(data);
for (int i = 0; i < jsonArray.length(); i++) {
try {
DiagRegPojo test = new DiagRegPojo();
JSONObject obj = jsonArray.getJSONObject(i);
String testName = obj.getString("content");
Log.d("Response From Cache", testName);
test.setTitle(testName);
// adding movie to movies array
testList.add(test);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else{
// Creating volley request obj
JsonArrayRequest testReq = new JsonArrayRequest(diag_url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
DiagRegPojo test = new DiagRegPojo();
test.setTitle(obj.getString("content"));
Log.d("Response From Server", obj.getString("content"));
// adding movie to movies array
testList.add(test);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
})
{
//**
// Passing some request headers
//*
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Cookie", MainActivity.sharedpreferences.getString(savedCookie, ""));
headers.put("Set-Cookie", MainActivity.sharedpreferences.getString(savedCookie, ""));
headers.put("Content-Type", "application/x-www-form-urlencoded");
//headers.put("Content-Type","application/json");
headers.put("Accept", "application/x-www-form-urlencoded");
return headers;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(testReq);
}
}
To cache images, I have used this. sure it can be of some help to you.
public ImageLoader getImageLoader() {
getRequestQueue();
if (mImageLoader == null) {
mImageLoader = new ImageLoader(this.mRequestQueue,
new LruBitmapCache());
}
return this.mImageLoader;
}
.
public class LruBitmapCache extends LruCache<String, Bitmap> implements
ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public LruBitmapCache() {
this(getDefaultLruCacheSize());
}
public LruBitmapCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
#Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
#Override
public Bitmap getBitmap(String url) {
return get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
I am trying to post some data to our webservice(written in c#) and get the response. The response is in JSON format.
I am using the Blackberry Code Sample which is BlockingSenderDestination Sample. When I request a page it returns with no problem. But when I send my data to our webservice it does not return anything.
The code part that I added is :
ByteMessage myMsg = bsd.createByteMessage();
//myMsg.setStringPayload("I love my BlackBerry device!");
myMsg.setMessageProperty("querytpe","myspecialkey");//here is my post data
myMsg.setMessageProperty("uname","myusername");
myMsg.setMessageProperty("pass","password");
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
// Send message and wait for response myMsg
response = bsd.sendReceive(myMsg);
What am i doing wrong? And what is the alternatives or more efficients way to do Post with Blackberry.
Regards.
Here is my whole code:
class BlockingSenderSample extends MainScreen implements FieldChangeListener {
ButtonField _btnBlock = new ButtonField(Field.FIELD_HCENTER);
private static UiApplication _app = UiApplication.getUiApplication();
private String _result;
public BlockingSenderSample()
{
_btnBlock.setChangeListener(this);
_btnBlock.setLabel("Fetch page");
add(_btnBlock);
}
public void fieldChanged(Field button, int unused)
{
if(button == _btnBlock)
{
Thread t = new Thread(new Runnable()
{
public void run()
{
Message response = null;
String uriStr = "http://192.168.1.250/mobileServiceOrjinal.aspx"; //our webservice address
//String uriStr = "http://www.blackberry.com";
BlockingSenderDestination bsd = null;
try
{
bsd = (BlockingSenderDestination)
DestinationFactory.getSenderDestination
("name", URI.create(uriStr));//name for context is name. is it true?
if(bsd == null)
{
bsd =
DestinationFactory.createBlockingSenderDestination
(new Context("ender"),
URI.create(uriStr)
);
}
//Dialog.inform( "1" );
ByteMessage myMsg = bsd.createByteMessage();
//myMsg.setStringPayload("I love my BlackBerry device!");
myMsg.setMessageProperty("querytpe","myspecialkey");//here is my post data
myMsg.setMessageProperty("uname","myusername");
myMsg.setMessageProperty("pass","password");
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
// Send message and wait for response myMsg
response = bsd.sendReceive(myMsg);
if(response != null)
{
BSDResponse(response);
}
}
catch(Exception e)
{
//Dialog.inform( "ex" );
// process the error
}
finally
{
if(bsd != null)
{
bsd.release();
}
}
}
});
t.start();
}
}
private void BSDResponse(Message msg)
{
if (msg instanceof ByteMessage)
{
ByteMessage reply = (ByteMessage) msg;
_result = (String) reply.getStringPayload();
} else if(msg instanceof StreamMessage)
{
StreamMessage reply = (StreamMessage) msg;
InputStream is = reply.getStreamPayload();
byte[] data = null;
try {
data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
} catch (IOException e) {
// process the error
}
if(data != null)
{
_result = new String(data);
}
}
_app.invokeLater(new Runnable() {
public void run() {
_app.pushScreen(new HTTPOutputScreen(_result));
}
});
}
}
..
class HTTPOutputScreen extends MainScreen
{
RichTextField _rtfOutput = new RichTextField();
public HTTPOutputScreen(String message)
{
_rtfOutput.setText("Retrieving data. Please wait...");
add(_rtfOutput);
showContents(message);
}
// After the data has been retrieved, display it
public void showContents(final String result)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
_rtfOutput.setText(result);
}
});
}
}
HttpMessage does not extend ByteMessage so when you do:
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
it throws a ClassCastException. Here's a rough outline of what I would do instead. Note that this is just example code, I'm ignoring exceptions and such.
//Note: the URL will need to be appended with appropriate connection settings
HttpConnection httpConn = (HttpConnection) Connector.open(url);
httpConn.setRequestMethod(HttpConnection.POST);
OutputStream out = httpConn.openOutputStream();
out.write(<YOUR DATA HERE>);
out.flush();
out.close();
InputStream in = httpConn.openInputStream();
//Read in the input stream if you want to get the response from the server
if(httpConn.getResponseCode() != HttpConnection.OK)
{
//Do error handling here.
}