public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequestMessage req,
            TraceWriter log)
        {
            log.Info($"C# HTTP trigger function '{FunctionName}' processed a request.");

            // parse query parameter
            string relativeUrl = req.GetQueryNameValuePairs()
                                 .FirstOrDefault(q => string.Compare(q.Key, "relativeUrl", true) == 0)
                                 .Value;

            if (string.IsNullOrEmpty(relativeUrl) == true)
            {
                return(req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a relative url on the query string."));
            }

            var tenantUrl = new Uri(CloudConfigurationManager.GetSetting("TenantUrl"));

            Uri.TryCreate(tenantUrl, relativeUrl, out Uri fullSiteUrl);
            var siteCollectionExistsMessage = new SiteCollectionExistsMessage()
            {
                Exists = false
            };

            try
            {
                var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());
                using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(fullSiteUrl.AbsoluteUri))
                {
                    ctx.Load(ctx.Web);
                    ctx.ExecuteQuery();
                    siteCollectionExistsMessage.Title = ctx.Web.Title;
                    var type = fullSiteUrl.PathAndQuery.Substring("/sites/".Length, 4).ToUpperInvariant();
                    if (string.IsNullOrEmpty(type) == true)
                    {
                        type = fullSiteUrl.PathAndQuery.Substring("/teams/".Length, 4).ToUpperInvariant();
                    }
                    siteCollectionExistsMessage.AbsoluteUri = fullSiteUrl.AbsoluteUri;
                    siteCollectionExistsMessage.RelativeUrl = fullSiteUrl.PathAndQuery;
                    siteCollectionExistsMessage.Type        = type;
                    siteCollectionExistsMessage.Exists      = true;
                }
            }
            catch
            {
                // site does not exist
            }
            return(req.CreateResponse(HttpStatusCode.OK, siteCollectionExistsMessage));
        }
        private static void GetTemplateFromSharePointOnline(string templateUrl, CloudBlockBlob blob)
        {
            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());
            var provisioningSiteUrl  = CloudConfigurationManager.GetSetting("ProvisioningSite");

            using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(provisioningSiteUrl))
            {
                var templateListItem = ctx.Web.GetListItem(templateUrl);
                var file             = templateListItem.File;

                // File in SPO is newer, so grab that
                var binaryStream = file.OpenBinaryStream();
                ctx.Load(file);
                ctx.ExecuteQuery();
                if (binaryStream != null && binaryStream.Value != null)
                {
                    // Save to blob
                    binaryStream.Value.Position = 0;
                    blob.UploadFromStream(binaryStream.Value);
                }
            }
        }
Ejemplo n.º 3
0
    void Start()
    {
        ClientContextManager context = null;

        foreach (GameObject rootGameObject in gameObject.scene.GetRootGameObjects())
        {
            context = rootGameObject.GetComponentInChildren <ClientContextManager>();
            if (context != null)
            {
                break;
            }
        }
        if (context == null)
        {
            return;
        }

        seat = GetComponent <Seat>();
        foreach (NetSync g in seat.ownerOf)
        {
            g.gameObject.AddComponent <PlayerController>();
            context.RegisterPlayerOwned(g.GUID);
        }
    }
Ejemplo n.º 4
0
        public static async void Run(
            [ServiceBusTrigger("new-sites-topic", "create-site-subscription", AccessRights.Manage, Connection = "ManageTopicConnection")] BrokeredMessage newSiteMsg,
            [OrchestrationClient] DurableOrchestrationClient orchestrationClient,
            TraceWriter log)
        {
            log.Info($"C# Service Bus trigger function '{FunctionName}' processed message: {newSiteMsg.MessageId}");

            /*
             * The following line should work, but doesn't, so small workaround here...
             */
            //var createSiteCollectionJob = newSiteMsg.GetBody<CreateSiteCollectionJob>();
            var          stream       = newSiteMsg.GetBody <Stream>();
            StreamReader streamReader = new StreamReader(stream);
            string       createSiteCollectionJobAsJson = streamReader.ReadToEnd();
            var          createSiteCollectionJob       = JsonConvert.DeserializeObject <CreateSiteCollectionJob>(createSiteCollectionJobAsJson);

            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureWebJobsStorage"));
            CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer  container      = blobClient.GetContainerReference(CloudConfigurationManager.GetSetting("JobFilesContainer"));

            var blob       = container.GetBlobReference(createSiteCollectionJob.FileNameWithExtension);
            var blobStream = new MemoryStream();

            blob.DownloadToStream(blobStream);
            streamReader        = new StreamReader(blobStream);
            blobStream.Position = 0;
            string blobContent = streamReader.ReadToEnd();

            JObject provisioningJobFile     = JObject.Parse(blobContent);
            var     provisioningTemplateUrl = provisioningJobFile["ProvisioningTemplateUrl"].Value <string>();
            var     tenantUrl = new Uri(CloudConfigurationManager.GetSetting("TenantUrl"));

            Uri.TryCreate(tenantUrl,
                          provisioningJobFile["RelativeUrl"].Value <string>(),
                          out Uri fullSiteUrl);
            //Properties of the New SiteCollection
            var siteCreationProperties = new SiteCreationProperties
            {
                //New SiteCollection Url
                Url = fullSiteUrl.AbsoluteUri,
                //Title of the Root Site
                Title = provisioningJobFile["SiteTitle"].Value <string>(),
                //Template of the Root Site. Using Team Site for now.
                Template = "STS#0",
                //Owner of thge Site
                Owner = provisioningJobFile["Owner"].Value <string>(),
                //Storage Limit in MB
                StorageMaximumLevel = provisioningJobFile["StorageMaximumLevel"].Value <int>(),
                StorageWarningLevel = provisioningJobFile["StorageWarningLevel"].Value <int>(),
                //UserCode Resource Points Allowed
                UserCodeMaximumLevel = provisioningJobFile["UserCodeMaximumLevel"].Value <int>(),
                UserCodeWarningLevel = provisioningJobFile["UserCodeWarningLevel"].Value <int>(),
                //TimeZone
                TimeZoneId = provisioningJobFile["TimeZone"].Value <int>(),
            };

            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());

            using (var adminCtx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(CloudConfigurationManager.GetSetting("TenantAdminUrl")))
            {
                var tenant = new Tenant(adminCtx);
                //Create the SiteCollection
                tenant.CreateSite(siteCreationProperties);

                try
                {
                    adminCtx.Load(tenant);
                    adminCtx.ExecuteQuery();
                    log.Info($"Initiated creation of site collection: {siteCreationProperties.Url}");

                    string instanceId = await orchestrationClient
                                        .StartNewAsync("monitor-site-collection-creation", new MonitorSiteCollectionCreationData
                    {
                        FullSiteUrl             = siteCreationProperties.Url,
                        ListItemID              = createSiteCollectionJob.ListItemID,
                        ProvisioningTemplateUrl = provisioningTemplateUrl,
                        TimeStamp = DateTime.Now,
                        CreateSiteCollectionJob = createSiteCollectionJob
                    });

                    // ToDo: Update value of field provisioning status in Azure Storage Table "CustomerDocumentCenterSites"
                    log.Info($"Durable Function Ochestration for site collection creation started: {instanceId}");
                }
                catch (Exception ex)
                {
                    log.Error($"Something went wrong while creating site collection: {siteCreationProperties.Url}.", ex);
                }
            }
        }
Ejemplo n.º 5
0
        public static async void Run(
            [OrchestrationTrigger] DurableOrchestrationContext orchestrationContext,
            [ServiceBus("site-updates-topic", Connection = "ManageTopicConnection")] ICollector <BrokeredMessage> updateSitesTopic,
            TraceWriter log)
        {
            log.Info($"C# Orchestration trigger function '{FunctionName}' started.");

            bool siteHasBeenCreated         = false;
            var  siteCollectionCreationData = orchestrationContext.GetInput <MonitorSiteCollectionCreationData>();

            log.Info($"Monitor creation of site '{siteCollectionCreationData.FullSiteUrl}'.");
            if (siteCollectionCreationData.TimeStamp == null ||
                DateTime.Now.Subtract(siteCollectionCreationData.TimeStamp) > new TimeSpan(24, 10, 00))
            {
                log.Warning($"SiteCollection {siteCollectionCreationData.FullSiteUrl} was not created within 24 hours or timestamp was empty.");
                return;
            }

            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());

            using (var adminCtx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(CloudConfigurationManager.GetSetting("TenantAdminUrl")))
            {
                var tenant = new Tenant(adminCtx);
                try
                {
                    //Get the site name
                    var properties = tenant.GetSitePropertiesByUrl(siteCollectionCreationData.FullSiteUrl, false);
                    tenant.Context.Load(properties);
                    // Will cause an exception if site URL is not there. Not optimal, but the way it works.
                    tenant.Context.ExecuteQueryRetry();
                    log.Info($"Site creation status: '{properties.Status}'.");
                    siteHasBeenCreated = properties.Status.Equals("Active", StringComparison.OrdinalIgnoreCase);
                }
                catch
                {
                    try
                    {
                        // Check if a site collection with this URL has been recycled (exists in garbage bin)
                        var deletedProperties = tenant.GetDeletedSitePropertiesByUrl(siteCollectionCreationData.FullSiteUrl);
                        tenant.Context.Load(deletedProperties);
                        tenant.Context.ExecuteQueryRetry();
                        if (deletedProperties.Status.Equals("Recycled", StringComparison.OrdinalIgnoreCase))
                        {
                            log.Info($"SiteCollection with URL{siteCollectionCreationData.FullSiteUrl} already exists in recycle bin.");

                            var provisioningSiteUrl = CloudConfigurationManager.GetSetting("ProvisioningSite");
                            using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(provisioningSiteUrl))
                            {
                                // Todo: get list title from configuration.
                                // Assume that the web has a list named "PnPProvisioningJobs".
                                List     provisioningJobsList = ctx.Web.Lists.GetByTitle("PnPProvisioningJobs");
                                ListItem listItem             = provisioningJobsList.GetItemById(siteCollectionCreationData.ListItemID);
                                // Write a new value to the PnPProvisioningJobStatus field of
                                // the PnPProvisioningJobs item.
                                listItem["PnPProvisioningJobStatus"] = "Failed (site with same URL exists in recycle bin)"; //ToDo: Should we have different statusses for actual site creation and the applying of the template?
                                listItem.Update();

                                ctx.ExecuteQuery();
                            }
                            return;
                        }
                    } catch
                    {
                        siteHasBeenCreated = false;
                    }
                }

                //Check if provisioning of the SiteCollection is complete.
                while (!siteHasBeenCreated)
                {
                    //Wait for 1 minute and then try again
                    DateTime deadline = orchestrationContext.CurrentUtcDateTime.Add(TimeSpan.FromMinutes(1));
                    await orchestrationContext.CreateTimer(deadline, CancellationToken.None);
                }

                if (siteHasBeenCreated)
                {
                    log.Info($"SiteCollection {siteCollectionCreationData.FullSiteUrl} created.");

                    var applyProvisioningTemplateJob = new ApplyProvisioningTemplateJob()
                    {
                        ListItemID              = siteCollectionCreationData.ListItemID,
                        FileNameWithExtension   = siteCollectionCreationData.CreateSiteCollectionJob.FileNameWithExtension,
                        ProvisioningTemplateUrl = siteCollectionCreationData.ProvisioningTemplateUrl
                    };
                    var applyProvisioningTemplateMsg = new BrokeredMessage(applyProvisioningTemplateJob,
                                                                           new DataContractJsonSerializer(typeof(ApplyProvisioningTemplateJob)))
                    {
                        ContentType = "application/json",
                        Label       = "UpdateSiteTemplate"
                    };
                    updateSitesTopic.Add(applyProvisioningTemplateMsg);
                }
            }
        }
        public static void Run(
            [ServiceBusTrigger("site-updates-topic", "update-metadata-subscription", AccessRights.Manage, Connection = "ManageTopicConnection")] BrokeredMessage updateMsg,
            TraceWriter log)
        {
            log.Info($"C# ServiceBus trigger function '{FunctionName}' processed message: {updateMsg.MessageId} (Label': {updateMsg.Label}')");

            var somethingWentWrong   = false;
            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());
            var updateMetadataJob    = updateMsg.GetBody <UpdateSiteJob>();

            using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(updateMetadataJob.Url))
            {
                // ToDo; currently we only support updating the Title (incl. Maritime Installations)
                // Maybe use switch statement here. Come up with some better way of resolving
                // what kind of site we're dealing with (info from property bag or Azure storage table)

                // Specific stuff happens here, like for instance updating the default column
                // value 'site' for an installation (metadata value for site is always the same
                // as the Title of an Installation site collection)
                if (updateMetadataJob.Url.ToLowerInvariant().Contains("/inst-") == true)
                {
                    try
                    {
                        const string propertyBagDefaultColumnValues = "_marlink_defaultcolumnvalues";
                        var          definitionJson = ctx.Web.GetPropertyBagValueString(propertyBagDefaultColumnValues, String.Empty);
                        if (string.IsNullOrEmpty(definitionJson))
                        {
                            log.Info($"Definition in site {updateMetadataJob.Url} was empty.");
                            return;
                        }

                        var          definition     = JsonConvert.DeserializeObject <DefaultColumnValuesDefinition>(definitionJson);
                        const string siteColumnName = "dc_Site";
                        definition.Libraries.ForEach(l =>
                        {
                            l.Folders.ForEach(f =>
                            {
                                var siteColumnIndex = f.DefaultColumnValues.FindIndex(c => String.CompareOrdinal(c.Name, siteColumnName) == 0);
                                if (siteColumnIndex != -1)
                                {
                                    f.DefaultColumnValues[siteColumnIndex].Value = updateMetadataJob.Title;
                                }
                                else
                                {
                                    f.DefaultColumnValues.Add(new DefaultColumnValue()
                                    {
                                        Name  = siteColumnName,
                                        Value = updateMetadataJob.Title
                                    });
                                }
                            });
                        });

                        // Save the template information in the target site
                        var updatedDefinition = definition;
                        updatedDefinition.AppliedOn = null;
                        string updatedJson = JsonConvert.SerializeObject(updatedDefinition);
                        // Validate if the defintion confirms to the schema

                        /*
                         * if (DefaultColumnValuesHelper.IsValidDefinition(updatedJson, out IEnumerable<string> errors) == false)
                         * {
                         *  log.Error($"Invalid JSON Definition was provided for {updateMetadataJob.Url}.");
                         *  foreach (var errMsg in errors)
                         *  {
                         *      log.Info(errMsg);
                         *  }
                         *  return;
                         * }
                         */

                        ctx.Web.SetPropertyBagValue("_marlink_defaultcolumnvalues", updatedJson);
                        log.Info($"Updated Default Column Values Definition in site {updateMetadataJob.Url}.");
                    }
                    catch (Exception ex)
                    {
                        log.Error($"Error occured while setting default column values to {updateMetadataJob.Url}.", ex);
                        somethingWentWrong = true;
                    }
                }

                try
                {
                    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureWebJobsStorage"));
                    CloudTableClient    tableClient    = storageAccount.CreateCloudTableClient();
                    CloudTable          customerDocumentCenterSitesTable = tableClient.GetTableReference(CloudConfigurationManager.GetSetting("SitesTable"));

                    // Update columns in Azure Storage table to reflect updates
                    var item = new CustomerDocumentCenterSitesTableEntry
                    {
                        PartitionKey = updateMetadataJob.Type,
                        RowKey       = updateMetadataJob.ID,
                        ETag         = "*",
                        Title        = updateMetadataJob.Title,
                    };
                    if (updateMetadataJob.Type == "INST")
                    {
                        item.Site = updateMetadataJob.Title;
                    }
                    var operation = TableOperation.Merge(item);
                    customerDocumentCenterSitesTable.ExecuteAsync(operation);
                }
                catch (Exception ex)
                {
                    log.Error($"Error occured while updating table entry of {updateMetadataJob.Url}.", ex);
                    somethingWentWrong = true;
                }

                if (somethingWentWrong == false)
                {
                    ctx.Web.Title = updateMetadataJob.Title;
                    ctx.Web.Update();
                    ctx.ExecuteQuery();
                    log.Info($"Updated title of site collection '{updateMetadataJob.Url}' to '{updateMetadataJob.Title}'");
                }
            }
        }
Ejemplo n.º 7
0
        public static void Run(
            [ServiceBusTrigger("site-updates-topic", "apply-template-subscription", AccessRights.Manage, Connection = "ManageTopicConnection")] BrokeredMessage updateMsg,
            [ServiceBus("new-sites-topic", Connection = "ManageTopicConnection")] ICollector <BrokeredMessage> newSitesTopic,
            ExecutionContext executionContext,
            TraceWriter log)
        {
            log.Info($"C# Service Bus trigger function '{FunctionName}' processed message: {updateMsg.MessageId} (Label': {updateMsg.Label}')");

            /*
             * The following line should work, but doesn't, so small workaround here...
             */
            //var applyProvisioningTemplateJobAsJson = updateMsg.GetBody<ApplyProvisioningTemplateJob>();
            var          stream       = updateMsg.GetBody <Stream>();
            StreamReader streamReader = new StreamReader(stream);
            string       applyProvisioningTemplateJobAsJson = streamReader.ReadToEnd();
            var          applyProvisioningTemplateJob       = JsonConvert.DeserializeObject <ApplyProvisioningTemplateJob>(applyProvisioningTemplateJobAsJson);

            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureWebJobsStorage"));
            CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer  container      = blobClient.GetContainerReference(CloudConfigurationManager.GetSetting("JobFilesContainer"));

            var blob       = container.GetBlobReference(applyProvisioningTemplateJob.FileNameWithExtension);
            var blobStream = new MemoryStream();

            blob.DownloadToStream(blobStream);
            streamReader        = new StreamReader(blobStream);
            blobStream.Position = 0;
            string blobContent = streamReader.ReadToEnd();

            JObject provisioningJobFile     = JObject.Parse(blobContent);
            var     provisioningTemplateUrl = provisioningJobFile["ProvisioningTemplateUrl"].Value <string>();
            var     relativeUrl             = provisioningJobFile["RelativeUrl"].Value <string>();
            // get JSON result objects into a list
            IList <JToken> parameters = provisioningJobFile["TemplateParameters"].Children().ToList();
            // serialize JSON results into .NET objects
            IDictionary <string, string> templateParameters = new Dictionary <string, string>();

            foreach (JProperty parameter in parameters)
            {
                templateParameters.Add(parameter.Name, parameter.Value.ToObject <string>());
            }

            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());
            var provisioningSiteUrl  = CloudConfigurationManager.GetSetting("ProvisioningSite");

            using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(provisioningSiteUrl))
            {
                // Todo: get list title from configuration.
                // Assume that the web has a list named "PnPProvisioningJobs".
                List     provisioningJobsList = ctx.Web.Lists.GetByTitle("PnPProvisioningJobs");
                ListItem listItem             = provisioningJobsList.GetItemById(applyProvisioningTemplateJob.ListItemID);
                // Write a new value to the PnPProvisioningJobStatus field of
                // the PnPProvisioningJobs item.
                listItem["PnPProvisioningJobStatus"] = "Running (applying template)";
                listItem.Update();
                ctx.ExecuteQuery();

                var templateContainer  = blobClient.GetContainerReference(CloudConfigurationManager.GetSetting("TemplateFilesContainer"));
                var templateFileName   = Path.GetFileName(provisioningTemplateUrl);
                var templateBlob       = templateContainer.GetBlobReference(templateFileName);
                var templateBlobStream = new MemoryStream();
                templateBlob.DownloadToStream(templateBlobStream);
                var provisioningTemplate = new SiteTemplate(templateBlobStream).ProvisioningTemplate;
                log.Info($"(id {executionContext.InvocationId}) Retrieved template {templateFileName} from blob storage.");

                foreach (var parameter in templateParameters)
                {
                    provisioningTemplate.Parameters[parameter.Key] = parameter.Value;
                }

                var ptai = new ProvisioningTemplateApplyingInformation
                {
                    ProgressDelegate = (string message, int progress, int total) =>
                    {
                        log.Info($"(id {executionContext.InvocationId})[Progress]: {progress:00}/{total:00} - {message}");
                    },
                    MessagesDelegate = (string message, ProvisioningMessageType messageType) =>
                    {
                        log.Info($"(id {executionContext.InvocationId})[{messageType.ToString()}]: {message}");
                    },
                };
                var tenantUrl = new Uri(CloudConfigurationManager.GetSetting("TenantUrl"));
                Uri.TryCreate(tenantUrl, relativeUrl, out Uri fullSiteUrl);
                var templateAppliedWithOutAnyErrors = false;
                log.Info($"Opening ctx to {fullSiteUrl.AbsoluteUri}");
                using (var newSiteContext = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(fullSiteUrl.AbsoluteUri))
                {
                    int       tryCount = 0;
                    const int maxTries = 3;
                    do
                    {
                        tryCount++;
                        try
                        {
                            log.Info($"Applying the provisioning template {provisioningTemplateUrl} to {fullSiteUrl.AbsoluteUri}.");
                            newSiteContext.Web.ApplyProvisioningTemplate(provisioningTemplate, ptai);
                            log.Info($"Provisioning template has been applied to {fullSiteUrl.AbsoluteUri}.");
                            templateAppliedWithOutAnyErrors = true;
                        }
                        catch (Exception ex)
                        {
                            log.Error($"Error occured while applying the provisioning template to {fullSiteUrl.AbsoluteUri}.", ex);
                            templateAppliedWithOutAnyErrors = false;
                            if (tryCount <= maxTries)
                            {
                                log.Warning($"An error occured while applying the provisioning template, but will try to apply the provisioning template to {fullSiteUrl.AbsoluteUri} once more. (max {maxTries} times, this was attempt number {tryCount}.)");
                            }
                            else
                            {
                                log.Warning($"Tried {maxTries} times to apply the provisioning template without succes.");
                            }
                        }
                    } while (templateAppliedWithOutAnyErrors == false && tryCount <= maxTries);
                }

                if (templateAppliedWithOutAnyErrors == true)
                {
                    var setDefaultColumnValuesMsg = new BrokeredMessage(applyProvisioningTemplateJob,
                                                                        new DataContractJsonSerializer(typeof(ApplyProvisioningTemplateJob)))
                    {
                        ContentType = "application/json",
                        Label       = "SetDefaultColumnValues"
                    };
                    newSitesTopic.Add(setDefaultColumnValuesMsg);
                    listItem["PnPProvisioningJobStatus"] = "Provisioned";
                }
                else
                {
                    listItem["PnPProvisioningJobStatus"] = "Failed (error while applying template)";
                }
                listItem.Update();
                ctx.ExecuteQuery();
            }
        }
        public static void Run(
            [ServiceBusTrigger("site-operations-topic", "new-sites-subscription", AccessRights.Manage, Connection = "ManageTopicConnection")] BrokeredMessage newSiteMsg,
            [Blob("provisioning-job-files", Connection = "AzureWebJobsStorage")] CloudBlobDirectory blobDirectory,
            [ServiceBus("new-sites-topic", Connection = "ManageTopicConnection")] ICollector <BrokeredMessage> newSitesTopic,
            TraceWriter log)
        {
            log.Info($"C# ServiceBus trigger function '{FunctionName}' processed message: {newSiteMsg.MessageId} (Label': {newSiteMsg.Label}')");

            /*
             * The following line should work, but doesn't, so small workaround here...
             */
            //var createSiteCollectionJob = newSiteMsg.GetBody<CreateSiteCollectionJob>();
            var          stream       = newSiteMsg.GetBody <Stream>();
            StreamReader streamReader = new StreamReader(stream);
            string       createSiteCollectionJobAsJson = streamReader.ReadToEnd();
            var          createSiteCollectionJob       = JsonConvert.DeserializeObject <CreateSiteCollectionJob>(createSiteCollectionJobAsJson);

            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());
            var provisioningSiteUrl  = CloudConfigurationManager.GetSetting("ProvisioningSite");

            using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(provisioningSiteUrl))
            {
                // Todo: construct URL in a more resililant way ;-)
                var    relativeSiteUrl       = new Uri(provisioningSiteUrl).PathAndQuery;
                string serverRelativeFileUrl = $"{relativeSiteUrl}/{createSiteCollectionJob.FolderPath}{createSiteCollectionJob.FileNameWithExtension}";
                var    jobFile = ctx.Web.GetFileByServerRelativeUrl(serverRelativeFileUrl);
                ctx.Load(jobFile, jf => jf.ServerRelativeUrl);
                // ToDo: what if file does not exist?
                var jobFileStream = jobFile.OpenBinaryStream();
                ctx.ExecuteQueryRetry();
                MemoryStream mem = new MemoryStream();
                jobFileStream.Value.CopyTo(mem);
                mem.Position = 0;
                StreamReader reader          = new StreamReader(mem, Encoding.Unicode);
                var          jobFileAsString = reader.ReadToEnd();

                // Store job file in blob storage
                CloudBlockBlob blob = blobDirectory.GetBlockBlobReference(createSiteCollectionJob.FileNameWithExtension);
                blob.Properties.ContentType = "application/json";
                //blob.Metadata.Add("abcd", "12345");
                blob.UploadText(jobFileAsString);
                log.Info($"JobFile '{createSiteCollectionJob.FileNameWithExtension}' stored in Azure blob storage");

                var createSiteCollectionMsg = new BrokeredMessage(createSiteCollectionJob,
                                                                  new DataContractJsonSerializer(typeof(CreateSiteCollectionJob)))
                {
                    ContentType = "application/json",
                    Label       = "CreateSiteCollection"
                };
                newSitesTopic.Add(createSiteCollectionMsg);

                // Todo: get list title from configuration.
                // Assume that the web has a list named "PnPProvisioningJobs".
                List     provisioningJobsList = ctx.Web.Lists.GetByTitle("PnPProvisioningJobs");
                ListItem listItem             = provisioningJobsList.GetItemById(createSiteCollectionJob.ListItemID);
                listItem["PnPProvisioningJobStatus"] = "Running (creating site collection)"; //ToDo: Should we have different statusses for actual site creation and the applying of the template?
                listItem.Update();

                ctx.ExecuteQuery();
            }
        }
Ejemplo n.º 9
0
        public static void Run(
            [ServiceBusTrigger("new-sites-topic", "set-default-column-values-subscription", AccessRights.Manage, Connection = "ManageTopicConnection")] BrokeredMessage setDefaultColumnValuesMsg,
            TraceWriter log)
        {
            log.Info($"C# Service Bus trigger function '{FunctionName}' processed message: {setDefaultColumnValuesMsg.MessageId} (Label': {setDefaultColumnValuesMsg.Label}')");

            /*
             * The following line should work, but doesn't, so small workaround here...
             */
            //var applyProvisioningTemplateJobAsJson = setDefaultColumnValuesMsg.GetBody<ApplyProvisioningTemplateJob>();
            var          stream       = setDefaultColumnValuesMsg.GetBody <Stream>();
            StreamReader streamReader = new StreamReader(stream);
            string       applyProvisioningTemplateJobAsJson = streamReader.ReadToEnd();
            var          applyProvisioningTemplateJob       = JsonConvert.DeserializeObject <ApplyProvisioningTemplateJob>(applyProvisioningTemplateJobAsJson);

            // ToDo: instead of retrieving this info from blob, get it from table storage
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("AzureWebJobsStorage"));
            CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer  container      = blobClient.GetContainerReference(CloudConfigurationManager.GetSetting("JobFilesContainer"));

            var blob       = container.GetBlobReference(applyProvisioningTemplateJob.FileNameWithExtension);
            var blobStream = new MemoryStream();

            blob.DownloadToStream(blobStream);
            streamReader        = new StreamReader(blobStream);
            blobStream.Position = 0;
            string blobContent = streamReader.ReadToEnd();

            JObject provisioningJobFile     = JObject.Parse(blobContent);
            var     provisioningTemplateUrl = provisioningJobFile["ProvisioningTemplateUrl"].Value <string>();
            var     relativeUrl             = provisioningJobFile["RelativeUrl"].Value <string>();

            var tenantUrl = new Uri(CloudConfigurationManager.GetSetting("TenantUrl"));

            Uri.TryCreate(tenantUrl, relativeUrl, out Uri fullSiteUrl);

            // Currently only do this for Maritime Installation sites
            if (relativeUrl.ToLowerInvariant().Contains("/inst-") == false)
            {
                log.Info($"Site collection {fullSiteUrl.AbsoluteUri} is not a maritime Installation site. Skip setting default column values.");
                return;
            }

            // get JSON result objects into a list
            IList <JToken> parameters = provisioningJobFile["TemplateParameters"].Children().ToList();
            // serialize JSON results into .NET objects
            var defaultColumnValues = new List <DefaultColumnValue>();

            foreach (JProperty parameter in parameters)
            {
                defaultColumnValues.Add(new DefaultColumnValue
                {
                    Name  = $"dc_{parameter.Name}",
                    Value = parameter.Value.ToObject <string>()
                });
            }

            var folders = new List <DefaultColumnValuesFolder> {
                new DefaultColumnValuesFolder {
                    Path = "/", DefaultColumnValues = defaultColumnValues
                }
            };

            var definition = new DefaultColumnValuesDefinition();

            definition.Libraries.AddRange(new List <DefaultColumnValuesLibrary> {
                new DefaultColumnValuesLibrary {
                    Name = "Installation", Folders = folders
                }
                , new DefaultColumnValuesLibrary {
                    Name = "Logistics", Folders = folders
                }
                , new DefaultColumnValuesLibrary {
                    Name = "Network", Folders = folders
                }
                , new DefaultColumnValuesLibrary {
                    Name = "Pictures", Folders = folders
                }
                , new DefaultColumnValuesLibrary {
                    Name = "Project", Folders = folders
                }
                , new DefaultColumnValuesLibrary {
                    Name = "Solutions", Folders = folders
                }
                , new DefaultColumnValuesLibrary {
                    Name = "Videos", Folders = folders
                }
            });

            var clientContextManager = new ClientContextManager(new BaseConfiguration(), new CertificateManager());

            using (var ctx = clientContextManager.GetAzureADAppOnlyAuthenticatedContext(fullSiteUrl.AbsoluteUri))
            {
                try
                {
                    var jsonDefinition = JsonConvert.SerializeObject(definition, Formatting.None);
                    ctx.Web.SetPropertyBagValue("_marlink_defaultcolumnvalues", jsonDefinition);
                    log.Info($"Added Default Column Values Definition object to property bag of site {fullSiteUrl.AbsoluteUri}.");
                }
                catch (Exception ex)
                {
                    log.Error($"Error occured while setting default column values to {fullSiteUrl.AbsoluteUri}.", ex);
                }
            }
        }