Bonnes pratiques du KIT de développement logiciel (SDK) des connecteurs Microsoft Graph

Cet article fournit les meilleures pratiques à suivre lorsque vous utilisez le Kit de développement logiciel (SDK) de connecteurs Microsoft Graph pour implémenter un connecteur personnalisé.

Utilisation du marqueur de progression de l’analyse

Le marqueur de progression de l’analyse agit comme un identificateur pour l’élément particulier envoyé par le connecteur qui a été traité pour la dernière fois par la plateforme. Vous pouvez implémenter deux types d’analyse : les analyses complètes périodiques et incrémentielles.

Les analyses complètes périodiques obtiennent tous les éléments de la source de données et ingèrent uniquement les éléments qui sont modifiés ou qui ne sont pas présents dans l’index. S’il ne trouve pas d’élément, il le supprime de l’index.

Les analyses incrémentielles obtiennent des éléments ajoutés ou modifiés depuis la dernière analyse incrémentielle. Le connecteur peut également envoyer des éléments à supprimer dans le cadre de cette analyse. Pour la première analyse incrémentielle, l’heure de début de la dernière analyse complète est également envoyée. Le connecteur peut éventuellement utiliser cette analyse pour extraire les éléments modifiés uniquement après la dernière analyse complète.

Les analyses complètes et incrémentielles périodiques ont leurs marqueurs de progression d’analyse.

Utilisation du marqueur de progression de l’analyse pendant les analyses complètes périodiques

Le SDK envoie le marqueur de progression de l’analyse si l’analyse précédente s’est bloquée ou si une analyse planifiée a été manquée en raison du fait que l’agent du connecteur Microsoft Graph est hors connexion pendant les analyses complètes périodiques.

Si l’analyse précédente ne s’est pas planté, vous devez analyser la source de données depuis le début.

Utilisation du marqueur de progression de l’analyse pendant les analyses incrémentielles

Au cours d’une analyse incrémentielle, le connecteur envoie le marqueur de progression de l’analyse à la plateforme du connecteur, et il continuera à le faire pour les analyses incrémentielles suivantes. Le connecteur peut utiliser cette analyse pour extraire les éléments ajoutés ou modifiés après ce marqueur.

Construction de types génériques

Les valeurs de propriété de l’élément de contenu peuvent avoir une plage de types de données. Étant donné que gRPC n’a pas de construction pour les objets génériques, le Kit de développement logiciel (SDK) inclut une structure GenericType qui peut contenir n’importe quel type de données pris en charge. GenericType a la structure suivante :

// Represents a generic type that can hold any supported value
message GenericType {
 // Value of the Generic type
 oneof value {
  // String type value
  string stringValue = 1;

  // Long value
  int64 intValue = 2;


  // Double value
  double doubleValue = 3;

  // DateTime value
  google.protobuf.Timestamp dateTimeValue = 4;

  // Boolean value
  bool boolValue = 5;

  // String collection value
  StringCollectionType stringCollectionValue = 6;

  // Long collection value
  IntCollectionType intCollectionValue = 7;

  // Double collection value
  DoubleCollectionType doubleCollectionValue = 8;

  // DateTime collection value
  TimestampCollectionType dateTimeCollectionValue = 9;
 }
}

// Collection of string
message StringCollectionType {
 // Value of string collection
 repeated string values = 1;
}

// Collection of long
message IntCollectionType {
 // Value of long collection
 repeated int64 values = 1;
}

// Collection of double
message DoubleCollectionType {
 // Value of double collection
 repeated double values = 1;
}

// Collection of DateTime
message TimestampCollectionType {
 // Value of DateTime collection
 repeated google.protobuf.Timestamp values = 1;
}

GenericType peut avoir l’un des types suivants : string, int64, double, DateTime et Boolean ou une collection de chaînes, int64, double et DateTime. Voici des exemples de définition de ces types :

// Setting string value in generic type
    GenericType stringType = new GenericType
    {
        StringValue = "Hello"
    };

    // Setting int64 value in generic type
    GenericType int64Type = new GenericType
    {
        IntValue = 1000
    };

    // Setting double value in generic type
    GenericType doubleType = new GenericType
    {
        DoubleValue = 12.54
    };

    // Setting dateTime value in generic type
    GenericType dateTimeType = new GenericType
    {
        DateTimeValue = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow)
    };

    // Setting boolean value in generic type
    GenericType boolType = new GenericType
    {
        BoolValue = true
    };

    // Setting string collection value in generic type - Initialize the string collection first, add the values to the string collection and then set it in the generic type
    StringCollectionType stringCollection = new StringCollectionType();
    stringCollection.Values.Add("Value1");
    stringCollection.Values.Add("Value2");
    GenericType stringCollectionType = new GenericType
    {
        StringCollectionValue = stringCollection
    };

    // Setting int64 collection value in generic type - Initialize the int64 collection first, add the values to the int64 collection and then set it in the generic type
    IntCollectionType intCollection = new IntCollectionType();
    intCollection.Values.Add(1234);
    intCollection.Values.Add(5436);
    GenericType intCollectionType = new GenericType
    {
        IntCollectionValue = intCollection
    };

    // Setting double collection value in generic type - Initialize the double collection first, add the values to the double collection and then set it in the generic type
    DoubleCollectionType doubleCollection = new DoubleCollectionType();
    doubleCollection.Values.Add(12.54);
    doubleCollection.Values.Add(34.213);
    GenericType doubleCollectionType = new GenericType
    {
        DoubleCollectionValue = doubleCollection
    };

    // Setting datetime collection value in generic type - Initialize the datetime collection first, add the values to the datetime collection and then set it in the generic type
    TimestampCollectionType dateTimeCollection = new TimestampCollectionType();
    dateTimeCollection.Values.Add(Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow));
    dateTimeCollection.Values.Add(Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow.AddDays(-1)));
    GenericType dateTimeCollectionType = new GenericType
    {
        DateTimeCollectionValue = dateTimeCollection
    };

Création d’un schéma de recherche

Le schéma des connecteurs présente les restrictions suivantes :

  • Nom de la propriété : le nom de la propriété peut comporter un maximum de 32 caractères et seuls les caractères alphanumériques sont autorisés.
  • annotations Recherche :
    • Seules les propriétés de type String ou StringCollection peuvent faire l’objet d’une recherche.
    • Seules les propriétés de type String peuvent être une propriété de contenu.
    • Les propriétés de contenu doivent faire l’objet d’une recherche.
    • Les propriétés de contenu ne peuvent pas être interrogeables ou récupérables.
    • La propriété refinable ne doit pas faire l’objet d’une recherche.
    • La propriété refinable doit être interrogeable et récupérable.
    • Les propriétés booléennes ne peuvent pas être redéfinies.
  • Alias : un ensemble d’alias ou un nom convivial pour la propriété peut avoir un maximum de 32 caractères et uniquement des caractères alphanumériques autorisés.

Extraction d’éléments pendant une analyse

La méthode GetCrawlStream est une méthode de diffusion en continu de serveur. Il convertit chaque élément de la source de données en CrawlStreamBit pendant l’analyse et l’envoie sur le flux de réponse.

Pour obtenir un débit correct, le connecteur doit récupérer un lot d’éléments à partir de la source de données, convertir chaque élément en CrawlStreamBit et les envoyer sur le flux de réponse. La taille du lot dépend de la source de données. Nous recommandons 25 comme taille optimale pour maintenir le flux continu d’éléments sur le flux.

Gestion des exceptions dans le code du connecteur

Toutes les réponses des appels gRPC ont un OperationStatus qui indique si l’opération a réussi ou échoué, la raison de l’échec et les détails de la nouvelle tentative en cas d’échec. Nous vous recommandons d’encapsuler l’intégralité du code dans un bloc try-catch. Le connecteur doit journaliser toutes les exceptions et envoyer une opération appropriée status à la plateforme.

Les flux de gestion des connexions envoient une réponse avec statusMessage qui apparaît dans le Centre d'administration Microsoft 365. L’envoi de messages significatifs facilite le débogage des erreurs sur l’interface utilisateur et évite de laisser des exceptions non gérées.

Délais d’expiration

Toutes les méthodes dans ConnectionManagementService doivent être terminées et retournées dans un délai de 30 secondes . sinon, la plateforme retourne un message d’erreur de délai d’attente pour la demande.

Renvoi d’erreurs du connecteur à la plateforme

Toutes les réponses utilisent OperationStatus dans la structure de réponse. Si des erreurs se sont produites, les connecteurs doivent utiliser OperationStatus pour envoyer la raison de l’échec et renvoyer les informations de nouvelle tentative à la plateforme. Utilisez OperationStatus pour définir les erreurs pendant les analyses si des erreurs au niveau de la connexion telles que des informations d’identification expirées pour accéder à la source de données se produisent.

La structure OperationStatus comporte trois champs qui peuvent être utilisés pour représenter les erreurs éventuelles.

OperationResult

OperationResult est une énumération qui peut contenir la raison de l’échec.

StatusMessage

StatusMessage est une propriété d’OperationStatus qui peut stocker le message personnalisé pour afficher la raison de l’échec qui apparaîtra à l’administrateur pendant la configuration de la connexion. Par exemple, si les informations d’identification sont incorrectes lors de la validation avec la méthode ValidateAuthentication , la propriété result peut être définie sur AuthenticationIssue et la propriété statusMessage peut être définie sur Informations d’identification incorrectes fournies. Lorsque la méthode ValidateAuthentication est appelée, ce statusMessage s’affiche à l’administrateur de recherche. Pendant les analyses, ce scénario déplace la connexion à l’état d’échec, affiche l’erreur d’authentification à l’administrateur et invite l’administrateur à mettre à jour les informations d’identification pour accéder à la source de données.

RetryDetails

RetryDetails permet au connecteur de renvoyer des informations à la plateforme sur les erreurs temporaires pendant les analyses et de les utiliser pour répéter l’opération.

La nouvelle tentative peut être une interruption standard ou exponentielle. Le connecteur peut définir le temps de pause, le taux d’interruption et le coefficient d’interruption, puis les renvoyer. Par exemple, si la source de données est limitée pendant l’analyse, le connecteur peut définir OperationResult sur DatasourceError et envoyer les détails de nouvelle tentative en fonction de l’en-tête de nouvelle tentative dans les en-têtes de réponse de la source de données.

Mappage d’erreur pour OperationResult

Les erreurs suivantes déplacent la connexion à l’état d’échec :

  • OperationResult.AuthenticationIssue

  • OperationResult.ValidationFailure

Les autres codes d’opération seront traités comme des échecs temporaires et seront retentés dans les analyses suivantes.