Use SpringAOP to intercept send and receive messages - spring-amqp

For some reasons, I have to intercept send and receive messages. (Wrap up the message and parse the message when it is received).
I know MessagePostProcessor is a form of interceptor, but it will influence current code. So, I am considering using Spring AOP.
For sending messages, I can simply intercept RabbitTemplate’s send and convertAndSend methods, Like the following code:
#Around("execution(* org.springframework.amqp.rabbit.core.RabbitTemplate.send(..))")
But for receiving messages, Which method is best to intercept? In most cases, RabbitListener is used to receive messages.
Any help is appreciated.

Add an Advice to the listener container's adviceChain. See https://docs.spring.io/spring-amqp/docs/2.2.10.RELEASE/reference/html/#containerAttributes
EDIT
#Bean
public MethodInterceptor advice() {
return invocation -> {
Message message = (Message) invocation.getArguments()[0];
try {
// before
invocation.proceed();
// after
}
catch (Exception e) {
// ...
throw e;
}
finally {
// ...
}
return null;
};
}

Related

Reading a POST request in Undertow without consuming it

In Undertow I have two handlers, that are chained:
The first handler reads the request and then calls calls the second handler via next.handleRequest(exchange);
The second handler is a proxy handler which send the request to and external server where it is processed.
My problem is the first handler which reads the request. The request headers are no big deal but getting the body data of POST requests is a problem.
Existing solutions as shown in the question How to properly read POST request body in a Handler? consume the request body su that the handler chaining does not work anymore.
How can I read the request body data without consuming it or altering the request in a way that the handler chain does not work afterwards?
I found the problem, in the end it was a missing call to ByteBuffer.flip().
If someone ever needs such an POST data reader one can use the following simplified implementation of an AbstractStreamSourceConduit that is able to read the incoming POST data without consuming it:
exchange.addRequestWrapper(new ConduitWrapper<StreamSourceConduit>() {
#Override
public StreamSourceConduit wrap(ConduitFactory<StreamSourceConduit> factory, HttpServerExchange exchange) {
StreamSourceConduit source = factory.create();
return new AbstractStreamSourceConduit<StreamSourceConduit>(source) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
#Override
public int read(ByteBuffer dst) throws IOException {
int x = super.read(dst);
if (x >= 0) {
ByteBuffer dup = dst.duplicate();
dup.flip();
byte[] data = new byte[x];
dup.get(data);
bout.write(data);
} else {
// end of stream reached
byte[] data = bout.toByteArray();
// ... to something with data
}
return x;
}
};
}
});

How to intercept delete and advise user it is not possible?

I am starting to develop with Breeze.js and ASP MVC+WebApi Controllers. I am concerned about securities, as we should all be concerned about the possibility of a hacker coming into play. Now I did find the BeforeSaveEntity intercept and it does seem to be exactly what I want to use on the server side. I managed to get the security I want on the server side, but how do I deal with it on the client side, in my case with AngularJS, what and how should I catch the output and deal with it? Let me show you some code sample I use on the server side:
public class ConferenceContextProvider : EFContextProvider<ConferenceContext>
{
public ConferenceContextProvider() : base() { }
// Creating the BeforeSaveEntity for Security purposes, see more details at http://www.breezejs.com/documentation/efcontextprovider#SaveInterception
protected override bool BeforeSaveEntity(EntityInfo entityInfo)
{
// return false if we don’t want the entity saved.if (entityInfo.Entity.GetType() == typeof(Role)
&& entityInfo.EntityState == EntityState.Deleted)
{
return false;
}
else
{
return true;
}
}
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
// return a map of those entities we want saved.
return saveMap;
}
}
and then on client side with AngularJS
// AngularJS DataService
function saveChanges() {
if (manager.hasChanges()) {
var promise =
manager.saveChanges()
.catch(queryFailed)
.finally(function (data) {
toastr.success('Save to DB Succeeded');
});
} else {
toastr.warning("Nothing to save");
};
}
How do I catch the result and deal with it? With Firebug I can see that the POST returns a JSON object with Entities array being filled (if user has access) or that same array being empty (if user has access denied). But if multiple changes happen, then the array might be filled with a portion of it applied. So what is the best approach on the client side with an access denied? Can someone give me a proper sample code on how to deal with acces denied? Thanks for your help
Overriding the BeforeSaveEntity method will mean that on the server once the payload it received your server will call the BeforeSaveEntity method once for each entity before the entity is saved. As the docs show if you return false it will simply not save the entity. Take note of the following line -
If the method returns false then the entity will be excluded from the
save. If the method throws an exception, the entire save is aborted
and the exception is returned to the client.
If you throw an HTTP error I think it should propagate properly you should be able to catch that error client side and display it. This is assuming if a payload contains an entity to delete you want to cancel the whole save.
Example -
protected override bool BeforeSaveEntity(EntityInfo entityInfo)
{
// throw http exception if there is an entity flagged for deletion
if (entityInfo.Entity.GetType() == typeof(Role)&& entityInfo.EntityState == EntityState.Deleted)
{
var response = new HttpResponseMessage(HttpStatusCode.BadRequest){ Content = new StringContent("Cannot delete an entity") };
throw new HttpResponseException(response);
}
else
{
return true;
}
}
And on your client-side query where you have a queryFailed method (pseudo code, examine the error that is thrown to construct this properly) -
function queryFailed (error) {
alert('Query failed - ' + error.message);
}
If you want to save all the other entities but this one and then return custom errors in the response you can do that as well but that will take additional customization and that would probably be a much more detailed answer

Neo4j: Exception handling and explict invoking of failure()/close()?

I am trying to handle exceptions in a Neo4j try transaction.
try(Transaction tx = graphDb.beginTx()) {
// more code
tx.sucess();
}
The code I posted is standard, it keeps the transaction in variable tx and upon the end of the try block tx.close() will automatically be called.
Hows does one handle exceptions in this type of block? I know the following works:
Transaction tx = graphDb.beginTx();
try{
// more code
tx.sucess(); // must always be called like so
} catch(Exception e) {
tx.failure(); // as an exception arised, would be best to call this.
} finally {
tx.close(); // is tx.close called automatically, or must I call it like I did here?
}
So really I have two questions, the first sample of code: how does one handle exceptions in that one?
Second sample of code: what must I call explicitly and what is automatically called?
Simply add the exception handling, but omit the finally:
try(Transaction tx = graphDb.beginTx()) {
// more code
tx.sucess();
} catch(Exception e) {
// ..
}

In OpenRasta, how should you handle codec errors or exceptions?

My scenario is this:
A client application executes a HTTP POST against an endpoint exposed by OpenRasta.
The body of the request contains an error that causes a problem in the codec - which is a custom implementation of OpenRasta.Codecs.IMediaTypeReader. This converts a JSON payload to the POCO expected by the handler.
The codec throws an exception that describes the error in a useful way. For example: Newtonsoft.Json.JsonReaderException: After parsing a value an unexpected character was encountered: ". Line 4, position 5.
The client application receives a HTTP 405 - MethodNotAllowed. The client doesn't see any of the exception details.
If the codec is modified to catch a JsonReaderException and return Missing.Value, similar to the Implementing a codec wiki, then the client receives a HTTP 500 - Internal Server Error. The body of the response also describes the following exception:
System.InvalidOperationException: The operation is not ready for invocation.
at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke()
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.<Invoke>b__0()
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke()
at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations)
at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context)
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call)
How should I modify my application so that:
The client receives a HTTP 400 Bad Request.
The client receives a string containing the details of the exception encountered in the codec.
Here is a minor variation of the answer above - this time with codec selection based on the operation result data.
Within IConfigurationSource:
using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Uses.PipelineContributor<ErrorCheckingContributor>();
ResourceSpace.Has.ResourcesOfType<ApplicationError>()
.WithoutUri
.TranscodedBy<ApplicationErrorCodec>();
// Or use a generic JSON serializer like this:
// .AsJsonDataContract();
// Other configuration here
}
Now ErrorCheckingContributor looks like this:
public class ErrorCheckingContributor : IPipelineContributor
{
public void Initialize(IPipeline pipelineRunner)
{
pipelineRunner
.Notify(CheckRequestDecoding)
.After<KnownStages.IOperationResultInvocation>()
.And.Before<KnownStages.ICodecResponseSelection>();
}
private static PipelineContinuation CheckRequestDecoding(ICommunicationContext context)
{
if (context.ServerErrors.Count == 0)
{
return PipelineContinuation.Continue;
}
Error err = context.ServerErrors[0];
// Get a suitable message (err.Message contains stack traces, so try to avoid that)
string msg = err.Title;
if (msg == null && err.Exception != null)
msg = err.Exception.Message;
if (msg == null)
msg = err.Message;
// Create instance of an error information resource which is specific for the application
// - This one is rather simple and only contains a copy of the message
ApplicationError error = new ApplicationError(msg);
// Set operation result to be "400 Bad Request" and remove errors
context.OperationResult = new OperationResult.BadRequest { ResponseResource = error };
context.ServerErrors.Clear();
// Render immediately without starting any handlers
return PipelineContinuation.RenderNow;
}
}
The class ApplicationError is:
public class ApplicationError
{
public string Message { get; set; }
public ApplicationError(string message)
{
Message = message;
}
}
At last we need a codec ApplicationErrorCodec for ApplicationError. This is not different from any other IMediaTypeWriter codec but depends a lot on your expected response media type. See https://github.com/openrasta/openrasta/wiki/Implementing-a-Codec for one example.
Having found this thread on Google Groups which contains all the answers, my current implementation looks something like this.
Within my implementation of IConfigurationSource:
using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Uses.PipelineContributor<ErrorCheckingContributor>();
// Other configuration here
}
Then ErrorCheckingContributor looks something like this:
public class ErrorCheckingContributor : IPipelineContributor
{
public void Initialize(IPipeline pipelineRunner)
{
pipelineRunner
.Notify(CheckRequestDecoding)
.After<KnownStages.IOperationResultInvocation>()
.And.Before<KnownStages.ICodecResponseSelection>();
}
private static PipelineContinuation CheckRequestDecoding(ICommunicationContext context)
{
if (context.ServerErrors.Count == 0)
{
return PipelineContinuation.Continue;
}
var first = context.ServerErrors[0];
if (first.Exception is Newtonsoft.Json.JsonReaderException)
{
context.Response.Entity.ContentType = MediaType.TextPlain;
context.Response.Entity.ContentLength = first.Exception.Message.Length;
using (var sw = new StreamWriter(context.Response.Entity.Stream))
{
sw.Write(first.Exception.Message);
}
}
return PipelineContinuation.Continue;
}
}
There's some things to be aware of with the above:
If a handler were to throw a JsonReaderException, it would also be processed here.
It doesn't check what media types the client accepts. This is different from exceptions thrown by Handlers that do go through codec selection.
Tried setting context.OperationResult to context.ServerErrors - but it doesn't go through the codec.

programmatically block outgoing calls on blackberry

I'm a beginner on this forum and first of all, hello for everyone!
Does anyone know how to block outgoing calls on blackberry or to stop sending SMS?
Can anyone provide me the java tutorials which is helpful to my program part?
Thank you in advance,
Katya
try using this code:
public void callInitiated(int callId) {
final PhoneCall call = Phone.getCall(callId);
final String number = call.getDisplayPhoneNumber();
System.out.println(number);
EventInjector.KeyCodeEvent pressEndKey = new EventInjector.KeyCodeEvent( KeyCodeEvent.KEY_DOWN, (char) Keypad.KEY_END, 0, 100);
EventInjector.KeyCodeEvent releaseEndKey = new EventInjector.KeyCodeEvent( KeyCodeEvent.KEY_UP, (char) Keypad.KEY_END, 0, 100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EventInjector.invokeEvent(pressEndKey);
EventInjector.invokeEvent(releaseEndKey);
}
You can see an example in the following LINK: how to block calls
Regarding sms - unfortunately there is no API to block outgoing sms messages.
There is no direct API available to interrupt/block outgoing call in BlackBerry. But there is a workaround. Use EventInjector class to send EndCall button event upon an active outgoing call.
Intercept outgoing calls via implementing and using PhoneListener interface in your application.
You can block Outgoing message as follows :
1) implemnt SendListner interface in your UiApplication class.
2) write SMS.addSendListener(this);in constructor
3) write implemented method as
public boolean sendMessage(Message message)
{
//You can Put other stuffs here
return false;
}

Resources