| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| *******************************************************************************/ |
| |
| package org.ofbiz.appservers; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.Reader; |
| import java.io.Writer; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.xml.transform.Result; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| |
| import javolution.util.FastList; |
| import javolution.util.FastMap; |
| |
| import org.ofbiz.base.component.ComponentConfig; |
| import org.ofbiz.base.container.Container; |
| import org.ofbiz.base.container.ContainerException; |
| import org.ofbiz.base.start.Classpath; |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.UtilProperties; |
| import org.ofbiz.base.util.UtilURL; |
| import org.ofbiz.base.util.UtilValidate; |
| import org.ofbiz.base.util.template.FreeMarkerWorker; |
| import org.w3c.dom.Document; |
| |
| /** |
| * GenerateContainer - Generates Configuration Files For Application Servers |
| * ** This container requires StartInfoLoader to be loaded at startup. |
| * ** This container requires the ComponentContainer to be loaded first. |
| * |
| */ |
| public class GenerateContainer implements Container { |
| |
| public static final String module = GenerateContainer.class.getName(); |
| public static final String source = "/framework/appserver/templates/"; |
| public static String target = "/setup/"; |
| |
| protected String configFile = null; |
| protected String ofbizHome = null; |
| protected String args[] = null; |
| |
| private boolean isGeronimo = false; |
| private String geronimoHome = null; |
| |
| /** |
| * @see org.ofbiz.base.container.Container#init(java.lang.String[], java.lang.String) |
| */ |
| public void init(String[] args, String configFile) { |
| ofbizHome = System.getProperty("ofbiz.home"); |
| this.configFile = configFile; |
| this.args = args; |
| isGeronimo = args[0].toLowerCase().contains("geronimo") || args[0].toLowerCase().contains("wasce"); |
| if (isGeronimo) { |
| target="/META-INF/"; |
| geronimoHome = System.getenv("GERONIMO_HOME"); |
| if (geronimoHome == null) { |
| geronimoHome = UtilProperties.getPropertyValue("appserver", "geronimoHome", null); |
| } |
| } |
| } |
| |
| /** |
| * @see org.ofbiz.base.container.Container#start() |
| */ |
| public boolean start() throws ContainerException { |
| generateFiles(); |
| return true; |
| } |
| |
| /** |
| * Stop the container |
| * |
| * @throws org.ofbiz.base.container.ContainerException |
| * |
| */ |
| public void stop() throws ContainerException { |
| } |
| |
| private void generateFiles() throws ContainerException { |
| if (isGeronimo) { |
| if (geronimoHome == null) { |
| Debug.logFatal("*** 'GERONIMO_HOME' was not found in your environment. Please set the location of Geronimo into a GERONIMO_HOME env var or as a geronimoHome property in appserver.properties file.", module); |
| throw new ContainerException("Error in Geronimo deployment, please check the log"); |
| } |
| } |
| File files[] = getTemplates(); |
| Map<String, Object> dataMap = buildDataMap(); |
| |
| String user = UtilProperties.getPropertyValue("appserver", "user", "system"); |
| String password = UtilProperties.getPropertyValue("appserver", "password", "manager"); |
| |
| boolean offline = UtilProperties.propertyValueEqualsIgnoreCase("appserver", "offline", "true"); |
| boolean redeploy = UtilProperties.propertyValueEqualsIgnoreCase("appserver", "redeploy", "true"); |
| |
| String geronimoHostHome = UtilProperties.getPropertyValue("appserver", "geronimoHostHome", null); |
| String host = UtilProperties.getPropertyValue("appserver", "host", ""); |
| String port = UtilProperties.getPropertyValue("appserver", "port", ""); |
| boolean pauseInGeronimoScript = UtilProperties.propertyValueEqualsIgnoreCase("appserver", "pauseInGeronimoScript", "true"); |
| |
| int instancesNumber = (int) UtilProperties.getPropertyNumber("appserver", "instancesNumber"); |
| String instanceNumber = ""; |
| |
| if (isGeronimo) { |
| File geronimoHomeDir = new File (geronimoHome); |
| if (!(geronimoHomeDir.isDirectory())) { |
| Debug.logFatal("*** " + geronimoHome + " does not exist or is not a directoy. Please set the location of Geronimo into a GERONIMO_HOME env var or as a geronimoHome property in appserver.properties file.", module); |
| throw new ContainerException("Error in Geronimo deployment, please check the log"); |
| } |
| |
| if (UtilValidate.isNotEmpty(host) && UtilValidate.isNotEmpty(geronimoHostHome)) { |
| geronimoHomeDir = new File ("//" + host + "/" + geronimoHostHome); |
| if (!(geronimoHomeDir.isDirectory())) { |
| Debug.logFatal("*** " + geronimoHostHome + " does not exist or is not a directoy. Please set the location of Geronimo on host as a geronimoHostHome property in appserver.properties file.", module); |
| throw new ContainerException("Error in Geronimo deployment, please check the log"); |
| } |
| } else { |
| geronimoHostHome = geronimoHome; |
| } |
| |
| if (redeploy && offline) { |
| Debug.logFatal("*** You can't use redeploy with a server offline.", module); |
| throw new ContainerException("Error in Geronimo deployment, please check the log"); |
| } |
| |
| for(int inst = 0; inst <= instancesNumber; inst++) { |
| instanceNumber = (inst == 0 ? "" : inst).toString(); |
| GenerateGeronimoDeployment geronimoDeployment = new GenerateGeronimoDeployment(); |
| List<String> classpathJars = geronimoDeployment.generate(args[0], geronimoHostHome, instanceNumber); |
| if (classpathJars == null) { |
| throw new ContainerException("Error in Geronimo deployment, please check the log"); |
| } |
| dataMap.put("classpathJars", classpathJars); |
| dataMap.put("pathSeparatorChar", File.pathSeparatorChar); |
| dataMap.put("instanceNumber", instanceNumber); |
| // if (UtilValidate.isNotEmpty(instanceNumber)) { |
| // List webApps = (List) dataMap.get("webApps"); |
| // for (Object webAppObject: webApps) { |
| // WebappInfo webAppInfo = (ComponentConfig.WebappInfo) webAppObject; |
| // String webAppLocation = webAppInfo.getLocation(); |
| // String webXmlLocation = webAppLocation + "/WEB-INF/web.xml"; |
| // if (isFileExistsAndCanWrite(webXmlLocation)) { |
| // DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); |
| // DocumentBuilder docBuilder = null; |
| // try { |
| // docBuilder = docFactory.newDocumentBuilder(); |
| // } catch (ParserConfigurationException e) { |
| // throw new ContainerException(e); |
| // } |
| // Document doc = null; |
| // try { |
| // doc = docBuilder.parse(webXmlLocation); |
| // } catch (SAXException e) { |
| // throw new ContainerException(e); |
| // } catch (IOException e) { |
| // throw new ContainerException(e); |
| // } |
| // Node webApp = doc.getFirstChild(); |
| // Node contextParam = doc.createElement("context-param"); |
| // NamedNodeMap contextParamAttributes = contextParam.getAttributes(); |
| // |
| // Attr paramName = doc.createAttribute("param-name"); |
| // paramName.setValue("instanceNumber"); |
| // contextParamAttributes.setNamedItem(paramName); |
| // |
| // Attr paramValue = doc.createAttribute("param-value"); |
| // paramValue.setValue(instanceNumber); |
| // contextParamAttributes.setNamedItem(paramValue); |
| // // Node nodeToAppend = doc.importNode(contextParam, true); this should not be needed |
| // // webApp.appendChild(nodeToAppend); |
| // |
| // // webApp.appendChild(contextParam); this is the line needed but commented for now |
| // |
| // Transformer transformer; |
| // try { |
| // transformer = TransformerFactory.newInstance().newTransformer(); |
| // } catch (TransformerConfigurationException e) { |
| // throw new ContainerException(e); |
| // } catch (TransformerFactoryConfigurationError e) { |
| // throw new ContainerException(e); |
| // } |
| // transformer.setOutputProperty(OutputKeys.INDENT, "yes"); |
| // |
| // StreamResult result = new StreamResult(new StringWriter()); |
| // DOMSource source = new DOMSource(doc); |
| // try { |
| // transformer.transform(source, result); |
| // } catch (TransformerException e) { |
| // throw new ContainerException(e); |
| // } |
| // String xmlString = result.getWriter().toString(); |
| // System.out.println(xmlString); //TODO write to file using writeToXmlFile |
| // break; // Only the 1st web.xml file need to be modified |
| // } else { |
| // Debug.logInfo("Unable to change the deployment descriptor : " + webXmlLocation + ". Maybe it does not exist, or is in read only mode ?", module); |
| // } |
| // } |
| // } |
| |
| //Debug.logInfo("Using Data : " + dataMap, module); |
| for (int i = 0; i < files.length; i++) { |
| if (!(files[i].isDirectory() || files[i].isHidden() || files[i].getName().equalsIgnoreCase("geronimo-web.xml"))) { |
| parseTemplate(files[i], dataMap); |
| } |
| } |
| |
| String ofbizName = "ofbiz" + instanceNumber; |
| String separator = File.separator; |
| File workingDir = new File(geronimoHome + separator + "bin"); |
| ProcessBuilder processBuilder = null; |
| Process process = null; |
| String command = null; |
| String commandCommonPart = null; |
| if ("\\".equals(separator)) { //Windows |
| commandCommonPart = "deploy --user " + user + " --password " + password; |
| } else { // Linux |
| commandCommonPart = workingDir + "/deploy.sh --user " + user + " --password " + password; |
| } |
| if (UtilValidate.isNotEmpty(host)) { |
| commandCommonPart += " --host " + host + (UtilValidate.isNotEmpty(port) ? " --port " + port : ""); |
| } |
| |
| if (!redeploy) { |
| if ("\\".equals(separator)) { //Windows |
| if (offline) { |
| command = commandCommonPart + " --offline undeploy " + ofbizName; |
| } else { |
| command = commandCommonPart + " undeploy " + ofbizName; |
| } |
| processBuilder = new ProcessBuilder("cmd.exe", "/c", command); |
| } else { // Linux |
| if (offline) { |
| command = commandCommonPart + " --offline undeploy " + ofbizName; |
| } else { |
| command = commandCommonPart + " undeploy " + ofbizName; |
| } |
| processBuilder = new ProcessBuilder("sh", "-c", command); |
| } |
| |
| if (pauseInGeronimoScript) { |
| Map<String, String> env = processBuilder.environment(); |
| env.put("GERONIMO_BATCH_PAUSE", "on"); |
| } |
| processBuilder.directory(workingDir); |
| |
| try { |
| System.out.println("Currently undeploying " + ofbizName + ", using : <<" + command + ">>, please wait ..."); |
| processBuilder.redirectErrorStream(true); |
| process = processBuilder.start(); |
| java.io.InputStream is = process.getInputStream(); |
| byte[] buf = new byte[2024]; |
| int readLen = 0; |
| while ((readLen = is.read(buf,0,buf.length)) != -1) { |
| if ("\\".equals(separator)) { //Windows |
| System.out.print(new String(buf,0,readLen)); |
| } else { |
| System.out.println(new String(buf,0,readLen)); |
| } |
| } |
| is.close(); |
| process.waitFor(); |
| // System.out.println(process.waitFor()); |
| // System.out.println("exit value" + process.exitValue()); |
| Debug.logInfo(ofbizName + " undeployment ended" , module); |
| } catch (IOException e) { |
| throw new ContainerException(e); |
| } catch (InterruptedException e) { |
| throw new ContainerException(e); |
| } finally { |
| process.destroy(); |
| } |
| } |
| |
| if (redeploy) { |
| if ("\\".equals(separator)) { //Windows |
| command = commandCommonPart + " redeploy " + ofbizHome; |
| processBuilder = new ProcessBuilder("cmd.exe", "/c", command); |
| } else { // Linux |
| command = commandCommonPart + " redeploy " + ofbizHome; |
| processBuilder = new ProcessBuilder("sh", "-c", command); |
| } |
| |
| } else { |
| if ("\\".equals(separator)) { //Windows |
| if (offline) { |
| command = commandCommonPart + " --offline deploy --inPlace " + ofbizHome; |
| } else { |
| command = commandCommonPart + " deploy --inPlace " + ofbizHome; |
| } |
| processBuilder = new ProcessBuilder("cmd.exe", "/c", command); |
| } else { // Linux |
| if (offline) { |
| command = commandCommonPart + " --offline deploy --inPlace " + ofbizHome; |
| } else { |
| command = commandCommonPart + " deploy --inPlace " + ofbizHome; |
| } |
| processBuilder = new ProcessBuilder("sh", "-c", command); |
| } |
| } |
| |
| if (pauseInGeronimoScript) { |
| Map<String, String> env = processBuilder.environment(); |
| env.put("GERONIMO_BATCH_PAUSE", "on"); |
| } |
| processBuilder.directory(workingDir); |
| |
| try { |
| System.out.println("Currently deploying " + ofbizName + ", using : <<" + command + ">>, please wait ..."); |
| processBuilder.redirectErrorStream(true); |
| process = processBuilder.start(); |
| java.io.InputStream is = process.getInputStream(); |
| byte[] buf = new byte[2024]; |
| int readLen = 0; |
| while ((readLen = is.read(buf,0,buf.length)) != -1) { |
| if ("\\".equals(separator)) { //Windows |
| System.out.print(new String(buf,0,readLen)); |
| } else { |
| System.out.println(new String(buf,0,readLen)); |
| } |
| } |
| is.close(); |
| process.waitFor(); |
| // System.out.println(process.waitFor()); |
| // System.out.println("exit value" + process.exitValue()); |
| Debug.logInfo(ofbizName + " deployment ended" , module); |
| } catch (IOException e) { |
| throw new ContainerException(e); |
| } catch (InterruptedException e) { |
| throw new ContainerException(e); |
| } finally { |
| process.destroy(); |
| } |
| } |
| } else { |
| //Debug.logInfo("Using Data : " + dataMap, module); |
| for (int i = 0; i < files.length; i++) { |
| if (!files[i].isDirectory() && !files[i].isHidden()) { |
| parseTemplate(files[i], dataMap); |
| } |
| } |
| } |
| } |
| |
| private File[] getTemplates() throws ContainerException { |
| if (args == null) { |
| throw new ContainerException("Invalid application server type argument passed"); |
| } |
| |
| String templateLocation = args[0]; |
| if (templateLocation == null) { |
| throw new ContainerException("Unable to locate Application Server template directory"); |
| } |
| |
| File parentDir = new File(ofbizHome + source + templateLocation); |
| if (!parentDir.exists() || !parentDir.isDirectory()) { |
| throw new ContainerException("Template location - " + templateLocation + " does not exist!"); |
| } |
| |
| return parentDir.listFiles(); |
| } |
| |
| private Map<String, Object> buildDataMap() throws ContainerException { |
| Map<String, Object> dataMap = FastMap.newInstance(); |
| List<?> c[] = getClasspath(); |
| dataMap.put("targetDirectory", getTargetDirectory()); |
| dataMap.put("pathSeparatorChar", File.pathSeparatorChar); |
| dataMap.put("classpath", System.getProperty("java.class.path")); |
| dataMap.put("classpathJars", c[0]); |
| dataMap.put("classpathDirs", c[1]); |
| dataMap.put("env", System.getProperties()); |
| dataMap.put("webApps", ComponentConfig.getAllWebappResourceInfos()); |
| dataMap.put("ofbizHome", System.getProperty("ofbiz.home")); |
| return dataMap; |
| } |
| |
| private List<?>[] getClasspath() { |
| Classpath classPath = new Classpath(System.getProperty("java.class.path")); |
| List<File> elements = classPath.getElements(); |
| List<String> jar = FastList.newInstance(); |
| List<String> dir = FastList.newInstance(); |
| |
| for (File f: elements) { |
| if (f.exists()) { |
| if (f.isDirectory()) { |
| String path = f.getAbsolutePath(); |
| dir.add(path.replace('\\','/')); |
| } else { |
| String path = f.getAbsolutePath(); |
| jar.add(path.replace('\\','/')); |
| } |
| } |
| } |
| List<?>[] lists = { jar, dir }; |
| return lists; |
| } |
| |
| private String getTargetDirectory() throws ContainerException { |
| // create the target file/directory |
| String targetDirectoryName = args.length > 1 ? args[1] : null; |
| if (targetDirectoryName == null) { |
| targetDirectoryName = target; |
| } |
| String targetDirectory = null; |
| if (!isGeronimo) { |
| targetDirectory = ofbizHome + targetDirectoryName + args[0]; |
| } else { |
| targetDirectory = ofbizHome + targetDirectoryName; |
| } |
| File targetDir = new File(targetDirectory); |
| if (!targetDir.exists()) { |
| boolean created = targetDir.mkdirs(); |
| if (!created) { |
| throw new ContainerException("Unable to create target directory - " + targetDirectory); |
| } |
| } |
| |
| if (!targetDirectory.endsWith("/")) { |
| targetDirectory = targetDirectory + "/"; |
| } |
| |
| return targetDirectory; |
| } |
| |
| private void parseTemplate(File templateFile, Map<String, Object> dataMap) throws ContainerException { |
| Debug.logInfo("Parsing template : " + templateFile.getAbsolutePath(), module); |
| Reader reader = null; |
| try { |
| reader = new InputStreamReader(new FileInputStream(templateFile)); |
| } catch (FileNotFoundException e) { |
| throw new ContainerException(e); |
| } finally { |
| if (reader != null) { |
| try { |
| reader.close(); |
| } catch (IOException e) { |
| throw new ContainerException(e); |
| } |
| } |
| } |
| |
| // create the target file/directory |
| String targetDirectory = getTargetDirectory(); |
| |
| // write the template to the target directory |
| Writer writer = null; |
| try { |
| writer = new FileWriter(targetDirectory + templateFile.getName()); |
| try { |
| FreeMarkerWorker.renderTemplate(UtilURL.fromFilename(templateFile.getAbsolutePath()).toExternalForm(), dataMap, writer); |
| } catch (Exception e) { |
| throw new ContainerException(e); |
| } |
| } catch (IOException e) { |
| throw new ContainerException(e); |
| } finally { |
| try { |
| if (writer != null) { |
| writer.flush(); |
| writer.close(); |
| } |
| } catch (IOException e) { |
| throw new ContainerException(e); |
| } |
| } |
| |
| } |
| |
| // This method writes a DOM document to a file |
| public static void writeToXmlFile(Document doc, String filename) { |
| try { |
| // Prepare the DOM document for writing |
| Source source = new DOMSource(doc); |
| |
| // Prepare the output file |
| File file = new File(filename); |
| Result result = new StreamResult(file); |
| |
| // Write the DOM document to the file |
| Transformer xformer = TransformerFactory.newInstance().newTransformer(); |
| xformer.transform(source, result); |
| } catch (TransformerConfigurationException e) { |
| } catch (TransformerException e) { |
| } |
| } |
| |
| public boolean isFileExistsAndCanWrite(String fileName) { |
| File f = new File(fileName); |
| return f.exists() && f.canWrite(); |
| } |
| } |