Fermer

novembre 7, 2018

Tâches planifiées de Sitefinity avec Azure App et les services Cloud


L'exécution de tâches planifiées dans Sitefinity peut vous faire gagner du temps et améliorer votre efficacité. Dans cet article, découvrez comment les rendre opérationnels sur les environnements Azure.

Les tâches planifiées dans Progress Sitefinity offrent aujourd'hui aux clients la possibilité d'exécuter une logique en arrière-plan, telle que l'importation / l'exportation de données, automatisation et plus. Cependant, il existe certaines limitations concernant les offres fournies par cette fonctionnalité. L'un des problèmes que je voudrais aborder aujourd'hui concerne la prise en charge d'instances dans nos deux environnements Azure pris en charge: Services Cloud et Services d'application.

Définition de la limitation

Si vous avez déjà travaillé avec nos tâches planifiées, vous Peut-être avez-vous vu cet article de la base de connaissances avec une solution permettant d'exécuter une tâche planifiée sur un nœud dans un environnement à équilibrage de charge sur site / sur machine virtuelle. Malheureusement, cet article ne s'applique pas à un environnement Azure en raison du manque d'URL uniques pour chaque instance. Dans cet article de blog, je vais vous montrer une solution utilisable pour Azure.

Quelle est la solution?

Pour cet article de blog et cette solution, nous utiliserons la première de deux instances sur Azure App Services et Cloud. Services comme où le code sera exécuté. Pour cela, nous allons obtenir la collection d'instances sur Azure, sélectionner la première par son nom / id et enfin valider qu'elle est identique à celle actuellement demandée.

Avant de commencer à programmer, vous devez suivre les deux étapes suivantes:

  • Téléchargez votre fichier de paramètres de publication Azure. Pour plus d'informations sur la procédure à suivre, reportez-vous à l'article du présent article MSDN . Ce fichier contient deux champs dont nous aurons besoin pour notre solution: l'abonnement Azure Id, et notre certificat de gestion .
  • Accédez au dossier bin de votre projet Sitefinity et notez la version de Newtonsoft.Json.dll.

Ouvrez votre projet Sitefinity dans Visual Studio et téléchargez les packages NuGet suivants. :

  • Microsoft.WindowsAzure.Management.Libraries
  • Newtonsoft.Json (installez la version notée précédemment, car le paquet ci-dessus installera une version plus ancienne conformément à sa dépendance)

À la racine de votre projet Sitefinity , créez la structure de dossiers suivante:

 Structure de dossier Sitefinity "title =" Structure de dossier Sitefinity "style =" border-width: 0px; </span data-recalc-dims=

Authentifier avec Azure et s'assurer que nous sommes en première instance

Sous notre structure de dossiers, créons la classe AzureValidator . Nous y allons héberge les informations de notre compte Azure, crée et utilise le certificat nécessaire à l'authentification avec l'API d'Azure et effectue la validation nécessaire pour que Sitefinity puisse savoir si l'instance où nous nous trouvons est la première.

Pour cette classe, il y en a trois. Des propriétés importantes doivent être ajoutées, la première est AzureMode qui est une énumération de deux éléments (AppServices, CloudServices). Les deuxième et troisième nécessitent des informations provenant du fichier de paramètres de publication Azure (souvenez-vous de ce qui précède? ): SubscriptionId, CertificateData . Ouvrez le fichier et vous devriez obtenir le résultat suivant:

 Authentification avec Azure "data-displaymode =" Original "title =" Authentification avec Azure "style = "border-width: 0px; border- style: solid; "/> </span data-recalc-dims=

Copiez les valeurs de Id et ManagementCertificate et collez-les dans les propriétés SubscriptionId et CertificateData . respectivement. Une fois terminé, vos propriétés doivent ressembler à ceci:

public enum AzureMode {AppServices = 0, CloudServices = 1};

// remplace < Id > et < ManagementCertificate [19659028]> avec les informations sur les paramètres Azure Publish

privé statique en lecture seule string SubscriptionId = "< Id >";

en lecture statique privée string string CertificateData = "<[19659027] ManagementCertificate > ";

Maintenant, pour les méthodes que nous allons utiliser dans cette classe, nous aurons la méthode GetCertificateCredentials qui convertit le CertificateData de son string value (Base64) et l'importe dans un nouveau certificat X509 et le renvoie. Pour vous authentifier avec l'API Azure, nous créons la classe AuthenticateAzure qui renvoie un objet CertificateCloudCredentials qui est généré lorsque nous transmettons notre SubscriptionId et le certificat créé dans notre méthode précédente. Enfin, nous avons la méthode ValidateForOneInstance dans laquelle nous transmettons notre ensemble AzureMode à la valeur de votre choix. Cette méthode sera utilisée lorsque notre tâche planifiée est en cours d'exécution afin de pouvoir la comparer si l'instance actuelle est la identique à la première instance et renvoie true ou false en fonction du résultat. Une fois terminé, la classe devrait ressembler à ceci:

en utilisant Microsoft.WindowsAzure;

en utilisant System;

en utilisant System.Collections.Generic;

utilisant System.Linq;

avec System.Security.Cryptography.X509Certificates;

avec System.Web;

. SitefinityWebApp.AzureTaskAssist

{

public class AzureValidator

{

privé GetCertificateCredentials ()

{

var cert = new X509Certificate2 ();

cert.Import (Convert.FromBase64String (CertificateData);

] retour cert;

}

public static CertificateCloudCredentials AuthenticateAzure ()

{

var cert = GetCertificateCredentials ();

19659055] new CertificateCloudCredentials (SubscriptionId, cert);

}

public statique bool ValidateForOneInstance (mode AzureMode)

chaîne currentInstance = AzureResourceHelper.GetCurrentInstance (mode);

chaîne firstInstance = AzureResourceHelper.GetFirstInstance (mode);

si == première instance)

{

retour [1 9659055] true ;

}

return false ;

}

public enum AzureMode {AppServices = 0, CloudServices = 1};

// remplace et par les informations sur les paramètres Azure Publish

private static readonly string SubscriptionId = "" ;

private static en lecture seule string CertificateData = ";

}

}

Obtention des instances à la fois des services Azure App et des services Cloud sous un même toit

Dans le dossier Helpers, créez une classe appelée AzureResourceHelper . Nous allons ajouter ici les méthodes et la logique. cela impliquera la bibliothèque de gestion Azure et les appels aux services Azure App et aux services Cloud, qui sont eux-mêmes dans des espaces de nom distincts. Pour éviter ce petit inconvénient, les méthodes des deux côtés renverront le même type de valeur: string. Après cela, nous créerons deux méthodes ( GetCurrentInstance et GetCurrentInstance) qui recevront notre enum AzureMode et, en fonction de la valeur, elles feront appel à des méthodes du service Azure spécifique.

Azure API de services d'application

Notre première méthode est la GetAppServiceCurrentInstanceId, qui ne renvoie que la variable d'environnement suivante: Environment.GetEnvironmentVariable ("WEBSITE_INSTANCE_ID"). ToString ();

The GetAppServiceFendant qui créera une instance de WebSiteManagementClient (les méthodes AuthenticateAzure de la classe AzureValidator doivent être transmises), et nous obtenons la collection WebSiteInstanceIdsResponse que nous pouvons récupère le client que nous avons créé avec sa méthode WebSites.GetInstanceIds . Ce processus peut être un peu délicat, car nous devons transmettre le nom du site Web et le nom de l'espace Web pour obtenir les instances. Le nom du site Web se trouve sur le portail Azure, car il s'agit du nom utilisé lors de la création du site Web sur App Service. Cependant, les valeurs WebSpace ne sont pas trouvées sur l'interface utilisateur du portail Azure et ont la syntaxe suivante: " espace Web "…. difficile, non? Un exemple de ceci serait: sfangelazuretask-CentralUSwebspace. Vous pouvez également obtenir cette valeur via le code, qui serait le suivant:

// var list = client.WebSpaces.List ();

Ceci vous donne la liste des espaces Web sur App Services, et à partir de là. vous pouvez trouver celle sur laquelle vous allez travailler pour la transmettre à l'API Azure.

API Azure Cloud Services

Semblable à notre première méthode sur App Services, GetCloudServiceCurrentInstanceId renvoie l'instance actuelle de la chaîne suivante: RoleEnvironment.CurrentRoleInstance.Id;

Pour obtenir la première instance sur des services de cloud computing, le GetCloudServiceFirstInstance doit s'authentifier auprès d'Azure afin de créer une instance de ComputeManagementClient, et celui-ci n'a besoin que du nom du service cloud (vous pouvez l'obtenir à partir du portail Azure) pour obtenir une liste des services hébergés ( HostedServices.GetDetailed ) fournis aux services cloud. Ensuite, vous pouvez obtenir une liste de déploiements et enfin, vous pouvez obtenir le premier et son RoleInstance .

Votre classe devrait ressembler à ceci lorsque vous avez terminé:

en utilisant SitefinityWebApp.AzureTaskAssist;

en utilisant System;

en utilisant en Microsoft.WindowsAzure.Management.WebSites;

en utilisant Microsoft.WindowsAzure ;

utilisant Microsoft.WindowsAzure.Management.WebSites.Models;

avec avec Microsoft.WindowsAzure.ServiceRuntime;

avec

avec statique ] Microsoft.WindowsAzure.Management.Compute.Models.HostedServiceGetDetailedResponse;

en utilisant en utilisant en utilisant en utilisant en utilisant en utilisant en utilisant en utilisant . utilisant System.Linq;

l'espace de noms SitefinityWebApp

{

public classe AzureResourceHelper

{

public statique en cours chaîne de caractères (19659055) (Mode AzureValidator.AzureMode)

{

si (mode == AzureValidator.AzureMode.AppServices)

{

{

. GetAppServiceCurrentInstanceId ();

}

sinon si (mode == AzureValidator.AzureMode.CloudServices)

{

. 19659039] GetCloudServiceCurrentInstanceId ();

}

return "" [19659028];

}

public static string GetFirstInstance (AzureValidator.AzureMode mode)

] if (mode == AzureValidator.AzureMode.AppServices)

{

Retourner GetAppServiceFirstInstance ();

. 19659072] else if (mode == AzureValidator.AzureMode.CloudServices)

{

return GetCloudServiceFirstInstance (); ]

return "" ;

}

[19659191] public static string GetAppServiceFirstInstance ()

{

{19659179]

en utilisant (client client = new WebSiteManagementClient (AzureValidator.AuthenticateAzure ()))

{

// Crée une nouvelle variable pour la collection d'instance

var instanceIds = . WebSiteInstanceIdsResponse ();

// FACULTATIF: obtenez une liste des espaces Web trouvés dans les services d'application

// liste_verses = client.WebSpaces. .List ();

// Obtention de la collection d’instances sur le service Azur App Service

. instanceIds = client.WebSites.GetInstanceIds (

" - webspace" / * nom de l'espace Web * /

"" " / * nom du site Web * / );

return instanceIds.InstanceIds [0];

}

19659064]}

public static string GetAppServiceCurrentInstanceId ()

{

de

Environment.GetEnvironmentVariable ( "WEBSITE_INSTANCE_ID" ). ToString ();

59060] public statique string GetCloudServiceCurrentInstanceId ()

{

retour du type rôleEnvironment.CurrentRoleInstance.Id;

du format

de la liste des fonctionnalités 19659064]}

public static string GetCloudServiceFirstInstance ()

{

(ComputeManagementClient computeManagementClient = new ComputeManagementClient (AzureValidator.AuthenticateAzure ())

{

var cloudServiceName = . ;

var cloudServiceDetails = computeManagementClient.HostedServices.GetDetailed (cloudServiceName); [19659057] var firstDeployment = cloudServiceDetails.Deployments.ToList (). FirstOrDefault ();

return firstDeployment.RoleInstances [0]. ]}

}

} [19459264]

}

Comment et où utiliser cette logique

lors de la création une tâche planifiée, tout ce que vous avez à faire est d'appeler ValidateForOneNode à partir de la classe AzureValidator et de transmettre le mode Azure avec lequel vous allez travailler. Par exemple:

SchedulingManager manager = new SchedulingManager ();

// Sélectionnez cette option si vous l'exécutez sur des services Cloud ou des services d'application

. // Exécuter uniquement sur le nœud sélectionné, puis vérifier si aucune tâche n'a déjà été créée.

// Exécute la tâche

si (AzureValidator.ValidateForOneNode (AzureValidator.AzureMode.CloudServices))

[

du même nom. ) .Where (t => t.Key == AzureScheduledTask.TaskKey);

if (task.Count ()> 0)

return ;

AzureScheduledTask Azuretask = new AzureScheduledTask ();)

Azuretask.ExecuteTask ();

]

Conclusion

La solution dont nous venons de parler vous permettra d’améliorer votre site Load Balanced Sitefinity CMS avec les fonctionnalités permettant de et ne vous inquiétez pas des problèmes de duplication liés aux tâches planifiées d’import / export ou d’arrière-plan. N'hésitez pas à améliorer cette solution selon vos besoins et à les partager avec la communauté. Comme toujours, faites-nous part de vos impressions en commentant ou sur notre portail de commentaires .

Téléchargez la logique et essayez-le Yourself

Dans ce fichier zip AzureScheduledTasks vous trouverez un fichier et un dossier Global.asax avec toute la logique couverte sur ce blog (avec des commentaires plus détaillés), ainsi qu'une tâche planifiée que vous peut utiliser comme référence pour tester cette logique. Placez les fichiers à la racine de votre projet Sitefinity et apportez les modifications nécessaires pour qu'il puisse fonctionner pour vous. Parallèlement à cela, vous pouvez trouver un fichier texte contenant de brèves instructions sur la création du module dynamique que contient la tâche.




Source link