Setting scan.all.resources for Swagger in JAXRS - annotations

I am using plain vanilla JAXRS in a provided Application Server with Swagger 1.5.18. I can get the Swagger annotated classes to appear in the swagger.json, but I am having trouble setting the Swagger to scan for non annotated classes, those with just the #Path JAXRS annotations.
I currently have the BeanConfig in the Class that is extending Application. I tried using a Servlet that extended DefaultJaxrsConfig with #WebInitParam(name="scan.all.resources", value="true") but that did not work at all.
The documentation states that setting ReaderConfig.scanAllResources would achieve what I am looking for. However, I am not sure of a good way to implement this. Any suggestions?
Current configuration class:
#ApplicationPath("services")
public class Configuration extends Application {
public Configuration() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.0");
beanConfig.setTitle("SwaggerExample");
beanConfig.setBasePath("/SwaggerExample/services");
beanConfig.setResourcePackage("com.xxxxxx.swagger.jaxrs");
beanConfig.setScan(true);
beanConfig.setPrettyPrint(true);
}
Thanks, Brian

I did find a way around the issue as posted in the Swagger blog post, by implementing a ReaderListener. However, I would think this could be set at the BeanConfig level. Here is my solution:
#SwaggerDefinition
public class ApiDefinitions implements ReaderListener {
#Override
public void afterScan(Reader reader, Swagger swagger) {
}
#Override
public void beforeScan(Reader reader, Swagger swagger) {
((DefaultReaderConfig) reader.getConfig()).setScanAllResources(true);
}
}
Brian

Related

Initialize swagger without web.xml to disable it in production

I am using Swagger with Jersey 2 and spring bootstrap. Currently I'm looking a solution to disable swagger on production as it will be concern in case any user
uses the API's with the swagger UI.
I'm registering io.swagger.jersey.config.JerseyJaxrsConfig servlet in web.xml and passing init parameters to it like api.version and swagger.api.basepath. Along with this I'm registering package to scan as io.swagger.jaxrs.listing so that org.glassfish.jersey.server.ResourceConfig will take care to prepare swagger UI.
I got to know from internet that we can achive this byb using #profile annotations. But I experienced that If we register any class in Web.xml, even though you are using #Profile on that class level, it will not work as the class going to be loaded at context load.
I have static contents in my project like swagger-ui-min.js, swagger-ui.js, index.html etc to load the swagger.
With this setup, how can I disable swagger UI in production? Also if some one have experience on , should swagger could be disabled in production or not?
You could have a flag which allows to load the Swagger Servlet only when you are not in production (here for Swagger 2):
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
import io.swagger.jaxrs2.integration.resources.OpenApiResource;
#ApplicationPath("") // no application path after the context root
public class MyApp extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(...); // your main service
if (notInProduction) { // a flag telling that you are not in production
classes.add(OpenApiResource.class);
}
return classes;
}
}
Below code worked for me.
String enable_swagger_ui = System.getenv("ENABLE_SWAGGER_UI");
if( enable_swagger_ui != null && enable_swagger_ui.equalsIgnoreCase("true"))
packages("io.swagger.jaxrs.listing");
You just need to add the ENABLE_SWAGGER_UI in system environment variable where you want to enable swagger.

Change Spring Data REST exposing link

By default, Spring Data REST will expose search resources to urls under {resource_name}/search. For example, findBySubject_Id in the following code will be exposed to {baseUrl}/questions/search/findBySubject_Id?subjectId={subjectId}.
public interface QuestionRepository extends PagingAndSortingRepository<Question, String> {
Page<Question> findBySubject_Id(#Param("subjectId")String subjectId, Pageable pageable);
}
For compatiblility reasons, I need the exposing link to be {baseUrl}/questions?subjectId={subjectId}. Is there any way to do it?
You can not override /search url. If you really need a link without search, you should override response handler for the entity via writing your own controller with annotation #RepositoryRestController

Olingo OData V2 Read Property not implemented

I implemented an OData V2 Service with Apache Olingo V2 in connectin with JPA using EclipseLink. All requests are working fine, but when it comes to the point, where I want to access a single property via GET request from an entity set like for the following URL:
http://localhost:8080/MyODataService/XXXXXX.svc/EntitySet(12345)/Property
the response in return is:
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code/>
<message xml:lang="de-DE">Not implemented</message>
</error>
The class which extends the ODataJPASeviceFactory looks as follows:
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
public class JPAODataServiceFactory extends ODataJPAServiceFactory
{
private static final String PERSISTENCE_UNIT_NAME = "MyPersistenceUnitName";
#Override
public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException
{
ODataJPAContext oDatJPAContext = this.getODataJPAContext();
try
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
oDatJPAContext.setEntityManagerFactory(emf);
oDatJPAContext.setPersistenceUnitName(PERSISTENCE_UNIT_NAME);
return oDatJPAContext;
} catch (Exception e)
{
throw new RuntimeException(e);
}
}
My question now is:
How do I implement the functionality, so that I can do GET and POST requests not only for a whole entity set, but also for a single property of an entity set like I tried with the mentioned URL?
Accessing a single property from one entity is currently not implemented if you use the Olingo JPA Extension.
If you want to support this behaviour you can register a custom processor and only override the "readEntityComplexProperty" and "readEntitySimpleProperty" methods. There you can have your custom code where you specifically get back the value.
Every method you don`t override will result in the standard Olingo functionality being executed.
Here is a tutorial on how to register a custom JPA processor: http://olingo.apache.org/doc/odata2/tutorials/CustomODataJPAProcessor.html
Here is the example on how your code can look like if you implement the functionality yourself: https://github.com/apache/olingo-odata2/blob/597465569fdd15976d0486711d4a38f93a7c6696/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java#L592
You need to create an association between your entity sets.
For example, to access the following URL: http://localhost:8080/myService.svc/Cars('6')/Manufacturer, you need to create an assocation between your car and your manufacturer association sets.
Have a look at the documentation: https://olingo.apache.org/doc/odata2/tutorials/basicread.html
Hegg,
you can use
http://localhost:8080/MyODataService/XXXXXX.svc/EntitySet(12345)/?$select=Property
Bye
Domenico

Questions about combining Hystrix with Feign

I am trying to use the new HystrixFeign support in Feign. Here is what my code looks like
route66Client =
HystrixFeign.builder()
.logger(new Slf4jLogger())
.encoder(new GsonEncoder())
.target(Route66Client.class, "http://route66/");
The Route66Client is defined as
public interface Route66Client {
#RequestLine("POST /route")
ApiResponse getRoute(
RouteRequest request);
}
When i try to run the code. I get UnknownHostException. As it is not able to resolve route66 for its hostname. Anyone knows what i could be missing ?
Further i had this working with regular Feign ( not HystrixFeign ). All i did was to annotate my Route66Client class with #FeignClient("...") and then injecting Route66Client in the calling class ( So no Feign.builder() was used )
But i couldn't find some #HystrixFeignClient annotation. So i went ahead and started using the HystrixFeign.builder(). But then when i did that the serviceName->Address resolution stopped working.
If you want the benefits of eureka, don't use the builder directly. Put #EnableFeignClients on an #Configuration class (usually your application). Then label Route66Client with #FeignClient("route66") and inject Route66Client. This is only available in Brixton's 2nd Milestone. See the documentation.

Creating a Spring 4 MVC project with annotations and no xml files

I'm new to Spring MVC and Hibernate. I'm trying to start a project by following tutorials but I have been running into problems as my project structure is not consistent with the tutorials I am reading.
I have downloaded the latest STS and I do see the option of creating an Spring MVC project. However it is based on Spring 3 and still uses XML files. From what I have read it looks like there is a way to do it without XML files since Spring 3. I prefer annotations over XML files greatly.
How can I create a Spring MVC 4 application that is based on annotations and relies on xml files minimally?
EDIT:
I want to create a web project
Here is a squeletal example of full java configuration. You will need :
a class extending AbstractAnnotationConfigDispatcherServletInitializer to replace the old web.xml file
one or more #Configuration annotaded class(es) to initialize the root context (replaces the old applicationContext.xml)
one or more #Configuration annotaded class(es) to initialize the DispatcherServlet context (replaces the old dispatcher-servlet.xml)
This is the web.xml :
public class WebAppConf extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// declare root context configuration classes
return new Class<?>[]{ RootConf.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
// declare servlet context configuration classes
return new Class<?>[]{ ServletConf.class };
}
#Override
protected String[] getServletMappings() {
// mapping of DispatcherServlet
return new String[]{"/"};
}
#Override
protected void customizeRegistration(Dynamic registration) {
// additional configuration, here for MultipartConfig
super.customizeRegistration(registration);
MultipartConfigElement multipartConf = new MultipartConfigElement("", 200000L, -1L, 0);
registration.setMultipartConfig(multipartConf);
}
}
RootConf will declare business model, service and dao beans and is not shown here.
ServletConf declares the controllers and servlet configuration :
#Configuration
#EnableWebMvc
// declare where to find annotated controllers
#ComponentScan({"org.example.web"})
public class ServletConf extends WebMvcConfigurerAdapter {
#Bean
MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
#Bean
ViewResolver internalViewResolver() {
// the view resolver bean ...
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
As said above, it is squeletal, but it comes from a working minimal example so you should be able to start with that and extend it at will. In my example, the above three classes live in a org.example.config package that will never be scanned for autodetecting other configuration classes or annotated beans.
Hope it helps ...
I know this doesn't answer your question fully, but hopefully the links will be useful.
WebApplicationInitializer - A 100% code based approach to configuration
as well as AnnotationConfigWebApplicationContext
Also, if you have the time, reading the relevant sections of Spring's MVC chapter of their documentation is helpful.
I Wish that this link will be helpful for you Spring security with annotation Mkyong
The latest versions of STS integrate the Spring guides from https://spring.io/guides directly, try the "Import Spring Getting Started Content" wizard. There are good guides included for creating a Spring Boot based web service, for example, among many others.