001: /**
002: * $Id: Cacao.java,v 1.41.2.2 2007/04/16 11:10:51 ns208321 Exp $
003: * Copyright 2004 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.fabric.tasks;
014:
015: import java.io.File;
016: import java.io.IOException;
017: import java.lang.reflect.*;
018: import java.util.ArrayList;
019: import java.util.List;
020: import java.util.logging.Level;
021: import java.util.logging.Logger;
022: import java.util.logging.LogRecord;
023: import com.sun.portal.log.common.PortalLogManager;
024: import com.sun.portal.log.common.PortalLogger;
025:
026: import com.sun.portal.admin.common.Tags;
027: import com.sun.portal.admin.common.context.PSConfigContext;
028: import com.sun.portal.fabric.util.ExecuteUtil;
029: import com.sun.portal.fabric.util.FileUtil;
030: import com.sun.portal.util.Platform;
031: import com.sun.portal.fabric.tasks.ConfigurationException;
032:
033: /**
034: * This class provides methods to configure
035: * the Cacao Node Agent and load the Portal
036: * Services into the Identity Server
037: */
038: public class Cacao {
039: private static String logProperties = "PSAdminLogConfig.properties";
040: private static final String logConfigFileOption = "com.sun.portal.log.config.file";
041: private static final String ubtVMOption = " -Djava.awt.headless=true ";
042: private static final String fs = Platform.fs;
043: private static final String CACAO_ADMIN = "cacaoadm";
044: public static final String STATUS = "status";
045: private static final String JAVA_FLAGS = "java-flags";
046: private static final String GET_PARAM = "get-param";
047: private static final String SET_PARAM = "set-param";
048: private static final String ENABLED = "ENABLED";
049: private static final String ENABLE = "enable";
050: private static final String START = "start";
051: private static final String STOP = "stop";
052: private static final String LIST_MODULES = "list-modules";
053: private static final String REGISTER = "register-module";
054: private static final String UNREGISTER = "unregister-module";
055: private static final String UNDEPLOY = "undeploy";
056: private static final String DEPLOY = "deploy";
057: private static final String RESTART = "restart";
058: private static final String SHOW_CERT_CHAIN = "show-cert-chain";
059:
060: public static final String CACAO_UPTIME = "ptime";
061: // CR 6401176. Parameter added to fix CR.
062: public static final String NETWORK_PARAM = "network-bind-address";
063: public static final String NETWORK_BIND_ADDRESS = "0.0.0.0";
064: public static final String NETWORK_LOCALHOST_ADDRESS = "127.0.0.1";
065:
066: private static Logger logger = PortalLogger.getLogger(Cacao.class);
067: private PSConfigContext pcc = null;
068: private ExecuteUtil execUtil = null;
069: private String cacaoadm = null;
070: private List ROUTINES = null;
071: private String cacaoAdmCmd = null;
072: private int iNumRoutines = 0;
073:
074: /**
075: * Constructor for Cacao
076: *
077: * @param psDataDir Portal Server data directory path as String
078: * @param psProductDir Portal Server installation directory path as String
079: * @param isProductDir Identity Server installation directory path as String
080: * @param cacaoProductDir Cacao framework install basedir path as String
081: */
082: public Cacao(PSConfigContext pcc) {
083:
084: this .pcc = pcc;
085: execUtil = new ExecuteUtil();
086: execUtil.storeOutput(true);
087: Platform.psConfDir = pcc.getPSConfigDir();
088: cacaoadm = Platform.getCommand("cacaoadm");
089:
090: ROUTINES = new ArrayList();
091:
092: // com.sun.portal.admin.server.module
093: ROUTINES.add("get_data_com_sun_portal_admin_server_module");
094:
095: iNumRoutines = ROUTINES.size();
096: }
097:
098: private LogRecord getLogRecord(Level level, String message,
099: Object[] parameters, Throwable t) {
100: LogRecord result = new LogRecord(level, message);
101: result.setLoggerName(logger.getName());
102: result.setParameters(parameters);
103: result.setThrown(t);
104: return result;
105: }
106:
107: public final List get_data_com_sun_portal_admin_server_module(
108: final boolean bIsConfigure) {
109:
110: String sModule = "com.sun.portal.admin.server.module";
111: String sTemplate = pcc.getPSBaseDir() + fs + "admin" + fs
112: + sModule + ".xml";
113:
114: List list = new ArrayList();
115: list.add(sModule);
116: list.add(sTemplate);
117:
118: if (bIsConfigure) {
119:
120: String[] sTokens = { Tags.SHARED_LIB_LOCATION,
121: Tags.AM_PRODUCT_LOCATION, Tags.AM_CONFIG_LOCATION,
122: Tags.PS_PRODUCT_LOCATION, Tags.PS_JARS,
123: Tags.PS_CONFIG_LOCATION,
124: Tags.PRIVATE_SHARE_LIB_LOCATION,
125: Tags.JSS_JAR_LIB_LOCATION, Tags.JDK_LIB_LOCATION,
126: Tags.JESMF_LIB_LOCATION,
127: Tags.REGISTRY_LIB_LOCATION, Tags.ANT_LIB_LOCATION,
128: Tags.JAX_LIB_LOCATION };
129:
130: String psLibDirName = pcc.getPSBaseDir() + fs + "lib";
131: File psLibDir = new File(psLibDirName);
132: String ls = System.getProperty("line.separator", "\n");
133: StringBuffer psJars = new StringBuffer();
134: File[] files = psLibDir.listFiles();
135:
136: for (int i = 0; i < files.length; i++) {
137:
138: String fileName = files[i].getName();
139:
140: if (fileName.endsWith(".jar")
141: && !fileName.startsWith("admin_cli")) {
142:
143: psJars.append(" <path-element>" + ls);
144: psJars.append(" file:");
145: psJars.append(psLibDirName + fs + fileName);
146: psJars.append(ls);
147: psJars.append(" </path-element>" + ls + ls);
148: }
149: }
150:
151: String sJesMfLibDir = pcc.getJESMFLibDir();
152: sJesMfLibDir = (sJesMfLibDir != null) ? sJesMfLibDir : "";
153:
154: String sJAXLibDir = pcc.getJAXLibDir();
155: sJAXLibDir = (sJAXLibDir != null) ? sJAXLibDir : "";
156:
157: String[] sValues = { pcc.getSharedLibsDir(),
158: pcc.getISBaseDir(), pcc.getISConfigDir(),
159: pcc.getPSBaseDir(), psJars.toString(),
160: pcc.getPSConfigDir(),
161: pcc.getPrivateSharedLibsDir(), pcc.getJSSJARDir(),
162: pcc.getJavaHome() + fs + "lib", sJesMfLibDir,
163: pcc.getRegistryLibDir(), pcc.getAntLibDir(),
164: sJAXLibDir };
165:
166: list.add(sTokens);
167: list.add(sValues);
168: }
169:
170: return list;
171: }
172:
173: public final List get_data_com_sun_cmm_ps_module(
174: final boolean bIsConfigure) {
175:
176: String sModule = "com.sun.cmm.ps";
177: String sTemplate = pcc.getPSBaseDir() + fs + "template" + fs
178: + "jesmf" + fs + sModule + ".xml";
179:
180: List list = new ArrayList();
181: list.add(sModule);
182: list.add(sTemplate);
183:
184: if (bIsConfigure) {
185:
186: String[] sTokens = { Tags.PS_PRODUCT_LOCATION,
187: Tags.PS_INSTALL_DATETIME, Tags.PRODUCT_VERSION };
188:
189: // Get PS Version
190: String psBaseDir = pcc.getPSBaseDir();
191: String psVersionPath = psBaseDir + fs + "lib" + fs
192: + "PSversion.properties";
193: File psVersionFile = new File(psVersionPath);
194: StringBuffer sb = new StringBuffer(256);
195:
196: String productVersion = null;
197: if (psVersionFile.exists()) {
198: productVersion = FileUtil.findTextInFile(psVersionFile,
199: "productversion=");
200: if (productVersion != null) {
201: int index = productVersion.indexOf("=");
202: productVersion = productVersion
203: .substring(index + 1);
204: }
205: }
206:
207: if (productVersion == null) {
208: productVersion = "???";
209: }
210:
211: String[] sValues = { pcc.getPSBaseDir(),
212: String.valueOf(System.currentTimeMillis()),
213: productVersion };
214:
215: list.add(sTokens);
216: list.add(sValues);
217: }
218:
219: return list;
220: }
221:
222: public final String execCommand(final String sScriptPath,
223: final String[] sArgs, final boolean bOutput) {
224: execUtil.storeOutput(bOutput);
225: execUtil.exec(sScriptPath, sArgs);
226: String result = execUtil.getOutput();
227: if (logger.isLoggable(Level.INFO)) {
228: StringBuffer sb = new StringBuffer();
229: sb.append(sScriptPath);
230: for (int i = 0; i < sArgs.length; i++) {
231: sb.append(" " + sArgs[i]);
232: }
233: String cmd = sb.toString();
234: logger.log(getLogRecord(Level.INFO, "PSFB_CSPFT0342",
235: new Object[] { cmd, result }, null));
236: }
237: return (bOutput ? execUtil.getOutput() : null);
238: }
239:
240: public final String execCacaoCommand(final String sCommand,
241: final String sParam, final boolean bOutput) {
242:
243: String[] args = (sParam != null) ? new String[] { sCommand,
244: sParam } : new String[] { sCommand };
245: return execCommand(cacaoadm, args, bOutput);
246: }
247:
248: /**
249: * Get token replaced module file.
250: */
251: public final String getTokenReplacedModuleFile(final List list) {
252:
253: String sModule = (String) list.get(0);
254: String template = (String) list.get(1);
255: String dd = System.getProperty("java.io.tmpdir", "/tmp") + fs
256: + sModule + ".xml";
257: File templateFile = new File(template);
258: File ddFile = new File(dd);
259: ddFile.deleteOnExit();
260: FileUtil.copyFile(templateFile, ddFile);
261: String[] sTokens = (String[]) list.get(2);
262: String[] sValues = (String[]) list.get(3);
263: FileUtil.replaceTokensInFile(ddFile, sTokens, sValues);
264:
265: return dd;
266: }
267:
268: /**
269: * Configures the Cacao Node Agent Server with the
270: * Portal Server Management Module.
271: */
272: public void configureDomain() throws ConfigurationException {
273:
274: try {
275:
276: // Generic setting
277: // set PS specific java flags
278: boolean requiresConfigChange = false;
279: boolean requiresConfigNWParamChange = false;
280: String pattern = JAVA_FLAGS + "=";
281:
282: // java.awt.headless property is essential for UBT reports
283: String line = execCacaoCommand(GET_PARAM, JAVA_FLAGS, true);
284: int index = line.indexOf(pattern);
285:
286: String logFileStr = " -D" + logConfigFileOption + "="
287: + pcc.getPSConfigDir() + fs
288: + "PSAdminLogConfig.properties";
289: String newLine = null;
290: String ubtVMOption = " -Djava.awt.headless=true ";
291: if (index < 0) {
292: newLine = pattern + "-Xms128M -Xmx256M" + ubtVMOption
293: + logFileStr;
294: requiresConfigChange = true;
295: } else {
296: newLine = modifyHeapSize(line, "-Xms", 128, "-Xms128M");
297: newLine = modifyHeapSize(newLine, "-Xmx", 256,
298: "-Xmx256M");
299:
300: // set the log config file option
301: if (newLine.indexOf(logConfigFileOption) < 0) {
302: newLine = newLine + logFileStr;
303: }
304:
305: // set the java.awt.headless property for UBT reports
306: if (newLine.indexOf(ubtVMOption) < 0) {
307: newLine = newLine + ubtVMOption;
308: }
309:
310: if (!newLine.equals(line)) {
311: requiresConfigChange = true;
312: }
313: }
314:
315: // Copy the Portal Admin Server cacao module deployment
316: // descriptor file into a temp directory and register it to cacao.
317: List modulesV = new ArrayList();
318: List deployLocV = new ArrayList();
319: Class cls = this .getClass();
320: Class[] paramTypes = new Class[] { Boolean.TYPE };
321: Object[] argList = new Object[] { Boolean.TRUE };
322: for (int i = 0; i < iNumRoutines; i++) {
323:
324: String sMethodName = (String) ROUTINES.get(i);
325: Method meth = cls.getMethod(sMethodName, paramTypes);
326:
327: List list = (List) meth.invoke(this , argList);
328:
329: String dd = getTokenReplacedModuleFile(list);
330: execCacaoCommand(REGISTER, dd, false);
331: String sModule = (String) list.get(0);
332: modulesV.add(sModule);
333: deployLocV.add(dd);
334: }
335:
336: String status = execCacaoCommand(STATUS, null, true);
337:
338: // Enable cacao if not already done.
339: if (status.indexOf(ENABLED) == -1) {
340:
341: execCacaoCommand(ENABLE, null, false);
342: }
343: // CR 6401176. To update Cacao config for network access
344: String networkBindAddr = execCacaoCommand(GET_PARAM,
345: NETWORK_PARAM, true);
346: int strIndex;
347:
348: if ((networkBindAddr != null)
349: && (strIndex = networkBindAddr.indexOf('=')) >= 0) {
350: //For CR 6401176 - Change the binding address to 0.0.0.0 only if it is not set previously by
351: //some other component (i.e.) if the bind address is 127.0.0.1(localhost)
352: if ((networkBindAddr.substring(strIndex + 1)).trim()
353: .equals(NETWORK_LOCALHOST_ADDRESS)) {
354: requiresConfigNWParamChange = true;
355: }
356: }
357:
358: boolean bStart = false;
359: if (requiresConfigChange || requiresConfigNWParamChange) {
360: if (status.indexOf(CACAO_UPTIME) > 0) {
361:
362: execCacaoCommand(STOP, null, false);
363: }
364:
365: if (requiresConfigChange) {
366: execCacaoCommand(SET_PARAM, newLine, false);
367: }
368: if (requiresConfigNWParamChange) {
369: execCacaoCommand(SET_PARAM, NETWORK_PARAM + "="
370: + NETWORK_BIND_ADDRESS, false);
371: logger.log(Level.SEVERE, "PSFB_CSPFT0344");
372: }
373: bStart = true;
374: } else if (status.indexOf(CACAO_UPTIME) == -1) {
375: bStart = true;
376: }
377:
378: if (bStart) {
379:
380: execCacaoCommand(START, null, false);
381: } else {
382:
383: // Undeploy any already existing instance before redeploying them.
384: String sListOfModules = execCacaoCommand(LIST_MODULES,
385: null, true);
386:
387: for (int i = 0; i < iNumRoutines; i++) {
388:
389: String sModule = (String) modulesV.get(i);
390: if (sListOfModules.indexOf(sModule) >= 0) {
391:
392: execCacaoCommand(UNDEPLOY, sModule, false);
393: }
394:
395: String dd = (String) deployLocV.get(i);
396: execCacaoCommand(DEPLOY, dd, false);
397: }
398: }
399: } catch (NoSuchMethodException e0) {
400: // FIXME: handle exception
401: logger.log(Level.SEVERE, "PSFB_CSPFT0203", e0);
402: throw new ConfigurationException(e0);
403: } catch (Exception e1) {
404: // FIXME: handle exception
405: logger.log(Level.SEVERE, "PSFB_CSPFT0203", e1);
406: throw new ConfigurationException(e1);
407: }
408: }
409:
410: /**
411: * Configure Cacao security.
412: * Required to establish trust between remote and local cacao
413: * start cacao
414: * cacaoadm show-cert-chain -u "service:jmx:cacao-rmi://<remote-host>;username=foo" -d /tmp
415: * keytool -import -alias remote_cert_alias -file /tmp/certificate1 -noprompt -storetype JKS -keystore /etc/opt/SUNWportal/truststore -storepass password
416: */
417: public void configureSecurity(String psHost, String amadmin,
418: String psDataDir) throws ConfigurationException {
419:
420: String tempDir = psDataDir + fs + "tmp" + fs
421: + FileUtil.getRandomDirName();
422: FileUtil.makeDir(tempDir);
423:
424: String[] showCertChain = { SHOW_CERT_CHAIN, "-u",
425: "service:jmx:cacao-rmi://" + psHost + ";username=root",
426: "-d", tempDir };
427: String status = execCommand(cacaoadm, showCertChain, true);
428:
429: String certificateName = tempDir + fs + "certificate1";
430: String truststore = pcc.getPSConfigDir() + fs + "truststore";
431:
432: String[] args = { "-import", "-alias", psHost, "-file",
433: certificateName, "-noprompt", "-storetype", "JKS",
434: "-keystore", truststore, "-storepass", "password" };
435:
436: String keytoolPath = pcc.getJavaHome() + fs + "bin" + fs
437: + "keytool";
438: execCommand(keytoolPath, args, false);
439: FileUtil.deleteDir(tempDir);
440: }
441:
442: /**
443: * Removes the Portal Admin Server Module from the Cacao framework.
444: */
445: public void unconfigureDomain() {
446: try {
447:
448: // Unregister the modules from cacao.
449: List modulesV = new ArrayList();
450: Class cls = this .getClass();
451: Class[] paramTypes = new Class[] { Boolean.TYPE };
452: Object[] argList = new Object[] { Boolean.FALSE };
453: for (int i = 0; i < iNumRoutines; i++) {
454:
455: String sMethodName = (String) ROUTINES.get(i);
456: Method meth = cls.getMethod(sMethodName, paramTypes);
457:
458: List list = (List) meth.invoke(this , argList);
459:
460: String sModule = (String) list.get(0);
461: String template = (String) list.get(1);
462:
463: execCacaoCommand(UNREGISTER, sModule + ".xml", false);
464:
465: modulesV.add(sModule);
466: }
467:
468: // Undeploy the modules from cacao.
469: String sStatus = execCacaoCommand(STATUS, null, true);
470: String sListOfModules = execCacaoCommand(LIST_MODULES,
471: null, true);
472:
473: // Undeploy existing instance if cacao started.
474: if (sStatus.indexOf(CACAO_UPTIME) >= 0) {
475:
476: for (int i = 0; i < iNumRoutines; i++) {
477:
478: String sModule = (String) modulesV.get(i);
479: if (sListOfModules.indexOf(sModule) >= 0) {
480:
481: execCacaoCommand(UNDEPLOY, sModule, false);
482: }
483: }
484: }
485: } catch (Exception e) {
486: // FIXME: handle exception
487: logger.log(Level.SEVERE, "PSFB_CSPFT0204", e);
488: }
489: }
490:
491: /**
492: * Modifies the heap size option in the given line containing
493: * "java.flags=" if the setting is less than the given preferred size.
494: *
495: * @param line the line to be modified.
496: * @param option the heap size option (either "-Xms" or "-Xmx").
497: * @param preferredSize the preferred heap size in MB.
498: * @param preferredSetting the complete preferred heap size setting.
499: * @return the modified line.
500: */
501: private String modifyHeapSize(String line, String option,
502: int preferredSize, String preferredSetting) {
503:
504: int index = line.indexOf(option);
505:
506: if (index < 0) {
507: line = line + " " + preferredSetting;
508: } else {
509: String sizeSetting = line.substring(index);
510: int iOptionSize = option.length();
511: index = sizeSetting.indexOf(" ", iOptionSize);
512:
513: if (index >= iOptionSize) {
514: sizeSetting = sizeSetting.substring(0, index);
515: }
516:
517: String sizeString = sizeSetting.substring(iOptionSize);
518: sizeString = sizeString.trim();
519: int divider = 1048576;
520:
521: if (sizeString.endsWith("k") || sizeString.endsWith("K")) {
522: divider = 1024;
523: sizeString = sizeString.substring(0, sizeString
524: .length() - 1);
525: } else if (sizeString.endsWith("m")
526: || sizeString.endsWith("M")) {
527: divider = 1;
528: sizeString = sizeString.substring(0, sizeString
529: .length() - 1);
530: }
531:
532: long size = 0;
533:
534: try {
535: size = Long.parseLong(sizeString);
536: } catch (NumberFormatException e) {
537: logger.log(Level.SEVERE, "PSFB_CSPFT0205", e);
538: }
539:
540: size = size / divider;
541:
542: if (size < preferredSize) {
543: line = line.replaceFirst(sizeSetting, preferredSetting);
544: }
545: }
546:
547: return line;
548: }
549:
550: public void resetJavaFlags() {
551: try {
552: final String psLibDir = pcc.getPSBaseDir() + fs + "lib";
553: String clsPath = psLibDir + fs + "config.jar:" + psLibDir
554: + fs + "jdom.jar:" + psLibDir + fs + "fabric.jar:"
555: + psLibDir + fs + "admin_common.jar:" + psLibDir
556: + fs + "pslogcommon.jar:" + psLibDir + fs
557: + "ps_util.jar:" + psLibDir + fs + "fscontext.jar:"
558: + psLibDir + fs + "providerutil.jar";
559: String cmdArgs[] = {
560: pcc.getJavaHome() + fs + "bin" + fs + "java",
561: "-classpath", clsPath,
562: "com.sun.portal.fabric.config.ResetCacaoParams",
563: pcc.getCacaoBaseDir() };
564: StringBuffer strBuf = new StringBuffer();
565: for (int i = 0; i < cmdArgs.length; i++) {
566: strBuf.append(" " + cmdArgs[i]);
567: }
568: String sTitle = strBuf.toString();
569: logger.log(Level.INFO, "Resetting Cacao java-flags "
570: + sTitle);
571: try {
572: Runtime.getRuntime().exec(cmdArgs);
573: } catch (IOException e) {
574: logger.log(Level.SEVERE, "PSFB_CSPFT0342");
575: }
576: } catch (Exception e) {
577: logger.log(Level.SEVERE, "PSFB_CSPFT0204", e);
578: }
579: }
580: }
|