Thursday, August 13, 2015

Observe folder to pick file when it's available


public class MMTServerStartListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    YourMonitorListenerImpl fileMonitor;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent context) {
        try {
            String filePath = "<file path>";
            startMonitor(filePath, fileMonitor);
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
        }
    }

    private void startMonitor(String filePath, YourMonitorListenerImpl fileMonitorImpl) {
        try {
            if (filePath != null && filePath.length() > 0) {

                final File directory = new File(filePath.trim());
                FileAlterationObserver fao = new FileAlterationObserver(directory);
                fao.addListener(fileMonitorImpl);

                final FileAlterationMonitor monitor = new FileAlterationMonitor();
                monitor.addObserver(fao);

                LOGGER.info("Starting monitor. CTRL+C to stop.");
                monitor.start();

                Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                    public void run() {
                        try {
                            LOGGER.info("Stopping monitor.");
                            monitor.stop();
                        } catch (Exception ignored) {
                            LOGGER.error(ignored.getMessage(), ignored);
                        }
                    }
                }));
            } else {
                LOGGER.error("Invalid input the monitor folder");
            }
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
        }
    }
}

With "YourMonitorListenerImpl" implements "FileAlterationListener" interface.

Wednesday, August 12, 2015

Thread with ExecutorService

ThreadFactory buildCache = new ThreadFactoryBuilder().setNameFormat("thread-name-%d").build();
ExecutorService executorService = Executors.newFixedThreadPool(totalThreads, buildCache);

List<Future> trackingTask = new ArrayList<Future>();

for (int index = 0; index < totalThreads; index++) {
        trackingTask.add(executorService.submit(new Runnable() {
              @Override
               public void run() {
                      //run your code
               }
        }));
}

// Run and waiting for task to finish
for (Future task : trackingTask) {
        task.get();
}

// Shutdown executor:
executorService.shutdownNow();

Using Redis cache

Installation:

Follow the instruction at: Install Redis cache in linux - DigitalOcean

Using Redis cache:

Create bean:
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          p:hostName="${atm.cache.redis.host}"
          p:port="${atm.cache.redis.port}"
          p:poolConfig-ref="jedisPoolConfig"
          p:usePool="true"/>
 <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
          p:connectionFactory-ref="jedisConnFactory" p:keySerializer-ref="stringRedisSerializer"/>

 Autowired in java implement:
@Autowired
private RedisTemplate<String, ProgramBasicInfo> programRedisTemplate;

Delete all cache: (in this case, it get connection and then flush all data)
programRedisTemplate.getConnectionFactory().getConnection().flushAll();

Delete cache:
programRedisTemplate.opsForHash().getOperations()
                                    .delete(Constants.CACHE_PROGRAM_GUIDE_KEY);

Put data to cache:
programRedisTemplate.opsForHash().put(Constants.CACHE_PROGRAM_GUIDE_KEY, program.getProgramId(),       programBasicInfo);

Get data from cache:
(ProgramBasicInfo) programRedisTemplate.opsForHash().get(Constants.CACHE_PROGRAM_GUIDE_KEY, programId);

References:

http://blog.joshuawhite.com/java/caching-with-spring-data-redis/
http://caseyscarborough.com/blog/2014/12/18/caching-data-in-spring-using-redis/


Tuesday, August 11, 2015

Synchronize SimpleDateFormat object in Java

SimpleDateFormat object does not work properly in a multi threaded environment. It may output a wrong date when parsing. So the safest way is to synchronize it.

private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public String formatDate(Date d) {
    synchronized(sdf) {
        return sdf.format(d);
    }
}
 
Hope that help.

Sunday, August 9, 2015

Check if a class is loaded and lib file location in JVM

Example below is to see if JVM using ojdbc6 version 11 or version 12.

final ClassLoader loader = Thread.currentThread().getContextClassLoader();
ClassPath clazzPath = ClassPath.from(loader);
Set<ClassInfo> classes = clazzPath.getTopLevelClasses();
for (final ClassPath.ClassInfo classInfo : classes) {
    if (classInfo.getName().startsWith("oracle")) {
         if (classInfo.getName().contains("oracle.jdbc.babelfish")) {
                 isVersion12 = true;
         }

    }
}
            

if(isVersion12) {
        LOGGER.info("Ojdbc version 12");

} else {
        LOGGER.info("Ojdbc version 11");

}

Class klass = OracleConnection.class;
URL location = klass.getResource('/' + klass.getName().replace('.',  '/') + ".class");
LOGGER.info(location.toString());

Read package name and version from Manifest file

Bean: 

public class BuildVersion {
   
    /** The build name. */
    private String buildName;
   
    /** The version. */
    private String version;

    /**
     * Gets the version.
     *
     * @return the version
     */
    public String getVersion() {
        return version;
    }

    /**
     * set version.
     *
     * @param version the new version
     */
    public void setVersion(String version) {
        this.version = version;
    }

    /**
     * Gets the builds the name.
     *
     * @return the builds the name
     */
    public String getBuildName() {
        return buildName;
    }

    /**
     * Sets the builds the name.
     *
     * @param buildName the new builds the name
     */
    public void setBuildName(String buildName) {
        this.buildName = buildName;
    }
}

VersionServiceImpl:

private BuildVersion getBuildVersion() {
        BuildVersion buildVersion = new BuildVersion();

        Class clazz = this.getClass();
        String className = clazz.getSimpleName() + ".class";
        String classPath = clazz.getResource(className).toString();
        try {
            String manifestPath = classPath.substring(0, classPath.lastIndexOf("/WEB-INF")) +
                    "/META-INF/MANIFEST.MF";
            Manifest manifest = new Manifest(new URL(manifestPath).openStream());
            Attributes attr = manifest.getMainAttributes();
            String title = attr.getValue("Specification-Title");
            String version = attr.getValue("Specification-Version");

            buildVersion.setBuildName(title);
            buildVersion.setVersion(version);
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
        }
        return buildVersion;
    }

VersionEndpoint:

@Component
@Path ("/")
public class VersionEndpoint {
   
    /** The version service. */
    @Autowired
    private VersionService versionService;
   
    /**
     * getVersion service use to retrieve the current release version.   
     *
     * @param format the format
     * @return Version response
     */
    @GET
    @Path ("/version")
    @Produces ({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    public Response getVersion(@DefaultValue (WSConstants.RESPONSE_TYPE_JSON) @QueryParam ("format") String format) {
        try {
            return Response.ok().entity(versionService.getVersion()).type(WSUtil.getWSResponseType(format)).build();
        } catch (Exception e) {
            return Response.ok().entity("Error: "  + e.getMessage()).type(WSUtil.getWSResponseType(format)).build();
        }       
    }                                       
}

Install Ibus-unikey in Linux for Vietnamese

Uninstall all preinstalled ibus package and its dependencies
    sudo apt-get remove --auto-remove ibus
Purging config/data too
    sudo apt-get purge --auto-remove ibus
Maybe restart is needed.

Install new ibus-unikey
    sudo apt-get install ibus-unikey

After installing done, run:
    ibus-setup

to open Ibus Preferences. 
Choose Input method tab, check 'Customize active input methods'. In selection box, click Show all input methods, choose Vietnamese->Unikey.

Logout your system to active the new input method.

Now in top right corner of your screen, you are able to select 'Unikey' to input Vietnamese.