Aop and Mono argument - spring-aop

I have method
Mono<ReceiptResponse> a01(Mono<DefaultBeneficiaryBankRequest> request)
and aspect
#Around("callAtMyServiceSecurityAnnotation(request)")
#Order(1)
public Object scheduleTimeout(ProceedingJoinPoint joinPoint, Mono<?> request) {
Mono<?> retVal = (Mono)joinPoint.proceed();
return retVal.doOnSuccess(i -> {
...
someMethod(<request.value>)// <-- How I can get requets value here?
...
});
}
How I can get request value as someMethod argument?

The information in your question is incomplete, but to me it seems your pointcut callAtMyServiceSecurityAnnotation(request) already captures the request and forwards it to your advice method as Mono<?> request parameter. So the answer to your question is simple: Just use request in order to get access to the request argument.
You do not show your actual pointcut, but assuming it is something like (untested, writing just freestyle because I do not have a test case from you to try it on)
#Pointcut("within(my.package.MyTargetClass) && execution(* a01(*)) && args(request)")
public void callAtMyServiceSecurityAnnotation(Mono<?> request) {}
it should just work.

Related

How to interrupt JoinPoint execution in AOP

Is it possible to interrupt invoking the actual method from within the aspect execution?
For example:
public class CheckPermissionAspect {
#Around("#annotation(CheckPermission)")
public Object methodLogging( ProceedingJoinPoint joinPoint) throws Throwable {
// before method execution
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
log.info("Enter ==> " + signature.getMethod().getName());
if ( getPermission( principal.getName()) == false ) {
// break the execution of actual method
Object result = null; // ???
log.info("Break ==> " + signature.getMethod().getName());
} else {
// invoke the actual method
Object result = joinPoint.proceed();
// after method execution
log.debug("Result: " + result);
log.info("Leave ==> " + signature.getMethod().getName());
}
return result;
}
}
To set Object result = null; does not work.
Thank you for any help.
From Spring Reference documentation : Around Advice
Within the body of the advice method, you must invoke proceed() on the
ProceedingJoinPoint in order for the underlying method to run
If joinPoint.proceed() is removed from the code or an exception is thrown before joinPoint.proceed() statement or a return is issued before joinPoint.proceed() statement , the execution of the underlying method would get interrupted.
Update : to answer the comment
Spring AOP is proxy based. To understand this concept better , do read through : Understanding AOP proxies
An advice is placed between the calling method and the target. All calls to the target method gets intercepted and advised.
You could throw an exception upon validation ( Do note that the exception type thrown should match the exception type of the target method . Go through this Q&A).
The exception/return value from the advise would reach back the calling method .

I want to obtain response of sub request in nginx module development

I am developing C modules in nginx
I want to issue a sub request and get a response(header,body)
The code I am writing now is as as follows
How can I get a response (heade, body) after executing the ngx_http_subrequest method?
ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
if (ps == NULL) {
return NGX_ERROR;
}
ps->handler = ngx_http_auth_request_done;
ps->data = "foo";
if (ngx_http_subrequest(r, &uri, NULL, &sr, ps, NGX_HTTP_SUBREQUEST_IN_MEMORY) != NGX_OK)
{
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "subrequest is failed!!");
return NGX_ERROR;
}
ngx_http_auth_request_done is the handler you have defined which is the callback that handles the response of the subrequest. You are supposed to implement this function. If you look at it's signature, it has the request structure you have sent out. The request structure's upstream variable contains a buffer where the response is stored. r->upstream->buffer. You can look at nginx's own modules for how to parse the response.

How to call and pass values to rest method with #QueryParam through angular

I am new to rest and I need to call and pass values from angular controller to rest #QueryParam method.
This is my rest code which i need to call and pass values:
#GET
#Path("/")
#Produces(MediaType.APPLICATION_JSON)
public List<DictionaryDetails> getAvailableDictionaries(#QueryParam("name") String name,
#QueryParam("domain") String domain, #QueryParam("businessDomain") String businessDomain, #QueryParam("type") String type) throws ApplicationException {
try {
return availableDictionaries.getAvailableDictionaries(name, domain, businessDomain, type);
}
This is my controller:
$scope.addRule = function(isValid) {
if(isValid) {
//I have to pass the values which i am getting in $scope.ruleModel to rest method
RulesService.addRule($scope.ruleModel);
}
}
Can anyone please help me out in doing this, i have searched on net too, but didn't get any working solution. Thanks in advance

How to extract the web service method name in mule <cxf:proxy-service>

I am working with mule <cxf:proxy-service> and need to extract the web service method name to attach to message for later use.
We've a service proxy class implementing Callable interface. Initially we tried to get operation name like this:
public Object onCall(MuleEventContext eventContext) throws Exception {
try {
MuleMessage inboundMessage = eventContext.getMessage();
Set<String> props = inboundMessage.getInvocationPropertyNames();
System.out.println("CXF invocation properties ==> " + props);
System.out.println("CXF invocation property ==> " + inboundMessage.getInvocationProperty("cxf_operation"));
but the above code gives incorrect operation name. (We've 4 operations in service and it always give the 2nd operation name). Below is the mule flow used for this:
<flow name="proxyService">
<http:inbound-endpoint address="${some.address}"
exchange-pattern="request-response">
<cxf:proxy-service wsdlLocation="classpath:abc.wsdl"
namespace="http://namespace"
service="MyService">
</cxf:proxy-service>
</http:inbound-endpoint>
<component class="com.services.MyServiceProxy" />
So, I resorted to write an inbound cxf interceptor to extract the operation name. I wrote below interceptor which works fine with <cxf:jaxws-service> but not with <cxf:proxy-service> element.
Here is my interceptor:
public class GetCXFOperation extends AbstractPhaseInterceptor<Message> {
public GetCXFOperation() {
super(Phase.PRE_INVOKE);
}
#Override
public void handleMessage(Message message) throws Fault {
Exchange exchange = message.getExchange();
Endpoint ep = exchange.get(Endpoint.class);
OperationInfo op = exchange.get(OperationInfo.class);
if(op != null){
System.out.println("Operation Name: " + op.getName().getLocalPart());
} else{
Object nameProperty = exchange.get("org.apache.cxf.resource.operation.name");
if(nameProperty != null)
System.out.println(nameProperty.toString());
}
}
}
Seeking guidance as to how to extract operation name in <cxf:proxy-service>? Is there an easy mule way of getting correct answer? Or is there a different phase in which I should be invoking my interceptor? What phases work with <cxf:proxy-service>

Return Value for "should cancel"

I have a method DoCleanUp(), which will ask user to proceed and then clear current workspace. It will return if user choose to cancel this process.
My question is, which signature is best to indicate a "cancel"?
bool DoCleanUp(); // return false to indicate canceled.
bool DoCleanUp(); // return true to indicate this method should be canceled.
void DoCleanUp(bool& cancel); // check parameter 'cancel' to see if this method was canceled.
UPDATE: As for the language, it's C++\CLI or C#.
UPDATE2: Now suppose I have to save a file in the DoCleanUp method. I'll prompt a dialog ask user whether to save/not save/cancel the file. Based on the answers, here is what I came up:
void DoCleanUp();
DialogResult AskToSaveFile(); // return yes/no/cancel
void DoCleanUp( bool saveFile );
Usage:
void DoCleanUp()
{
DialogResult result = AskToSaveFile();
if( result == DialogResult::Cancel ) return;
bool saveFile = (result == DialogResult::Yes) ? true : false;
DoCleanUp( saveFile );
}
Then by calling DoCleanUp(), you know user will have the opportunity to cancel;
By calling DoCleanUp(bool saveFile), you can control whether to save file without asking user.
Is that looks better?
This is a classic single responsibility problem.
The reason that you are unsure about the signature is that the method is doing 2 things.
I would create 2 methods:
bool CheckIfTheUserWantsToCancel()
void DoCleanUp()
EDIT
Based on the comments and edits to the question I would create a 3rd method:
void SaveFile()
The DoCleanUp would then first call CheckIfTheUserWantsToCancel, and then if not cancelled would call SaveFile.
IMHO this is much better than trying to remember that DoCleanUp with parameter false will save the file without asking the user, or was it the other way around?
Without more details I would say answer 1 is the best IMHO. Third is rather ugly since it requires more code for calling.
But maybe consider rewriting code to this
void CleanUp() {
switch (AskUser()) {
case ButtonOk: CleanUpDesk(); break;
case ButtonNo: break;
default:
case ButtonCancel: CancelCleanUpDesk(); break;
}
}
This seems to in the spirit of single responsibility. My code somehow breaks your problem into two steps: asking user and performing action.
I would use your 1 version.
bool DoCleanUp(); // return false to indicate canceled.
The assumption is, that it returns true when the cleanup is done. Returning false would indicate a 'Error' state. It might even make sense to return an int. In this case the convention usually is that 0 represents success and everything else is an error code.
Regardless of what you decide, document what your return values mean!
The confusing bit is the calling it DoSomething(), when it might not do anything. How about
if (QueryCleanup()) // boolean
DoCleanup(); // void
More verbose but clearer, even without seeing the declaration.
You should not use a boolean for statuses (or status messages). Create an Enum:
public Enum CleanupStatus
{
Ok = 0,
Cancel
}
This way it is more clear what the return value is ... and if you need to add more statuses, you can.
(This is all from Code Complete 2, you should read it if you haven't yet.)
You have two requests basically. The outer request is to create a new workspace. The inner request is to save the current workspace. You want to return true if the outer request continues and false if the outer request is aborted. The action of the inner request is not important to the outer request and so should be some kind of delegate/functor/closure.
Make a class to genericize this:
class YesNoCancel {
string question; // question to ask the user about the inner state
delegate doit; // function to call to
delegate dontdoit;
public:
YesNoCancel(string question, delegate doit, delegate dontdoit = null) {...}
bool run() {
switch (AskUser(question)) {
case ANSWER_YES: doit(); return true;
case ANSWER_NO: return true;
case ANSWER_CANCEL: if (dontdoit) dontdoit(); return false;
};
//usage
void NewWorkspace() {
if (m_workspace) {
YesNoCancel ync("Save current workspace?", saveworkspace);
if (!ync.run()) return;
}
// new workspace code
}
void CloseApp() {
YesNoCancel ync("Save current workspace?", saveworkspace);
if (ync.run()) ExitApplication();
}
I believe option three gives the most clarity. When you have the bool as a return type it is not immediately clear what it is used for.
I usually go with
bool DoCleanUp(); // Returns true if cancel
but mostly it depends on whether the calling code looks like this:
if (DoCleanUp()) {
// Do cancel up code
}
or:
if (DoCleanUp()) {
// Do non-cancel post clean up code
}
Basically I try to make my tests not have to use a ! or language equivilent as I find it hard to see.
I definitely would not do number 3.
I prefer the third signature, only because by looking at it (without any extra documentation), I can tell more about what the method does. I would call the argument something more explicit, like processCancelled, though.

Resources