Java Is it possible to send a httpServletRequest to a function? - java

i got a function that looks like this:
#GET
#Path("/execute/{scriptId}")
public String execute(#Context HttpServletRequest req, #PathParam("scriptId") Long scriptId) {
/* ... */
engine.eval(getSrc(req.getServletContext().getRealPath("js/boot.js")));
if (scriptId == 1L)
engine.eval(getSrc(req.getServletContext().getRealPath("js/test.js")));
else
engine.eval(getSrc(req.getServletContext().getRealPath("js/test2.js")));
/* that above, its the only place i need the req */
}
i call it from a html page...
execute 1
and it works fine...
now...i made a timer....and in the timer i need to call that function, but i have no idea how to get the httpservletrequest parameter for the function...
here is the code:
#Timeout
public void execute(Timer timer) {
Long scriptId = Long.parseLong(timer.getInfo().toString());
execute(/*here i need something*/, scriptId);
System.out.println("Timer Service : " + scriptId);
System.out.println("Current Time : " + new Date());
System.out.println("Next Timeout : " + timer.getNextTimeout());
System.out.println("Time Remaining : " + timer.getTimeRemaining());
System.out.println("____________________________________________");
}
so, basically, i need to call that function with the timer...
any ideas?

If your function doesn't need the HttpServletRequest (i.e. it doesn't need to call methods on the HttpServletRequest) then you can extract your existing code into an implementation method that does not depend on an HttpServletRequest and in your execute method call that implementation:
#GET
#Path("/execute/{scriptId}")
public String execute(#Context HttpServletRequest req, #PathParam("scriptId") Long scriptId) {
return executeImpl(scriptId);
}
public String executeImpl(Long scriptId) {
...// your current implementation
}
And then your timer can also call that method:
#Timeout
public void execute(Timer timer) {
Long scriptId = Long.parseLong(timer.getInfo().toString());
executeImpl(scriptId);
System.out.println("Timer Service : " + scriptId);
System.out.println("Current Time : " + new Date());
System.out.println("Next Timeout : " + timer.getNextTimeout());
System.out.println("Time Remaining : " + timer.getTimeRemaining());
System.out.println("____________________________________________");
}

Sure, it's just an interface which you can implement.
Of course implementing it to do something useful may not be trivial, depending on what you're doing with the request in the other method.
Getting a ready implementation of an HttpServletRequest from some 3rd party library that implements the JEE standard might help, but may well be overkill.

Related

state processing function not working as expected

I'm working on state processing function where im keying on an ID and would like to hold a state for like 60 secs.
DataStream<String> keyedStream = stream.keyBy(Events::getAnonymousId)
.process(new KeyedProcessingWithCallBack(Long.parseLong(parameters.get("ttl"))))
.uid("keyed-processing");
keyedStream.sinkTo(sink(parameters))
.uid("kafka-sink");
public class KeyedProcessingWithCallBack extends KeyedProcessFunction<String, Events, String> {
ValueState<Boolean> anonymousIdHasBeenSeen;
private final long stateTtl;
public KeyedProcessingWithCallBack(long stateTtl) {
this.stateTtl = stateTtl;
}
#Override
public void open(Configuration parameters) throws Exception {
ValueStateDescriptor<Boolean> desc = new ValueStateDescriptor<>("anonymousIdHasBeenSeen", Types.BOOLEAN);
// defines the time the state has to be stored in the state backend before it is auto cleared
anonymousIdHasBeenSeen = getRuntimeContext().getState(desc);
}
#Override
public void processElement(EngagerEvents value, KeyedProcessFunction<String, Events, String>.Context ctx, Collector<String> out) throws Exception {
if (anonymousIdHasBeenSeen.value() == null) {
System.out.println("Value is NULL : " +value.getAnonymousId());
// key is not available in the state
anonymousIdHasBeenSeen.update(true);
System.out.println("TIMER START TIME: " +ctx.timestamp());
ctx.timerService().registerProcessingTimeTimer(ctx.timestamp() + (stateTtl * 1000));
out.collect(value.getEventString());
}
}
#Override
public void onTimer(long timestamp, OnTimerContext ctx, Collector<String> out)
throws Exception {
// triggers after ttl has passed
System.out.println("Call back triggered : time : " +timestamp + " value : " +anonymousIdHasBeenSeen.value());
if (anonymousIdHasBeenSeen.value()) {
anonymousIdHasBeenSeen.clear();
}
}
I have registered a timer to clear value from state. however as per my logs it is triggering correctly. but my process element is accepting the value for the same key before even it is cleared in the call back.
Expect data in the output topic are separated by a minute gap, but is not.
Can someone point out the mistake in my implementation here. I'm spanning multiple threads to pump request at the same time.

How can I start and stop a timer in different classes?

I want to measure the time from the start of an incoming HTTP request and the application getting to a certain point. Both those points in time are located in different classes. How would I start and stop a timer from these different classes. I don't see a way to use 'named' timers from the MeterRegistry.
How would I go about this?
You can use AOP as below :
#Aspect
#Component
public class ControllerMonitor {
protected static final Logger LOGGER = LoggerFactory.getLogger(ControllerMonitor.class);
#Before("execution(public * com.demo.controller.*Controller.*(..))")
public void logBeforeAccess(JoinPoint joinPoint) {
if(joinPoint!=null){
String packageName = joinPoint.getSignature()!=null?joinPoint.getSignature().getDeclaringTypeName():"LOG-404";
LOGGER.info(". . .A request initiated from controller [" + packageName + "."+ getMethodSignature(joinPoint) + "]. . .");
}
}
#After("execution(public * com.demo.controller.*Controller.*(..))")
public void logAfterAccess(JoinPoint joinPoint) {
if(joinPoint!=null){
String packageName = joinPoint.getSignature()!=null?joinPoint.getSignature().getDeclaringTypeName():"LOG-404";
LOGGER.info(". . .Request from controller [" + packageName + "."+ getMethodSignature(joinPoint) + "] completed. . .");
}
}
#AfterThrowing(pointcut = "execution(public * com.demo.controller.*Controller.*(..))",throwing="exception")
public void logAfterThrowing(Exception exception){
LOGGER.error("Exception caught:"+ exception.getMessage());
}
private String getMethodSignature(JoinPoint joinPoint){
if(joinPoint!=null){
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
StringBuilder sb=new StringBuilder();
if(arguments!=null){
for (Object param: arguments) {
sb.append(param).append(",");
}
sb =(sb.length()>1)?sb.deleteCharAt(sb.length()-1):sb;
}
methodName = methodName+"("+new String(sb)+")";
return methodName;
}else{
return "LOG-405";
}
}
}
Use AOP …...No need to do changes on each class level. It will be one place config..

How to trace a Method in a spring aop?

I want to log a message in the format MethodName invoked at date-time in the console whenever the method successfully completes.
I have defined a custom performance intwerceptor by extending the AbstarctMonitoringInterceptor. Then I am confused what to do next? I mean how to include it in xml or in my aspect class, so that it executes?
Here is my code:
public class MyPerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {
public MyPerformanceMonitorInterceptor() {
}
public MyPerformanceMonitorInterceptor(boolean useDynamicLogger) {
setUseDynamicLogger(useDynamicLogger);
}
#Override
protected Object invokeUnderTrace(MethodInvocation mi, Log log) throws Throwable {
// TODO Auto-generated method stub
String name = createInvocationTraceName(mi);
long start = System.currentTimeMillis();
log.info("Method " + name + " execution started at:" + new Date());
try {
return mi.proceed();
}
finally {
long end = System.currentTimeMillis();
long time = end - start;
log.info("Method "+name+" execution lasted:"+time+" ms");
log.info("Method "+name+" execution ended at:"+new Date());
}
}
Logging is my aspect class. How to add this custom to my aspect class and get the invocation time?

Get input value to ejb 3.1 throw interceptor

Do you know if there is any way to log, throw an interceptor, the input values of the called method?
my actual interceptor is
public class Interceptor {
#AroundInvoke
public Object interceptor(InvocationContext invocationcontext) throws Exception{
//Stampa prima del metodo
long startTime = System.currentTimeMillis();
log.debug("Invoked method: "+invocationcontext.getMethod().getName());
//here I would like to log also parameters.
try{
return invocationcontext.proceed();
} finally{
log.debug("End of method: " + invocationcontext.getMethod().getName());
log.debug(" duration: " + (System.currentTimeMillis() - startTime));
}
}
}
The bean is
#Interceptors({Interceptor.class})
#Stateless
public class MrBean implements MrBeanRemote, MrBeanLocal {
/**
* Default constructor.
*/
public MrBean() {
}
public void print(String in){
System.out.println("Print: " + in);
}
}
So if i call the print method with in = "print that" the interceptor should log "print that". Is it possible?
Thanks in advance
You want to log the parameters of your method, so you can use the getParameters() method on the InvocationContext :
http://docs.oracle.com/javaee/6/api/javax/interceptor/InvocationContext.html#getParameters()

Hystrix async methods within javanica not running inside spring-boot java application

I am using spring-cloud-starter (ie.. spring boot with all the microservices features). When I create hystrix method in a component annotated using the javanica #HystrixCommand, follow the directions on the javanica github site (https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica) to make that method run async, regardless of whether I use their 'Future<>' or Reactive execution 'Observable<>', nothing runs/executes and I get
java.lang.ClassCastException: springbootdemo.EricComponent$1 cannot be cast to springbootdemo.Eric whenever I attempt to pull the result (in the case of Future<>) or get a callback (in case of Reactive Execution .. and println's dont trigger so it really didnt run).
public class Application { ...
}
#RestController
#RequestMapping(value = "/makebunchofcalls/{num}")
class EricController { ..
#RequestMapping(method={RequestMethod.POST})
ArrayList<Eric> doCalls(#PathVariable Integer num) throws IOException {
ArrayList<Eric> ale = new ArrayList<Eric>(num);
for (int i =0; i<num; i++) {
rx.Observable<Eric> oe = this.ericComponent.doRestTemplateCallAsync(i);
oe.subscribe(new Action1<Eric>() {
#Override
public void call(Eric e) { // AT RUNTIME, ClassCastException
ale.add(e);
}
});
}
return ale;
}
#Component
class EricComponent { ...
// async version =========== using reactive execution via rx library from netflix ==============
#HystrixCommand(fallbackMethod = "defaultRestTemplateCallAsync", commandKey = "dogeAsync")
public rx.Observable<Eric> doRestTemplateCallAsync(int callNum) {
return new ObservableResult<Eric>() {
#Override
public Eric invoke() { // NEVER CALLED
try {
ResponseEntity<String> result = restTemplate.getForEntity("http://doges/doges/24232/photos", String.class); // actually make a call
System.out.println("*************** call successfull: " + new Integer(callNum).toString() + " *************");
} catch (Exception ex) {
System.out.println("=============== call " + new Integer(callNum).toString() + " not successfull: " + ex.getMessage() + " =============");
}
return new Eric(new Integer(callNum).toString(), "ok");
}
};
}
public rx.Observable<Eric> defaultRestTemplateCallAsync(int callNum) {
return new ObservableResult<Eric>() {
#Override
public Eric invoke() {
System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum).toString() + "!!!!!!!!!!!!!");
return new Eric(new Integer(callNum).toString(), "bomb");
}
};
}
}
Why would I be getting back an EricComponent$1 instead of a Eric? btw, Eric is just a simple class with 2 strings... its ommitted.
I am figuring that I must have to explicitly execute, but that alludes me because: 1) Doing it with Future<> the queue() method is not available as the documentation claims and 2) doing it with Observable<> there really isn't a way to execute it that I get.
Do you have the #EnableHystrix annotation on you application class?
The subscribe method is asynchronous and you are trying to populate a list in a synchronous controller method so there may be a problem there. Can you change the subscribe to toBlockingObservable().forEach() and see if that helps?
Update #1
I was able to duplicate. Your default method should not return an Observable<Eric>, just an Eric.
public Eric defaultRestTemplateCallAsync(final int callNum) {
System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum) + "!!!!!!!!!!!!!");
return new Eric(new Integer(callNum).toString(), "bomb");
}
Update #2
See my code here https://github.com/spencergibb/communityanswers/tree/so26372319
Update #3
When I commented out the fallbackMethod attribute, it complained that it couldn't find a public version of EricComponent for AOP. I made EricComponent public static and it worked. A top level class in its own file would work to. My code, linked above, works (assuming the restTemplate call works) and returns n OK.

Categories

Resources