I am trying to work with both swagger-codegen and springfox to gain time during webservice development.
I am facing an issue with an endpoint being created for my annotated interface classes as well as my controller implementations as you can see below:
I found a workaround by adding the tag where the controller should be (ex: #Api(tags={ "Player" })) in my controller but I am looking for a better one preventing this because if I am using code generation its to avoid this kind of situation where you have to add stuff in your code.
With swagger-codegen, I just have to write a RestController (PlayerApiImpl) like this:
#RestController
public class PlayerApiImpl implements PlayerApi {
#Override
public ResponseEntity<Player> playerIdGet(String id) {
PlayerDTO ret = service.getOne(Long.parseLong(id));
if (ret == null) {
throw new PlayerNotFoundException();
}
return ResponseEntity.ok(mapper.toModel(ret));
}
}
While everything is generated into an interface (here PlayerApi). So I would like to stay as simple as it is possible.
I decided to push my workaround a bit more and found this solution:
It's actualy possible de add the #Api annotation directly in the generated interface to prevent you to add it in your implementation. For that you need to work with mustache templates files that you can create in the directory where is located your swagger file.
It might not be the best solution, so if you have a better proposolal, feel free to comment.
Related
i have a little kont in my brain about structuring our code. We have a REST Backend based on SpringBoot. To handle requests regarding to security checks we use HandlerInterceptors. In some specific cases we need a specific interceptor and not our default one. The default one is registered in a 3rd party lib that no one can forget it. But i want all coders to think about this specific interceptor.
Actually, i just said it to them to achieve this.
Here's my question: Is there an option to create required (or necessary) interfaces which must be implemented? This would be a way to provide our security code by lib and to have the security that every coder implemented our specific interface (also if he just does nothing with it).
pseudo code:
public interface thinkForIt(){
Object SecBean specificSecBean;
public void methodToThinkOn();
}
public SecImpl implements thinkForIt(){
#Override
public void methodToThinkOn(){
return null; // i thought about it but i do not need to do anyting!
}
If the interface thinkForIt would have any annotations like #required, users could get warning or error if they did not implement it...
Looking for a solution and thanks for your comments in advance!
Your overall design is questionable; you are reinventing security code, which is always a red flag. Use Spring Security instead.
However, there's a simple way to ensure that "some bean of type Foo" has been registered with the context:
#Component
#RequiredArgsConstructor
public class ContextConfigurationVerifier {
final Foo required;
}
I have created a simple controller
#GetMapping("/playerAccount")
public Iterable<PlayerAccount> getPlayerAccounts(com.querydsl.core.types.Predicate predicate) {
return repository.findAll(predicate);
}
When I call the GET /playerAccount API, I get the exception IllegalStateException "No primary or default constructor found for interface com.querydsl.core.types.Predicate" (thrown by org.springframework.web.method.annotation.ModelAttributeMethodProcessor#createAttribute).
After some (deep!) digging, I found out that if I delete the following line in my spring.xml file:
<mvc:annotation-driven />
And if I add the following line in my Spring.java file:
#EnableWebMvc
then the problem disappears.
I really don't understand why. What could be the cause of that ? I thought that these were really equivalent (one being a xml based configuration, the other being java/annotation based).
I read this documentation on combining Java and Xml configuration, but I didn't see anything relevant there.
edit:
from the (few) comments/answers that I got so far, I understand that maybe using a Predicate in my API is not the best choice.
Although I would really like to understand the nature of the bug, I first want to address the initial issue I'm trying to solve:
Let's say I have a MyEntity entity that is composed of 10 different fields (with different names and types). I would like to search on it easily. If I create the following (empty) interface:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, QuerydslPredicateExecutor<MyEntity> {
}
then without any other code (apart from the xml configuration ), I am able to easily search a myEntity entity in the database.
Now I just want to expose that functionality to a Rest endpoint. And ideally, if I add a new field to my MyEntity, I want that API to automatically work with that new field, just like the MyEntityRepository does, without modifying the controller.
I thought this was the purpose of Spring Data and a good approach, but please tell me if there's a better / more common way of creating a search API to a given Entity.
I didn't see that it returned an exception, that's why I thought it was a dependency problem.
Try to make your code look like this, and it will do it.
#RestController
public class MyClass {
#Autowired
private final MyRepository repository;
#GetMapping("/playerAccount")
public Iterable<PlayerAccount> getPlayerAccounts() {
return repository.findAll();
}
If you have a parameter in your request you add #RequestParam.
Code time (yaaaaaay) :
#RestController
public class MyClass {
#Autowired
private final MyRepository repository;
#GetMapping("/playerAccount")
public Iterable<PlayerAccount> getPlayerAccounts(#RequestParam(required = false) Long id) {
return repository.findById(id);
}
Ps: the request should keep the same variable name e.g
.../playerAccount?id=6
I am using cucumber-java in groovy code. I prefer cucumber-java to cucumber-groovy because I can run the tests like plain old good JUnit tests. However, the step definition templates spitted out by cucumber are in java style. Instead, I would like to have a groovy style. For example, in java style, you will get something like
#When("^an HTTP GET request is sent to obtain config.xml of \"([^\"]*)\"$")
public void an_HTTP_GET_request_is_sent_to_obtain_config_xml_of(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
Since I am using groovy, I would like to get something like
#When(/^an HTTP GET request is sent to obtain config.xml of "([^"]*)"$/)
void 'an HTTP GET request is sent to obtain config.xml of'(String arg1) {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
I am thinking to implement such a feature. Basically, my idea is to add a new field, maybe called templateLanguage, in cucumber.api.CucumberOptions. When this new field is equal to groovy, then the groovy-style templates will be spitted. This will probably involve an if statement in cucumber.runtime.java.JavaSnippet.template(), such as
if( runtimeOptions.getTemplateLanguage().toLowerCase().equals('groovy') ) {...}
However, my question is: how can I get a reference of the runtimeOptions that is passed in like
#CucumberOptions(
format = ["pretty", "html:build/cucumber"],
features="src/test/resources/cucumber_features/api/job_view.feature",
glue=['com.yahoo.adcd.jenkins.tests.smoke.api.cucumber.job.view'],
strict = true
)
Thank you very much!
In a case like this, you would need to write your own boot class since there is no dependency injection for RuntimeOptions. A good starting location is to look at cucumber.api.cli.Main. You would need to create your own class that extends RuntimeOptions, then add in your logic there.
This solution, however, will not allow you run the app using the CucumberOptions annotation anymore. If you do prefer using the annotation though, you would need to also implement your own custom annotation and override the RuntimeOptionsFactory to use your annotation, and then use that factory in your new main class to create the runtime dynamically.
Do you know, if there is the possibility to check who is calling a method and to restrict whether they are allowed to execute it with Java Annotations?
For example if you have a client and a server. There are several users, which have different roles and they login into the client. Then (the same client) with different users wants to call a getMethod on the server.
Can I restrict, who is allowed to call this methos with Java Annotations?
Like:
#Role(role="AllowedRole")
public ReturnType getMethod() {
...
}
Well, I used to achieve this with Seam/DeltaSpike in JBoss Server. It's pretty straightforward.
Basically, you have a method which you annotate with your annotation. For example, mine is #User:
public class MyClass {
#User
public Object getMethod() {
//implementation
}
}
Next, you need a class where you define how you check your annotations:
public class Restrictions {
#Secures #User
public boolean isOk(Identity identity) {
if (identity.getUsername("Peter")) {
return true;
}
return false;
}
}
That's it! Ofcourse, you need some libraries and to define these intercepting stuff in certain xml files (like beans.xml) but it can be easily done with a little googling.
Start from these links:
Seam framework
Questions I asked on JBoss community when I was starting with this
This seems to be a good case for Method Security of Spring Security.
Annotations do not include code and are not processed magically. They just define metadata, so you need some kind of engine that processes the annotations and performs the access validation.
There are a lot of frameworks and tools that do this. For example you can implement this using AspectJ, Spring framework and Java EE support similar annotations.
You can also implement this logic yourself using dynamic proxy, byte code engineering or other technique.
So, please explain better what kind of application are you implementing and we can probably give you better advice.
How can I change what a method is doing in Java ?
I mean, I am trying to use annotations to make the following code
#Anno1(Argument = "Option1")
public class TestClass
{
#Anno2
public void test()
{
}
}
Into
public class TestClass
{
private static StaticReference z;
public void test()
{
z.invokeToAll();
}
}
This is a very simplified example of what I am trying to do. Anno1 will have many possible combinations, but this is not my problem so far. My problem is how to add code to method test()
I am looking for a more generic solution if possible. Eg. A way to add every kind of code in the method (not just a way to .invokeToAll())
So far I am using import javax.annotation.processing.*; and I have the following code, but I don't know how to go on from there
private void processMethodAnnotations(RoundEnvironment env)
{
for (Element e : env.getElementsAnnotatedWith(Anno2.class))
{
//If it is a valid annotation over a method
if (e.getKind() == ElementKind.METHOD)
{
//What to do here :S
}else
{
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!", e);
}
}
}
I have found something about Java Reflection but I have not found any source to help me with what I am doing.
Obviously I extends AbstractProcessor in my code
I have found this tutorial (http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm) But this concerns creating a new class, not just changing a method. and the javax.lang.model.elements do not provide any way of editing that element (which in my case represents a Method).
I hope my question is clear and inline with the rules. If not please comment and I will clarify. Thanks.
Annotation processing is the wrong way to go for you, from Wikipedia:
When Java source code is compiled,
annotations can be processed by
compiler plug-ins called annotation
processors. Processors can produce
informational messages or create
additional Java source files or
resources, which in turn may be
compiled and processed, but annotation
processors cannot modify the annotated
code itself.
People suggested to you the right way - AOP. Specifically, you can use AspectJ. "Quick result" way is (if you use Eclipse):
Install AJDT (AspectJ Development Tools)
Create an AspectJ project and add there your classes and annotations
Create Aspect:
public aspect Processor {
private StaticReference z;
pointcut generic()
// intercept execution of method named test, annotated with #Anno1
// from any class type, annotated with #Anno2
: execution(#Anno2 * (#Anno1 *).test())
// method takes no arguments
&& args ();
// here you have written what you want the method to actually do
void around () : generic() {
z.invokeToAll();
}
}
now you can execute a test and you will see that it works ;) AJDT compiles code for you automatically, so do not need any manual work to do, hope that's what you called "magic" ;)
UPDATE:
if your code in the test() method depends on the Anno1 annotation value, then inside aspect you can get class annotation for which it is executed this way:
void around () : generic() {
Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
String ArgumentValue = null;
for ( Annotation annotation : classAnnotations ) {
if ( annotation instanceof Anno1 ) {
ArgumentValue = ((Anno1) annotation).Argument();
break;
}
}
if ( ArgumentValue != null && ArgumentValue.equals("Option1")) {
z.invokeToAll();
}
}
where thisJoinPoint is a special reference variable.
UPDATE2:
if you want to add System.out.println( this ) in your aspect, you need to write there System.out.println( thisJoinPoint.getThis() ), just tested and it works. thisJoinPoint.getThis() returns you "this" but not exactly; in fact this is Object variable and if you want to get any propery you need either to cast or to use reflection. And thisJoinPoint.getThis() does not provide access to private properties.
Well, now seems that your question is answered, but if I missed anything, or you get additional question/problems with this way - feel free to ask ;)
It's perfectly possible to do what you ask, although there is a caveat: relying on private compiler APIs. Sounds scary, but it isn't really (compiler implementations tend to be stable).
There's a paper that explains the procedure: The Hacker's Guide to Javac.
Notably, this is used by Project Lombok to provide automatic getter/setter generation (amongst other things). The following article explains how it does it, basically re-iterating what is said the aforementioned paper.
Well, you might see if the following boilerplate code will be useful:
public void magic(Object bean, String[] args) throws Exception {
for (Method method : bean.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(Anno2.class)) {
// Invoke the original method
method.invoke(bean, args);
// Invoke your 'z' method
StaticReference.invokeAll();
}
}
}
As an alternative your might employ aspect oriented programming, for instance you have the AspectJ project.
I'm not sure at all if it is even possible to change the source or byte code via annotations. From what your describing it looks as if aspect oriented programming could provide a solution to your problem.
Your annotations are pretty similiar to the pointcut concept (they mark a location where code needs to be inserted) and the inserted code is close the advice concept.
Another approach would be parsing the java source file into an abstract syntax tree, modify this AST and serialize to a java compiler input.
If your class extends a suitable interface, you could wrap it in a DynamicProxy, which delegates all calls to the original methods, except the call to test.