Package eu.planets_project.tb.impl

Source Code of eu.planets_project.tb.impl.AdminManagerImpl

/*******************************************************************************
* Copyright (c) 2007, 2010 The Planets Project Partners.
*
* All rights reserved. This program and the accompanying
* materials are made available under the terms of the
* Apache License, Version 2.0 which accompanies
* this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
*******************************************************************************/
/**
*
*/
package eu.planets_project.tb.impl;

import java.io.StringWriter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.VelocityException;

import eu.planets_project.ifr.core.common.conf.PlanetsServerConfig;
import eu.planets_project.ifr.core.common.mail.PlanetsMailMessage;
import eu.planets_project.ifr.core.security.api.model.User;

import eu.planets_project.tb.api.AdminManager;
import eu.planets_project.tb.api.TestbedManager;
import eu.planets_project.tb.api.model.Experiment;
import eu.planets_project.tb.api.model.ExperimentPhase;
import eu.planets_project.tb.api.model.ExperimentSetup;
import eu.planets_project.tb.gui.UserBean;
import eu.planets_project.tb.gui.util.JSFUtil;
import eu.planets_project.tb.impl.system.BackendProperties;

/**
* @author alindley
*
*/
public class AdminManagerImpl implements AdminManager {
    private static Log log = LogFactory.getLog(AdminManagerImpl.class);

  private static AdminManagerImpl instance;
 
    public static final String IDENTIFY = "identify";
    public static final String VALIDATE = "validate";
    public static final String CHARACTERISE = "characterise";
    public static final String MIGRATE = "migrate";
    public static final String EMULATE = "emulate";
    public static final String EXECUTABLEPP = "executablepp";
 
  //e.g. key:"identify" -> "Identify"
  private static HashMap<String,String> hmExperimentTypes;
  // No longer read from XML, by statically coded:
  static {
      hmExperimentTypes = new HashMap<String,String>();
        //hmExperimentTypes.put(IDENTIFY, "Identify");
        hmExperimentTypes.put(MIGRATE, "Migrate");
        //hmExperimentTypes.put(VALIDATE, "Validate");
        //hmExperimentTypes.put(CHARACTERISE, "Characterise");
        hmExperimentTypes.put(EMULATE, "View in Emulator");
        hmExperimentTypes.put(EXECUTABLEPP, "Executable Preservation Plan");
  }

    private static HashMap<String,String> hmOldExperimentTypes;
    static {
        hmOldExperimentTypes = new HashMap<String,String>();
        hmOldExperimentTypes.put("experimentType.simpleMigration","simple migration");
        hmOldExperimentTypes.put("experimentType.simpleCharacterisation", "simple characterisation");
    }

  private AdminManagerImpl(){
    // Also read basic properties:
    BackendProperties bp = new BackendProperties();
    APPROVAL_THRESHOLD_NUMBER_OF_INPUTS = bp.getExpAdminNoInputs();
    log.info("Set number of inputs before admin approval required at: "+APPROVAL_THRESHOLD_NUMBER_OF_INPUTS);
    }
 
  /**
   * This class is implemented following the Java Singleton Pattern.
   * Use this method to retrieve the instance of this class.
   * @return
   */
  public static synchronized AdminManagerImpl getInstance(){
    if (instance == null){
      instance = new AdminManagerImpl();
    }
    return instance;
  }
 
  /* ----------------------------------------------------------- */
 
  public Collection<String> getExperimentTypeIDs() {
    return hmExperimentTypes.keySet();
  }

  public Collection<String> getExperimentTypesNames() {
    return hmExperimentTypes.values();
  }
 
    public Map<String, String> getExperimentTypeIDsandNames() {
        return hmExperimentTypes;
    }

  public String getExperimentTypeID(String expTypeName) {
        if(hmExperimentTypes.containsValue(expTypeName)) {
            return getKeyFromHashMap(expTypeName, hmExperimentTypes);
        }
        if(hmOldExperimentTypes.containsValue(expTypeName)) {
            return getKeyFromHashMap(expTypeName, hmOldExperimentTypes);
        }
    return null;
  }
 
  public String getExperimentTypeName(String typeID) {
        if(hmExperimentTypes.containsKey(typeID)){
            return hmExperimentTypes.get(typeID);
        }
        if(hmOldExperimentTypes.containsKey(typeID)){
            return hmOldExperimentTypes.get(typeID);
        }
    return null;
  }

    private String getKeyFromHashMap( String expTypeName, HashMap<String,String> experimentTypes ) {
        Iterator<String> itKeys = experimentTypes.keySet().iterator();
        while(itKeys.hasNext()){
            String sKey = itKeys.next();
            if(experimentTypes.get(sKey).equals(expTypeName)){
                return sKey;
            }
        }
        return null;
    }
   
    /**
     * @param etype
     * @return
     */
    public boolean isDeprecated(String typeID) {
        if(hmOldExperimentTypes.containsKey(typeID)){
            return true;
        }
        return false;
    }
   


  /**
   * Code for Experiment Approval:
   */
 
    /**
     * Threshold for the number of inputs before approval is required.
     * Can be overridden from BackendProperties. See constructor.
     */
    public static int APPROVAL_THRESHOLD_NUMBER_OF_INPUTS = 0;
   
    /**
     * Decision flags:
     */
    public static final String APPROVAL_DECISION_AWAITING = null;
    public static final String APPROVAL_DECISION_APPROVED = "Approved";
    public static final String APPROVAL_DECISION_DENIED = "Denied";
    public static final String APPROVAL_AUTOMATIC_USER = "{automatic}";

    /**
     * Does this experiment require administrator approval?
     * @param exp The Experiment to evaluate.
     * @return TRUE if experimental approval is required to execute it, false in all other cases.
     */
    public static boolean experimentRequiresApproval(Experiment exp) {
        if( exp == null ) return false;
        if( exp.getExperimentExecutable() == null ) return false;
       
        // Go thru reasons for requiring approval:
        if( exp.getExperimentExecutable().getInputData() != null &&
                exp.getExperimentExecutable().getInputData().size() > APPROVAL_THRESHOLD_NUMBER_OF_INPUTS ) {
            // Requires Approval:
            return true;
        }
        // Otherwise, approve the experiment:
        return false;
    }
   
    public static void requestExperimentApproval(Experiment exp) {
        // Check if approval is require:
        if( ! experimentRequiresApproval(exp) ) return;

        // Store the 'Asking for approval' status as a NULL decision:
        exp.getExperimentApproval().setDecision(APPROVAL_DECISION_AWAITING);
       
        TestbedManager testbedMan = (TestbedManager) JSFUtil.getManagedObject("TestbedManager");
        testbedMan.updateExperiment(exp);
       
        // Mail the administrator:
        sendApprovalRequest(exp);
        log.info("The experiment '"+exp.getExperimentSetup().getBasicProperties().getExperimentName()+"' requires administrator approval.");
    }
   
    public static void approveExperimentAutomatically(Experiment exp) {
        if( exp == null ) return;
        if( exp.getExperimentExecutable() == null );
       
        exp.getExperimentApproval().setExplanation("Experiment was approved automatically.");
        exp.getExperimentApproval().setDecision(APPROVAL_DECISION_APPROVED);
        exp.getExperimentApproval().setGo(true);
        exp.getExperimentApproval().setState(Experiment.STATE_COMPLETED);
        exp.getExperimentExecution().setState(Experiment.STATE_IN_PROGRESS);
        exp.getExperimentApproval().addApprovalUser(APPROVAL_AUTOMATIC_USER);
       
        TestbedManager testbedMan = (TestbedManager) JSFUtil.getManagedObject("TestbedManager");
        testbedMan.updateExperiment(exp);
       
        log.info("The experiment '"+exp.getExperimentSetup().getBasicProperties().getExperimentName()+"' was automaticallu approved for execution.");
    }
   
    public static void approveExperimentManually(Experiment exp) {
        if( exp == null ) return;
        if( exp.getExperimentExecutable() == null ) return;

        // Find out who is responsible:
        UserBean currentUser = (UserBean) JSFUtil.getManagedObject("UserBean");
       
        // Approve it
        if( exp.getExperimentApproval().getExplanation() == null ||
                "".equals(exp.getExperimentApproval().getExplanation()))
            exp.getExperimentApproval().setExplanation("Experiment was approved for execution.");
        exp.getExperimentApproval().setDecision(APPROVAL_DECISION_APPROVED);
        exp.getExperimentApproval().setGo(true);
        exp.getExperimentApproval().addApprovalUser(currentUser.getUserid());
        exp.getExperimentApproval().setState(Experiment.STATE_COMPLETED);
        exp.getExperimentExecution().setState(Experiment.STATE_IN_PROGRESS);
       
        TestbedManager testbedMan = (TestbedManager) JSFUtil.getManagedObject("TestbedManager");
        testbedMan.updateExperiment(exp);
       
        // Mail the user:
        sendApprovalNotice(exp);
        log.info("The experiment '"+exp.getExperimentSetup().getBasicProperties().getExperimentName()+"' was approved for execution.");
    }
   
    public static void denyExperimentManually(Experiment exp) {
        if( exp == null ) return;
        if( exp.getExperimentExecutable() == null ) return;
       
        // Find out who is responsible:
        UserBean currentUser = (UserBean) JSFUtil.getManagedObject("UserBean");
       
        // Deny approval
        if( exp.getExperimentApproval().getExplanation() == null ||
                "".equals(exp.getExperimentApproval().getExplanation()))
            exp.getExperimentApproval().setExplanation("Experiment was denied approval for execution.");
        exp.getExperimentApproval().setDecision(APPROVAL_DECISION_DENIED);
        exp.getExperimentApproval().setGo(false);
        exp.getExperimentApproval().addApprovalUser(currentUser.getUserid());
       
        TestbedManager testbedMan = (TestbedManager) JSFUtil.getManagedObject("TestbedManager");
        testbedMan.updateExperiment(exp);
       
        // Mail the user:
        sendDenialNotice(exp);
        log.info("The experiment '"+exp.getExperimentSetup().getBasicProperties().getExperimentName()+"' was denied approval for execution.");
    }
   
    public static boolean experimentAwaitingApproval( Experiment exp ) {
        if( exp.getCurrentPhasePointer() != ExperimentPhase.PHASE_EXPERIMENTAPPROVAL ) return false;
        if( exp.getExperimentApproval().getDecision() == null ) return true;
        if( "".equals(exp.getExperimentApproval().getDecision()) ) return true;
        return false;
    }
   
    public static boolean experimentWasApproved( Experiment exp ) {
        if( exp.getCurrentPhasePointer() <= ExperimentPhase.PHASE_EXPERIMENTAPPROVAL ) return false;
        if( APPROVAL_DECISION_APPROVED.equals( exp.getExperimentApproval().getDecision()) ) return true;
        return false;
    }
   
    public static boolean experimentWasDenied( Experiment exp ) {
        if( exp.getCurrentPhasePointer() != ExperimentPhase.PHASE_EXPERIMENTAPPROVAL ) return false;
        return !experimentWasApproved(exp);
    }
   
    public static void toEditFromDenied(Experiment exp) {
        if( exp == null ) return;
        if( exp.getExperimentExecutable() == null );
       
        exp.getExperimentApproval().setExplanation("");
        exp.getExperimentApproval().setDecision("");
        exp.getExperimentApproval().setGo(false);
        exp.getExperimentSetup().setState(Experiment.STATE_IN_PROGRESS);
        exp.getExperimentSetup().setSubStage(ExperimentSetup.SUBSTAGE3);
        exp.getExperimentApproval().setState(Experiment.STATE_NOT_STARTED);
        exp.getExperimentExecution().setState(Experiment.STATE_NOT_STARTED);
        List<String> approvalUsers = exp.getExperimentApproval().getApprovalUsersIDs();
        // Need to clone to avoid a 'java.util.ConcurrentModificationException':
        List<String> usersToRemove = new ArrayList<String>();
        for( String user : approvalUsers ) usersToRemove.add(user);
        exp.getExperimentApproval().removeApprovalUsers(usersToRemove);
       
        TestbedManager testbedMan = (TestbedManager) JSFUtil.getManagedObject("TestbedManager");
        testbedMan.updateExperiment(exp);
       
        log.info("The experiment '"+exp.getExperimentSetup().getBasicProperties().getExperimentName()+"' was made editable again.");
    }
   
    /**
     * Code for emails related to Approval.
     *
     */
    private static void sendNotification(String username, String templateName, Experiment exp ) {
       
        VelocityEngine velocityEngine = new VelocityEngine();
        Properties props = new Properties();
        props.setProperty("resource.loader", "class");
        props.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        props.setProperty("velocimacro.library", "");
        try {
            velocityEngine.init(props);
        } catch( Exception e ) {
            log.error("Failed to initialise the Velocity engine. :: " + e );
        }
       
        // Look up the user.
        User user = UserBean.getUser(username);
        if( user == null ) return;
       
        // Create a message:
        PlanetsMailMessage message = new PlanetsMailMessage();
       
        // Add the recipient in properly.
        message.addRecipient(user.getFullName() + "<" + user.getEmail() + ">");
       
        // Determine the Testbed URL:
        // FIXME This is a HACK for the TB Service URL in emails:
        String testbedURL = "http://testbed.planets-project.eu/testbed/";
//        String testbedURL = "http://"+AdminManagerImpl.getAuthority()+"/testbed/";

        Map<String,Object> model = new HashMap<String,Object>();
        model.put("user", user);
        model.put("exp", exp);
        model.put("expName", exp.getExperimentSetup().getBasicProperties().getExperimentName());
        model.put("applicationURL", testbedURL);
       
        VelocityContext velocityContext;
        StringWriter result = new StringWriter();
        try {
            velocityContext = new VelocityContext(model);
            velocityEngine.mergeTemplate("eu/planets_project/tb/"+templateName+".vm", velocityContext, result);
        } catch  (VelocityException ex) {
            log.error("Mailing failed! :: "+ex);
            return;
        } catch  (RuntimeException ex) {
            log.error("Mailing failed! :: "+ex);
            return;
        } catch  (Exception ex) {
            log.error("Mailing failed! :: "+ex);
            return;
        }
        message.setSubject(velocityContext.get("subject").toString());
        message.setBody(result.toString());
       
        try {
            message.send();
        } catch( Exception e ) {
            log.error("An error occured while trying to send an email to "+user.getFullName()+"! :: "+e);
            e.printStackTrace();
        }
    }
   
    private static void sendApprovalRequest(Experiment exp) {
        sendNotification("admin", "RequestApproval", exp);
    }

    private static void sendApprovalNotice(Experiment exp) {
        if( exp.getExperimentSetup().getBasicProperties().getInvolvedUserIds() == null ) return;
        String username = exp.getExperimentSetup().getBasicProperties().getInvolvedUserIds().get(0);
        if( username == null ) return;
        sendNotification(username, "ApprovalGranted", exp );
    }

    private static void sendDenialNotice(Experiment exp) {
        if( exp.getExperimentSetup().getBasicProperties().getInvolvedUserIds() == null ) return;
        String username = exp.getExperimentSetup().getBasicProperties().getInvolvedUserIds().get(0);
        if( username == null ) return;
        sendNotification(username, "ApprovalDenied", exp);
    }

    /**
     * Helper function that looks up the actual authority for this server.
     * Could also be done via the DR I think.
     * @return The authority in the form 'server:port'.
     */
    public static String getAuthority() {
        return PlanetsServerConfig.getHostname() + ":" + PlanetsServerConfig.getPort();
    }

    /**
     * @param selectedExperiment
     * @return
     */
    public static boolean isExperimentDeprecated(Experiment exp) {
        log.info("Checking if "+exp.getExperimentSetup().getExperimentTypeID()+" is a deprecated type");
        if( AdminManagerImpl.hmOldExperimentTypes.containsKey(
                exp.getExperimentSetup().getExperimentTypeID() ) ) {
            return true;
        }
        return false;
    }

}
TOP

Related Classes of eu.planets_project.tb.impl.AdminManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.