How to Junit test servlet filter which has specific response - testing

What is the best way to unit test this code? I need to establish a consistent check for httpResponse which sendError() when condition is true. Thanks in advance!
Edit: Unfortunately, this filter is not with Spring MVC so my choice is limited.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterchain) throws IOException, ServletException {
String ipAddress = request.getRemoteAddr();
if( SomeParameterCheckingFunction ((request)) ) {
logger.error("Error detected! Time: " + new Date().toString() + ", Originating IP: " + ipAddress);
if (response instanceof HttpServletResponse){
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN,"You are not allowed to access the server!");
}
}
filterchain.doFilter(request, response);
}

For example when using the Mockito mock framework, the provided doFilter() method could be JUnit tested using below test case:
#Test
public void testDoFilter() throws IOException, ServletException {
// create the objects to be mocked
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
FilterChain filterChain = mock(FilterChain.class);
// mock the getRemoteAddr() response
when(httpServletRequest.getRemoteAddr()).thenReturn("198.252.206.16");
AccessFilter accessFilter = new AccessFilter();
accessFilter.doFilter(httpServletRequest, httpServletResponse,
filterChain);
// verify if a sendError() was performed with the expected values
verify(httpServletResponse).sendError(HttpServletResponse.SC_FORBIDDEN,
"You are not allowed to access the server!");
}

One option might be to pull the definition of SomeParameterCheckingFunction out of the filter itself (and consume it in the filter). Then, you could separately unit test that logic. But, I'm not sure this will be sufficient for you.
Another option might be to test the filter class using Mockito. This would involve some labor, mocking the request, response, filterchain, logging, and such. You should be able to verify the response.sendError() call afterwards something like so (assumes static import of Mockito.* methods):
//setup mock with concrete class for instanceof check
ServletResponse resp = mock(HttpServletResponse.class);
//define behavior for desired method with void return type. this appears optional for mocks.
//doNothing().when(resp).sendError(anyInt(), anyString());
//your test here, passing in resp
if(resp instanceof HttpServletResponse) resp.sendError(400, "blah");
//verify method was called
verify(resp).sendError(400, "blah");
There may or may not be a way to test your filter with HttpUnit, but that might not meet your desire for a proper unit test.

Updated Feb 2018: OpenBrace Limited has closed down, and its ObMimic product is no longer supported.
Here's an example of how you could test the "sendError" using my ObMimic library of out-of-container test-doubles for the Servlet API.
First, some notes on the given doFilter code:
"((request))" is presumably meant to just be "(request)".
The nature of "logger" isn't shown, so I've ignored that for now as irrelevant.
The filter as given will check non-HTTP requests but if they're rejected the usual log message is written but then sendError is skipped and the normal processing carried out instead. Depending on what you're trying to do, you might want to reject non-HTTP requests up-front, or not check them at all, or do some other type of rejection in place of "sendError". For now I'm assuming we're only interested in how to test "sendError" on HTTP requests.
The example test below has shown that even when sendError is called the processing still drops through to the normal "doFilter" call. Assuming this isn't intentional, the "sendError" should be followed by a "return", or "doFilter" should be in an "else" clause.
For the example code below:
I've used JUnit as the test framework, but it could just as well be TestNG or anything else.
For "SomeParameterCheckingFunction", I've just used one that returns true if the remote IP address is "1.1.1.1".
"sendError" produces an HTML response that displays the given message. For this example I just check that the response body contains the given message. If you instead wanted to check what parameter values were passed to "sendError", the "Professional Edition" of ObMimic has a "history" feature that would let you do that. Or you could do a "sendError" on a separate response instance and then check that the response bodies match exactly.
Anyway, here's the example code:
package com.openbrace.experiments.examplecode.stackoverflow13365536;
import static org.junit.Assert.*;
import com.openbrace.experiments.examplecode.stackoverflow13365536.YourFilter;
import com.openbrace.obmimic.mimic.servlet.FilterChainMimic;
import com.openbrace.obmimic.mimic.servlet.FilterConfigMimic;
import com.openbrace.obmimic.mimic.servlet.ServletMimic;
import com.openbrace.obmimic.mimic.servlet.http.HttpServletRequestMimic;
import com.openbrace.obmimic.mimic.servlet.http.HttpServletResponseMimic;
import com.openbrace.obmimic.support.servlet.EndPoint;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Example tests for {#link YourFilter#doFilter(ServletRequest, ServletResponse,
* FilterChain)}.
*
* #author Mike Kaufman, OpenBrace Limited
*/
public class YourFilterTest {
/** The filter to be tested by this instance's test. */
private YourFilter filter;
/** The "mimic" request to be used in this instance's test. */
private HttpServletRequestMimic request;
/** The "mimic" response to be used in this instance's test. */
private HttpServletResponseMimic response;
/** The filter chain to be used in this instance's test. */
private FilterChainMimic filterChain;
/**
* Set up for this instance's test by creating an initialized filter and a
* request, response and filter chain for use in the test.
*
* #throws ServletException if the filter's init method throws such an
* exception.
*/
#Before
public void setUp() throws ServletException {
/*
* Note that for this example's simple filter and tests:
* - We don't need anything particular in the filter's FilterConfig.
* - We don't need any particular ServletContext, so we can leave
* ObMimic to use its default ServletContext throughout.
* - We don't need to retain any references to the filter's FilterConfig
* or ServletContext.
* - We can use a FilterChainMimic with default values as the filter
* chain. This has a ServletMimic as the next thing in the chain, and
* ServletMimic keeps a count of the calls to its service method, so
* we can use this to check whether the filter chain's doFilter has
* been invoked.
*/
filter = new YourFilter();
filter.init(new FilterConfigMimic());
request = new HttpServletRequestMimic();
response = new HttpServletResponseMimic();
filterChain = new FilterChainMimic();
}
/**
* Test the doFilter method with an example request for which
* SomeParameterCheckingFunction returns true (so that the FORBIDDEN
* response should result).
*
* #throws ServletException if the servlet throws such an exception.
* #throws IOException if the servlet throws such an exception.
*/
#Test
public void testYourFilterWithForbiddenRequest()
throws ServletException, IOException {
// Configure the request so that SomeParameterCheckingFunction will
// return true, which for purposes of this example is triggered by a
// particular "remote address".
request.getMimicState().setRemoteEndPoint(
new EndPoint(null, "1.1.1.1", null));
// Invoke the doFilter method.
filter.doFilter(request, response, filterChain);
// Check that the response is now FORBIDDEN, and that its HTML content
// does include the expected text message.
int responseCode = response.getMimicState().getHttpStatusCode();
String responseBody = response.getMimicState().getBodyContentAsString();
String expectedMessage = "You are not allowed to access the server!";
assertEquals("Response has incorrect status code",
HttpServletResponse.SC_FORBIDDEN, responseCode);
Assert.assertThat("FORBIDDEN response does not include expected message",
responseBody, CoreMatchers.containsString(expectedMessage));
// Check that the filter chain was not invoked. As we've used a
// FilterChainMimic with default values, its "target" is a ServletMimic,
// so we can just check if there have been any calls to that Servlet.
ServletMimic targetServlet
= (ServletMimic) filterChain.getMimicState().getTarget();
boolean filterChainInvoked
= targetServlet.getMimicState().getServiceCount() > 0;
assertFalse("FORBIDDEN response but filterChain.doFilter still called",
filterChainInvoked);
}
}
If you want to try it, there are full details of ObMimic and a free download at the ObMimic website.

Related

Project Reactor TcpServer -> Process incoming chunked message in its entirety

I have a TcpServer created with Project Reactor, where I want to read in a large String (potentially XML) on the inbound channel, and perform some work on it, and send this back out on the outbound channel.
For me to do the work, I need to have the incoming data in its entirety, without it being chunked. I cannot seem to handle correctly aggregating the data together. Most of the examples in the reactor test code base are just outputting a simple String constant, or a non chunked version of the inbound eg:
https://github.com/reactor/reactor-netty/blob/main/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpServerTests.java#L444
I have tried to String::concat the incoming data like so
inbound.receive().asString().reduce(String::concat)
But the subsequent flatmap never seems to be called.
Perhaps there is something with adding a channelHandler, but I was unable to find something that would aggregate, similar to the JsonObjectDecoder
for example:
TcpServer.create().doOnConnection(conn -> connection.addHandlerLast(new AggregatingStringDecoder))`
import reactor.netty.DisposableServer;
import reactor.netty.tcp.TcpServer;
public class Application {
public static void main(String[] args) {
DisposableServer server =
TcpServer.create()
//inbound.connection.addHandlerLast() Is there a combiner I can use here?
.handle((inbound, outbound) -> {
//Tried to concat here, but then the flatMap is never called.
//return inbound.receive().asString().reduce(String::concat)
return inbound.receive().asString().flatMap(s -> {
//this is chunked, but I need the S to be the complete string.
NettyOutbound out = outbound.sendString(Mono.just(s.toUpperCase()));
return out
})
.bindNow();
server.onDispose()
.block();
}
}

Mono.zip request fails when subscribed

I have the following piece of code, where externalgetcall is a GET request to a external service asking for some data
myservice.externalgetcall(id).blockOptional();
this code works, but if i get rid of the blockOptional and write the following, externalgetcall fails with a java.lang.NullPointerException:
java.lang.NullPointerException: null
at org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository.saveAuthorizedClient(HttpSessionOAuth2AuthorizedClientRepository.java:63) ~[spring-security-oauth2-client-5.7.2.jar:5.7.2]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ? Request to GET
myservice.externalgetcall(id).subscribe();
moreover, if I do this, the blocking one right before the non blocking one, it works, so it clearly has to do with Oauth not completing somehow if the call is non blocking:
myservice.externalgetcall(id).blockOptional();
myservice.externalgetcall(id).subscribe();
externalgetcall(id)
public Mono<MyClass> externalgetcall(String id) {
logger.debug("getting contact: {}", id);
return this.webClient
.get()
.uri(externaluri)
.retrieve()
.bodyToMono(MyClass.class)
.doOnNext(myClass -> logger.debug("success {}", myClass))
.doOnError(throwable -> logger.error("error : ", throwable))
}
it fails at this point:
it looks like it happens when trying to run the setAttribute method,when debugging i can see this:
this = {FluxSubscribeOnCallable$CallableSubscribeOnSubscription#13199} size = 1
Unable to evaluate the expression Method threw 'java.lang.UnsupportedOperationException' exception.
public final class HttpSessionOAuth2AuthorizedClientRepository implements OAuth2AuthorizedClientRepository {
private static final String DEFAULT_AUTHORIZED_CLIENTS_ATTR_NAME = HttpSessionOAuth2AuthorizedClientRepository.class.getName() + ".AUTHORIZED_CLIENTS";
private final String sessionAttributeName;
public HttpSessionOAuth2AuthorizedClientRepository() {
this.sessionAttributeName = DEFAULT_AUTHORIZED_CLIENTS_ATTR_NAME;
}
public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal, HttpServletRequest request, HttpServletResponse response) {
if (this.isPrincipalAuthenticated(principal)) {
this.authorizedClientService.saveAuthorizedClient(authorizedClient, principal);
} else {
this.anonymousAuthorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, request, response);
}
}
public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal, HttpServletRequest request, HttpServletResponse response) {
Assert.notNull(authorizedClient, "authorizedClient cannot be null");
Assert.notNull(request, "request cannot be null");
Assert.notNull(response, "response cannot be null");
Map<String, OAuth2AuthorizedClient> authorizedClients = this.getAuthorizedClients(request);
authorizedClients.put(authorizedClient.getClientRegistration().getRegistrationId(), authorizedClient);
request.getSession().setAttribute(this.sessionAttributeName, authorizedClients);
}
This is not much context to come to a rock-solid explanation, but the NPE leads me to believe that this is a case of race condition.
Something to consider is the fact that you are replacing a blocking terminal operation with an asynchronous terminal operation on the publisher. blockOptional and subscribe both initiate a subscription, but in the latter case, execution will not wait at that point for the publisher's onComplete signal.
Again, hard to tell without the complete code, but my guess is that whatever code comes after this snippet is using some data that is populated or hydrated as a result of this publisher. Using blockOptional ensures that the publisher completes before this happens, while subscribe does not.

Can someone explain to me what's the proper usage of gRPC StreamObserver.onError?

I am trying to handle gRPC errors properly (Java, Spring-boot app).
Basically, I need too transfer error details from gRPC server to client, but I find it hard to understand the proper usage of StreamObserver.onError();
The method doc says:
"Receives a terminating error from the stream. May only be called once
and if called it must be the last method called. In particular if an
exception is thrown by an implementation of onError no further calls
to any method are allowed."
What does this "no further calls are allowed" mean? In the app that I maintain, they call other gRPC methods and they get java.lang.IllegalStateException: call already closed which is just fine, as per documentation.
I am wondering - should I (the developer) terminate the current java method (which usus gRPC calls) after an error is received? Like for example throwing an exception to stop execution. Or it is expected tht gRPC is going to terminate the execution.. (something like throwing an exception from gRPC)
Basically how do I properly use onError() and what should I expect and handle if I call it?
I need an explanation of its usage and effects.
There are two StreamObserver instances involved. One is for the inbound direction, which is the StreamObserver instance you implement and pass to the gRPC library. This is the StreamObserver containing your logic for how to handle responses. The other is for the outbound direction, which is the StreamObserver instance that gRPC library returns to you when calling the RPC method. This is the StreamObserver that you use to send requests. Most of the time, these two StreamObservers are interacting with each other (e.g., in a fully duplexed streaming call, the response StreamObserver usually calls the request StreamObserver's onNext() method, this is how you achieve ping-pong behavior).
"no further calls are allowed" means you should not call any more onNext(), onComplete() and/or onError() on the outbound direction StreamObserver when the inbound StreamObserver's onError() method is invoked, even if your implementation for the inbound onError() throws an exception. Since the inbound StreamObserver is invoked asynchronously, it has nothing to do with your method that encloses the StreamObserver's implementation.
For example:
public class HelloWorld {
private final HelloWorldStub stub;
private StreamObserver<HelloRequest> requestObserver;
...
private void sendRequest(String message) {
requestObserver.onNext(HelloRequest.newBuilder.setMessage(message).build());
}
public void start() {
stub.helloWorld(new StreamObserver<HelloResponse> {
#Override
public void onNext(HelloResponse response) {
sendRequest("hello from client");
// Optionally you can call onCompleted() or onError() on
// the requestObserver to terminate the call.
}
#Override
public void onCompleted() {
// You should not call any method on requestObserver.
}
#Override
public void onError(Throwable error) {
// You should not call any method on requestObserver.
}
});
}
}
It has nothing to do with the start() method.
The doc is also mentioning that you should not do things like
try {
requestObserver.onCompleted();
} catch(RuntimeException e) {
requestObserver.onError();
}
It's mostly for user's own StreamObserver implementations. StreamObserver's returned by gRPC never throws.
I've extracted a template for GRPC streaming which sort of abstracts away a lot of the GRPC boilerplate that also addresses the the logic for onError. In the DechunkingStreamObserver
I use the following general pattern for GRPC streaming which is something along the lines of
META DATA DATA DATA META DATA DATA DATA
An example of where I would use it would be to take one form and transform it to another form.
message SavedFormMeta {
string id = 1;
}
message SavedFormChunk {
oneof type {
SavedFormMeta meta = 1;
bytes data = 2;
}
}
rpc saveFormDataStream(stream SavedFormChunk) returns (stream SavedFormChunk) {}
I use a flag that would track the inError state to prevent further processing and catch exceptions on the onNext and onComplete both of which I redirect to onError which forwards the error to the server side.
The code below pulls the GRPC semantics and takes lamdas that do the processing.
/**
* Dechunks a GRPC stream from the request and calls the consumer when a complete object is created. This stops
* further processing once an error has occurred.
*
* #param <T> entity type
* #param <R> GRPC chunk message type
* #param <S> GRPC message type for response streams
*/
class DechunkingStreamObserver<T, R, S> implements StreamObserver<R> {
/**
* This function takes the current entity state and the chunk and returns a copy of the combined result. Note the combiner may modify the existing data, but may cause unexpected behaviour.
*/
private final BiFunction<T, R, T> combiner;
/**
* A function that takes in the assembled object and the GRPC response observer.
*/
private final BiConsumer<T, StreamObserver<S>> consumer;
/**
* Predicate that returns true if it is a meta chunk indicating a start of a new object.
*/
private final Predicate<R> metaPredicate;
/**
* this function gets the meta chunk and supplies a new object.
*/
private final Function<R, T> objectSupplier;
/**
* GRPC response observer.
*/
private final StreamObserver<S> responseObserver;
/**
* Currently being processed entity.
*/
private T current = null;
/**
* In error state. Starts {#code false}, but once it is set to {#code true} it stops processing {#link #onNext(Object)}.
*/
private boolean inError = false;
/**
* #param metaPredicate predicate that returns true if it is a meta chunk indicating a start of a new object.
* #param objectSupplier this function gets the meta chunk and supplies a new object
* #param combiner this function takes the current entity state and the chunk and returns a copy of the combined result. Note the combiner may modify the existing data, but may cause unexpected behaviour.
* #param consumer a function that takes in the assembled object and the GRPC response observer.
* #param responseObserver GRPC response observer
*/
DechunkingStreamObserver(
final Predicate<R> metaPredicate,
final Function<R, T> objectSupplier,
final BiFunction<T, R, T> combiner,
final BiConsumer<T, StreamObserver<S>> consumer,
final StreamObserver<S> responseObserver) {
this.metaPredicate = metaPredicate;
this.objectSupplier = objectSupplier;
this.combiner = combiner;
this.consumer = consumer;
this.responseObserver = responseObserver;
}
#Override
public void onCompleted() {
if (inError) {
return;
}
try {
if (current != null) {
consumer.accept(current, responseObserver);
}
responseObserver.onCompleted();
} catch (final Exception e) {
onError(e);
}
}
#Override
public void onError(final Throwable throwable) {
responseObserver.onError(throwable);
inError = true;
}
#Override
public void onNext(final R chunk) {
if (inError) {
return;
}
try {
if (metaPredicate.test(chunk)) {
if (current != null) {
consumer.accept(current, responseObserver);
}
current = objectSupplier.apply(chunk);
} else {
current = combiner.apply(current, chunk);
}
} catch (final Exception e) {
onError(e);
}
}
}
I have 4 lamdas
Predicate<R> metaPredicate which takes in a chunk and returns whether the chunk is meta or not.
Function<R, T> objectSupplier which takes in a meta chunk and creates a new object that is used by your module.
BiFunction<T, R, T> combiner, which takes in a data chunk and the current object and returns a new object that contains the combination.
BiConsumer<T, StreamObserver<S>> consumer which will consume a completed object. It also passes in a stream observer in the case of sending new objects in response.
the only thing you want to do is mark as return after calling the responseObserver.onError(); like below. because there is nothing to do after sending the error.
if(condition){
responseObserver.onError(StatusProto.toStatusException(status));
//this is the required part
return;
}else{
responseObserver.onComplete(DATA);
}

Fitnesse wiki unable to call selenium method correctly

I am trying to write a simple fixture that opens the browser and navigates to www.google.com. When I run the wiki page, it passes with all green, but the browser never opens up (I don't think the method even gets called by the wiki). Can someone take a look at my fixture and wiki to see what I am doing wrong? Many thanks in advance,
Here is the Wiki -
!|SeleniumFitness|
|URL |navigateToSite?|
|http://www.google.com| |
After Running -
!|SeleniumFitnesse| java.lang.NoSuchMethodError: org.openqa.selenium.remote.service.DriverCommandExecutor.<init>(Lorg/openqa/selenium/remote/service/DriverService;Ljava/util/Map;)V
|URL |The instance decisionTable_4.setURL. does not exist|navigateToSite?
|http://www.google.com|!The instance decisionTable_4.navigateToSite. does not exist |
Here is the Fixture -
package FitNesseConcept.fitNesse;
import java.util.Properties;
import org.junit.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeMethod;
//import com.google.common.base.Preconditions.*;
//import com.google.common.collect.Lists;
import fit.ColumnFixture;
public class SeleniumFitnesse extends ColumnFixture {
public static ChromeDriver driver = null;
private String navigateToSite = "";
public String URL = "";
public SeleniumFitnesse() {
Properties props = System.getProperties();
props.setProperty("webdriver.chrome.driver", "/home/ninad/eclipse-workspace/chromedriver");
driver = new ChromeDriver();
}
// SET-GET Methods
public String getURL() {
return URL;
}
public void setURL(String uRL) {
URL = uRL;
}
public String getNavigateToSite() {
return navigateToSite;
}
public void setNavigateToSite(String navigateToSite) {
this.navigateToSite = navigateToSite;
}
// Navigate to URL
public void navigateToSite() throws Throwable {
System.out.println("Navigating to Website");
try {
driver.navigate().to(URL);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
You are getting some good recommendations as comments - but to answer your question directly, for an old-style ColumnFixture, which is what you have written, the method "navigateToSite" is indeed not going to be called.
These styles of fixtures are not often used anymore, Slim is preferred, and your fitnesse instance in its documentation will show you how to use Slim style. However, for a column fixture as you have written, if you want a method to be called it needs to be a "?" following name of the method in the header row.
See basic docs for column fixture:
http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.BasicFitFixtures.ColumnFixture
You are mis-using column fixture, even granted the old style though. Column fixture's pattern is "here is a series of columns that represent inputs, now here is a method call I want to make to get the output and check result". Navigating a website does not often fit that pattern. In old style fitnesse it would probably be approached by an ActionFixture:
http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.BasicFitFixtures.ActionFixture
In the newer Slim style, a good fit for navigation and checking where you are would be a Scenario Table.
http://www.fitnesse.org/FitNesse.UserGuide.WritingAcceptanceTests.SliM.ScenarioTable
In general doing WebDriver / Selenium tests through a wiki is worth extra thought as to whether it's your best medium. Fitnesse is really designed to be a collaborative tool for documenting and verifying business requirements, directly against source code.
Here's an example of how to do with a ColumnFixture, although again ColumnFixture not exactly appropriate:
|url|navigateToUrl?|
|www.google.com| |
java class:
public String url;
public void navigateToUrl() {
}
You could return an "OK" if it navigates alright, or return the title of the page as opposed to void if you wanted.

Check SolrConnection in Java

How can I check the connection of my ApacheSolrServer (HttpSolrServer) with java?
I've already tried:
if(server == null){
But this doesn't work. Can someone help me?
To check the actual connection between your CQ5 box and Solr instance you need to create SolrServer and call ping()
You can use the official SolrJ API, invoke http://lucene.apache.org/solr/4_2_1/solr-solrj/org/apache/solr/client/solrj/SolrServer.html#ping%28%29
/**
* Issues a ping request to check if the server is alive
* #throws IOException If there is a low-level I/O error.
*/
public SolrPingResponse ping() throws SolrServerException, IOException {
return new SolrPing().process( this );
}