package hudson.plugins.deploy.websphere; import hudson.FilePath; import hudson.plugins.deploy.ContainerAdapter; import java.io.File; import java.io.IOException; import java.util.Hashtable; import java.util.Properties; import java.util.Set; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MalformedObjectNameException; import javax.management.Notification; import javax.management.NotificationFilterSupport; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.ReflectionException; import com.ibm.websphere.management.AdminClient; import com.ibm.websphere.management.AdminClientFactory; import com.ibm.websphere.management.Session; import com.ibm.websphere.management.application.AppConstants; import com.ibm.websphere.management.application.AppManagement; import com.ibm.websphere.management.application.AppManagementProxy; import com.ibm.websphere.management.application.AppNotification; import com.ibm.websphere.management.exception.AdminException; import com.ibm.websphere.management.exception.ConnectorException; import com.ibm.websphere.management.filetransfer.client.FileTransferClient; import com.ibm.ws.management.fileservice.FileTransferFactory; /** * Base class for WebSphere adapters. * * @author Antonio Sanso */ public abstract class WebSphereAdapter extends ContainerAdapter { public final String url; private String hostName; private String connectPort; private Hashtable prefs; private String earFile; private String appName; private AdminClient adminClient; private AppManagement appProxy; private String cellName; private String nodeName; private String serverInstance; private String installedAppsDir; private final String waitObject = "waitObject"; private boolean successFlag = true; private boolean isUpdate; private String taskType = null; private Properties waitProps = null; private String workspaceId; private Session session; private static final int HTTP_PREFIX=7; public WebSphereAdapter(String url) { this.url=url; prefs = new Hashtable(); session = new Session(); workspaceId = session.toString(); } private void setApplication(FilePath war) throws IOException, InterruptedException{ this.earFile=war.absolutize().toString(); String appNameTemp=earFile.substring(earFile.lastIndexOf("\\")+1); this.appName=appNameTemp.split("\\.")[0]; } private void createAppMgmtProxy() throws Exception{ appProxy = AppManagementProxy.getJMXProxyForClient(this.adminClient); } private void createAdminClient() throws ConnectorException{ Properties connectionProps = new Properties(); connectionProps.put (AdminClient.CONNECTOR_HOST, this.hostName); connectionProps.put (AdminClient.CONNECTOR_PORT, this.connectPort); connectionProps.put (AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP); connectionProps.put ("open.securityEnabled", "false"); // Get an AdminClient based on the connector properties adminClient = AdminClientFactory.createAdminClient(connectionProps); } private void setTargetServerString() throws ConnectorException{ ObjectName mBean; mBean = adminClient.getServerMBean(); if(mBean != null){ cellName = mBean.getKeyProperty("cell"); nodeName = mBean.getKeyProperty("node"); serverInstance = mBean.getKeyProperty("name"); } } private String getTargetServerString(){ StringBuffer targetServerString = new StringBuffer(); targetServerString.append("WebSphere:cell="); targetServerString.append(cellName); targetServerString.append(",node="); targetServerString.append(nodeName); targetServerString.append(",server="); targetServerString.append(serverInstance); return targetServerString.toString(); } private void setInstalledAppsDir()throws Exception{ String stagingLocation = null; FileTransferClient ftc = null; String installedAppsIPath = null; StringBuffer stb=new StringBuffer(); ftc = FileTransferFactory.getFileTransferClient(adminClient); stagingLocation = ftc.getServerStagingLocation(); installedAppsIPath = stagingLocation; if(installedAppsIPath.contains("temp")){ installedAppsIPath = installedAppsIPath.substring(0,installedAppsIPath.lastIndexOf("temp")); } if(installedAppsIPath.contains("config")){ installedAppsIPath = installedAppsIPath.substring(0,installedAppsIPath.lastIndexOf("config")); } stb.append(installedAppsIPath).append("installedApps").append(File.separator).append(cellName); installedAppsDir = stb.toString(); } private void setPreferences(){ Hashtable module2server = new Hashtable(); module2server.put("*", getTargetServerString()); prefs.put("moduleToServer", module2server); prefs.put("classLoadingMode", "1"); prefs.put (AppConstants.APPDEPL_MODULE_TO_SERVER, module2server); } private AdminAppJMXClient addJMXListener(String type) throws MalformedObjectNameException, NullPointerException, ConnectorException, InstanceNotFoundException{ AdminAppJMXClient adminAppJMXClient=null; NotificationFilterSupport myFilter = new NotificationFilterSupport (); myFilter.enableType (AppConstants.NotificationType); adminAppJMXClient = new AdminAppJMXClient(myFilter, (new StringBuilder()).append("Install: ").append(appName).toString(), type); return adminAppJMXClient; } private void setNotfStatus(boolean flag){ successFlag = flag; } private boolean getNotfStatus(){ return successFlag; } private void setHostnameAndPort(){ String urlTemp=url.substring(HTTP_PREFIX); this.hostName=urlTemp.split(":")[0]; this.connectPort=urlTemp.split(":")[1]; } public void installApplication(FilePath war)throws Exception{ setHostnameAndPort(); setApplication(war); createAdminClient(); createAppMgmtProxy(); AdminAppJMXClient adminAppJMXClient=addJMXListener("InstallApplication"); setTargetServerString(); setInstalledAppsDir(); setPreferences(); setNotfStatus(false); synchronized (waitObject){ if(appProxy.checkIfAppExists(appName, prefs, null)){ isUpdate = true; taskType = AppNotification.UPDATE; prefs.put("contenttype", "app"); appProxy.updateApplication(appName, null, earFile, "update", prefs, workspaceId); waitObject.wait(86400000); //oneday in milliseconds } else{ isUpdate = false; taskType = AppNotification.INSTALL; appProxy.installApplication(earFile, appName, prefs, null); waitObject.wait(86400000); //oneday in milliseconds } } if (getNotfStatus()){ String appStatus = getDistributionStatus(appName); int count = 0; while (appStatus != null && appStatus.equals(AppNotification.DISTRIBUTION_NOT_DONE) && count < 10){ Thread.sleep(1000); count++; appStatus =getDistributionStatus(appName); } if (appStatus != null){ if (appStatus.equals(AppNotification.DISTRIBUTION_DONE)){ if(!isUpdate){ adminAppJMXClient.startApplication(appName); } } /*else if (appStatus.equals(AppNotification.DISTRIBUTION_UNKNOWN)){ } else{ } }else{*/ } } } private String getDistributionStatus(String appName) throws AdminException, InterruptedException, MalformedObjectNameException, NullPointerException{ setNotfStatus(false); synchronized (waitObject){ taskType = AppNotification.DISTRIBUTION_STATUS_NODE; appProxy.getDistributionStatus(appName, new Hashtable(), session.getSessionId()); waitObject.wait(86400000); //oneday in milliseconds } String appStatus = (waitProps != null) ? waitProps.getProperty(AppNotification.DISTRIBUTION_STATUS_COMPOSITE) : null; ObjectName on = new ObjectName(appStatus); return on.getKeyProperty("distribution"); } //INNER CLASS class AdminAppJMXClient implements NotificationListener{ NotificationFilterSupport filterSupport; Object handback; ObjectName appMBean; String type; NotificationFilterSupport filter; public AdminAppJMXClient(NotificationFilterSupport filter, Object handback, String type) throws MalformedObjectNameException, NullPointerException, ConnectorException, InstanceNotFoundException{ this.filterSupport = filter; this.handback = handback; this.type = type; this.filter = filter; setAppManagementMBean(); registerNotificationListener(); } private void setAppManagementMBean() throws MalformedObjectNameException, NullPointerException, ConnectorException{ // Query for the ObjectName of the AppManagement MBean String query = "WebSphere:type=AppManagement,*"; ObjectName queryName = new ObjectName(query); Set s = adminClient.queryNames(queryName, null); if (!s.isEmpty()) { appMBean = (ObjectName)s.iterator().next(); } /*else{ }*/ } private void registerNotificationListener() throws InstanceNotFoundException, ConnectorException{ adminClient.addNotificationListener(appMBean, this, this.filter, this.handback); } public void handleNotification(Notification notification,Object handback) { AppNotification ev = (AppNotification)notification.getUserData (); if ((ev.taskName.equals("InstallApplication") ||ev.taskName.equals("AppDistributionNode")) && (ev.taskStatus.equals (AppNotification.STATUS_COMPLETED) || ev.taskStatus.equals (AppNotification.STATUS_FAILED))){ synchronized (waitObject){ if (AppNotification.STATUS_COMPLETED.equals (ev.taskStatus)){ setNotfStatus(true); } else{ setNotfStatus(false); } taskType = null; waitProps = ev.props; waitObject.notify(); } }/*else{ }*/ } private String startApplication(String appName) throws InstanceNotFoundException, MBeanException, ReflectionException, ConnectorException{ return (String) adminClient.invoke(appMBean, "startApplication", new Object[] { appName, new Hashtable(), null}, new String[] { String.class.getName(), Hashtable.class.getName(), String.class.getName()} ); } } }