Sunday, August 18, 2019

The Evolution of The Java Ecosystem

It has been a long time no posts. Since my last post, a lot has happened in the Java and software development ecosystem. Looking forward to posting some newer material that I have had the pleasure of using in production and for fun.

Saturday, February 28, 2015

10 Steps To Creating Bootiful RESTful API Documentation Using Swagger

It's been a while since I posted, so here goes the ten steps on how to set up a SpringBoot RESTful service with Swagger-UI.

1. Go to start.spring.io and download a 'web' starter project or use SpringSTS ide.

2. Add the swagger-springmvc dependency.

 <dependency>  
   <groupId>com.mangofactory</groupId>  
   <artifactId>swagger-springmvc</artifactId>  
   <version>0.8.8</version>  
 </dependency>  


3. Download the swagger-ui from https://github.com/swagger-api/swagger-ui and copy the files in the
/dist
folder to your
{application}\src\main\resources\public\docs


4. Modify the swagger-ui index.html script (thanks to http://raibledesigns.com/rd/entry/documenting_your_spring_api_with)

       $(function () {  
         var url = window.location.protocol + "//" + window.location.host;  
         if (window.location.pathname.indexOf('/api') > 0) {  
           url += window.location.pathname.substring(0, window.location.pathname.indexOf('/api'))  
         }  
         url += "/api-docs";  
         log('API URL: ' + url  


5. Add a RestController
 package demo.swagger;  
 import java.util.ArrayList;  
 import java.util.List;  
 import org.springframework.http.HttpStatus;  
 import org.springframework.http.MediaType;  
 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;  
 @RestController  
 @RequestMapping("/api")  
 public class MainController{  
   @RequestMapping(value ="/users",   
       consumes=MediaType.APPLICATION_JSON_VALUE,  
       method=RequestMethod.GET)  
   public ResponseEntity<List<User>> getUser(){  
     User user = new User();  
     user.setName("all the swag I got");  
     user.setId(12312);  
     List<User> users = new ArrayList<>();  
     users.add(user);  
     return new ResponseEntity<>(users, HttpStatus.OK);  
   }  
 }  


6. Add a domain class

 public class User {  
   private String name;  
   private Integer id;  
   @Override  
   public String toString() {  
     return "User{" + "name=" + name + ", id=" + id + '}';  
   }  
   /**  
    * @return the name  
    */  
   public String getName() {  
     return name;  
   }  
   /**  
    * @param name the name to set  
    */  
   public void setName(String name) {  
     this.name = name;  
   }  
   /**  
    * @return the id  
    */  
   public Integer getId() {  
     return id;  
   }  
   /**  
    * @param id the id to set  
    */  
   public void setId(Integer id) {  
     this.id = id;  
   }  
 }  


7. Add the SwaggerConfiguration.
 package demo.swagger;  
 import com.mangofactory.swagger.configuration.SpringSwaggerConfig;  
 import com.mangofactory.swagger.plugin.EnableSwagger;  
 import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;  
 import com.wordnik.swagger.model.ApiInfo;  
 import org.slf4j.Logger;  
 import org.slf4j.LoggerFactory;  
 import org.springframework.boot.bind.RelaxedPropertyResolver;  
 import org.springframework.context.EnvironmentAware;  
 import org.springframework.context.annotation.Bean;  
 import org.springframework.context.annotation.Configuration;  
 import org.springframework.core.env.Environment;  
 import org.springframework.http.ResponseEntity;  
 import org.springframework.util.StopWatch;  
 @Configuration  
 @EnableSwagger  
 public class SwaggerConfiguration implements EnvironmentAware {  
   private final Logger log = LoggerFactory.getLogger(SwaggerConfiguration.class);  
   public static final String DEFAULT_INCLUDE_PATTERN = "/api/.*";  
   private RelaxedPropertyResolver propertyResolver;  
   @Override  
   public void setEnvironment(Environment environment) {  
     this.propertyResolver = new RelaxedPropertyResolver(environment, "swagger.");  
   }  
   /**  
    * Swagger Spring MVC configuration.  
    */  
   @Bean  
   public SwaggerSpringMvcPlugin swaggerSpringMvcPlugin(SpringSwaggerConfig springSwaggerConfig) {  
     log.debug("Starting Swagger");  
     StopWatch watch = new StopWatch();  
     watch.start();  
     SwaggerSpringMvcPlugin swaggerSpringMvcPlugin = new SwaggerSpringMvcPlugin(springSwaggerConfig)  
       .apiInfo(apiInfo())  
       .genericModelSubstitutes(ResponseEntity.class)  
       .includePatterns(DEFAULT_INCLUDE_PATTERN);  
     swaggerSpringMvcPlugin.build();  
     watch.stop();  
     log.debug("Started Swagger in {} ms", watch.getTotalTimeMillis());  
     return swaggerSpringMvcPlugin;  
   }  
   /**  
    * API Info as it appears on the swagger-ui page.  
    */  
   private ApiInfo apiInfo() {  
     return new ApiInfo(  
         propertyResolver.getProperty("title"),  
         propertyResolver.getProperty("description"),  
         propertyResolver.getProperty("termsOfServiceUrl"),  
         propertyResolver.getProperty("contact"),  
         propertyResolver.getProperty("license"),  
         propertyResolver.getProperty("licenseUrl"));  
   }  
 }  


8. run from ide or commandline
mvn clean install

9. run
mvn spring-boot:run

10. Access your application api documentation at http://localhost:8080/docs/index.html

Monday, January 26, 2015

Interesting Reads lately

Interesting reads;


The speakers provide insight into design and architectural challenges for creating REST services with Spring Integration with RabbitMQ.
http://www.infoq.com/presentations/rest-rabbitmq-spring-nodejs


I am also going to post some tutorials of some new materials soon.



Wednesday, October 22, 2014

JavaEE with Spring Security @RolesAllowed

   @RolesAllowed({"ROLE_ADMIN"})  
   @GET  
   public User getObject(final @Context SecurityContext securityContext) {  
     User user = getUserFromSecurityContext(securityContext);  
     if(user == null) {  
       throw new UserNotFoundException();  
     }  
     return new User(user);  
   }  

Tuesday, August 5, 2014

JavaEE REST JAX-RS with Spring Security

Java EE REST JAX-RS with Spring Security


If you are using a JavaEE application server like Jboss, WildFly, GlassFish you get JAX-RS , JPA etc runtimes for 'free', if using Tomcat, Jetty etc, you might as well use the full Spring stack.
I tested on Jboss EAP 6.11, 7, WildFly and Glassfish.






/WEB-INF/applicationContext.xml Spring context file.
 <?xml version='1.0' encoding='UTF-8' ?>  
 <!-- was: <?xml version="1.0" encoding="UTF-8"?> -->  
 <beans xmlns="http://www.springframework.org/schema/beans"  
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xmlns:security="http://www.springframework.org/schema/security"  
     xmlns:p="http://www.springframework.org/schema/p"  
     xmlns:aop="http://www.springframework.org/schema/aop"  
     xmlns:tx="http://www.springframework.org/schema/tx"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd  
     http://www.springframework.org/schema/security  
     http://www.springframework.org/schema/security/spring-security.xsd">  
   <!--bean id="propertyConfigurer"  
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"  
      p:location="/WEB-INF/jdbc.properties" />  
   <bean id="dataSource"  
   class="org.springframework.jdbc.datasource.DriverManagerDataSource"  
   p:driverClassName="${jdbc.driverClassName}"  
   p:url="${jdbc.url}"  
   p:username="${jdbc.username}"  
   p:password="${jdbc.password}" /-->  
   <!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) -->  
   <!--basic login security-->  
   <security:http>  
     <security:intercept-url pattern="/**" access="ROLE_USER" />  
     <security:form-login />  
     <security:logout />  
   </security:http>  
   <!--example from spring.io security reference-->  
   <security:authentication-manager>  
     <security:authentication-provider>  
       <security:user-service>  
         <security:user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />  
         <security:user name="bob" password="bobspassword" authorities="ROLE_USER" />  
       </security:user-service>  
     </security:authentication-provider>  
   </security:authentication-manager>  
   <!--secures all methods-->  
   <security:global-method-security secured-annotations="enabled" />  
 </beans>  



The web.xml


 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">  
   <context-param>  
     <param-name>contextConfigLocation</param-name>  
     <param-value>/WEB-INF/applicationContext.xml</param-value>  
   </context-param>  
   <listener>  
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
   </listener>  
   <filter>  
    <filter-name>springSecurityFilterChain</filter-name>  
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
   </filter>  
   <filter-mapping>  
    <filter-name>springSecurityFilterChain</filter-name>  
    <url-pattern>/*</url-pattern>  
   </filter-mapping>  
   <session-config>  
     <session-timeout>  
       30  
     </session-timeout>  
   </session-config>  
   <welcome-file-list>  
     <welcome-file>redirect.jsp</welcome-file>  
   </welcome-file-list>  
 </web-app>  


The jax-rs path secured with annotation.


1:   @Secured("ROLE_ADMIN")  
2:    @GET  
3:    @Override  
4:    @Produces({ "application/json"})  
5:    public List<Customer> findAll() {  
6:      Authentication authentication = SecurityContextHolder.getContext().getAuthentication();  
7:      Object principal = authentication.getPrincipal();  
8:      if(principal instanceof User)  
9:        System.err.println("principal: " + ((User)principal).getUsername());  
10:      else  
11:        System.err.println("instance"+ principal.getClass().getTypeName());  
12:      System.err.println("roles :" + authentication.getAuthorities());  
13:      return super.findAll();  
14:    }  


Dependencies for spring security -


     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-context</artifactId>  
       <version>4.0.6.RELEASE</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-context-support</artifactId>  
       <version>4.0.6.RELEASE</version>  
     </dependency>   
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-config</artifactId>  
       <version>3.2.4.RELEASE</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-core</artifactId>  
       <version>3.2.4.RELEASE</version>  
     </dependency>        
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-web</artifactId>  
       <version>3.2.4.RELEASE</version>  
     </dependency>  

Thursday, July 10, 2014

Use Spring Integration To Consume Soap Web Services

Spring Integration Consume Soap Web Service




 //interface  
 import javax.jws.WebMethod;  
 import javax.jws.WebParam;  
 import javax.jws.WebService;  
 import javax.jws.soap.SOAPBinding;  
 /**  
  *  
  * @author  
  */  
 @WebService  
 @SOAPBinding(style= SOAPBinding.Style.DOCUMENT,parameterStyle= SOAPBinding.ParameterStyle.BARE,use= SOAPBinding.Use.LITERAL)  
 public interface IService {  
   @WebMethod(operationName="calculateSomething")  
   public String calculateSomething();  
 }  
 //implementation  
 import java.util.Date;  
 import javax.jws.WebService;  
 import javax.xml.ws.*;  
 import javax.jws.*;  
 /**  
  *  
  * @author  
  */  
 @WebService  
 public class ServiceClass implements IService {  
   public static void main(String ... args){  
     ServiceClass sc = new ServiceClass();  
     Endpoint.publish("http://127.0.0.1:15041/service", sc);  
     System.out.println("Server Started: " + new Date().toString());  
   }  
   public String calculateSomething() {  
    System.out.println(" method called " + new Date());  
  return new Date().toString();  
   }  
 }  
 //consumer  
 import org.springframework.context.support.ClassPathXmlApplicationContext;  
 import org.springframework.integration.support.MessageBuilder;  
 import org.springframework.integration.support.channel.BeanFactoryChannelResolver;  
 import org.springframework.messaging.Message;  
 import org.springframework.messaging.MessageChannel;  
 import org.springframework.messaging.core.DestinationResolver;  
 public class MyConsumer {  
  public static void main(String[] args) {  
  ClassPathXmlApplicationContext context =  
   new ClassPathXmlApplicationContext("/META-INF/spring/integration/ws-context.xml");  
  DestinationResolver<MessageChannel> channelResolver = new BeanFactoryChannelResolver(context);  
  // Compose the XML message according to the server's schema  
  String requestXml =   
    "<calculateSomething xmlns=\"http://samplenamespacefromwsdl/\">"+  
  "</calculateSomething>";  
  // Create the Message object  
  Message<String> message = MessageBuilder.withPayload(requestXml).build();  
  // Send the Message to the handler's input channel  
  MessageChannel channel = channelResolver.resolveDestination("myChannel");  
  boolean response = channel.send(message);  
  System.out.println("channel: "+channel.toString());  
  System.out.println("msg sent: "+response + " payload " + message.getPayload());  
  }  
 }  
 //spring integration context  
 <?xml version="1.0" encoding="UTF-8"?>  
 <beans:beans xmlns="http://www.springframework.org/schema/integration"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xmlns:beans="http://www.springframework.org/schema/beans"  
  xmlns:stream="http://www.springframework.org/schema/integration/stream"  
  xmlns:ws="http://www.springframework.org/schema/integration/ws"  
  xsi:schemaLocation="http://www.springframework.org/schema/beans  
   http://www.springframework.org/schema/beans/spring-beans.xsd  
   http://www.springframework.org/schema/integration  
   http://www.springframework.org/schema/integration/spring-integration.xsd  
   http://www.springframework.org/schema/integration/stream  
   http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd  
   http://www.springframework.org/schema/integration/ws  
   http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd">  
  <chain input-channel="myChannel" output-channel="outChannel">  
  <!--ws:header-enricher>  
   <ws:soap-action value=""/>  
  </ws:header-enricher-->  
  <ws:outbound-gateway uri="http://localhost:15041/service"/>  
  </chain>  
  <!-- The response from the service is logged to the console. -->  
  <stream:stdout-channel-adapter id="outChannel"/>   
 </beans:beans>  
 // For The Maven Dependencies  
 <dependencies>  
 <dependency>  
 <groupId>org.springframework.integration</groupId>  
 <artifactId>spring-integration-stream</artifactId>  
 <version>4.0.0.RELEASE</version>  
 <scope>compile</scope>  
 </dependency>  
 <dependency>  
 <groupId>junit</groupId>  
 <artifactId>junit</artifactId>  
 <version>4.11</version>  
 <scope>test</scope>  
 </dependency>  
 <dependency>  
 <groupId>org.hamcrest</groupId>  
 <artifactId>hamcrest-all</artifactId>  
 <version>1.3</version>  
 <scope>test</scope>  
 </dependency>  
 <dependency>  
 <groupId>org.springframework.integration</groupId>  
 <artifactId>spring-integration-ws</artifactId>  
 <version>4.0.0.RELEASE</version>  
 <scope>compile</scope>  
 </dependency>  
 <dependency>  
 <groupId>log4j</groupId>  
 <artifactId>log4j</artifactId>  
 <version>1.2.17</version>  
 <scope>compile</scope>  
 </dependency>  
 <dependency>  
 <groupId>org.mockito</groupId>  
 <artifactId>mockito-core</artifactId>  
 <version>1.9.5</version>  
 <scope>test</scope>  
 </dependency>  
 <dependency>  
 <groupId>org.springframework</groupId>  
 <artifactId>spring-test</artifactId>  
 <version>4.0.3.RELEASE</version>  
 <scope>test</scope>  
 </dependency>  
 </dependencies>