Is recursion always good?

Problem Definition

Is this always correct to say – “Recursive functions are common in computer science because they allow programmers to write efficient programs using a minimal amount of code.”

Below piece of code is simply trying to find the next lexicographical order of string.

Note: Algorithm is not correct. it is this incorrect algorithm highlighted which I will conclude later.

Sample Code

getNextOrder(…) is the recursive function in below sample code.

Source: https://github.com/sabirhussain/java-sample/tree/master/LexicographicalOrder

Run below code with and without Thread.sleep and observe the output. You will get stackoverflow error without Thread.sleep, which is self-explanatory. Hence it is evident that recursive functions are not the best option always.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

public class NextLexicographicalOrder {

  public static void main(String[] args) throws IOException {
    try (
      BufferedReader br = new BufferedReader(new FileReader(new File("testcase1.txt")))) {
      String line = null;

      while ((line = br.readLine()) != null) {
        String result = processLine(line);
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }

        System.out.println(line + ": " + result);
      }
    }
  }

  static String processLine(String w) {

    if (w.length() == 1)
      return "no answer";

    char[] chars = w.toCharArray();

    return getNextOrder(chars, chars.length - 1, chars.length - 2);
  }

  static String getNextOrder(char[] chars, int i, int j) {

    if (chars[i] > chars[j]) {
      char tmp = chars[i];
      chars[i] = chars[j];
      chars[j] = tmp;

      if (i == j + 1)
        return new String(chars);

      char[] subChars = Arrays.copyOfRange(chars, j + 1, chars.length);
      Arrays.sort(subChars);

      return new StringBuilder().append(Arrays.copyOfRange(chars, 0, j + 1)).append(subChars).toString();
    }

    if (i == 1)
      return "no answer";

    if (j == 0)
      return getNextOrder(chars, (i - 1), (i - 2));
    else
      return getNextOrder(chars, i, --j);
  }
}

Conclusion

Although recursive functions are an efficient way of implementation wherever possible, in some specific situations it is not the best solution as it may fill up your stack faster than it is garbage collected.

Advertisements

Increase LVM space in VirtualBox

Problem Definition

Getting out of disk space error on your VirtualBox VM where your guest Linux OS is using LVM with Dynamic disk allocation, and you are wondering why this error when available space is 30 GB and used space is only 4 GB.

Solution

  • Login to your vm and run ‘df -h’
    if your output is nearby –>

    then run below 2 steps
  • sudo lvextend -L +2G /dev/mapper/ubuntu--vg-ubuntu--lv
  • sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
    df -h

DONE!

File Download Component – Java

Problem Definition

Many a time we need to provide file download feature in our application, and it perfectly makes sense to create a component that can be reused.

Solution

This component is created for spring boot web application, although you can customize the code or get the idea for the reusable component.

The Component

FileDownloadHelper this is the main helper class that downloads the file or more technically writes file content on http response.

public class FileDownloadHelper {

    public static ResponseEntity downloadFile(FileResource file, WritableStream stream) {
        Assert.notNull("file and stream parameters are not optional.", file, stream);

        if (!file.exists())
            return ResponseEntity.notFound().build();

        byte[] content = file.getContent();

        if (!FileUtil.verifyChecksum(content, file.getChecksum())) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Verify checksum fail");
        }

        stream.setContentType(file.getContentType());
        stream.write(content);

        return ResponseEntity.ok().build();
    }

}

Supporting Implementaion

FileResource
This allows to wrap underlying complexity of file resource and expose common access pattern.

public interface FileResource {

    String getPath();

    String getChecksum();

    String getContentType();

    boolean exists();

    byte[] getContent();

    InputStream getStream();

}

WritableStream
This allows to wrap writable resource (ex: servlet response) to hide complexity and expose common access pattern.

public interface WritableStream {

    void setContentType(String type);

    void write(byte[] content);
}

In Action

Sample code to download file from google cloud storage.

GoogleFileResource

public final class GoogleFileResource implements FileResource {
    private Blob blob;
    private FileMeta meta;

    public GoogleFileResource(Blob blob, FileMeta meta) {
        this.blob = blob;
        this.meta = meta;
    }

    @Override
    public String getPath() {
        return blob.getName();
    }

    @Override
    public String getChecksum() {
        return meta.getChecksum();
    }

    @Override
    public String getContentType() {
        return meta.getType();
    }

    @Override
    public boolean exists() {
        return blob.exists();
    }

    @Override
    public byte[] getContent() {
        return blob.getContent();
    }

    @Override
    public InputStream getStream() {
        return null;
    }

}

ServletWritableStream

public class ServletWritableStream implements WritableStream {
    private HttpServletResponse response;

    public ServletWritableStream(HttpServletResponse response) {
        Assert.notNull(response);
        this.response = response;
    }

    @Override
    public void setContentType(String type) {
        response.setContentType(type);
    }

    @Override
    public void write(byte[] content) {
        try {
            response.getOutputStream().write(content);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

Final Piece

@GetMapping
public ResponseEntity getFile(@PathVariable String consultationReference,
            HttpServletResponse response) {
        return service.getFile(consultationReference)
                .map(file -> FileDownloadHelper.downloadFile(file, new ServletWritableStream(response)))
                .orElse(ResponseEntity.notFound().build());
    }

Artifactory with Multi-Module Gradle Project

Prerequisites

1. Oracle JDK8

Environment Details

1. OS – Ubuntu 16.04 x64 Server
2. Artifactory – oss-5.3.0

Problem

Publish your jar from Multi-module gradle project and use in other projects.

Steps

Install Artifactory

Start Artifactory

  • Goto artifactory home. (to extracted location)
  • run – bin/artifactory.sh

Setup repository

Your framework project parent/root build.gradle


buildscript {
  repositories {
    jcenter {
      url 'http://localhost:8081/artifactory/jcenter/'
    }
  }

  dependencies {
    //Check for the latest version here: http://plugins.gradle.org/plugin/com.jfrog.artifactory
    classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
  }
}

allprojects {
  apply plugin: 'maven'

  group = 'com.example'
  version = '1.0.0-SNAPSHOT'

  ext {
    springBootVersion = '1.5.2.RELEASE'
  }
}

subprojects {
  apply plugin: 'java'
  apply plugin: 'maven-publish'
  apply plugin: "com.jfrog.artifactory"

  sourceCompatibility = 1.8
  targetCompatibility = 1.8
  tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
  }

  repositories {
    jcenter {
      url 'http://localhost:8081/artifactory/jcenter/'
    }
  }

  dependencies {
    testCompile group: 'junit', name: 'junit', version:'4.12'
  }

  artifactory {
    contextUrl = "${artifactory_contextUrl}" //The base Artifactory URL if not overridden by the publisher/resolver
    publish {
      repository {
        repoKey = 'example-framework-snapshot-local'
        username = "${artifactory_user}"
        password = "${artifactory_password}"
        maven = true
      }
      defaults {
        publications ('mavenJava')
      }
    }

    resolve {
      repository {
        repoKey = 'example-framework-snapshot'
        username = "${artifactory_user}"
        password = "${artifactory_password}"
        maven = true
      }
    }
  }

  publishing {
    publications {
      mavenJava(MavenPublication) {
        from components.java
      }
    }
  }
}

build.gradle for user of your Framework Code

Assuming your virtual repository is ‘example-framework-snapshot’

buildscript {
  ext {
    springBootVersion = '1.5.2.RELEASE'
  }
  repositories {
    maven {
      // Your virtual repository
      url 'http://localhost:8081/artifactory/example-framework-snapshot'
    }
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
}

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'war'
apply plugin: 'org.springframework.boot'

group = 'com.security.sample'
version = '0.0.1-SNAPSHOT'

description = """sample-security Webapp"""

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
  maven {
    url 'http://localhost:8081/artifactory/example-framework-snapshot'
  }
}

dependencies {
  compile ('com.example:example-security-extras:0.0.1-SNAPSHOT')
  compile ('org.springframework.boot:spring-boot-starter-web')
  compile ('redis.clients:jedis')
  testCompile ('junit:junit')
}

Sorting and Cross Join Problem – Spring Data JPA

Affected Version

Spring boot – 1.2.2
Spring data JPA version – 1.7.2
Spring data common – 1.9.2

Problem Statement

When you use custom query using @Query in your spring data JPA repository and pass sort parameter, where sort parameter is a child attribute; the query generated uses cross join instead of left outer join. This gives unexpected result.

Problem Sample


@Query("SELECT e FROM EventApprovalRequest e WHERE e.approvalRequestType = (:approvalRequestType) "
+ "AND e.status = (:status)")
Page getEventsForApproval(
@Param("approvalRequestType") int approvalRequestType, @Param("status") int status, Pageable pageable);

Solution

Pre-define left outer join in your query.

@Query("SELECT e FROM EventApprovalRequest e LEFT OUTER JOIN e.event LEFT OUTER JOIN e.event.director WHERE e.approvalRequestType = (:approvalRequestType) "
+ "AND e.status = (:status)")
Page getEventsForApproval(
@Param("approvalRequestType") int approvalRequestType, @Param("status") int status, Pageable pageable);

Get Enum type with id

Here is a simple technique to retrieve Enum type using custom ‘id’ property instead of name.

Define Contract

/**
 * Contract that will allow Types with id to have generic implementation.
 */
public interface IdentifierType<T> {
  T getId();
}

Apply Contract

public enum EntityType implements IdentifierType<Integer> {
  ENTITY1(1, "ONE), ENTITY2(2, "TWO");

  private Integer id;
  private String name;

  private EntityType(int id, String name) {
    this.id = id;
    this.name = name;
  }

  public static EntityType valueOf(Integer id) {
    return EnumHelper.INSTANCE.valueOf(id, EntityType.values());
  }

  @Override
  public Integer getId() {
    return id;
  }
}

Make use of contract (helper)

public enum EnumHelper {
  INSTANCE;

  /**
   * This will return {@link Enum} constant out of provided {@link Enum} values with the specified id.
   * @param id the id of the constant to return.
   * @param values the {@link Enum} constants of specified type.
   * @return the {@link Enum} constant.
   */
  public <T extends IdentifierType<S>, S> T valueOf(S id, T[] values) {
    if (!values[0].getClass().isEnum()) {
        throw new IllegalArgumentException("Values provided to scan is not an Enum");
    }

    T type = null;

    for (int i = 0; i < values.length && type == null; i++) {
        if (values[i].getId().equals(id)) {
            type = values[i];
        }
    }

    return type;
  }
}

Search Framework Idea – Java

Introduction

Writing code to implement search in application is a repetitive task, and need understanding of query language provided by underlying search engine. Search framework reduces the development effort and hides implementation complexity by leveraging good Object Oriented principles. It helps to make your design extensible and maintainable.

The solution built using following design patterns

  • Builder
  • Factory
  • Template
  • Strategy

 

Architecture

SearchFramework

Core Components

It consist of interfaces defining contract for searcher, and beans defining search request object format.

Code Sample

public interface Searcher {
   T search(SearchCriteria criteria);
}

public class SearchCriteria {
   private int groupCondition;
   private List searchFilters;
}

public class SearchFilter {
   private String fieldName;
   private String fieldValue;
   private int filterCondition;
}

Provider Integration

In this layer we do provider specific implementation, such that it is implemented once and reused.

Sample for JPA Searcher

public abstract class JPASearcher implements Searcher {
   @Autowired
   private PredicateBuilder predicateBuilder;

   protected Specification getSpecification(final SearchCriteria searchCriteria) {
     return new Specification() {

      @Override
       public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery,
 CriteriaBuilder criteriaBuilder) {
         criteriaQuery.distinct(true);
         return predicateBuilder.build(searchCriteria, criteriaBuilder, root);
       }

   };
}

JPA Predicate builder

@Component
public class PredicateBuilder {
   @Autowired
   private PredicateConditionBuilderFactory conditionBuilderFactory;
   
   public Predicate build(SearchCriteria criteria, CriteriaBuilder cb, Root root) {
     …
     for (SearchFilter searchFilter : criteria.getSearchFilters()) {
       …
     }
     if (criteria.getGroupCondition() == GroupCondition.AND) {
       predicate = cb.and(predicates.toArray(new Predicate[predicates.size()]));
     } else {
       predicate = cb.or(predicates.toArray(new Predicate[predicates.size()]));
     }
   return predicate;
   }
}
 

JPA Condition Builder

public interface PredicateConditionBuilder {

 Predicate build(SearchFilter filter, CriteriaBuilder criteriaBuilder, Root root,
 final DistinctJoinHolder joinHolder);

}

Sample Implementation

public class IsNotNullBuilder implements PredicateConditionBuilder {

private final ConditionBuilderHelper builderHelper = ConditionBuilderHelper.INSTANCE;

@Override
public  Predicate build(SearchFilter filter, CriteriaBuilder criteriaBuilder, Root root,
 final DistinctJoinHolder joinHolder) {
    String fieldName = filter.getField().getSearchFieldName();
    GroupCondition groupCondition = filter.getSearchCriteria().getGroupCondition();
    Path path = builderHelper.getPath(fieldName, root, groupCondition, joinHolder);
    return criteriaBuilder.isNotNull(path);
  }
}

JPA Condition Builder Factory

@Component
public class PredicateConditionBuilderFactory {

  private Map builders;

  @PostConstruct
  protected void init() {
     builders = new HashMap();
     builders.put(FilterCondition.EQUAL, new EqualBuilder());
     builders.put(FilterCondition.NOT_EQUAL, new NotEqualBuilder());
     builders.put(FilterCondition.GT, new GreaterThanBuilder());
     builders.put(FilterCondition.LT, new LessThanBuilder());
     builders.put(FilterCondition.EQ_GT, new GreaterThanEqualBuilder());
     builders.put(FilterCondition.EQ_LT, new LessThanEqualBuilder());
     builders.put(FilterCondition.BETWEEN, new BetweenBuilder());
     builders.put(FilterCondition.LIKE, new LikeBuilder());
     builders.put(FilterCondition.IN, new InBuilder());
     builders.put(FilterCondition.IS_NULL, new IsNullBuilder());
     builders.put(FilterCondition.IS_NOT_NULL, new IsNotNullBuilder());
   }

  public PredicateConditionBuilder getBuilder(FilterCondition filterCondition) {
     return builders.get(filterCondition);
  }

}

Search Configuration

It is not used directly by core framework, but needed by various search utilities – for example search criteria builder utility may want to get list of fields supported in application’s basic search, or may be for validation configuration.

Search Utilities

This layer consist of various search supporting utilities –

  • Search criteria builder & validator.
  • Search filter builder & validator.

Simple JPA Searcher implementation (Search Services)

@Component
public class EventSearcher extends JPASearcher {
   @Autowired
   private EventRepository repository;

   @Override
   public List search(SearchCriteria criteria) {
     return repository.findAll(getSpecification(criteria));
   }
}

All you have to do is

  • Extend JPASearcher and provide entity to search.
  • Provide jpa repository for entity.
  • Call search with search criteria.