/*
* Copyright (C) 2014 Intel Corporation
* All rights reserved.
*/
package com.intel.mtwilson.setup.tasks;
import com.intel.dcsg.cpg.extensions.AnnotationRegistrar;
import com.intel.dcsg.cpg.extensions.Extensions;
import com.intel.dcsg.cpg.extensions.ImplementationRegistrar;
import com.intel.dcsg.cpg.extensions.Registrar;
import com.intel.mtwilson.MyFilesystem;
import com.intel.mtwilson.launcher.ExtensionDirectoryLauncher;
import com.intel.mtwilson.launcher.ext.annotations.Background;
import com.intel.mtwilson.launcher.ws.ext.RPC;
import com.intel.mtwilson.launcher.ws.ext.V1;
import com.intel.mtwilson.launcher.ws.ext.V2;
import com.intel.mtwilson.setup.LocalSetupTask;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Create or update the extension cache file by scanning available jar files
* for extensions
*
* You can execute this task from command line with something like this:
* mtwilson setup setup-manager update-extensions-cache-file
*
* @author jbuhacoff
*/
public class UpdateExtensionsCacheFile extends LocalSetupTask {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UpdateExtensionsCacheFile.class);
private String getCacheFilePath() {
return MyFilesystem.getApplicationFilesystem().getConfigurationPath()+File.separator+"extensions.cache";
}
private File getCacheFile() {
return new File(getCacheFilePath());
}
@Override
protected void configure() throws Exception {
checkFileExists("Mt Wilson configuration folder", MyFilesystem.getApplicationFilesystem().getConfigurationPath());
}
@Override
protected void validate() throws Exception {
if( checkFileExists("Extension cache file", getCacheFilePath()) ) {
// load the cache
Set<String> cache = loadCache();
// initialize the whiteboard
Set<String> extensions = getWhiteboardExtensions();
// compare the cache to the loaded extensions
HashSet<String> inCacheButNotPresent = new HashSet<>();
HashSet<String> presentButNotInCache = new HashSet<>();
inCacheButNotPresent.addAll(cache);
inCacheButNotPresent.removeAll(extensions);
presentButNotInCache.addAll(extensions);
presentButNotInCache.removeAll(cache);
if( !inCacheButNotPresent.isEmpty() ) {
validation("Extensions cache contains removed extensions: %s", StringUtils.join(", ", inCacheButNotPresent));
}
if( !inCacheButNotPresent.isEmpty() ) {
validation("Extensions cache missing added extensions: %s", StringUtils.join(", ", presentButNotInCache));
}
}
}
private void scanExtensions() {
ExtensionDirectoryLauncher launcher = new ExtensionDirectoryLauncher();
launcher.setRegistrars(new Registrar[] { new ImplementationRegistrar(), new AnnotationRegistrar(V2.class), new AnnotationRegistrar(V1.class), new AnnotationRegistrar(RPC.class), new AnnotationRegistrar(Background.class) });
launcher.run(); // loads and scans the jars
}
private Set<String> getWhiteboardExtensions() {
// first use the directory launcher to scan and register all available extensions
scanExtensions();
// second make a list of loaded classes
Map<String,List<Class<?>>> map = Extensions.getWhiteboard();
Collection<List<Class<?>>> collection = map.values();
// consolidate the whiteboard datastructure into a set of unique extension class names
HashSet<Class<?>> set = new HashSet<>();
for(List<Class<?>> list : collection) {
set.addAll(list);
}
HashSet<String> extensions = new HashSet<>();
for(Class<?> clazz : set) {
// log.debug("Caching extension: {}", clazz.getName());
extensions.add(clazz.getName());
}
return extensions;
}
private void storeCache(Set<String> extensions) throws IOException {
String text = StringUtils.join(extensions, "\n");
try(FileOutputStream out = new FileOutputStream(new File(getCacheFilePath()))) {
IOUtils.write(text, out);
}
}
private Set<String> loadCache() throws IOException {
HashSet<String> cache = new HashSet<>();
try(FileInputStream in = new FileInputStream(getCacheFile())) {
String text = IOUtils.toString(in);
String[] lines = text.split("\n");
for(String line : lines) {
if( !line.trim().isEmpty() ) {
cache.add(line.trim());
}
}
}
return cache;
}
@Override
protected void execute() throws Exception {
if( checkFileExists("Extension cache file", getCacheFilePath()) ) {
getCacheFile().delete();
}
Set<String> extensions = getWhiteboardExtensions();
storeCache(extensions);
}
}