Is there any way to force Spring to check EL expressions on app start? - spring

I have endpoints in #RestControllers that look similar to this:
#RestController
#RequestMapping("/rest/x")
public class XApiController
{
// ...
#PostMapping(...)
#PreAuthorize("#apiAuthService.canAccessX(#headers)")
public void saveX(...)
{
// ...
}
}
These endpoints require the developer to make the HttpHeaders object available and name it correctly in the method declaration:
public void saveX(#RequestHeader HttpHeaders headers)
Our problem is that if this last step isn't done, the endpoint only fails at runtime when the endpoint is invoked. This means that issues from large refactors later (say, to change the HttpHeaders argument to HttpServletRequest) aren't easy to identify. Is there any way to tell Spring to validate these expressions are valid on app startup?

I suggest you to create integration tests and then invoke saveX from the test to verify this before you deploy an application.
I would also state my opinion that if you want to have testable code with good quality - try to get rid of SpringEL as soon as possible. In my experience this approach proved as poorly testable, hardly maintainable and also introducing unnecessary complications to your source code.
In modern spring framework there are lots of ways to avoid writing SpringEl.

Spring always validates all beans on start up. But your problem is not within validation your problem is test problem. The process of pre authorization is a runtime job. Spring can not know what to do with this expression spring just checks its syntax over SPEL rules.
You can create tests to check header.
You can increase your IDE inspection level of spring spel to error.
You can simply write a static method to get the headers without a rest parameter.

Related

Spring Batch Step Integration Testing

I'm looking for some general opinions and advice on testing a Spring batch step and step execution.
My basic step reads in from an api, processes into an entity object and then writes to a DB. I have tested the happy path, that the step completes successfully. What I now want to do is test the exception handling when data is missing at the processor stage. I could test the processor class in isolation, but I'd rather test the step as a whole to ensure the process failure is reflected correctly at step/job level.
I've read the spring batch testing guidelines and if I'm honest, I'm slightly lost within it. Is it possible to use StepScopeTestUtils.doInStepScope or updating the StepExecution to test this scenario? Ideally I'd force the reader to return faulty data before the processor kicks in.
Any advice would be greatly appreciated.
The best approach depends on the scope of your test. Reading a little between the lines here, I assume you are using a Spring IT, setting up a Spring context and using the JobLauncherTestUtils to start a job or a step.
I think the easiest way is replace one of your beans with a mock that triggers the error scenario. Using Mockito, this can be done by adding something like this to your test-configuration.
#Bean
public ReaderDataRepository dataApi(){
return mock(ReaderDataRepository.class);
}
This bean then overrides the actual implementation. In the test setup you can then configure this mock very explicitly.
#Autowired
private ReaderDataRepository mockedRepository;
#Before
public void setUp() {
when(mockedRepository.getData()).thenReturn(faultyData())
}
This involves very little manipulation of Spring 'magic' and very explicitly defines the error from within the test.

Difference between #Controller and RouterFunction in Spring 5 WebFlux

There are two ways to expose HTTP endpoints in spring 5 now.
#Controller or #RestController by making the controller's class, e.g.
#RestController
#RequestMapping("persons")
public class PersonController {
#Autowired
private PersonRepo repo;
#GetMapping("/{id}")
public Mono<Person> personById(#PathVariable String id){
retrun repo.findById(id);
}
}
Route in #Configuration class by using RouterFunctions:
#Bean
public RouterFunction<ServerResponse> personRoute(PersonRepo repo) {
return route(GET("/persons/{id}"), req -> Mono.justOrEmpty(req.pathVariable("id"))
.flatMap(repo::getById)
.flatMap(p -> ok().syncBody(p))
.switchIfEmpty(notFound().build()));
}
Is there any performance difference in using anyone approach? Which one should I use when writing my application from scratch.
Programming Paradigm: Imperative vs Functional
In the case with the #Controller or #RestController annotations, we agree with the annotation-based model where we use annotations for mappings (and not only) and as a result side effects (that is not allowed in the functional world) to make our API works. Such side effects could be #Valid annotation that provides inbuilt bean validation for requests' bodies or #RequestMapping with the root path for the whole controller.
On the other hand, with the router functions, we get rid of annotations that consist of any side effects in terms of API implementation and delegate it directly to the functional chain: router -> handler. Those two are perfectly suited for building the basic reactive block: a sequence of events and two protagonists, a publisher and a subscriber to those events.
MVC Legacy: Servlets Stack vs Netty Stack
When we are talking about #Controller I would say that we usually will think in term of synchronous Java world: Servlets, ServletContext, ServletContainerInitializer, DispatcherServlet etc. Even if we will return Mono from a controller to make our application reactive we still will play in terms of Servlet 3.0 specification that supports java.nio.* and running on the same servlets containers such as Jetty or Tomcat. Subsequently, here we will use corresponding design patterns and approaches for building web apps.
RouterFunction on the other hand was inspired by the true reactive approach that originates from the async Java world - Netty and its Channel Model.
Subsequently new set of classes and their APIs for reactive environment emerged: ServerRequest, ServerResponse, WebFilter and others. As for me, they were designed by the Spring team in accordance with the previous years of maintaining the framework and understanding new web systems requirements. The name for those requirements is Reactive Manifesto.
Use Case
Recently my team faced the issue that it is impossible to integrate Swagger with RouterFucntion endpoints. It could upvote for #Controlers, but the Spring team introduced their solution - Spring REST Docs that could be easily connected to reactive WebTestClient. And I use here word 'connected' cause it follows true reactive meaning behind: instead of Swagger with its overloaded configurations and side-effect annotations, you easily could build your API docs in tests without touching your working code at all.
Update 2020: Despite since now Spring Webflux already could be integrated with Swagger subsequently using OpenAPI specification, it still lacks configuration simplicity and transparency that, in my humble opinion, is the consequence of being a part of the archaic MVC approach.
Closure (opinion)
Cause of no performance impact it's likely to hear something similar to 'it is absolutely based on individual preference what to use'. And I agree that it's individual preference indeed among two options: moving forward or moving backwards when you let yourself stay in the same domain for a decade. I think that reactive support for #Controller was done by the Spring team to make it possible for old projects to somehow be in tune with requirements of time and have at least the opportunity for the migration.
If you are going to create a web application from scratch then do not hesitate and use the introduced reactive stack.
Though it's a bit late, but this may be useful for future readers.
By switching to a functional route declaration:
you maintain all routing configuration in one place
you get almost the same flexibility as the usual annotation-based approach in terms of accessing incoming request parameters, path variables, and other important components of the request
you get an ability to avoid the whole Spring Framework infrastructure being run which may decrease the bootstrapping time of the application
Regarding point 3, there are some cases where the whole functionality(IoC, annotation processing, autoconfiguration) of the Spring ecosystem may be redundant, therefore decreasing the overall startup time of the application.
In the era of tiny microservices, Amazon Lambdas, and similar cloud services, it is important to offer functionality that allows developers to create lightweight applications that have almost the same arsenal of framework features. This is why the Spring Framework team decided to incorporate this feature into the WebFlux module.
The new functional web framework allows you to build a web application without starting the whole Spring infrastructure. The main method in that case should be somewhat like the following(note, there is no #SpringBootApplication annotation)
class StandaloneApplication {
public static void main(String[] args) {
HttpHandler httpHandler = RouterFunctions.toHttpHandler(
routes(new BCryptPasswordEncoder(18))
);
ReactorHttpHandlerAdapter reactorHttpHandler = new ReactorHttpHandlerAdapter(httpHandler);
HttpServer.create()
.port(8080)
.handle(reactorHttpHandler)
.bind()
.flatMap(DisposableChannel::onDispose)
.block();
}
static RouterFunction<ServerResponse> routes(PasswordEncoder passwordEncoder ) {
return
route(
POST("/check"),
request -> request
.bodyToMono(PasswordDTO.class)
.map(p -> passwordEncoder
.matches(p.getRaw(), p.getSecured()))
.flatMap(isMatched -> isMatched
? ServerResponse
.ok()
.build()
: ServerResponse
.status(HttpStatus.EXPECTATION_FAILED)
.build()
)
);
}
}

Available paths listing for Spring actions

I have an application which exposes RESTful actions using spring annotations and Spring MVC.
It looks like
#RequestMapping(value = "/example/{someId}",
method = RequestMethod.GET, consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public void isRegisteredToThread(#PathVariable long someId, HttpServletResponse response) {
[something]
}
What I want is an automatically generated listing of all URL's, methods and available parameters - possibly within a WSDL. Is there a plugin or is it somehwere available?
WSDL is not done for rest, it's used for SOAP.
You might use WADL, but I really do not suggest it.
In my project I always use swagger (there is a release for spring). You may find more info here https://github.com/martypitt/swagger-springmvc and here http://blog.zenika.com/index.php?post/2013/07/11/Documenting-a-REST-API-with-Swagger-and-Spring-MVC
Give it a try.
As an alternative, if you don't need something web-based, you may try rest-shell (https://github.com/spring-projects/rest-shell)
You could take a look at the source code of RequestMappingEndpoint provided by the Spring Boot and see how Spring Boot reports the mappings.
Looking through that code one can see that the mappings (both handler and method mappings) can easily be obtained from the applicationContext
(using
applicationContext.getBeansOfType(AbstractUrlHandlerMapping.class)
and
applicationContext.getBeansOfType(AbstractHandlerMethodMapping.class)
respectively). After you have obtained the mapping you can process them anyway you like.
You might want to create a library that could include in all your projects that processes the mapping your organizations desired form

Best way to mock complex soap responses

I have a Java method I want to Unit test, but it requires a mocked SOAP response which contains multiple lists and layers of nodes. I am doing this with a handwritten mock i.e. just manually creating the objects and setting the values, but as the response is quite complex its a pain building up the response. I have a sample XML response is there an easy way of creating the mock using the XML?
Also I looked at Mockito and it looks fine for simple Objects, but it doesnt seem that good for complex responses (I may not be using it to its full potential).
The app stack is Java 1.6, Spring 3 and using JAX-WS.
I do something like this
#WebService
public class MyWebService {
#Autowired
private ServiceBean serviceBean;
public SomeReturedData getData(SomeInputData inputData) {
return serviceBean.getData(inputData);
}
}
For my UnitTest, I have a mock instanciation of "ServiceBean" which I inject in to #MyWebService, and "MyWebService" is deployed using the "in-vm" transport as described here
By Using the in-vm transport, All the XML marshalling/unmarshalling is still done by the web-service framework ,and you only have to deal with Java part.
Now someone might ask, why not test the "ServiceBean" directly, why the need to deply a WS using in-vm transport ? Well 2 things, Using in-vm transport you get to test that the JAXB XML marshalling/unmarshalling is working correctly, and it also allows you to test any intercepting handlers that you might have defined for your webservice.

Spring Design By Contract: where to start?

I am trying to put a "Contract" on a method call. My web application is in Spring 3.
Is writing customs Annotations the right way to go. If so, any pointers( I didn't find anything in spring reference docs).
Should I use tools like "Modern Jass", JML ...? Again any pointers will be useful.
Thanks
Using Spring EL and Spring security could get you most of the way. Spring security defines the #PreAuthorize annotation which is fired before method invocation and allows you to use Spring 3's new expression engine, such as:
#PreAuthorize("#customerId > 0")
public Customer getCustomer(int customerId) { .. }
or far more advanced rules like the following which ensures that the passed user does not have role ADMIN.
#PreAuthorize("#user.role != T(com.company.Role).ADMIN)")
public void saveUser(User user) { .. }
You can also provide default values for your contract with the #Value annotation
public Customer getCustomer(#Value("#{434}") int customerId) { .. }
You can even reference system properties in your value expressions.
Setting up Spring security for this purpose is not to hard as you can just create a UserDetailsService that grants some default role to all users. Alternatively you could make you own custom Spring aspect and then let this use the SpelExpressionParser to check method values.
if you don't mind writing some parts of your Java web application in Groovy (which is possible with Spring) I would suggest using GContracts.
GContracts is a Design by Contract (tm) library entirely written in Java - without any dependencies to other libraries - and has full support for class invariants, pre- and postconditions and inheritance of those assertions.
Contracts for Java which is based on Modern Jass is one way to write contracts.
http://code.google.com/p/cofoja/
As per the writing of this reply, this is pretty basic. Hopefully this will improve as we go on.
I didn't find an ideal solution to this, interestingly it is a planned feature for the Spring framework (2.0 implemented patch):
http://jira.springframework.org/browse/SPR-2698
The best thing I suggest to use JSR 303 which is for bean validation. AFAIK there are two implementations for this:
Agimatec Validations
Hibernate Validator
There's a guide here for integrating it into Spring, I haven't followed it through but it looks ok:
http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/
I personally recommend C4J for 2 reasons:
It has Eclipse plugin so you don't need to manually configure it.
The documentation is written in a clear, structured format so you can easily use it.
Her's the link to C4J

Resources