コード例 #1
0
 private BeaconEntity TrackPageEvent(string id, SpoofedHttpRequestBase spoofedRequest, PageEventType eventType, string page, string contactId, string data = null, string dataKey = null, IDictionary <string, string> extras = null, string monetaryValue = "0")
 {
     return(this.ExecuteTrackingRequest(string.Format("[PageVisit] : Page = {0} : Event = {1} : CID = {2}", page, eventType, contactId), delegate
     {
         if (string.IsNullOrWhiteSpace(id))
         {
             throw HttpExceptionHelper.BadRequest("Bad Request", "No event identifier was specified.");
         }
         PageEventParameters pageEventParameters;
         if (id.IsGuid())
         {
             pageEventParameters = new PageEventParameters(spoofedRequest.Url, new ID(id), eventType, contactId);
         }
         else
         {
             pageEventParameters = new PageEventParameters(spoofedRequest.Url, id, eventType, contactId);
         }
         pageEventParameters.Data = data;
         pageEventParameters.DataKey = dataKey;
         pageEventParameters.Extras = extras;
         if (eventType == PageEventType.Outcome)
         {
             decimal monetaryValue2;
             if (!decimal.TryParse(monetaryValue, out monetaryValue2))
             {
                 throw HttpExceptionHelper.BadRequest("Bad Request", "The outcome monetary value is invalid.");
             }
             pageEventParameters.MonetaryValue = monetaryValue2;
         }
         return this.trackingManager.TrackPageEvent(this.httpContextBase.Request, spoofedRequest, this.httpContextBase.Response, pageEventParameters);
     }));
 }
        /// <summary>
        /// The initialize template tables.
        /// </summary>
        /// <exception cref="ValidationException">
        /// The workflow is invalid
        /// </exception>
        private void InitializeTemplateTables()
        {
            try
            {
                // Cache definitions so we don't run CacheMetadata more than once.
                if (!UriTemplateTables.ContainsKey(this.Activity))
                {
                    WorkflowInspectionServices.CacheMetadata(this.Activity);
                    UriTemplateTables.Add(this.Activity, new List <UriTemplateTable>());
                    foreach (var uriTemplateTable in
                             this.BaseAddresses.Select(baseAddress => new UriTemplateTable(baseAddress)))
                    {
                        UriTemplateTables[this.Activity].Add(uriTemplateTable);
                        this.LocateHttpReceiveActivities(this.Activity, uriTemplateTable);

                        // No UriTemplates in this activity
                        if (uriTemplateTable.KeyValuePairs.Count == 0)
                        {
                            throw new ValidationException(
                                      "Activity must contain at least one HttpReceive activity with a valid Uri template");
                        }
                    }
                }
            }

#if DEBUG
            catch (Exception ex)
            {
                HttpExceptionHelper.WriteThread(ex.Message);
                throw;
            }
#endif
        }
コード例 #3
0
 /// <summary>
 /// The wait for unload.
 /// </summary>
 /// <param name="timeout">
 /// The timeout.
 /// </param>
 /// <exception cref="TimeoutException">
 /// The unload event did not occur within the timeout
 /// </exception>
 public void WaitForUnload(TimeSpan timeout)
 {
     if (!this.unloadEvent.WaitOne(timeout))
     {
         HttpExceptionHelper.WriteThread(
             "Timeout waiting for workflow to unload");
         throw new TimeoutException();
     }
 }
        /// <summary>
        /// The run until bookmark.
        /// </summary>
        /// <param name="bookmarkName">
        /// The bookmark name.
        /// </param>
        /// <exception cref="HttpResponseException">
        /// Timeout while waiting for bookmark
        /// </exception>
        private void RunUntilBookmark(string bookmarkName)
        {
            this.pendingBookmark = bookmarkName;
            this.workflowApplication.Run();

            if (!this.protocolEvent.WaitOne(this.serviceHost.WorkflowTimeout))
            {
                throw HttpExceptionHelper.CreateResponseException(
                          HttpStatusCode.InternalServerError,
                          "Timeout waiting for idle with bookmark {0}",
                          this.pendingBookmark);
            }
        }
コード例 #5
0
        public long MigrationNumber(string encodedBranch, MigrationType type)
        {
            var branch = HttpUtility.UrlDecode(encodedBranch);

            try
            {
                return(_provider.ReadMigrationNumber(branch, type));
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw HttpExceptionHelper.ServerError(e.Message);
            }
        }
        /// <summary>
        /// The select matching receive activity.
        /// </summary>
        /// <returns>
        /// </returns>
        private HttpReceive SelectMatchingReceiveActivity()
        {
            var match = this.serviceHost.MatchSingle(this.Request);

            if (match == null)
            {
                HttpExceptionHelper.CreateResponseException(
                    HttpStatusCode.NotFound,
                    "No Http Receive activity found with Uri template matching Uri {0}",
                    this.Request.RequestUri);
            }

            return(match != null ? (HttpReceive)match.Data : null);
        }
コード例 #7
0
        public string MigrationNumber(string encodedBranch, MigrationType type, long number)
        {
            var branch = HttpUtility.UrlDecode(encodedBranch);

            try
            {
                _provider.UpdateMigrationNumber(branch, type, number);
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw HttpExceptionHelper.ServerError(e.Message);
            }
            return("ok");
        }
        /// <summary>
        /// The on idle.
        /// </summary>
        /// <param name="args">
        /// The args.
        /// </param>
        private void OnIdle(WorkflowApplicationIdleEventArgs args)
        {
            HttpExceptionHelper.WriteThread(
                "OnWorkflowIdle waiting for bookmark {0} instance Id {1} with bookmarks {2}",
                this.pendingBookmark,
                args.InstanceId,
                args.BookmarksToDelimitedList());

            this.Idle = true;

            if (args.ContainsBookmark(this.pendingBookmark))
            {
                this.pendingBookmark = null;
                this.protocolEvent.Set();
            }
        }
コード例 #9
0
        protected BeaconEntity ExecuteTrackingRequest(string requestInfo, Func <TrackingResult> implementation)
        {
            BeaconEntity result;

            try
            {
                string text;
                if (!this.TryGetSessionId(out text))
                {
                    throw HttpExceptionHelper.BadRequest("Bad Request", "Session could not be initialized with the details provided.");
                }
                TrackingResult trackingResult = implementation();
                if (trackingResult == null)
                {
                    throw HttpExceptionHelper.InternetServerError("Unexpected server error", "Tracking result could not be determined.");
                }
                if (trackingResult.ResultCode != TrackingResultCode.Success)
                {
                    this.logger.Debug(string.Format("[FXM Tracking] [Failed] : Session = {0} : Code : {1} : Message : {2} : {3}", new object[]
                    {
                        text,
                        trackingResult.ResultCode,
                        trackingResult.Message,
                        requestInfo
                    }), null);
                    throw HttpExceptionHelper.BadRequest(trackingResult.ResultCode.ToString(), trackingResult.Message);
                }
                this.logger.Debug((!trackingResult.DoNotTrack) ? string.Format("[FXM Tracking] : Session = {0} : {1}", text, requestInfo) : string.Format("[FXM Tracking] [DoNotTrack] : Session = {0} : {1}", text, requestInfo), null);
                BeaconEntity beaconEntity = (BeaconEntity)trackingResult;
                beaconEntity.SessionId = text;
                result = beaconEntity;
            }
            catch (HttpResponseException exception)
            {
                this.logger.Error(string.Format("[FXM Tracking] [Error] : {0}", requestInfo), exception, typeof(BeaconController));
                throw;
            }
            catch (Exception ex)
            {
                this.logger.Error(string.Format("[FXM Tracking] [Error] : {0}", requestInfo), ex, typeof(BeaconController));
                throw HttpExceptionHelper.InternetServerError("Unexpected server error", ex.Message);
            }
            return(result);
        }
コード例 #10
0
        protected SpoofedHttpRequestBase GetSpoofedRequest(string page, string referrer)
        {
            Uri url;

            if (string.IsNullOrWhiteSpace(page) || !Uri.TryCreate(page, UriKind.Absolute, out url))
            {
                throw HttpExceptionHelper.BadRequest("Bad Request", "No valid page was specified.");
            }
            Uri urlReferrer = null;

            if (!string.IsNullOrEmpty(referrer) && !Uri.TryCreate(referrer, UriKind.RelativeOrAbsolute, out urlReferrer))
            {
                throw HttpExceptionHelper.BadRequest("Bad Request", "An invalid referrer was specified.");
            }
            SpoofedHttpRequestBase spoofedHttpRequestBase = new SpoofedHttpRequestBase(this.httpContextBase.Request);

            spoofedHttpRequestBase.SetUrl(url);
            spoofedHttpRequestBase.SetUrlReferrer(urlReferrer);
            return(spoofedHttpRequestBase);
        }
        /// <summary>
        /// The unload if idle.
        /// </summary>
        /// <param name="state">
        /// The state.
        /// </param>
        private void UnloadIfIdle(object state)
        {
            if (this.idle)
            {
                HttpExceptionHelper.WriteThread(
                    "Unloading Idle Instance {0} at {1}", this.workflowApplication.Id, DateTime.Now.ToString("mm:ss"));
                if (this.serviceHost.OnUnload != null)
                {
                    // The host may decide it does not want to unload this instance.
                    if (!this.serviceHost.OnUnload(this.workflowApplication))
                    {
                        HttpExceptionHelper.WriteThread(
                            "Host OnUnload returned false for Instance {0}", this.workflowApplication.Id);
                        return;
                    }
                }

                // Once unloaded you cannot use the instance again
                WorkflowApplicationCache.Remove(this.workflowApplication.Id);
                this.workflowApplication.Unload();
            }
        }
コード例 #12
0
 public BeaconEntity StopTracking(string contactId = "", bool killContact = false, string endTime = "")
 {
     if (this.httpContextBase != null && this.httpContextBase.Session != null)
     {
         string arg;
         if (!this.TryGetSessionId(out arg))
         {
             HttpExceptionHelper.InternetServerError("Unexpected server error", "Session could not be initialized.");
         }
         this.logger.Debug(string.Format("[StopTracking]: CID: {0} SID: {1}", contactId, arg), null);
         HttpRequestBase httpRequestBase = this.httpContextBase.Request;
         if (!base.Request.Headers.Referrer.Host.Equals(base.Request.RequestUri.Host))
         {
             SpoofedHttpRequestBase spoofedHttpRequestBase = new SpoofedHttpRequestBase(this.httpContextBase.Request);
             spoofedHttpRequestBase.SetUrl(base.Request.Headers.Referrer);
             httpRequestBase = spoofedHttpRequestBase;
             IDomainMatcher domainMatcher;
             Language       language;
             if (!this.trackingManager.DomainIsValid(httpRequestBase, out domainMatcher, out language))
             {
                 throw new HttpResponseException(HttpStatusCode.BadRequest);
             }
             TrackPageVisitArgs args = new TrackPageVisitArgs(this.sitecoreContext, this.trackerProvider, this.httpContextBase.Request, this.httpContextBase.Response, httpRequestBase, new PageVisitParameters(this.httpContextBase.Request.Url, null, contactId), domainMatcher, false);
             InitializeTrackingCookieProcessor initializeTrackingCookieProcessor = new InitializeTrackingCookieProcessor();
             initializeTrackingCookieProcessor.Process(args);
             InitializeExternalTrackingProcessor initializeExternalTrackingProcessor = new InitializeExternalTrackingProcessor();
             initializeExternalTrackingProcessor.Process(args);
             InitializeContextSiteProcessor initializeContextSiteProcessor = new InitializeContextSiteProcessor();
             initializeContextSiteProcessor.Process(args);
         }
         else
         {
             Tracker.Initialize();
             Tracker.Current.Session.SetClassification(0, 0, false);
         }
         if (!string.IsNullOrWhiteSpace(endTime))
         {
             DateTime           dateTime    = DateTime.Parse(endTime, DateTimeFormatInfo.InvariantInfo);
             CurrentInteraction interaction = this.trackerProvider.Current.Interaction;
             Assert.IsNotNull(interaction, "interaction");
             TimeSpan t = DateTime.UtcNow - DateUtil.ToUniversalTime(dateTime);
             interaction.EndDateTime    = dateTime;
             interaction.StartDateTime -= t;
             Page[] pages = interaction.Pages;
             for (int i = 0; i < pages.Length; i++)
             {
                 Page page = pages[i];
                 page.DateTime -= t;
             }
         }
         this.httpContextBase.Session.Abandon();
         this.httpContextBase.Response.Cookies.Clear();
         if (killContact)
         {
             DateTime expires = new DateTime(1979, 1, 1, 0, 0, 0, DateTimeKind.Utc);
             string[] allKeys = this.httpContextBase.Request.Cookies.AllKeys;
             for (int j = 0; j < allKeys.Length; j++)
             {
                 string     text   = allKeys[j];
                 HttpCookie cookie = new HttpCookie(text)
                 {
                     Expires = expires,
                     Value   = string.Empty,
                     Domain  = this.httpContextBase.Request.Cookies.GetSafely(text).Domain
                 };
                 this.httpContextBase.Response.Cookies.Add(cookie);
             }
             this.httpContextBase.Response.Cookies.Add(new HttpCookie("SC_ANALYTICS_GLOBAL_COOKIE")
             {
                 Domain  = "." + this.httpContextBase.Request.Url.Host,
                 Value   = string.Empty,
                 Expires = expires
             });
         }
     }
     return(new BeaconEntity
     {
         Id = "TBC",
         ContactId = string.Empty,
         SessionId = string.Empty,
         Url = string.Empty
     });
 }
        /// <summary>
        /// Delivers the Http message to the receive activity and waits until the receive is closed before returning
        /// </summary>
        /// <param name="bookmarkName">
        /// The name of the bookmark to wait for
        /// </param>
        /// <param name="receive">
        /// The HttpReceive activity to deliver to
        /// </param>
        private void DeliverMessage(string bookmarkName, HttpReceive receive)
        {
            HttpExceptionHelper.WriteThread(
                "Delivering message to HttpReceive activity {0} ID {1} \"{2}\"",
                bookmarkName,
                receive.Id,
                receive.DisplayName);
            var timeLeft   = this.serviceHost.WorkflowTimeout;
            var retryMsecs = 10;

            while (timeLeft > TimeSpan.Zero)
            {
                // When resuming, the workflow might not be ready
                var result = this.workflowApplication.ResumeBookmark(bookmarkName, this);
                switch (result)
                {
                case BookmarkResumptionResult.Success:
                    if (!this.responseEvent.WaitOne(timeLeft))
                    {
                        throw HttpExceptionHelper.CreateResponseException(
                                  HttpStatusCode.InternalServerError,
                                  "Workflow timeout while waiting for response for {0}",
                                  bookmarkName);
                    }

                    // If the workflow terminated with an exception throw it
                    if (this.terminationException != null)
                    {
                        throw this.terminationException;
                    }

                    return;

                case BookmarkResumptionResult.NotFound:
                    throw HttpExceptionHelper.CreateResponseException(
                              HttpStatusCode.InternalServerError,
                              "Workflow was not waiting for bookmark {0}",
                              bookmarkName);

                case BookmarkResumptionResult.NotReady:
                    HttpExceptionHelper.WriteThread(
                        "Workflow Instance {0} was not ready to receive bookmark {1} retrying...",
                        bookmarkName,
                        this.workflowApplication.Id);

                    // The workflow was not ready to receive the resumption
                    Thread.Sleep(retryMsecs);
                    timeLeft   = timeLeft - TimeSpan.FromMilliseconds(retryMsecs);
                    retryMsecs = retryMsecs * 2;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            throw HttpExceptionHelper.CreateResponseException(
                      HttpStatusCode.InternalServerError,
                      "Unable to deliver message to Workflow ID {0} for bookmark {1}",
                      this.workflowApplication.Id,
                      bookmarkName);
        }
        public HttpResponseMessage InvokeWorkflow()
        {
#if DEBUG
            this.testName = this.Request.Headers.GetHeaderValue("TestName");
            this.testInfo = this.Request.Headers.GetHeaderValue("TestInfo");
            HttpExceptionHelper.WriteThread(
                "HttpResponseMessage InvokeWorkflow() message received {0} {1} Test: \"{2}\" Info:{3}",
                this.Request.Method,
                this.Request.RequestUri,
                this.testName,
                this.testInfo);
#endif

            // Step 1 - locate a receive activity that matches the Uri template
            // This will throw if no matching activity is found
            var receive = this.SelectMatchingReceiveActivity();

            if (receive == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            // Step 2 - Load or Create a workflow instance
            this.LoadOrCreateWorkflowInstance();

            HttpExceptionHelper.WriteThread(
                "Trying to Lock instance {0} {1} {2} Test: \"{3}\" Info:{4}",
                this.workflowApplication.Id,
                this.Request.Method,
                this.Request.RequestUri,
                this.testName,
                this.testInfo);
            if (!Monitor.TryEnter(this.workflowApplication, this.ServiceHost.WorkflowTimeout))
            {
                throw HttpExceptionHelper.CreateResponseException(
                          HttpStatusCode.InternalServerError,
                          "Timeout waiting for lock on instance {0}",
                          this.workflowApplication.Id);
            }

            try
            {
                HttpExceptionHelper.WriteThread(
                    "Successfully Locked instance {0} {1} {2} Test: \"{3}\" Info:{4}",
                    this.workflowApplication.Id,
                    this.Request.Method,
                    this.Request.RequestUri,
                    this.testName,
                    this.testInfo);

                // There may be a bookmark pending for this receive activity
                var bookmarkName =
                    receive.GetBookmarkName(this.serviceHost.GetMatchingBaseAddress(this.Request.RequestUri));

                // If the instance does not have the bookmark, create and run it
                if (!this.workflowApplication.ContainsBookmark(bookmarkName))
                {
                    // This will run the workflow until it becomes idle with the named bookmark
                    // Or it aborts, times out or completes
                    this.RunUntilBookmark(bookmarkName);
                }

                // Deliver the message to the receive activity by resuming the bookmark
                this.DeliverMessage(bookmarkName, receive);

                // The receive activity may or may not set a response
                HttpExceptionHelper.WriteThread("Returning response {0}", this.Response);

                // TODO: This makes IQueryable not work - can we return a response as an object?
                // If we do return an object, what if it is already an HttpResponse?
                return(this.Response);
            }
            finally
            {
                HttpExceptionHelper.WriteThread(
                    "Unlocking instance {0} {1} {2} Test: \"{3}\" Info:{4}",
                    this.workflowApplication.Id,
                    this.Request.Method,
                    this.Request.RequestUri,
                    this.testName,
                    this.testInfo);
                Monitor.Exit(this.workflowApplication);
            }
        }