Ejemplo n.º 1
0
        /// <summary>
        /// Parses the appInfo and experiment ticket, inserts the task into the database and
        /// creates a dataManager and dataSources defined in the appInfo.
        /// </summary>
        /// <param name="appInfo"></param>
        /// <param name="expCoupon"></param>
        /// <param name="expTicket"></param>
        /// <returns></returns>
        public virtual LabTask CreateLabTask(LabAppInfo appInfo, Coupon expCoupon, Ticket expTicket)
        {
            LabTask labTask = CreateLabTask(appInfo, expTicket);

            if (((labTask.storage != null) && (labTask.storage.Length > 0)))
            {
                // Create DataSourceManager to manage dataSources
                DataSourceManager dsManager = new DataSourceManager();

                // set up an experiment storage handler
                ExperimentStorageProxy ess = new ExperimentStorageProxy();
                ess.OperationAuthHeaderValue = new OperationAuthHeader();
                ess.OperationAuthHeaderValue.coupon = expCoupon;
                ess.Url = labTask.storage;
                dsManager.essProxy = ess;
                dsManager.ExperimentID = labTask.experimentID;
                dsManager.AppKey = appInfo.appKey;
                // Note these dataSources are written to by the application and sent to the ESS
                if ((appInfo.dataSources != null) && (appInfo.dataSources.Length > 0))
                {
                    string[] sources = appInfo.dataSources.Split(',');
                    // Use the experimentID as the storage parameter
                    foreach (string s in sources)
                    {
                       // dsManager.AddDataSource(createDataSource(s));
                    }
                }
                TaskProcessor.Instance.AddDataManager(labTask.taskID, dsManager);
            }
            TaskProcessor.Instance.Add(labTask);
            return labTask;
        }
Ejemplo n.º 2
0
        // Create DataSourceManager to manage dataSources
        public DataSourceManager CreateDataSourceManager(LabTask task, Coupon expCoupon)
        {
            DataSourceManager dsManager = new DataSourceManager();

                // set up an experiment storage handler
                ExperimentStorageProxy ess = new ExperimentStorageProxy();
                ess.OperationAuthHeaderValue = new OperationAuthHeader();
                ess.OperationAuthHeaderValue.coupon = expCoupon;
                ess.Url = task.storage;
                dsManager.essProxy = ess;
                dsManager.ExperimentID = task.experimentID;
                //dsManager.AppKey = task.labAppID.;
                return dsManager;
        }
Ejemplo n.º 3
0
 public void AddDataManager(long taskID, DataSourceManager mgr)
 {
     lock (dataManagers)
     {
         dataManagers.Add(taskID, mgr);
     }
 }
        public LabTask CreateLabTask(LabAppInfo appInfo, Coupon expCoupon, Ticket expTicket)
        {
            // set defaults
            DateTime startTime = DateTime.UtcNow;
            long duration = -1L;
            long experimentID = 0;
            int status = -1;

            string statusViName = null;
            string statusTemplate = null;
            string templatePath = null;
            LabDB dbManager = new LabDB();
            string qualName = null;
            string fullName = null;  // set defaults
            string viName = null;

            //CHeck that a labVIEW interface revision is set
            //if (appInfo.rev == null || appInfo.rev.Length < 2)
            //{
            //    appInfo.rev = ConfigurationManager.AppSettings["LabViewVersion"];
            //}

            ////Parse experiment payload, only get what is needed
            string payload = expTicket.payload;
            XmlQueryDoc expDoc = new XmlQueryDoc(payload);
            string essService = expDoc.Query("ExecuteExperimentPayload/essWebAddress");
            string startStr = expDoc.Query("ExecuteExperimentPayload/startExecution");
            string durationStr = expDoc.Query("ExecuteExperimentPayload/duration");
            string groupName = expDoc.Query("ExecuteExperimentPayload/groupName");
            string userName = expDoc.Query("ExecuteExperimentPayload/userName");
            string expIDstr = expDoc.Query("ExecuteExperimentPayload/experimentID");

            if ((startStr != null) && (startStr.Length > 0))
            {
                startTime = DateUtil.ParseUtc(startStr);
            }
            if ((durationStr != null) && (durationStr.Length > 0) && !(durationStr.CompareTo("-1") == 0))
            {
                duration = Convert.ToInt64(durationStr);
            }
            if ((expIDstr != null) && (expIDstr.Length > 0))
            {
                experimentID = Convert.ToInt64(expIDstr);
            }

            if (appInfo.extraInfo != null && appInfo.extraInfo.Length > 0)
            {
                // Note should have either statusVI or template pair
                // Add Option for VNCserver access
                try
                {
                    XmlQueryDoc viDoc = new XmlQueryDoc(appInfo.extraInfo);
                    statusViName = viDoc.Query("extra/status");
                    statusTemplate = viDoc.Query("extra/statusTemplate");
                    templatePath = viDoc.Query("extra/templatePath");
                }
                catch (Exception e)
                {
                    string err = e.Message;
                }
            }

            // log the experiment for debugging

            Logger.WriteLine("Experiment: " + experimentID + " Start: " + DateUtil.ToUtcString(startTime) + " \tduration: " + duration);
            long statusSpan = DateUtil.SecondsRemaining(startTime, duration);

            if (!IsLoaded(appInfo.application))
            {
                viName = LoadVI(appInfo.path, appInfo.application);
                if (false) // Check for controls first
                {
                    string[] names = new string[4];
                    object[] values = new object[4];
                    names[0] = "CouponId";
                    values[0] = expCoupon.couponId;
                    names[1] = "Passcode";
                    values[1] = expCoupon.passkey;
                    names[2] = "IssuerGuid";
                    values[2] = expCoupon.issuerGuid;
                    names[3] = "ExperimentId";
                    values[3] = experimentID;
                    SetControlValues(viName, names, values);
                }
                OpenFrontPanel(viName, true, LabViewTypes.eFPState.eVisible);
            }
            else
            {
                viName = LoadVI(appInfo.path, appInfo.application);
            }
            if (viName == null)
            {
                status = -1;
                string err = "Unable to Find: " + appInfo.path + @"\" + appInfo.application;
                Logger.WriteLine(err);
                throw new Exception(err);
            }
            // Get qualifiedName
            qualName = qualifiedName(viName);
            fullName = appInfo.path + @"\" + appInfo.application;

            status = GetVIStatus(viName);

            Logger.WriteLine("CreateLabTask - " + qualName + ": VIstatus: " + status);
            switch (status)
            {
                case -10:
                    throw new Exception("Error GetVIStatus: " + status);
                    break;
                case -1:
                    // VI not in memory
                    throw new Exception("Error GetVIStatus: " + status);

                    break;
                case 0: // eBad == 0
                    break;
                case 1: // eIdle == 1 vi in memory but not running
                    //LabViewTypes.eFPState fpState = GetFPStatus(viName);
                   //if (fpState != LabViewTypes.eFPState.eVisible)
                    //{
                        OpenFrontPanel(viName, true, LabViewTypes.eFPState.eVisible);
                    //}
                    ResetVI(viName);
                    break;
                case 2: // eRunTopLevel: this should be the LabVIEW application
                    break;
                case 3: // eRunning
                    //Unless the Experiment is reentrant it should be stopped and be reset.
                    if (!appInfo.reentrant)
                    {
                        int stopStatus = StopVI(viName);
                        if (stopStatus != 0)
                        {
                            AbortVI(viName);
                        }
                        ResetVI(viName);
                    }
                    break;
                default:
                    throw new Exception("Error GetVIStatus: unknown status: " + status);
                    break;
            }
            try
            {
                SetBounds(viName, 0, 0, appInfo.width, appInfo.height);
                Logger.WriteLine("SetBounds: " + appInfo.application);
            }
            catch (Exception sbe)
            {
                Logger.WriteLine("SetBounds exception: " + Utilities.DumpException(sbe));
            }
            SubmitAction("unlockvi", qualifiedName(viName));
            Logger.WriteLine("unlockvi Called: ");

            // Create the labTask & store in database;
            LabViewTask task = new LabViewTask();
            task.labAppID = appInfo.appID;
            task.experimentID = experimentID;
            task.groupName = groupName;
            task.startTime = startTime;
            if (duration > 0)
                task.endTime = startTime.AddTicks(duration * TimeSpan.TicksPerSecond);
            else
                task.endTime = DateTime.MinValue;
            task.Status = LabTask.eStatus.Scheduled;
            task.couponID = expTicket.couponId;
            task.storage = essService;
            task.data = task.constructTaskXml(appInfo.appID, fullName, appInfo.rev, statusViName, essService);
            long taskID = dbManager.InsertTaskLong(task);
            task.taskID = taskID;

            if ((statusTemplate != null) && (statusTemplate.Length > 0))
            {
                statusViName = CreateFromTemplate(templatePath, statusTemplate, task.taskID.ToString());
            }

            if (((essService != null) && (essService.Length > 0)))
            {
                // Create DataSourceManager to manage dataSocket connections
                DataSourceManager dsManager = new DataSourceManager();

                // set up an experiment storage handler
                ExperimentStorageProxy ess = new ExperimentStorageProxy();
                ess.OperationAuthHeaderValue = new OperationAuthHeader();
                ess.OperationAuthHeaderValue.coupon = expCoupon;
                ess.Url = essService;
                dsManager.essProxy = ess;
                dsManager.ExperimentID = experimentID;
                dsManager.AppKey = qualName;
                // Note these dataSources are written to by the application and sent to the ESS
                if ((appInfo.dataSources != null) && (appInfo.dataSources.Length > 0))
                {
                    string[] sockets = appInfo.dataSources.Split(',');
                    // Use the experimentID as the storage parameter
                    foreach (string s in sockets)
                    {
                        LVDataSocket reader = new LVDataSocket();
                        dsManager.AddDataSource(reader);
                        if (s.Contains("="))
                        {
                            string[] nv = s.Split('=');
                            reader.Type = nv[1];
                            reader.Connect(nv[0], LabDataSource.READ_AUTOUPDATE);

                        }
                        else
                        {
                            reader.Connect(s, LabDataSource.READ_AUTOUPDATE);
                        }
                    }
                }
                TaskProcessor.Instance.AddDataManager(task.taskID, dsManager);
            }

            TaskProcessor.Instance.Add(task);
            return task;
        }
Ejemplo n.º 5
0
        protected void Application_Start(Object sender, EventArgs e)
        {
            try
            {
                string path = ConfigurationManager.AppSettings["logPath"];
                if (path != null && path.Length > 0)
                {
                    Logger.LogPath = path;
                    Logger.WriteLine("");
                    Logger.WriteLine("#############################################################################");
                    Logger.WriteLine(iLabGlobal.Release);
                    Logger.WriteLine("Application_Start: starting");
                }
                ProcessAgentDB.RefreshServiceAgent();
                //Should load any active tasks and update any expired tasks
                LabDB dbService = new LabDB();

                TaskProcessor.Instance.WaitTime = 60000;
                LabTask[] activeTasks = dbService.GetActiveTasks();
                int count = 0;
                foreach (LabTask task in activeTasks)
                {
                    if (task != null)
                    {
                        if (task.storage != null && task.storage.Length > 0)
                        {
                            Coupon expCoupon = dbService.GetCoupon(task.couponID, task.issuerGUID);
                            DataSourceManager dsManager = new DataSourceManager(task);
                            BeeAPI api = new BeeAPI();
                            FileWatcherDataSource fds = api.CreateBeeDataSource(expCoupon, task, "data", false);
                            dsManager.AddDataSource(fds);
                            fds.Start();
                            TaskProcessor.Instance.AddDataManager(task.taskID, dsManager);
                        }
                        TaskProcessor.Instance.Add(new BeeTask(task));
                        count++;
                    }
                }
                taskThread = new TaskHandler(TaskProcessor.Instance);
                ticketRemover = new TicketRemover();
                if (Logger.IsLogging)
                    Logger.WriteLine("Added " + count + " active Tasks\r\n");

            }
            catch (Exception err)
            {
                if (Logger.IsLogging)
                Logger.WriteLine(Utilities.DumpException(err));
            }
        }
Ejemplo n.º 6
0
        public static LabTask CreateLabTask(LabAppInfo appInfo, Coupon expCoupon, Ticket expTicket)
        {
            // set defaults
            DateTime startTime = DateTime.UtcNow;
            long duration = -1L;
            long experimentID = 0;
            int status = -1;

            string statusViName = null;
            string statusTemplate = null;
            string templatePath = null;
            LabDB dbManager = new LabDB();
            string qualName = null;
            string fullName = null;  // set defaults
           
            LabTask labTask = null;
            LabViewTask task = null;
            VirtualInstrument vi = null;
            LabViewInterface lvi = null;
            

            ////Parse experiment payload, only get what is needed 	
            string payload = expTicket.payload;
            XmlQueryDoc expDoc = new XmlQueryDoc(payload);
            string essService = expDoc.Query("ExecuteExperimentPayload/essWebAddress");
            string startStr = expDoc.Query("ExecuteExperimentPayload/startExecution");
            string durationStr = expDoc.Query("ExecuteExperimentPayload/duration");
            string groupName = expDoc.Query("ExecuteExperimentPayload/groupName");
            string userName = expDoc.Query("ExecuteExperimentPayload/userName");

            if ((startStr != null) && (startStr.Length > 0))
            {
                startTime = DateUtil.ParseUtc(startStr);
            }
            if ((durationStr != null) && (durationStr.Length > 0) && !(durationStr.CompareTo("-1") == 0))
            {
                duration = Convert.ToInt64(durationStr);
            }


            if (appInfo.extraInfo != null && appInfo.extraInfo.Length > 0)
            {
                // Note should have either statusVI or template pair
                // Add Option for VNCserver access
                try
                {
                    XmlQueryDoc viDoc = new XmlQueryDoc(appInfo.extraInfo);
                    statusViName = viDoc.Query("extra/status");
                    statusTemplate = viDoc.Query("extra/statusTemplate");
                    templatePath = viDoc.Query("extra/templatePath");
                }
                catch (Exception e)
                {
                    string err = e.Message;
                }
            }

            // log the experiment for debugging

            Utilities.WriteLog("Experiment: " + experimentID + " Start: " + DateUtil.ToUtcString(startTime) + " \tduration: " + duration);
            long statusSpan = DateUtil.SecondsRemaining(startTime, duration);



            if ((appInfo.server != null) && (appInfo.server.Length > 0) && (appInfo.port > 0))
            {
                lvi = new LabViewRemote(appInfo.server, appInfo.port);
            }
            else
            {
                lvi = new LabViewInterface();
            }
            if (!lvi.IsLoaded(appInfo.application))
            {
                vi = lvi.loadVI(appInfo.path, appInfo.application);
                vi.OpenFrontPanel(true, FPStateEnum.eVisible);
            }
            else
            {
                vi = lvi.GetVI(appInfo.path, appInfo.application);
            }
            if (vi == null)
            {
                status = -1;
                string err = "Unable to Find: " + appInfo.path + @"\" + appInfo.application;
                Utilities.WriteLog(err);
                throw new Exception(err);
            }
            // Get qualifiedName
            qualName = lvi.qualifiedName(vi);
            fullName = appInfo.path + @"\" + appInfo.application;


            status = lvi.GetVIStatus(vi);

            Utilities.WriteLog("CreateLabTask - " + qualName + ": VIstatus: " + status);
            switch (status)
            {
                case -10:
                    throw new Exception("Error GetVIStatus: " + status);
                    break;
                case -1:
                    // VI not in memory
                    throw new Exception("Error GetVIStatus: " + status);

                    break;
                case 0: // eBad == 0
                    break;
                case 1: // eIdle == 1 vi in memory but not running 
                    FPStateEnum fpState = vi.FPState;
                    if (fpState != FPStateEnum.eVisible)
                    {
                        vi.OpenFrontPanel(true, FPStateEnum.eVisible);
                    }
                    vi.ReinitializeAllToDefault();
                    break;
                case 2: // eRunTopLevel: this should be the LabVIEW application
                    break;
                case 3: // eRunning
                    //Unless the Experiment is reentrant it should be stopped and be reset.
                    if(!appInfo.reentrant){
                        int stopStatus = lvi.StopVI(vi);
                        if (stopStatus != 0)
                        {
                            lvi.AbortVI(vi);
                        }
                        vi.ReinitializeAllToDefault();
                    }
                    break;
                default:
                    throw new Exception("Error GetVIStatus: unknown status: " + status);
                    break;
            }
            try
            {
                lvi.SetBounds(vi, 0, 0, appInfo.width, appInfo.height);
                Utilities.WriteLog("SetBounds: " + appInfo.application);
            }
            catch (Exception sbe)
            {
                Utilities.WriteLog("SetBounds exception: " + Utilities.DumpException(sbe));
            }
            lvi.SubmitAction("unlockvi", lvi.qualifiedName(vi));
            Utilities.WriteLog("unlockvi Called: ");


            // Set up in-memory and database task control structures
            DataSourceManager dsManager = null;

            // Create the labTask & store in database;
            labTask = dbManager.InsertTask(appInfo.appID, experimentID,
           groupName, startTime, duration,
           LabTask.eStatus.Scheduled, expTicket.couponId, expTicket.issuerGuid, null);
            if (labTask != null)
            {
                //Convert the generic LabTask to a LabViewTask
                task = new LabViewTask(labTask);
            }
            if ((statusTemplate != null) && (statusTemplate.Length > 0))
            {
                statusViName = lvi.CreateFromTemplate(templatePath, statusTemplate, task.taskID.ToString());
            }


            if (((essService != null) && (essService.Length > 0)) && ((appInfo.dataSources != null) && (appInfo.dataSources.Length > 0)))
            {
                // Create DataSourceManager to manage dataSocket connections
                dsManager = new DataSourceManager();

                // set up an experiment storage handler
                ExperimentStorageProxy ess = new ExperimentStorageProxy();
                ess.OperationAuthHeaderValue = new OperationAuthHeader();
                ess.OperationAuthHeaderValue.coupon = expCoupon;
                ess.Url = essService;
                dsManager.essProxy = ess;
                dsManager.ExperimentID = experimentID;
                dsManager.AppKey = qualName;
                string[] sockets = appInfo.dataSources.Split(',');
                // Use the experimentID as the storage parameter
                foreach (string s in sockets)
                {
                    LVDataSocket reader = new LVDataSocket();
                    dsManager.AddDataSource(reader);
                    if (s.Contains("="))
                    {
                        string[] nv = s.Split('=');
                        reader.Type = nv[1];
                        reader.Connect(nv[0], LabDataSource.READ_AUTOUPDATE);

                    }
                    else
                    {
                        reader.Connect(s, LabDataSource.READ_AUTOUPDATE);
                    }

                }
                TaskProcessor.Instance.AddDataManager(task.taskID, dsManager);
            }
            string taskData = null;
            taskData = LabTask.constructTaskXml(appInfo.appID, fullName,appInfo.rev, statusViName, essService);
            dbManager.SetTaskData(task.taskID, taskData);
            task.data = taskData;
            TaskProcessor.Instance.Add(task);
            return task;
        }
        protected void Page_Load(object sender, System.EventArgs e)
        {
            LabDB dbManager = new LabDB();
            int appID = 0;
            long expID = 0;
            LabTask task = null;
            string expLen = null;
            string pageURL = null;
            bool useTaskDuration = true;
            // Query values from the request
            if (!IsPostBack)
            {
                string appKey = Request.QueryString["app"];
                string coupon_Id = Request.QueryString["coupon_id"];
                string passkey = Request.QueryString["passkey"];
                string issuerGUID = Request.QueryString["issuer_guid"];
                string returnTarget = Request.QueryString["sb_url"];
                expLen = Request.QueryString["explen"];
                if ((returnTarget != null) && (returnTarget.Length > 0))
                    Session["sbUrl"] = returnTarget;

                Logger.WriteLine("BEElab: " + Request.Url.ToString());

                // this should be the Experiment Coupon data
                if (!(passkey != null && passkey != "" && coupon_Id != null && coupon_Id != "" && issuerGUID != null && issuerGUID != ""))
                {
                    Logger.WriteLine("BEElab: " + "AccessDenied missing Experiment credentials");
                    Response.Redirect("AccessDenied.aspx?text=missing+Experiment+credentials.", true);
                }

                long expCoupId = Convert.ToInt64(coupon_Id);
                Coupon expCoupon = new Coupon(issuerGUID, expCoupId, passkey);

                //Check the database for ticket and coupon, if not found Redeem Ticket from
                // issuer and store in database.
                //This ticket should include group, experiment id and be valid for this moment in time??
                Ticket expTicket = dbManager.RetrieveAndVerify(expCoupon, TicketTypes.EXECUTE_EXPERIMENT);

                if (expTicket != null)
                {
                    if (expTicket.IsExpired())
                    {
                        Response.Redirect("AccessDenied.aspx?text=The ExperimentExecution+ticket+has+expired.", true);

                    }
                    Session[""] = issuerGUID;
                    Session[""] = expCoupId;
                    Session[""] = passkey;
                    ////Parse experiment payload, only get what is needed
                    string payload = expTicket.payload;
                    XmlQueryDoc expDoc = new XmlQueryDoc(payload);
                    string tzStr = expDoc.Query("ExecuteExperimentPayload/userTZ");
                    if ((tzStr != null) && (tzStr.Length > 0))
                        Session["userTZ"] = tzStr;
                    string groupName = expDoc.Query("ExecuteExperimentPayload/groupName");
                    Session["groupName"] = groupName;
                    string sbStr = expDoc.Query("ExecuteExperimentPayload/sbGuid");
                    string essUrl = expDoc.Query("ExecuteExperimentPayload/essWebAddress");
                    expID = Convert.ToInt64(expDoc.Query("ExecuteExperimentPayload/experimentID"));
                    Session["brokerGUID"] = sbStr;

                    //Get Lab specific info for this URL or group
                    LabAppInfo appInfo = null;
                    // Experiment is specified by 'app=appKey'
                    if (appKey != null && appKey.Length > 0)
                    {
                        appInfo = dbManager.GetLabApp(appKey);
                    }
                    // This is no longer the case as the USS handles groups and permissions
                    //else // Have to use groupName & Servicebroker THIS REQUIRES groups & permissions are set in database
                    //{
                    //    appInfo = dbManager.GetLabAppForGroup(groupName, sbStr);
                    //}
                    if (appInfo == null)
                    {
                        Response.Redirect("AccessDenied.aspx?text=Unable+to+find+application+information,+please+notify+your+administrator.", true);
                    }

                    // Check to see if an experiment with this ID is already running
                    // Check for an existing task for this experiment
                    // If found redirect to the graph page, do not abort running controller program
                    LabTask.eStatus status = dbManager.ExperimentStatus(expID, sbStr);
                    if (status == LabTask.eStatus.NotFound)
                    {
                        // Check for existing tasks that may be using resources
                        // For now only close other instances of the lab
                        List<LabTask> curTasks = TaskProcessor.Instance.GetTasks(appInfo.appID);
                        if (curTasks != null && curTasks.Count > 0)
                        {
                            foreach (LabTask t in curTasks)
                            {
                                //ToDo: check if the tasks should all be closed
                                DataSourceManager dsManager = TaskProcessor.Instance.GetDataManager(t.taskID);
                                if (dsManager != null)
                                {
                                    // Need to close existing data Sources
                                    TaskProcessor.Instance.Remove(t);
                                    t.Close();
                                }
                            }
                        }

                        // Create a new Experiment task
                        // Use taskFactory to create a new task
                        BeeAPI factory = new BeeAPI();
                        task = factory.CreateLabTask(appInfo, expTicket);

                        if (task != null)
                        {
                            if (task.storage != null && task.storage.Length > 0)
                            {
                                DataSourceManager dsManager = new DataSourceManager(task);
                                FileWatcherDataSource fds = factory.CreateBeeDataSource(expCoupon, task, "data", true);
                                dsManager.AddDataSource(fds);
                                fds.Start();
                                TaskProcessor.Instance.AddDataManager(task.taskID, dsManager);
                            }
                            TaskProcessor.Instance.Add(new BeeTask(task));

                            //set Presentation page tp appPage
                            pageURL = appInfo.page;

                        }
                        else
                        {
                            Response.Redirect("AccessDenied.aspx?text=Unable+to+launch++application,+please+notify+your+administrator.", true);
                        }
                    }
                    else
                    { // An existing Experiment
                        task = dbManager.GetTask(expID, sbStr);
                        if (task.Status == LabTask.eStatus.Scheduled)
                        {
                            pageURL = appInfo.appURL;
                        }
                        else if (task.Status == LabTask.eStatus.Running)
                        {
                            pageURL = ProcessAgentDB.ServiceAgent.codeBaseUrl + @"/BEEgraph.aspx";
                        }
                        else if (task.Status == LabTask.eStatus.Aborted
                            || task.Status == LabTask.eStatus.Closed
                            || task.Status == LabTask.eStatus.Completed
                            || task.Status == LabTask.eStatus.Expired)
                        {
                            Response.Redirect("AccessDenied.aspx?text=The+requested+experiment+is+no+longer+running.", true);
                        }

                    }
                }
                if (pageURL != null && pageURL.Length > 0)
                {
                    StringBuilder buf = new StringBuilder(pageURL + "?expid=" + expID);
                    Session["opCouponID"] = coupon_Id;
                    Session["opPasscode"] = passkey;
                    Session["opIssuer"] = issuerGUID;
                    buf.Append("&coupon_id=" + coupon_Id);
                    buf.Append("&passkey=" + passkey);
                    buf.Append("&issuer_guid=" + issuerGUID);
                    buf.Append("&sb_url=" + returnTarget);
                    if(expLen != null && expLen.Length > 0)
                        buf.Append("&explen=" + expLen);
                    //if (useTaskDuration)
                    //{
                    //    TimeSpan taskDur = task.endTime.Subtract(DateTime.UtcNow);
                    //    int hours = Convert.ToInt32(taskDur.TotalHours);
                    //    buf.Append("&explen=" + hours);
                    //}
                    Response.Redirect(buf.ToString(), true);
                }
                else
                {
                    Response.Redirect("AccessDenied.aspx?text=Unable+to+launch++application,+please+notify+your+administrator.", true);
                }
            }
        }