コード例 #1
0
        public CreateExperiment(AnalyticsAccount account, string name, bool serverSide = true, int?nodeUnderTest = null)
            : base(account)
        {
            if (!serverSide && nodeUnderTest < 1)
            {
                throw new InvalidOperationException("A valid node ID must be specificed for front-end tests");
            }

            if (serverSide && nodeUnderTest.HasValue)
            {
                throw new InvalidOperationException("A server side experiment cannot specify a node ID");
            }

            if (string.IsNullOrEmpty(name))
            {
                if (serverSide)
                {
                    throw new InvalidOperationException("Experiment name is required for server-side experiments");
                }
                else
                {
                    if (!ServerSide && string.IsNullOrEmpty(name))
                    {
                        var node = UmbracoContext.Application.Services.ContentService.GetById(NodeUnderTestId);
                        name = node.Name;
                    }
                }
            }

            ServerSide      = serverSide;
            NodeUnderTestId = nodeUnderTest ?? -1;
            Name            = name;
        }
コード例 #2
0
        public IEnumerable <MSADLA.Models.JobInformation> JobList(AnalyticsAccount account,
                                                                  Microsoft.Rest.Azure.OData.ODataQuery <MSADLA.Models.JobInformation> odata_query, int top)
        {
            // Other parameters
            string opt_select = null;
            bool?  opt_count  = null;

            int item_count = 0;
            var page       = this.RestClient.Job.List(account.Name, odata_query, opt_select, opt_count);

            foreach (
                var job in
                RestUtil.EnumItemsInPages <MSADLA.Models.JobInformation>(page,
                                                                         p => this.RestClient.Job.ListNext(p.NextPageLink)))
            {
                yield return(job);

                item_count++;

                if ((top > 0) && (item_count >= top))
                {
                    break;
                }
            }
        }
コード例 #3
0
        public async Task <HttpResponseMessage> CheckAccess(CancellationToken cancellationToken)
        {
            var response = new List <object>();

            foreach (var config in AnalyticsAccount.GetAll())
            {
                bool   hasAccess   = false;
                bool   isConnected = false;
                string error       = string.Empty;

                try
                {
                    isConnected = await uSplitAuthorizationCodeFlow.GetInstance(config).IsConnected(cancellationToken);

                    if (isConnected)
                    {
                        hasAccess = await new CheckAccess(config).ExecuteAsync();
                    }
                }
                catch (Exception ex)
                {
                    error = ex.Message;
                }
                response.Add(new
                {
                    Name        = config.Name,
                    HasAccess   = hasAccess,
                    IsConnected = isConnected,
                    Error       = error,
                    ProfileId   = config.UniqueId,
                });
            }
            return(CreateResponse(response));
        }
コード例 #4
0
 public Account(AnalyticsAccount account)
 {
     Id      = account.Id;
     Name    = account.Name;
     Created = account.Created;
     Updated = account.Updated;
 }
コード例 #5
0
        protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
        {
            var menu = new MenuItemCollection();

            var accounts = AnalyticsAccount.GetAll().ToList();

            if (IsRootNode(id))
            {
                if (accounts.Count == 1)
                {
                    menu.Items.Add <ActionNew>("Create a new experiment", "profileId", accounts.First().UniqueId);
                }
            }
            else if (accounts.Any(x => x.UniqueId == id))
            {
                menu.Items.Add <ActionNew>("Create a new experiment", "profileId", id);
            }
            else //experiment node
            {
                //TODO: Nice-to-haves
                //menu.Items.Add<ActionPublish>("Start this experiment");
                //menu.Items.Add<ActionDisable>("Stop this experiment");
                menu.Items.Add <ActionDelete>("Delete this experiment");
            }

            return(menu);
        }
コード例 #6
0
        public async Task UpdateExperimentsCacheAsync()
        {
            //TODO: check if we are configured, otherwise this will generate errors every now and then

            var experiments = new List <GoogleExperiment>();

            foreach (var config in AnalyticsAccount.GetAll())
            {
                logger.Info(typeof(ExperimentsUpdater), $"Updating experiments data from Google Analytics for {config.Name} (ID {config.UniqueId}).");
                try
                {
                    var result = await new GetExperiments(config).ExecuteAsync();
                    experiments.AddRange(result.Items);
                }
                catch (Exception ex)
                {
                    logger.Error(typeof(ExperimentsUpdater), $"Failed to download A/B testing data for {config.Name} (ID {config.UniqueId}).", ex);
                }
            }

            try
            {
                var cache = ApplicationContext.Current.ApplicationCache.RuntimeCache;
                cache.InsertCacheItem(Constants.Cache.RawExperimentData, () => experiments,
                                      Constants.Cache.ExperimentsRefreshInterval);
                cache.ClearCacheItem(Constants.Cache.ParsedExperiments);
            }
            catch (Exception ex)
            {
                logger.Error(typeof(ExperimentsUpdater), $"Failed to update cache after downloading experiments.", ex);
            }
        }
コード例 #7
0
        public async Task <GoogleExperiment> CreateExperimentAsync(string profileId, string name, int?nodeId = null)
        {
            var command = new CreateExperiment(AnalyticsAccount.GetByUniqueId(profileId),
                                               name, nodeId == null, nodeId);

            return(await ExecuteAsync(command));
        }
コード例 #8
0
        private static string GetStoragePath(AnalyticsAccount config)
        {
            var appName     = Constants.ApplicationName;
            var storagePath = HostingEnvironment.MapPath($"~/App_Data/TEMP/{appName}/google/auth/{config.UniqueId}");

            return(storagePath);
        }
コード例 #9
0
 public static uSplitAuthorizationCodeFlow GetInstance(AnalyticsAccount config)
 {
     if (!Instances.ContainsKey(config.UniqueId))
     {
         Instances[config.UniqueId] = new uSplitAuthorizationCodeFlow(config);
     }
     return(Instances[config.UniqueId]);
 }
コード例 #10
0
 public async Task DeleteVariationAsync(string profileId, [FromBody] DeleteVariationRequest request)
 {
     await ExecuteAsync(new DeleteVariation(AnalyticsAccount.GetByUniqueId(profileId))
     {
         GoogleExperimentId = request.ExperimentId,
         VariationName      = request.VariationName
     });
 }
コード例 #11
0
        public JobInfo JobBuild(AnalyticsAccount account, SubmitJobOptions options)
        {
            var job_props = options.ToJobInformationObject();
            var job_info  = this.RestClient.Job.Build(account.Name, job_props);
            var j         = new JobInfo(job_info, account);

            return(j);
        }
コード例 #12
0
        public IEnumerable <MSADL.Analytics.Models.SasTokenInfo> ListSasTokens(AnalyticsAccount account, string storage_account, string container)
        {
            var initial_page = this.RestClient.StorageAccounts.ListSasTokens(account.ResourceGroup, account.Name, storage_account, container);

            foreach (var acc in RestUtil.EnumItemsInPages(initial_page, p => this.RestClient.StorageAccounts.ListSasTokensNext(p.NextPageLink)))
            {
                yield return(acc);
            }
        }
コード例 #13
0
        public static ManagementResource.ExperimentsResource.ListRequest List(
            this ManagementResource.ExperimentsResource experiments, AnalyticsAccount config)
        {
            var accountId     = config.GoogleAccountId;
            var webPropertyId = config.GoogleWebPropertyId;
            var profileId     = config.GoogleProfileId;

            return(experiments.List(accountId, webPropertyId, profileId));
        }
コード例 #14
0
        public async Task <IHttpActionResult> SetSegmentAsync(string profileId, [FromBody] SetSegmentRequest request)
        {
            await ExecuteAsync(new SetSegment(AnalyticsAccount.GetByUniqueId(profileId)) {
                ExperimentId = request.ExperimentId,
                ProviderKey  = request.ProviderKey,
                Value        = request.Value
            });

            return(Ok());
        }
コード例 #15
0
        public override Task <ActionResult> IndexAsync(AuthorizationCodeResponseUrl authorizationCode, CancellationToken taskCancellationToken)
        {
            var stateWithoutRandomToken = authorizationCode.State.Substring(0, authorizationCode.State.Length - AuthorizationCodeWebApp.StateRandomLength);
            var uri       = new Uri(stateWithoutRandomToken);
            var profileId = uri.ParseQueryString().Get("profileId");
            var config    = AnalyticsAccount.GetByUniqueId(profileId);

            _flowData = new uSplitFlowMetadata(config);
            return(base.IndexAsync(authorizationCode, taskCancellationToken));
        }
コード例 #16
0
        public IEnumerable <MSADLA.Models.USqlTableStatistics> ListTableStatistics(AnalyticsAccount account, string dbname, string schema, string tablename)
        {
            var oDataQuery = new Microsoft.Rest.Azure.OData.ODataQuery <MSADLA.Models.USqlTableType>();

            var page = this.RestClient.Catalog.ListTableStatistics(account.Name, dbname, schema, tablename);

            foreach (var stats in RestUtil.EnumItemsInPages <MSADLA.Models.USqlTableStatistics>(page, p => this.RestClient.Catalog.ListTableStatisticsNext(p.NextPageLink)))
            {
                yield return(stats);
            }
        }
コード例 #17
0
        public async Task <HttpResponseMessage> AddVariationAsync(string profileId, [FromBody] AddVariationRequest request)
        {
            var variationDetails = await ExecuteAsync(new AddVariation(AnalyticsAccount.GetByUniqueId(profileId))
            {
                Name = request.Name,
                GoogleExperimentId = request.ExperimentId,
                NodeId             = request.NodeId
            });

            return(CreateResponse(variationDetails));
        }
コード例 #18
0
        public async Task <HttpResponseMessage> StopExperimentAsync(string id, string profileId)
        {
            var experiment = await ExecuteAsync(new StopExperiment(AnalyticsAccount.GetByUniqueId(profileId), id));

            var details = await ExecuteAsync(new GetExperimentDetails()
            {
                Experiment = experiment
            });

            return(CreateResponse(details));
        }
コード例 #19
0
        public IEnumerable <MSADLA.Models.USqlSchema> ListSchemas(AnalyticsAccount account, string dbname)
        {
            var    oDataQuery = new Microsoft.Rest.Azure.OData.ODataQuery <MSADLA.Models.USqlSchema>();
            string @select    = null;
            bool?  count      = null;

            var page = this.RestClient.Catalog.ListSchemas(account.Name, dbname, oDataQuery, @select, count);

            foreach (var schema in RestUtil.EnumItemsInPages <MSADLA.Models.USqlSchema>(page, p => this.RestClient.Catalog.ListSchemasNext(p.NextPageLink)))
            {
                yield return(schema);
            }
        }
コード例 #20
0
        public IEnumerable <MSADLA.Models.USqlAssemblyClr> ListAssemblies(AnalyticsAccount account, string dbname)
        {
            var oDataQuery = new Microsoft.Rest.Azure.OData.ODataQuery <Microsoft.Azure.Management.DataLake.Analytics.Models.USqlAssembly>();

            string @select = null;
            bool?  count   = null;

            var page = this.RestClient.Catalog.ListAssemblies(account.Name, dbname, oDataQuery, @select, count);

            foreach (var asm in RestUtil.EnumItemsInPages <MSADLA.Models.USqlAssemblyClr>(page, p => this.RestClient.Catalog.ListAssembliesNext(p.NextPageLink)))
            {
                yield return(asm);
            }
        }
コード例 #21
0
 private static Initializer CreateFlowInitializer(AnalyticsAccount config)
 {
     return(new Initializer
     {
         ClientSecrets = new ClientSecrets
         {
             ClientId = WebConfigurationManager.AppSettings[Constants.AppSettings.GoogleClientId],
             ClientSecret = WebConfigurationManager.AppSettings[Constants.AppSettings.GoogleClientSecret]
         },
         Scopes = new[] { AnalyticsService.Scope.AnalyticsEdit },
         DataStore = new FileDataStore(GetStoragePath(config), true),
         UserDefinedQueryParams = new [] { new KeyValuePair <string, string>("testkey", "testvalue"), },
     });
 }
コード例 #22
0
        public async Task <ActionResult> ReauthorizeAsync(string originalUrl, string profileId, CancellationToken cancellationToken)
        {
            var config = AnalyticsAccount.GetByUniqueId(profileId);
            var flow   = uSplitAuthorizationCodeFlow.GetInstance(config);

            if (await flow.IsConnected(cancellationToken))
            {
                await flow.DeleteTokenAsync(Constants.Google.SystemUserId, cancellationToken);
            }

            return(RedirectToAction(nameof(AuthorizeAsync), new
            {
                originalUrl,
                profileId
            }));
        }
コード例 #23
0
        public async Task <ActionResult> AuthorizeAsync(string originalUrl, string profileId, CancellationToken cancellationToken)
        {
            var config = AnalyticsAccount.GetByUniqueId(profileId);
            var result = await new AuthorizationCodeMvcApp(this, new uSplitFlowMetadata(config)).AuthorizeAsync(cancellationToken);

            if (result.Credential == null)
            {
                //no token, lets go to Google
                return(new RedirectResult(result.RedirectUri));
            }

            //refresh the experiments cache
            await ExperimentsUpdater.Instance.UpdateExperimentsCacheAsync();

            //got a token, we can return back
            return(new RedirectResult(originalUrl));
        }
コード例 #24
0
        private TreeNode CreateAccountNode(AnalyticsAccount config, FormDataCollection queryStrings)
        {
            var name = config.Name;

            if (name.IsNullOrWhiteSpace())
            {
                name = config.UniqueId;
            }

            const string icon = Constants.Icons.Account + " color-black";

            var url  = $"content/{Constants.Trees.AbTesting}/dashboard/{config.UniqueId}/";
            var node = CreateTreeNode(config.UniqueId, $"{UmbracoConstants.System.Root}", queryStrings, name, icon, url);

            node.HasChildren = true;
            return(node);
        }
コード例 #25
0
        private async Task <TreeNodeCollection> GetNodesForAccountAsync(AnalyticsAccount config, FormDataCollection queryStrings)
        {
            var nodes = new TreeNodeCollection();

            string parentId = config.UniqueId;

            if (!await uSplitAuthorizationCodeFlow.GetInstance(config).IsConnected(CancellationToken.None))
            {
                nodes.Add(CreateTreeNode("error", parentId, queryStrings,
                                         "ERROR - Google API not connected", "icon-alert"));
            }
            else
            {
                nodes.AddRange(await CreateExperimentNodes(queryStrings, parentId, config));
            }

            return(nodes);
        }
コード例 #26
0
        protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
        {
            if (IsRootNode(id))
            {
                var nodes = AsyncHelpers.RunSync(() => GetNodesUnderRootAsync(queryStrings));
                return(nodes);
            }

            var accounts = AnalyticsAccount.GetAll().ToList();
            var account  = accounts.FirstOrDefault(x => x.UniqueId == id);

            if (account != null)
            {
                var nodes = AsyncHelpers.RunSync(() => GetNodesForAccountAsync(account, queryStrings));
                return(nodes);
            }

            throw new NotSupportedException("Invalid node id");
        }
コード例 #27
0
        private async Task <TreeNodeCollection> GetNodesUnderRootAsync(FormDataCollection queryStrings)
        {
            var nodes    = new TreeNodeCollection();
            var accounts = AnalyticsAccount.GetAll().ToList();

            if (accounts.Count() > 1)
            {
                foreach (var account in accounts)
                {
                    var accountNode = CreateAccountNode(account, queryStrings);
                    nodes.Add(accountNode);
                }
            }
            else if (accounts.Count() == 1)
            {
                return(await GetNodesForAccountAsync(accounts[0], queryStrings));
            }

            return(nodes);
        }
コード例 #28
0
        public async Task DeleteExperimentAsync(string id, string profileId)
        {
            var accountConfigs = AnalyticsAccount.GetAll().ToList();
            AnalyticsAccount config;

            if ((id.IsNullOrWhiteSpace() || id == "-1") && accountConfigs.Count == 1)
            {
                config = accountConfigs.First();
            }
            else
            {
                config = AnalyticsAccount.GetByUniqueId(profileId);
            }


            //TODO: add an option to delete variations (e.g. Umbraco content linked to it)
            await ExecuteAsync(new DeleteExperiment(config)
            {
                GoogleExperimentId = id
            });
        }
コード例 #29
0
        internal JobInfo(MSADLA.Models.JobInformation job, AnalyticsAccount acct)
        {
            // this method is only meant to be called for JobInformation
            // objects that come back from list jobs or from get job

            if (!job.JobId.HasValue)
            {
                throw new System.ArgumentException("job's id is null");
            }

            this.Account             = acct;
            this.Name                = job.Name;
            this.LogFolder           = job.LogFolder;
            this.DegreeOfParallelism = job.DegreeOfParallelism;
            this.EndTime             = job.EndTime;
            this.Id         = job.JobId.Value;
            this.Priority   = job.Priority;
            this.Result     = job.Result;
            this.StartTime  = job.StartTime;
            this.State      = job.State;
            this.SubmitTime = job.SubmitTime;
            this.Type       = job.Type;
            this.Submitter  = job.Submitter;
        }
コード例 #30
0
 public CheckAccess(AnalyticsAccount config) : base(config)
 {
 }