Java tutorial
/** * $Header: /home/master/nWave-DM-Common/src/com/npower/dm/processor/JobProcessSelector.java,v 1.29 2008/06/16 10:11:14 zhao Exp $ * $Revision: 1.29 $ * $Date: 2008/06/16 10:11:14 $ * * =============================================================================================== * License, Version 1.1 * * Copyright (c) 1994-2006 NPower Network Software Ltd. All rights reserved. * * This SOURCE CODE FILE, which has been provided by NPower as part * of a NPower product for use ONLY by licensed users of the product, * includes CONFIDENTIAL and PROPRIETARY information of NPower. * * USE OF THIS SOFTWARE IS GOVERNED BY THE TERMS AND CONDITIONS * OF THE LICENSE STATEMENT AND LIMITED WARRANTY FURNISHED WITH * THE PRODUCT. * * IN PARTICULAR, YOU WILL INDEMNIFY AND HOLD NPower, ITS RELATED * COMPANIES AND ITS SUPPLIERS, HARMLESS FROM AND AGAINST ANY CLAIMS * OR LIABILITIES ARISING OUT OF THE USE, REPRODUCTION, OR DISTRIBUTION * OF YOUR PROGRAMS, INCLUDING ANY CLAIMS OR LIABILITIES ARISING OUT OF * OR RESULTING FROM THE USE, MODIFICATION, OR DISTRIBUTION OF PROGRAMS * OR FILES CREATED FROM, BASED ON, AND/OR DERIVED FROM THIS SOURCE * CODE FILE. * =============================================================================================== */ package com.npower.dm.processor; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import sync4j.framework.config.Configuration; import sync4j.framework.config.ConfigurationConstants; import sync4j.framework.core.Alert; import sync4j.framework.core.ComplexData; import sync4j.framework.core.Item; import sync4j.framework.core.MetInf; import sync4j.framework.core.Meta; import sync4j.framework.core.Source; import sync4j.framework.core.dm.ddf.DevInfo; import sync4j.framework.engine.dm.DeviceDMState; import sync4j.framework.engine.dm.ManagementException; import sync4j.framework.engine.dm.ManagementProcessor; import sync4j.framework.protocol.ManagementInitialization; import sync4j.framework.server.dm.ProcessorSelector; import sync4j.framework.tools.beans.BeanInitializationException; import sync4j.framework.tools.beans.LazyInitBean; import com.npower.dm.core.DMException; import com.npower.dm.core.Device; import com.npower.dm.core.ProvisionJob; import com.npower.dm.core.Update; import com.npower.dm.management.DeviceBean; import com.npower.dm.management.ManagementBeanFactory; import com.npower.dm.management.ProvisionJobBean; import com.npower.dm.management.UpdateImageBean; import com.npower.dm.server.engine.EngineConfig; /** * This is an implementation of ProcessorSelector that selects a management * processor looking up the DM Provision jobs . * <p> * If no device doesn't found for the given session id, the processor specified by * <i>errorProcessor</i> is used. * <p> * If queue for the given device is empty, the processor specified by * <i>defaultProcessor</i> is used. * <p> * If found queued job for the given device, the processor will be selected and specified * based on JobType: * <li>CommandProcessor</li> * <li>TreeDiscoveryProcessor</li> * <li>ProfileAssignmentProcessor</li> * <li>ProfileReAssignmentProcessor</li> * * * <p> * * <p> * * * @author Zhao DongLu * @version $Revision: 1.29 $ $Date: 2008/06/16 10:11:14 $ */ public class JobProcessSelector implements ProcessorSelector, LazyInitBean, ConfigurationConstants { private static Log log = LogFactory.getLog(JobProcessSelector.class); /** * The default processor server bean name */ private String defaultProcessor; /** * The error processor server bean name */ private String errorProcessor; /** * If true, will always return JobQueueProcessor. */ private boolean alwaysQueueProcessor = true; /** * */ public JobProcessSelector() { super(); } class ProcessorRecord { private String processName = null; private long jobID = 0; /** * */ public ProcessorRecord() { super(); } /** * @param jobID * @param processName */ public ProcessorRecord(long jobID, String processName) { super(); this.jobID = jobID; this.processName = processName; } /** * @return Returns the processName. */ public String getProcessName() { return processName; } /** * @param processName The processName to set. */ public void setProcessName(String processName) { this.processName = processName; } /** * @return Returns the jobID. */ public long getJobID() { return jobID; } /** * @param jobID The jobID to set. */ public void setJobID(long jobID) { this.jobID = jobID; } } // Setter and Getters ******************************************************************* /** * Sets defaultProcessor * * @param defaultProcessor the new default processor name */ public void setDefaultProcessor(String defaultProcessor) { this.defaultProcessor = defaultProcessor; } /** * Returns defaultProcessor * * @return defaultProcessor property value */ public String getDefaultProcessor() { return this.defaultProcessor; } /** * Sets errorProcessor * * @param errorProcessor the new error processor name */ public void setErrorProcessor(String errorProcessor) { this.errorProcessor = errorProcessor; } /** * Returns errorProcessor * * @return errorProcessor property value */ public String getErrorProcessor() { return this.errorProcessor; } // /** // * Sets the jobProcessor // * @return // */ // public String getJobProcessor() { // return jobProcessor; // } // // /** // * Return jobProcessor // * @param jobProcessor // */ // public void setJobProcessor(String jobProcessor) { // this.jobProcessor = jobProcessor; // } /** * Processor name postfix (to be appended to the operation name). */ private String namePostfix; /** * Processor name prefix (to be prepended to the operation name). */ private String namePrefix; /** * Sets namePrefix * * @param namePrefix the new processor name prefix */ public void setNamePrefix(String namePrefix) { this.namePrefix = namePrefix; } /** * Returns namePrefix * * @return namePrefix property value */ public String getNamePrefix() { return namePrefix; } /** * Sets namePostfix * * @param namePostfix the new processor name postfix */ public void setNamePostfix(String namePostfix) { this.namePostfix = namePostfix; } /** * Returns namePostfix * * @return namePostfix property value */ public String getNamePostfix() { return namePostfix; } /** * @return the alwaysQueueProcessor */ public boolean isAlwaysQueueProcessor() { return alwaysQueueProcessor; } /** * @param alwaysQueueProcessor the alwaysQueueProcessor to set */ public void setAlwaysQueueProcessor(boolean alwaysQueueProcessor) { this.alwaysQueueProcessor = alwaysQueueProcessor; } // Private methods --------------------------------------------------------------------------- /** * Get a processor for client initiated. * @param dms * @param devInfo * @param init * @return */ private ManagementProcessor getProcessor4ClientInitiated(DeviceDMState dms, DevInfo devInfo, ManagementInitialization init) { Alert alert = null; if (init != null) { alert = init.getClientAlert(); } boolean isClientInitiated = false; if (alert != null) { // Check Client Alert content List<Item> items = alert.getItems(); for (Item item : items) { ComplexData cData = item.getData(); // "405" String data = cData.getData(); Meta meta = item.getMeta(); MetInf metInf = meta.getMetInf(); // "org.openmobilealliance.firmwareupdate.downloadandupdate" String type = metInf.getType(); // "critical" String mark = metInf.getMark(); Source source = item.getSource(); // "./Fw/FwPkg01" String locURI = null; if (source != null) { locURI = source.getLocURI(); } log.info("Client Initiated Alert command:" + "\n\tCommand: " + alert.getName() + "\n\tData: " + data + "\n\tType: " + type + "\n\tMark: " + mark + "\n\tLocURI: " + locURI); if (StringUtils.isNotEmpty(type)) { // Got Client Initiated session from Phone terminal. if (type.equalsIgnoreCase("org.openmobilealliance.dm.firmwareupdate.userrequest") || type.equalsIgnoreCase("org.openmobilealliance.firmwareupdate.userrequest")) { // User initited FOTA Update. log.info("Firmware update request by user."); ManagementBeanFactory factory = null; try { // 1. Checking availiable Update package. factory = ManagementBeanFactory.newInstance(EngineConfig.getProperties()); UpdateImageBean updateBean = factory.createUpdateImageBean(); String deviceExternalID = dms.deviceId; DeviceBean deviceBean = factory.createDeviceBean(); Device device = deviceBean.getDeviceByExternalID(deviceExternalID); if (device == null) { throw new ManagementException("Could not load device: from DM inventory."); } String currentVersion = deviceBean.getCurrentFirmwareVersionId(device.getID()); log.info("Firmware update request by user. device current version: " + currentVersion); List<Update> updates = updateBean.findUpdates4Upgrade(device.getModel(), currentVersion); log.info( "Firmware update request by user, found total of availiable upgrade firmwares: " + updates.size()); if (updates != null && updates.size() > 0) { ProvisionJobBean jobBean = factory.createProvisionJobBean(); // Using last update. try { // Submit a Firmware Job. factory.beginTransaction(); ProvisionJob job = jobBean.newJob4FirmwareUpdate(device, updates.get(updates.size() - 1)); factory.commit(); log.info( "Firmware update request by user, found more than one update package, create a job ID: " + job.getID()); } catch (Exception ex) { factory.rollback(); } } } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { if (factory != null) { factory.release(); } } isClientInitiated = false; break; } else if (type.startsWith("org.openmobilealliance.firmwareupdate") || type.startsWith("org.openmobilealliance.dm.firmwareupdate")) { // FOTA Alert: Terminal notificate the Update status. isClientInitiated = true; break; } } } } if (isClientInitiated) { return new ClientInitiatedProcessor(); } else { return null; } } /** * <pre> * JobQueueProcessor. * 1. JobQueue * 2. JobQueueJob, Processor * 3. JobQueueJob, QueueProcessor. * </pre> * @param jobBean * @param device * @return * @throws DMException */ private ProcessorRecord getProcessorByJobQueue(ProvisionJobBean jobBean, Device device) throws DMException { ProcessorRecord result = new ProcessorRecord(); List<ProvisionJob> jobs = jobBean.findJobsQueued(device); if (jobs == null || jobs.size() == 0) { if (log.isDebugEnabled()) { log.debug("No job in queue for this device: " + device.getID() + " , reset the DMState.mssid=0"); } // No any job queued for this device. // result.setProcessName(this.getDefaultProcessor()); result.setProcessName(com.npower.dm.processor.JobQueueProcessor.class.getName()); // Generic Processor: job id is 0 result.setJobID(0); } else if (jobs.size() == 1) { // QueueProcessor if (this.isAlwaysQueueProcessor()) { // Always queue processor. result.setProcessName(com.npower.dm.processor.JobQueueProcessor.class.getName()); } else { // Bundle a processor against the job type ProvisionJob job = (ProvisionJob) jobs.get(0); if (log.isDebugEnabled()) { log.debug("Job queue size is " + jobs.size() + ", select a processor for the first job: " + job.getID()); } result.setProcessName(JobProcessSelector.getProcessorByJobType(job.getJobType())); // Caution: Job-bundle processor must assign the jobID into the DeviceDMState result.setJobID(job.getID()); } } else { // multiple jobs, using queue processor. if (log.isDebugEnabled()) { log.debug("Job queue size is " + jobs.size()); } result.setProcessName(com.npower.dm.processor.JobQueueProcessor.class.getName()); } return result; } /** * Get a processor for server initiated. * @param dms * @param devInfo * @param init * @return */ private ManagementProcessor getProcessor4ServerInitiated(DeviceDMState dms, DevInfo devInfo, ManagementInitialization init) { if (log.isDebugEnabled()) { log.debug("select a processor for DMState: " + dms); } String deviceExternalID = devInfo.getDevId(); if (log.isDebugEnabled()) { log.debug("device id: " + deviceExternalID); } if (deviceExternalID.toUpperCase().startsWith("IMEI:")) { // Clear the prefix "IMEI:" //deviceExternalID = deviceExternalID.substring(5, deviceExternalID.length()); } ManagementBeanFactory factory = null; try { factory = ManagementBeanFactory.newInstance(EngineConfig.getProperties()); DeviceBean deviceBean = factory.createDeviceBean(); Device device = deviceBean.getDeviceByExternalID(deviceExternalID); if (device == null) { // Return a defaultProcessor for none-register device. if (log.isDebugEnabled()) { log.debug("No job for this processor, reset the DMState.mssid=0"); } dms.mssid = "0"; return getProcessorByName(this.getErrorProcessor()); } ProvisionJobBean jobBean = factory.createProvisionJobBean(); /** * SelectorProcessor: * 1. DeviceDMStatemssid0, DefaultProcessor. * 2. DeviceDMStatemssidJobID, jobIDJobTypeProcessor. * 3. mssid0jobID, JobIDJobDone, RuntimeException, mssidJob * * 0JobIDJobQueueProcessor, JobQueueProcessor,getProcessor(...)mssidJobID. */ String processorName = null; long jobID = 0; try { if (dms.mssid != null) { jobID = new Long(dms.mssid).longValue(); } } catch (NumberFormatException e) { } if (jobID <= 1) { // Find job if (log.isDebugEnabled()) { log.debug("No jobID assigned for ProcessorSelector, Find jobs from DM inventory."); } // JobQueue, Processor ProcessorRecord result = getProcessorByJobQueue(jobBean, device); jobID = result.getJobID(); processorName = result.getProcessName(); } else { // Load Job, checking the job status. ProvisionJob job = jobBean.loadJobByID(jobID); if (job == null) { throw new RuntimeException("Invalidate jobID: " + jobID + ", no exists!"); } processorName = JobProcessSelector.getProcessorByJobType(job.getJobType()); jobID = job.getID(); } // Store the jobID into dmState.mssid if (log.isDebugEnabled()) { log.debug("Set the jobID: " + jobID + " to the DMState.mssid"); } dms.mssid = Long.toString(jobID); if (log.isDebugEnabled()) { log.debug("selected processor: " + processorName); } log.info("selected processor: " + processorName + " for device: " + device.getID()); ManagementProcessor processor = getProcessorByName(processorName); return processor; } catch (Exception e) { log.error("Error select procesor: " + e.getMessage(), e); } finally { if (factory != null) { factory.release(); } } return null; } /** * Get a processor by the name. * @return */ private ManagementProcessor getProcessorByName(String processorName) throws DMException { try { Object object = Configuration.getConfiguration().getBeanInstanceByName(processorName); ManagementProcessor processor = null; if (object instanceof ManagementProcessor) { processor = (ManagementProcessor) object; } return processor; } catch (Exception e) { throw new DMException("Error creating the management processor: " + e.getMessage(), e); } } // Implements interface ***************************************************************************** /* (non-Javadoc) * @see sync4j.framework.tools.beans.LazyInitBean#init() */ public void init() throws BeanInitializationException { if (this.namePostfix == null) { this.namePostfix = ""; } if (this.namePrefix == null) { this.namePrefix = ""; } } /* (non-Javadoc) * @see sync4j.framework.server.dm.ProcessorSelector#getProcessor(sync4j.framework.engine.dm.DeviceDMState, sync4j.framework.core.dm.ddf.DevInfo) */ public ManagementProcessor getProcessor(DeviceDMState dms, DevInfo devInfo, ManagementInitialization init) { if (log.isDebugEnabled()) { log.debug("select a processor for DMState: " + dms); } ManagementProcessor processor = this.getProcessor4ClientInitiated(dms, devInfo, init); if (processor != null) { log.debug("select a client initiated processor for DMState: " + dms); return processor; } processor = this.getProcessor4ServerInitiated(dms, devInfo, init); log.debug("select a server initiated processor for DMState: " + dms); return processor; } /** * Find a name of Processor based on the Job's Type. * @param jobs */ public static String getProcessorByJobType(String jobType) { String processorName = null; if (jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_DISCOVERY)) { processorName = TreeDiscoveryProcessor.class.getName(); } else if (jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SCRIPT)) { processorName = CommandProcessor.class.getName(); } else if (jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_ASSIGN_PROFILE)) { processorName = SmartProfileAssignmentProcessor.class.getName(); } else if (jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_RE_ASSIGN_PROFILE)) { processorName = SmartProfileAssignmentProcessor.class.getName(); } else if (jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_FIRMWARE)) { processorName = FumoProcessor.class.getName(); } else if (jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_INSTALL) || jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_INSTALL_STAGE_2) || jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_UN_INSTALL) || jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_ACTIVE) || jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_DEACTIVE) || jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_UPGRADE) || jobType.equalsIgnoreCase(ProvisionJob.JOB_TYPE_SOFTWARE_DISCOVERY)) { processorName = SoftwareManagementProcessor.class.getName(); } return processorName; } }