/******************************************************************************* * =========================================================== * Ankush : Big Data Cluster Management Solution * =========================================================== * * (C) Copyright 2014, by Impetus Technologies * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License (LGPL v3) as * published by the Free Software Foundation; * * This software is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ******************************************************************************/ package com.impetus.ankush; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletContext; import org.apache.log4j.FileAppender; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.springframework.context.ApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import com.impetus.ankush.common.config.ConfigurationReader; import com.impetus.ankush.common.domain.Log; import com.impetus.ankush.common.mail.MailConf; import com.impetus.ankush.common.mail.MailManager; import com.impetus.ankush.common.service.AsyncExecutorService; import com.impetus.ankush.common.service.GenericManager; import com.impetus.ankush.common.utils.FileUtils; import com.impetus.ankush.common.utils.PasswordUtil; import com.impetus.ankush.common.utils.XmlUtil; import com.impetus.ankush2.constant.Constant; import com.impetus.ankush2.hadoop.config.CmpConfigMapping; import com.impetus.ankush2.hadoop.config.CmpConfigMappingSet; import com.impetus.ankush2.hadoop.utils.HadoopConstants; import com.impetus.ankush2.hadoop.utils.HadoopConstants.ConfigXmlKeys.Attributes; import com.impetus.ankush2.logger.AnkushLogger; /** * The Class AppStoreWrapper. */ public class AppStoreWrapper { /** The Constant KEY_AGENT_VERISON. */ public static final String KEY_AGENT_VERISON = "agentVersion"; private static final String COMPONENT_CONF_FILE = "/ankush-component-config.xml"; /** The Constant KEY_APPLICATION_CONTEXT. */ private static final String KEY_APPLICATION_CONTEXT = "applicationContext"; /** The Constant KEY_ANKUSH_CONF_READER. */ private static final String KEY_ANKUSH_CONF_READER = "ankushConfReader"; /** The Constant KEY_ANKUSH_PROPERTIES. */ private static final String KEY_ANKUSH_PROPERTIES = "ankushProperties"; /** The Constant KEY_SERVLET_CONTEXT. */ private static final String KEY_SERVLET_CONTEXT = "servletContext"; /** The Constant KEY_APP_PATH. */ private static final String KEY_APP_PATH = "appPath"; private static final String KEY_CLUSTER_RESOURCES = "clusterResourcePath"; /** The Constant KEY_RESOURCE_PATH. */ private static final String KEY_RESOURCE_PATH = "resourcePath"; /** The Constant PACKAGED_BUNDLE_PATH. */ private static final String KEY_PACKAGED_BUNDLE_PATH = "packagedBundlePath"; /** The Constant SETUP_BUNDLE_FOLDER. */ private static final String SETUP_BUNDLE_FOLDER = "setupBundles/"; /** The Constant KEY_MAIL_MANAGER. */ private static final String KEY_MAIL_MANAGER = "mailManager"; /** The Constant KEY_EXECUTOR. */ private static final String KEY_EXECUTOR = "executor"; /** The Constant KEY_LOG_MANAGER. */ private static final String KEY_LOG_MANAGER = "logManager"; /** The Constant KEY_OPERATION_MANAGER. */ private static final String KEY_OPERATION_MANAGER = "operationManager"; /** The Constant KEY_SERVER. */ private static final String KEY_SERVER = "server"; private static final String KEY_SERVER_LOGS_DIR = "serverLogsDir"; /** The Constant KEY_REPO. */ private static final String KEY_REPO = "repo"; /** The Constant KEY_PATCHES. */ private static final String KEY_PATCHES = "patches"; /** The Constant APP_ACCESS_URL. */ private static final String KEY_APP_ACCESS_URL = "appAccessURL"; /** The Constant AGENT_BUNDLE_PATH */ private static final String AGENT_BUNDLE_PATH = "scripts/agent/agent.zip"; /** The Constant AGENT_VERSION_FILE */ private static final String AGENT_VERSION_FILE = "VERSION.txt"; /** The log. */ private static AnkushLogger log = new AnkushLogger(AppStoreWrapper.class); /** * Get Database manager. * * @param <S> * the generic type * @param managerName * the manager name * @param targetClass * the target class * @return the manager */ public static <S> GenericManager<S, Long> getManager(String managerName, Class<S> targetClass) { return getManager(managerName, targetClass, Long.class); } /** * Get Database manager. * * @param <A> * * @param <S> * the generic type * @param managerName * the manager name * @param targetClass * the target class * @return the manager */ public static <A, B extends Serializable> GenericManager<A, B> getManager( String managerName, Class<A> targetClass, Class<B> className) { if (getApplicationContext() == null) { return null; } return (GenericManager<A, B>) getApplicationContext().getBean( managerName); } /** * Get service. * * @param <S> * the generic type * @param serviceName * the service name * @param targetClass * the target class * @return the service */ public static <S> S getService(String serviceName, Class<S> targetClass) { if (getApplicationContext() == null) { return null; } return (S) getApplicationContext().getBean(serviceName); } /** * Sets the application context. * * @param applicationContext * the applicationContext to set */ public static void setApplicationContext( ApplicationContext applicationContext) { AppStore.setObject(KEY_APPLICATION_CONTEXT, applicationContext); } /** * Gets the application context. * * @return the application context */ public static ApplicationContext getApplicationContext() { return (ApplicationContext) AppStore.getObject(KEY_APPLICATION_CONTEXT); } /** * Gets the ankush conf reader. * * @return the ankushConfReader * @author Hokam Chauhan */ public static ConfigurationReader getAnkushConfReader() { return (ConfigurationReader) AppStore.getObject(KEY_ANKUSH_CONF_READER); } /** * Sets the ankush conf reader. * * @param ankushConfReader * the ankushConfReader to set * @author Hokam Chauhan */ public static void setAnkushConfReader(ConfigurationReader ankushConfReader) { /* Getting user home path */ String userHome = System.getProperty("user.home"); if (ankushConfReader != null) { /* setting serverMetadataPath */ AppStore.setObject(KEY_SERVER, userHome + ankushConfReader.getStringValue(KEY_SERVER)); AppStore.setObject( KEY_SERVER_LOGS_DIR, userHome + ankushConfReader .getStringValue(KEY_SERVER_LOGS_DIR)); /* setting serverRepoPath */ AppStore.setObject(KEY_REPO, userHome + ankushConfReader.getStringValue(KEY_REPO)); /* setting serverPatchesPath */ AppStore.setObject(KEY_PATCHES, userHome + ankushConfReader.getStringValue(KEY_PATCHES)); // Setting initial delay value for agent down check. AppStore.setObject( com.impetus.ankush2.constant.Constant.Keys.KEY_INITIAL_DELAY_AGENT_CHECK, ankushConfReader .getIntValue(com.impetus.ankush2.constant.Constant.Keys.KEY_INITIAL_DELAY_AGENT_CHECK)); AppStore.setObject( com.impetus.ankush2.constant.Constant.Keys.AGENT_DOWN_INTERVAL, ankushConfReader .getIntValue(com.impetus.ankush2.constant.Constant.Keys.AGENT_DOWN_INTERVAL)); } AppStore.setObject(KEY_ANKUSH_CONF_READER, ankushConfReader); } public static String getServerLogsDirPath() { return (String) AppStore.getObject(KEY_SERVER_LOGS_DIR); } /** * Method to get app path. * * @return returns server metadata path */ public static String getServerMetadataPath() { return (String) AppStore.getObject(KEY_SERVER); } /** * Method to get repository path. * * @return returns path of component repository on server */ public static String getServerRepoPath() { return (String) AppStore.getObject(KEY_REPO); } /** * Method to get repository path. * * @return returns path of component repository on server */ public static String getServerPatchesRepoPath() { return (String) AppStore.getObject(KEY_PATCHES); } /** * Method to get Servlet Context. * * @return the servlet context */ public static ServletContext getServletContext() { return (ServletContext) AppStore.getObject(KEY_SERVLET_CONTEXT); } /** * Method to set servlet context. * * @param servletContext * the new servlet context */ public static void setServletContext(ServletContext servletContext) { String appPath = servletContext.getRealPath("/"); String resourcesPath = ""; appPath = FileUtils.getSeparatorTerminatedPathEntry(appPath); resourcesPath = appPath + "WEB-INF/classes/"; if (appPath.contains("src" + File.separator)) { resourcesPath = appPath + "../resources/"; } AppStore.setObject(KEY_APP_PATH, appPath); AppStore.setObject(KEY_RESOURCE_PATH, resourcesPath); AppStore.setObject(KEY_CLUSTER_RESOURCES, resourcesPath + "clusters/"); AppStore.setObject(KEY_PACKAGED_BUNDLE_PATH, resourcesPath + SETUP_BUNDLE_FOLDER); AppStore.setObject(KEY_SERVLET_CONTEXT, servletContext); } /** * Method to get app path. * * @return path of application */ public static String getAppPath() { return (String) AppStore.getObject(KEY_APP_PATH); } public static String getClusterResourcesPath() { return (String) AppStore.getObject(KEY_CLUSTER_RESOURCES); } /** * Method to get resource path. * * @return returns path to resources */ public static String getResourcePath() { return (String) AppStore.getObject(KEY_RESOURCE_PATH); } /** * Method to get packaged bundles path. * * @return returns path to resources */ public static String getPackagedBundlesPath() { return (String) AppStore.getObject(KEY_PACKAGED_BUNDLE_PATH); } /** * Method to get configured MailManager. * * @return returns the currently configured mail manager object in * AppStoreWrapper */ public static MailManager getMailManager() { return (MailManager) AppStore.getObject(KEY_MAIL_MANAGER); } /** * Method to setup mail manager in AppStoreWrapper. * * @param mailManager * mailmanager object configured with proper mail configuration * that will be used to send mail */ public static void setMailManager(MailManager mailManager) { AppStore.setObject(KEY_MAIL_MANAGER, mailManager); } /** * Method to get executor. * * @return the executor */ public static AsyncExecutorService getExecutor() { return (AsyncExecutorService) AppStore.getObject(KEY_EXECUTOR); } /** * Method to set executor. * * @param executor * the new executor */ public static void setExecutor(AsyncExecutorService executor) { AppStore.setObject(KEY_EXECUTOR, executor); } /** * Get Log manager. * * @return Log Manager. */ public static GenericManager<Log, Long> getLogManager() { return (GenericManager<Log, Long>) getApplicationContext().getBean( KEY_LOG_MANAGER); } /** * Get Operation manager. * * @return Operation Manager. */ public static GenericManager<Log, Long> getOperationManager() { return (GenericManager<Log, Long>) getApplicationContext().getBean( KEY_OPERATION_MANAGER); } /** * Method to setup app access URL by extracting server configuration from a * map. * * @param serverAccessConf * the new serverAccessConf */ public static void setAppAccessURL(Map serverAccessConf) { if (serverAccessConf == null) { return; } String appName = "ankush"; String serverIP = ""; String port = ""; if ((serverAccessConf != null) && serverAccessConf.size() > 0) { serverIP = (String) serverAccessConf.get("publicIp"); port = (String) serverAccessConf.get("port"); } String appURL = "http://" + serverIP + ":" + port + "/" + appName + "/"; String accessURL = null; if ((serverIP != null) && !serverIP.equals("")) { accessURL = appURL; } AppStore.setObject(KEY_APP_ACCESS_URL, accessURL); } /** * Method to get app Access URL. * * @return returns app access URL */ public static String getAppAccessURL() { return (String) AppStore.getObject(KEY_APP_ACCESS_URL); } /** * Method to setup mail manager in AppStoreWrapper by extracting mail * configuration from a map. * * @param mailMap * the new up mail */ public static void setupMail(Map mailMap) { if (mailMap == null) { return; } MailConf appMail = new MailConf(); int port = 0; try { port = Integer.parseInt((String) mailMap.get("port")); } catch (Exception e) { log.error(e.getMessage(), e); } appMail.setPort(port); appMail.setServer((String) mailMap.get("server")); appMail.setUserName((String) mailMap.get("userName")); appMail.setEmailAddress((String) mailMap.get("emailAddress")); String decoded = new PasswordUtil().decrypt((String) mailMap .get("password")); appMail.setPassword(decoded); try { Boolean secured = (Boolean) mailMap.get("secured"); if (secured != null) { appMail.setSecured(secured); } } catch (Exception e) { log.error(e.getMessage(), e); } if (appMail != null) { MailManager mm = new MailManager(appMail); AppStoreWrapper.setMailManager(mm); } } public static FileAppender getAppender(String fileName) { return (FileAppender) AppStore.getObject(fileName); } public static void setAppender(String fileName, FileAppender appender) { AppStore.setObject(fileName, appender); } public static void setComponentConfiguration() { log.debug("setComponentConfiguration()"); try { // getting configuration file Resource resource = new ClassPathResource(COMPONENT_CONF_FILE); String filePath = resource.getFile().getAbsolutePath(); List<String> subItems = new ArrayList<String>(); subItems.add(Constant.AppStore.ComponentConf.Key.NAME); subItems.add(Constant.AppStore.ComponentConf.Key.PRIORITY); subItems.add(Constant.AppStore.ComponentConf.Key.DEPLOYER); subItems.add(Constant.AppStore.ComponentConf.Key.MONITOR); subItems.add(Constant.AppStore.ComponentConf.Key.SERVICE); Map items = XmlUtil .loadConfigXMLParameters( filePath, Constant.AppStore.ComponentConf.Key.COMPONENT, subItems); AppStore.setObject( Constant.AppStore.COMPONENT_MAP, items); } catch (Exception e) { log.error(e.getMessage(), e); } } public static CmpConfigMappingSet getCmpConfigMapping(String component) { Map<String, CmpConfigMappingSet> cmpConfigMapping = (HashMap) AppStore .getObject(Constant.AppStore.CompConfigXmlMapping.KEY_APP_STORE_OBJECT); return cmpConfigMapping.get(component.toLowerCase()); } /** * Sets the component config classes. */ public static void setCompConfigClasses() { List<String> componentList = Arrays .asList(AppStoreWrapper .getAnkushConfReader() .getStringValue( Constant.AppStore.CompConfigXmlMapping.KEY_ANKUSH_CONSTANT_PROPERTY) .toLowerCase().split(",")); Map<String, CmpConfigMappingSet> cmpConfigMapping = new HashMap<String, CmpConfigMappingSet>(); for (String component : componentList) { List<String> subItems = new ArrayList<String>(); subItems.add(HadoopConstants.ConfigXmlKeys.ClassType.INSTALLER); subItems.add(HadoopConstants.ConfigXmlKeys.ClassType.CONFIGURATOR); subItems.add(HadoopConstants.ConfigXmlKeys.ClassType.SERVICE_MANAGER); subItems.add(HadoopConstants.ConfigXmlKeys.ClassType.COMMANDS_MANAGER); subItems.add(HadoopConstants.ConfigXmlKeys.ClassType.MONITOR); String filePath = AppStoreWrapper.getConfigClassNameFile(component); CmpConfigMappingSet cmpConfigXmlSet = null; if (filePath != null) { try { cmpConfigXmlSet = AppStoreWrapper.loadConfigXmlParameters( filePath, HadoopConstants.ConfigXmlKeys.CLASS, subItems); cmpConfigMapping.put(component, cmpConfigXmlSet); System.out.println("cmpConfigXmlSet for " + component + " : " + cmpConfigXmlSet); } catch (Exception e) { System.err.println(e.getMessage()); } } } AppStore.setObject( Constant.AppStore.CompConfigXmlMapping.KEY_APP_STORE_OBJECT, cmpConfigMapping); } private static CmpConfigMappingSet loadConfigXmlParameters(String filePath, String root, List<String> subItems) { // map of item. CmpConfigMappingSet cmpConfigXmlSet = new CmpConfigMappingSet(); try { // creating sax builder obj. SAXBuilder builder = new SAXBuilder(); // getting file object. File xml = new File(filePath); // input file stream. InputStream inputStream = new FileInputStream(xml); // jdom document object. org.jdom.Document doc = builder.build(inputStream); // getting root element. Element elements = doc.getRootElement(); // getting child elements. List child = elements.getChildren(root); // iterating over the childs. for (int index = 0; index < child.size(); index++) { // getting element. Element e = (Element) child.get(index); String installationType = e.getAttribute( Attributes.INSTALLATION_TYPE).getValue(); String vendor = e.getAttribute(Attributes.VENDOR).getValue(); String version = e.getAttribute(Attributes.VERSION).getValue(); Map<String, String> classMap = new HashMap<String, String>(); // iterating over the element properties. for (String subItem : subItems) { // getting element values. String value = XmlUtil.getTagContent(e, subItem); // putting element value. classMap.put(subItem, value); } CmpConfigMapping configXmlObject = new CmpConfigMapping( installationType, vendor, version, classMap); // putting map against the attribute value. cmpConfigXmlSet.add(configXmlObject); } // closing input stream. inputStream.close(); } catch (Exception e) { // printing stack trace. e.printStackTrace(); } // returning items. return cmpConfigXmlSet; } public static void setAnkushConfigurableClassNames() { List<String> classTypes = new ArrayList<String>(); classTypes.add("cluster"); classTypes.add("monitor"); classTypes.add("service"); classTypes.add("clusterconf"); for (String classType : classTypes) { Map map = new HashMap(); String filePath = getConfigClassNameFile(classType); if (filePath != null) { try { Map items = XmlUtil.loadConfigXMLParameters(filePath, classType, Collections.singletonList("class")); AppStore.setObject(classType, items); } catch (Exception e) { System.err.println(e.getMessage()); } } } List<String> subItems = new ArrayList<String>(); subItems.add("priority"); subItems.add("conf"); subItems.add("class"); subItems.add("jsonmapper"); subItems.add("upgrader"); String filePath = getConfigClassNameFile("deployer"); Map items = XmlUtil.loadConfigXMLParameters(filePath, "deployer", subItems); Map priorityMap = new HashMap(); for (Object id : items.keySet()) { Map map = (Map) items.get(id); String className = map.get("class").toString(); priorityMap.put(className, map.get("priority")); } // setting priority map of classname and priority. items.put("priority", priorityMap); System.out.println("deployer : " + items); AppStore.setObject("deployer", items); } /** * Gets the app config. * * @param type * the type * @return the app config */ public static String getConfigClassNameFile(String type) { // getting configuration file Resource resource = new ClassPathResource("/ankush-" + type + "-config.xml"); try { return resource.getFile().getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Gets the deployable priority. * * @param className * the class name * @return the deployable priority */ public static int getDeployablePriority(String className) { Map map = (Map) AppStore.getObject("deployer"); Map priorityMap = (Map) map.get("priority"); String priority = (String) priorityMap.get(className); if (priority == null) { return Integer.MAX_VALUE; } return Integer.parseInt(priority); } /** * Gets the instance by id. * * @param id * the id * @return the instance by id */ public static String getDeployableConfClassName(String id) { Map map = (Map) AppStore.getObject("deployer"); Map classConfMap = (Map) map.get(id); String className = (String) classConfMap.get("conf"); if (className == null) { return null; } return className; } public static String getDeployableConfJsonMapperName(String id) { Map map = (Map) AppStore.getObject("deployer"); Map classConfMap = (Map) map.get(id); String className = (String) classConfMap.get("jsonmapper"); if (className == null) { return null; } return className; } /** * Method to get agent build version */ public static String getAgentBuildVersion() { return (String) AppStore.getObject(AppStoreWrapper.KEY_AGENT_VERISON); } public static String getComponentCustomMetadataFolderPath( String componentName) { String techNameKey = componentName; String metadataFolderPrefix = "/metadata."; String customConfFolderCompletePath = AppStoreWrapper .getServerRepoPath() + metadataFolderPrefix + techNameKey + "/"; return customConfFolderCompletePath; } public static String getComponentCustomMetadataFilePath(String componentName) { return getComponentCustomMetadataFolderPath(componentName) + componentName + ".json"; } public static String getComponentCustomMetadataFilePath( String componentName, String fileName) { return getComponentCustomMetadataFolderPath(componentName) + fileName; } }