swagger documentation for hybris - rest

I need to generate rest api documentation using swagger for hybris.
I got Kongchan's sample pom.xml, but I couldn't really modify to match with hybris code. Can anyone pls provide me sample pom.xml for hybris or any links or documents.

Find the Wiki for generating Hybris API Documentation with Swagger
Edit:
You can follow spring-xml-swagger example to integrate it with Hybris using XML configuration. Also, this and this posts will help you.

Here is the class I use for OCC (tested on hybris 6.6)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* #author ajaninmanificat Spring configuration for swagger. Only available if spring profile "swagger" is enabled.
*
*/
#Configuration
#EnableSwagger2
#Profile("swagger")
public class SwaggerConfig extends WebMvcConfigurationSupport
{
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry)
{
registry.addResourceHandler("**/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
#Bean
public Docket api()
{
final ApiInfo apiInfo = new ApiInfoBuilder().title("OCC API documentation")
.description("This document contains the generated API documentation for Omni Commerce Connect v2.")
.version("Version v2").build();
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any())
.build().apiInfo(apiInfo).useDefaultResponseMessages(false).enableUrlTemplating(true);
}
}
To enable Swagger you have to set this property : spring.profiles.active=swagger. The idea is to prevent Swagger from being loaded in production.
To avoid any troubles with BaseSiteMatchingFilter I suggest to create a subclass IgnorableBaseSiteMatchingFilter
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IgnorableBaseSiteMatchingFilter extends BaseSiteMatchingFilter
{
private String regexpIgnore;
#Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException
{
final boolean shouldIgnore = (regexpIgnore != null) && matchesUrl(request, regexpIgnore);
if (shouldIgnore)
{
filterChain.doFilter(request, response);
}
else
{
// Is not ignored, call the real stuff
super.doFilterInternal(request, response, filterChain);
}
}
public void setRegexpIgnore(final String regexpIgnore)
{
this.regexpIgnore = regexpIgnore;
}
}
And the bean declaration looks like this :
<alias alias="baseSiteMatchingFilter" name="myBaseSiteMatchingFilter" />
<bean id="myBaseSiteMatchingFilter" class="mypackage.IgnorableBaseSiteMatchingFilter" parent="defaultBaseSiteMatchingFilter">
<property name="regexpIgnore" value="(swagger|api-docs|info|login|logout|/health/|/css/|/img/|/js/|/font-awesome/|/bootstrap/|/assets/|/node_modules/)" />
</bean>

Related

How to use Rest Service while using Spring Boot & Spring Data Jpa

Im working on a spring boot application for rest service with using spring data jpa. I followed instructors and read much answers but I couldn't fix my rest service.
Here is application.class
package tr.kasim.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories("tr.kasim.Dao")
#EntityScan("tr.kasim.Model")
#ComponentScan({"tr.kasim.Service", "tr.kasim.Application" })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Here is `restcontroller.class
package tr.kasim.Controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import tr.kasim.Service.PersonelService;
import tr.kasim.Model.Personel;
#RestController
public class STRestController {
#Autowired
public PersonelService personelService;
#RequestMapping(value = "/api/personels", method = RequestMethod.GET)
public ResponseEntity<List<Personel>> getPersonels(){
List<Personel> personels = personelService.findAll();
return ResponseEntity.ok().body(personels);
}
}
`
Here is Service.class`
package tr.kasim.Service;
import java.util.List;
import tr.kasim.Model.Personel;
public interface PersonelService {
List<Personel> findAll();
}
`
Here is ServiceImplemantion.class
package tr.kasim.Service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tr.kasim.Dao.PersonelDao;
import tr.kasim.Model.Personel;
#Service
public class PersonelServiceImpl implements PersonelService {
#Autowired
private PersonelDao personelDao;
#Override
#Transactional
public List<Personel> findAll() {
return personelDao.findAll();
}
}
Here is Dao.class
package tr.kasim.Dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import tr.kasim.Model.Personel;
#Repository
public interface PersonelDao extends JpaRepository<Personel, Long> {
List<Personel> findAll();
}
Lastly here is my application.properties
#MySql Connection
spring.datasource.url=jdbc:mysql://localhost:3306/exampleproject?verifyServerCertificate=false&useSSL=true
spring.datasource.username=root
spring.datasource.password=*******
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#Jpa/Hibernate
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#Logging
logging.file=staffTracking.log
logging.level.org.springframework.web=debug
Im not sure about componentScan. When I read answers I discovered someone mentioned about it but I tried and I got still nothing. Please show me where I failed. Best Regards.
I updated Application.class, now I can deploying project but rest service not working still.
How did you try ComponentScan? The issue here seems that you have a package structure like this:
tr.kasim.Application
- Application.java
tr.kasim.Service
- PersonelService.java
- PersonelServiceImpl.java
tr.kasim.Dao
- PersonelDao.java
Now since, the mainClass is in tr.kasim.Application it would scan for bean definitions inside that package (or a sub-package in tr.kasim.Application). So,
either you move the mainClass out to a parent-package like tr.kasim, or
use #ComponentScan({ "tr.kasim.Dao", "tr.kasim.Service", "tr.kasim.Application" }) and so on.
-- Update --
Based on the discussion so far, I'd suggest taking the first option as that reduces the effort to manually enable scan for entity, repository, etc.

Will Spring Mail module be alternate to javax.mail

I have a Spring boot application where I need to send an alert mail to both a gmail account and a Zoho account. I try to use Javax.mail, where I set the properties of a both Gmail and a Zoho account using Java class and use it. Will Spring mail be a best replacement for Javax.mail. I have a doubt if Spring mail module can be used because we set the SMTP server properties in application.yml
The first thing to do is to import the dependency from Maven Central Repository.
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>spring-boot-email-core</artifactId>
<version>0.5.0</version>
</dependency>
Then, you populate the application.yml with the following entries
spring.mail.host: smtp.gmail.com
spring.mail.port: 587
spring.mail.username: hari.seldon#gmail.com
spring.mail.password: Th3MuleWh0
spring.mail.properties.mail.smtp.auth: true
spring.mail.properties.mail.smtp.starttls.enable: true
spring.mail.properties.mail.smtp.starttls.required: true
Now, for the sake of the example, assume that you have a service that sends a very simple plain text email. It will be something like:
package com.test;
import com.google.common.collect.Lists;
import it.ozimov.springboot.mail.model.Email;
import it.ozimov.springboot.mail.model.defaultimpl.DefaultEmail;
import it.ozimov.springboot.mail.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.mail.internet.InternetAddress;
import java.io.UnsupportedEncodingException;
import static com.google.common.collect.Lists.newArrayList;
#Service
public class TestService {
#Autowired
private EmailService emailService;
public void sendEmail() throws UnsupportedEncodingException {
final Email email = DefaultEmail.builder()
.from(new InternetAddress("hari.seldon#the-foundation.gal",
"Hari Seldon"))
.to(newArrayList(
new InternetAddress("the-real-cleon#trantor.gov",
"Cleon I")))
.subject("You shall die! It's not me, it's Psychohistory")
.body("Hello Planet!")
.encoding("UTF-8").build();
emailService.send(email);
}
}
Let's do it in the main application, where we'll send the email just after starting and initialising the Spring context.
package com.test;
import it.ozimov.springboot.mail.configuration.EnableEmailTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
#SpringBootApplication
#EnableEmailTools
public class PlainTextApplication {
#Autowired
private TestService testService;
public static void main(String[] args) {
SpringApplication.run(PlainTextApplication.class, args);
}
#PostConstruct
public void sendEmail() throws UnsupportedEncodingException, InterruptedException {
testService.sendEmail();
}
}
Observe that to enable the Email Tools you need to annotate the main app with the annotation
#EnableEmailTools
that will trigger the configuration class for the extension.

How to invoke restful webservice using apache camel

my restful service is
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.hibernate.Query;
import org.hibernate.Session;
import org.json.JSONArray;
#Path("/detailsservice/")
public class DetailsService {
Dao d=new Dao();
#GET
#Path("/details/{id}/")
#Produces("text/xml")
public Details getDetails(#PathParam("id") String id) {
Session hs = d.dao();
Details de = (Details) hs.load(Details.class,new Integer(id));
return de;
}
}
I exposed this service on the web by using jetty server
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
public class Server {
protected Server() throws Exception {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(DetailsService.class);
System.out.println("two");
sf.setResourceProvider(DetailsService.class, new SingletonResourceProvider(new DetailsService()));
sf.setAddress("http://localhost:9000/");
sf.create();
}
public static void main(String args[]) throws Exception {
new Server();
System.out.println("Server ready...");
Thread.sleep(5 * 6000 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
How can i invoke this service by using apache camel.
please explain me in detail because i am new to the camel.
Thanks in advance
You can use the http4 component:
<route>
<from uri="http4://localhost:9000/detailsservice/details/1234" />
<!-- add your processors here -->
<to uri="..." />
</route>

JAX-RS REST service implementation in EJB J2EE

Looking for a an example of using JAX-RS to implement an EJB 3 REST service. Would like to have the transactional functionality of EJB and be able to call the EJB from other J2EE apps as well as from AJAX apps (web, mobile, etc).
Service implemented as a stateless session bean. Used a singleton bean to simulate a DAO for illustration purposes.
 
PUT example:
http://mydomain/MyApp/rest/carbean/savecarorder
ContentType:    application/json
JSON:                    {"equipmentId":"570674","status":"L","operation":"PS"}
 
GET example (after the PUT operation to insert or update):
http://mydomain/MyApp/rest/carbean/getcarorder?equipmentId=570674
Results:                {"status":"L","operation":"PS","equipmentId":"570674"}
package com.samnunnally.services;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import com.samnunnally.CarManager;
import com.samnunnally.CarOrder;
/**
* Session Bean implementation class CarService
*/
#Stateless(mappedName = "ejb/CarService")
#LocalBean
#Path ("/carbean")
public class CarService {
#EJB
CarManager carManager;
#GET
#Produces({ MediaType.APPLICATION_JSON })
#Path("/getcarorder")
public CarOrder getCar(#QueryParam("equipmentId") String equipmentId) {
return carManager.getCarOrder(equipmentId);
}
#Path("/savecarorder")
#PUT
#Consumes({ "application/xml", "application/json" })
public String saveCarOrder(CarOrder carOrder) {
carManager.saveCarOrder(carOrder);
return "true";
}
}
This needed to added to the web.xml file of the war file in the ear:
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Manager to simulate data layer
package com.samnunnally.managers;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import com.samnunnally.model.CarOrder;
/**
* Session Bean implementation class CarManager
*
* #author Sam Nunnally
*
*/
#Singleton(mappedName = "ejb/CarManager")
#LocalBean
public class CarManager {
/*
* this should be a database of some sort
*/
private Map<String, CarOrder> carOrders = null;
public CarOrder getCarOrder(String equipmentId) {
return getCarOrders().get(equipmentId);
}
public void saveCarOrder(CarOrder carOrder) {
getCarOrders().put(carOrder.getEquipmentId(), carOrder);
}
private Map<String, CarOrder> getCarOrders(){
if(carOrders == null){
carOrders = new HashMap<String, CarOrder>();
}
return carOrders;
}
}

HTTP Basic Authentication in Restlet with a JAXRS Application?

I'm trying to authenticate access to all resources on my server via HTTP Basic authentication. Currently, my setup looks like this when starting the server:
this.component = new Component();
this.server = this.component.getServers().add(Protocol.HTTP, 8118);
JaxRsApplication application = new JaxRsApplication(component.getContext()
.createChildContext());
application.add(new RestletApplication());
ChallengeAuthenticator authenticator = new ChallengeAuthenticator(
this.component.getContext(),
ChallengeScheme.HTTP_BASIC, "test");
authenticator.setVerifier(new ApplicationVerifier());
this.component.getDefaultHost().attachDefault(authenticator);
this.component.getDefaultHost().attach(application);
this.component.start();
Here's my RestletApplication:
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class RestletApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(TestResource.class);
return classes;
}
}
Here's my ApplicationVerifier:
import java.util.HashMap;
import java.util.Map;
import org.restlet.security.LocalVerifier;
public class ApplicationVerifier extends LocalVerifier {
private Map<String, char[]> localSecrets = new HashMap<String, char[]>();
public ApplicationVerifier() {
this.localSecrets.put("username", "password".toCharArray());
}
#Override
public char[] getLocalSecret(String key) {
if (this.localSecrets.containsKey(key))
return this.localSecrets.get(key);
return null;
}
}
Finally, here's my TestResource:
import java.util.*;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Path("test")
public class TestResource {
#GET
#Path("list")
public TestList getTestList() {
return makeTestList();
}
}
However, I'm not seeing any prompt or requirement for authentication when I try to access the resource. What am I doing wrong? I'm not having any issues with marshalling and unmarshalling items and I'm sure that my resource is getting hit with requests. What am I not doing right?
According to the JavaDocs for JaxRsApplication, an authenticator can be set using the following code before starting things up:
((JaxRsApplication)application).setGuard((Authenticator)authenticator);
Do that, and all requests will fly through your authenticator :)