Planifier et diffuser des travaux (Java)
Utilisez Azure IoT Hub pour planifier et suivre des travaux qui mettent à jour des millions d’appareils. Utilisez les travaux pour :
- Mettre à jour les propriétés souhaitées
- Mettre à jour les balises
- Appeler des méthodes directes
Un travail encapsule l’une de ces actions et suit l’exécution sur un ensemble d’appareils. Une requête de jumeau d’appareil définit l’ensemble d’appareils sur lesquels le travail s’exécute. Par exemple, une application principale peut utiliser un travail pour appeler une méthode directe sur 10 000 appareils et les redémarrer. Vous spécifiez l’ensemble des appareils avec une requête de jumeau d’appareil et planifiez le travail à exécuter ultérieurement. Le travail suit la progression à mesure que chacun de ces appareils reçoit et exécute la méthode directe de redémarrage.
Pour plus d’informations sur chacune de ces fonctionnalités, consultez les pages :
Jumeau d’appareil et propriétés : Prise en main des représentations d’appareils (Node) et Comprendre et utiliser les jumeaux d’appareil IoT Hub
Méthodes directes : Guide du développeur IoT Hub - méthodes directes
Notes
Les fonctionnalités décrites dans cet article sont uniquement disponibles au niveau Standard d’IoT Hub. Pour plus d’informations sur les niveaux de base et standard/gratuit d’IoT Hub, consultez Choisir le niveau IoT Hub correspondant à votre solution.
Cet article vous montre comment créer deux applications Java :
Une application pour appareils, simulated-device, implémentant une méthode directe nommée lockDoor, qui peut être appelée par l’application back-end.
Une application back-end, schedule-jobs, qui crée deux travaux. Un travail appelle la méthode directe lockDoor et un autre travail envoie les mises à jour de propriété souhaitées à plusieurs appareils.
Notes
Pour plus d’informations sur les outils SDK disponibles pour créer des applications d’appareil et de back-end, consultez les SDK Azure IoT.
Prérequis
Un hub IoT dans votre abonnement Azure. Si vous n’avez pas encore de hub, vous pouvez suivre les étapes décrites dans Créer un hub IoT.
Un appareil inscrit dans votre hub IoT. Si vous n’avez pas d’appareil dans votre hub IoT, suivez les étapes décrites dans Inscrire un appareil.
Java SE Development Kit 8. Veillez à sélectionner Java 8 sous Prise en charge à long terme pour accéder aux téléchargements du kit JDK 8.
Vérifiez que le port 8883 est ouvert dans votre pare-feu. L’exemple d’appareil décrit dans cet article utilise le protocole MQTT, qui communique via le port 8883. Ce port peut être bloqué dans certains environnements réseau professionnels et scolaires. Pour plus d’informations sur les différentes façons de contourner ce problème, consultez Connexion à IoT Hub (MQTT).
Notes
Pour simplifier les choses, cet article n’implémente aucune stratégie de nouvelles tentatives. Dans le code de production, vous devez implémenter des stratégies de nouvelle tentative (par exemple, une interruption exponentielle), comme indiqué dans l’article Gestion des erreurs temporaires.
Obtention de la chaîne de connexion de l’IoT Hub
Dans cet article, vous créez un service back-end qui planifie une tâche pour appeler une méthode directe sur un appareil, planifie une tâche pour mettre à jour le jumeau d’appareil, et supervise l’avancement de chaque tâche. Pour effectuer ces opérations, votre service requiert les autorisations de lecture du registre et d’écriture du registre. Par défaut, chaque hub IoT est créé avec une stratégie d’accès partagé nommée registryReadWrite qui accorde ces autorisations.
Pour obtenir la chaîne de connexion IoT Hub pour la stratégie registryReadWrite, procédez comme suit :
Dans le portail Azure, sélectionnez Groupes de ressources. Sélectionnez le groupe de ressources dans lequel se trouve votre hub, puis sélectionnez votre hub dans la liste des ressources.
Dans le volet de gauche de votre hub, sélectionnez Stratégies d’accès partagé.
Dans la liste des stratégies, sélectionnez la stratégie registryReadWrite.
Copiez la Chaîne de connexion principale, puis enregistrez la valeur.
Pour plus d’informations sur les autorisations et les stratégies d’accès partagé IoT Hub, consultez Contrôle d’accès et autorisations.
Important
Cet article comprend les étapes à suivre pour se connecter à un service à l’aide d’une signature d’accès partagé. Cette méthode d’authentification est pratique pour les tests et les évaluations, mais l’authentification à un service avec Microsoft Entra ID ou des identités managées est une approche plus sécurisée. Pour plus d’informations, consultez Meilleures pratiques de sécurité > Sécurité du cloud.
Créer l’application de service
Dans cette section, vous créez une application console Java qui utilise des travaux pour :
Appeler la méthode directe lockDoor sur plusieurs appareils.
Envoyer les propriétés souhaitées à plusieurs appareils.
Pour créer l’application :
Sur votre ordinateur de développement, créez un dossier vide nommé iot-java-schedule-jobs.
Dans le dossier iot-java-schedule-jobs, créez un projet Maven nommé schedule-jobs en entrant la commande ci-dessous à l'invite de commandes. Il s’agit d’une commande unique et longue :
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=schedule-jobs -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
À l'invite de commandes, accédez au dossier schedule-jobs.
À l'aide d'un éditeur de texte, ouvrez le fichier pom.xml situé dans le dossier schedule-jobs et ajoutez la dépendance suivante au nœud dependencies. Cette dépendance vous permet d’utiliser le package iot-service-client dans votre application pour communiquer avec votre IoT Hub :
<dependency> <groupId>com.microsoft.azure.sdk.iot</groupId> <artifactId>iot-service-client</artifactId> <version>1.17.1</version> <type>jar</type> </dependency>
Notes
Vous pouvez rechercher la dernière version de iot-service-client avec la recherche Maven.
Ajoutez le nœud build suivant après le nœud dependencies. Cette configuration ordonne à Maven d’utiliser Java 1.8 pour générer l’application :
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
Enregistrez et fermez le fichier pom.xml.
À l'aide d'un éditeur de texte, ouvrez le fichier schedule-jobs\src\main\java\com\mycompany\app\App.java.
Ajoutez les instructions import suivantes au fichier :
import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice; import com.microsoft.azure.sdk.iot.service.devicetwin.Pair; import com.microsoft.azure.sdk.iot.service.devicetwin.Query; import com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery; import com.microsoft.azure.sdk.iot.service.jobs.JobClient; import com.microsoft.azure.sdk.iot.service.jobs.JobResult; import com.microsoft.azure.sdk.iot.service.jobs.JobStatus; import java.util.Date; import java.time.Instant; import java.util.HashSet; import java.util.Set; import java.util.UUID;
Ajoutez les variables de niveau classe suivantes à la classe App . Remplacez
{youriothubconnectionstring}
par la chaîne de connexion de votre IoT Hub que vous avez précédemment copiée dans Obtention de la chaîne de connexion de l’IoT Hub :public static final String iotHubConnectionString = "{youriothubconnectionstring}"; public static final String deviceId = "myDeviceId"; // How long the job is permitted to run without // completing its work on the set of devices private static final long maxExecutionTimeInSeconds = 30;
Ajoutez la méthode suivante à la classe App pour planifier un travail et mettre à jour les propriétés Construction et Plancher souhaitées dans le jumeau d’appareil :
private static JobResult scheduleJobSetDesiredProperties(JobClient jobClient, String jobId) { DeviceTwinDevice twin = new DeviceTwinDevice(deviceId); Set<Pair> desiredProperties = new HashSet<Pair>(); desiredProperties.add(new Pair("Building", 43)); desiredProperties.add(new Pair("Floor", 3)); twin.setDesiredProperties(desiredProperties); // Optimistic concurrency control twin.setETag("*"); // Schedule the update twin job to run now // against a single device System.out.println("Schedule job " + jobId + " for device " + deviceId); try { JobResult jobResult = jobClient.scheduleUpdateTwin(jobId, "deviceId='" + deviceId + "'", twin, new Date(), maxExecutionTimeInSeconds); return jobResult; } catch (Exception e) { System.out.println("Exception scheduling desired properties job: " + jobId); System.out.println(e.getMessage()); return null; } }
Pour planifier un travail afin d’appeler la méthode lockDoor, ajoutez la méthode suivante à la classe App :
private static JobResult scheduleJobCallDirectMethod(JobClient jobClient, String jobId) { // Schedule a job now to call the lockDoor direct method // against a single device. Response and connection // timeouts are set to 5 seconds. System.out.println("Schedule job " + jobId + " for device " + deviceId); try { JobResult jobResult = jobClient.scheduleDeviceMethod(jobId, "deviceId='" + deviceId + "'", "lockDoor", 5L, 5L, null, new Date(), maxExecutionTimeInSeconds); return jobResult; } catch (Exception e) { System.out.println("Exception scheduling direct method job: " + jobId); System.out.println(e.getMessage()); return null; } };
Pour surveiller un travail, ajoutez la méthode suivante à la classe App :
private static void monitorJob(JobClient jobClient, String jobId) { try { JobResult jobResult = jobClient.getJob(jobId); if(jobResult == null) { System.out.println("No JobResult for: " + jobId); return; } // Check the job result until it's completed while(jobResult.getJobStatus() != JobStatus.completed) { Thread.sleep(100); jobResult = jobClient.getJob(jobId); System.out.println("Status " + jobResult.getJobStatus() + " for job " + jobId); } System.out.println("Final status " + jobResult.getJobStatus() + " for job " + jobId); } catch (Exception e) { System.out.println("Exception monitoring job: " + jobId); System.out.println(e.getMessage()); return; } }
Pour obtenir les détails des travaux que vous avez exécutés, ajoutez la méthode suivante :
private static void queryDeviceJobs(JobClient jobClient, String start) throws Exception { System.out.println("\nQuery device jobs since " + start); // Create a jobs query using the time the jobs started Query deviceJobQuery = jobClient .queryDeviceJob(SqlQuery.createSqlQuery("*", SqlQuery.FromType.JOBS, "devices.jobs.startTimeUtc > '" + start + "'", null).getQuery()); // Iterate over the list of jobs and print the details while (jobClient.hasNextJob(deviceJobQuery)) { System.out.println(jobClient.getNextJob(deviceJobQuery)); } }
Mettez à jour la signature de la méthode main pour qu’elle inclue la clause
throws
suivante :public static void main( String[] args ) throws Exception
Pour exécuter et surveiller les deux travaux de manière séquentielle, remplacez le code de la méthode main par le code suivant :
// Record the start time String start = Instant.now().toString(); // Create JobClient JobClient jobClient = JobClient.createFromConnectionString(iotHubConnectionString); System.out.println("JobClient created with success"); // Schedule twin job desired properties // Maximum concurrent jobs is 1 for Free and S1 tiers String desiredPropertiesJobId = "DPCMD" + UUID.randomUUID(); scheduleJobSetDesiredProperties(jobClient, desiredPropertiesJobId); monitorJob(jobClient, desiredPropertiesJobId); // Schedule twin job direct method String directMethodJobId = "DMCMD" + UUID.randomUUID(); scheduleJobCallDirectMethod(jobClient, directMethodJobId); monitorJob(jobClient, directMethodJobId); // Run a query to show the job detail queryDeviceJobs(jobClient, start); System.out.println("Shutting down schedule-jobs app");
Enregistrez et fermez le fichier schedule-jobs\src\main\java\com\mycompany\app\App.java.
Générez l’application schedule-jobs et corrigez les erreurs éventuelles. À l'invite de commandes, accédez au dossier schedule-jobs et exécutez la commande suivante :
mvn clean package -DskipTests
Créer une application d’appareil
Dans cette section, vous créez une application de console Java qui gère les propriétés souhaitées envoyées à partir de IoT Hub et implémente l’appel de méthode directe.
Important
Cet article comprend les étapes à suivre pour connecter un appareil en utilisant une signature d’accès partagé, également appelée « authentification par clé symétrique ». Cette méthode d’authentification est pratique pour les tests et les évaluations, mais l’authentification d’un appareil en utilisant des certificats X.509 est une approche plus sécurisée. Pour plus d’informations, consultez Meilleures pratiques de sécurité > Sécurité des connexions.
Dans le dossier iot-java-schedule-jobs, créez un projet Maven nommé simulated-device en entrant la commande suivante à l'invite de commandes. Il s’agit d’une commande unique et longue :
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
À l'invite de commandes, accédez au dossier simulated-device.
À l'aide d'un éditeur de texte, ouvrez le fichier pom.xml situé dans le dossier simulated-device et ajoutez les dépendances suivantes au nœud dependencies. Cette dépendance vous permet d’utiliser le package iot-device-client dans votre application pour communiquer avec votre IoT Hub :
<dependency> <groupId>com.microsoft.azure.sdk.iot</groupId> <artifactId>iot-device-client</artifactId> <version>1.17.5</version> </dependency>
Notes
Vous pouvez rechercher la dernière version de iot-device-client avec la recherche Maven.
Ajoutez la dépendance suivante au nœud dependencies. Cette dépendance configure un NOP pour la façade de journalisation Apache SLF4J utilisée par le kit de développement logiciel (SDK) du client d'appareil afin d'implémenter la journalisation. Cette configuration est facultative, mais si vous l'omettez, un avertissement peut s'afficher sur la console lorsque vous lancez l'application. Pour plus d'informations sur la journalisation dans le SDK du client d'appareil, consultez Journalisation dans le fichier Readme Exemples relatifs à Azure IoT device SDK pour Java.
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.28</version> </dependency>
Ajoutez le nœud build suivant après le nœud dependencies. Cette configuration ordonne à Maven d’utiliser Java 1.8 pour générer l’application :
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
Enregistrez et fermez le fichier pom.xml.
À l'aide d'un éditeur de texte, ouvrez le fichier simulated-device\src\main\java\com\mycompany\app\App.java.
Ajoutez les instructions import suivantes au fichier :
import com.microsoft.azure.sdk.iot.device.*; import com.microsoft.azure.sdk.iot.device.DeviceTwin.*; import java.io.IOException; import java.net.URISyntaxException; import java.util.Scanner;
Ajoutez les variables de niveau classe suivantes à la classe App . Remplacez
{yourdeviceconnectionstring}
par la chaîne de connexion de l’appareil que vous avez vu au moment de l’inscription d’un appareil dans votre IoT Hub :private static String connString = "{yourdeviceconnectionstring}"; private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT; private static final int METHOD_SUCCESS = 200; private static final int METHOD_NOT_DEFINED = 404;
Cet exemple d’application utilise la variable protocol lorsqu’il instancie un objet DeviceClient.
Pour imprimer des informations du jumeau d’appareil dans la console, ajoutez la classe imbriquée suivante à la classe App :
// Handler for device twin operation notifications from IoT Hub protected static class DeviceTwinStatusCallBack implements IotHubEventCallback { public void execute(IotHubStatusCode status, Object context) { System.out.println("IoT Hub responded to device twin operation with status " + status.name()); } }
Pour imprimer des notifications relatives à la méthode directe dans la console, ajoutez la classe imbriquée suivante à la classe App :
// Handler for direct method notifications from IoT Hub protected static class DirectMethodStatusCallback implements IotHubEventCallback { public void execute(IotHubStatusCode status, Object context) { System.out.println("IoT Hub responded to direct method operation with status " + status.name()); } }
Pour gérer les appels de méthode directe à partir de IoT Hub, ajoutez la classe imbriquée suivante à la classe App :
// Handler for direct method calls from IoT Hub protected static class DirectMethodCallback implements DeviceMethodCallback { @Override public DeviceMethodData call(String methodName, Object methodData, Object context) { DeviceMethodData deviceMethodData; switch (methodName) { case "lockDoor": { System.out.println("Executing direct method: " + methodName); deviceMethodData = new DeviceMethodData(METHOD_SUCCESS, "Executed direct method " + methodName); break; } default: { deviceMethodData = new DeviceMethodData(METHOD_NOT_DEFINED, "Not defined direct method " + methodName); } } // Notify IoT Hub of result return deviceMethodData; } }
Mettez à jour la signature de la méthode main pour qu’elle inclue la clause
throws
suivante :public static void main( String[] args ) throws IOException, URISyntaxException
Remplacez le code de la méthode main par le code suivant pour :
- créer un client d’appareil afin de communiquer avec IoT Hub.
- créer un objet Device afin de stocker les propriétés du jumeau d’appareil.
// Create a device client DeviceClient client = new DeviceClient(connString, protocol); // An object to manage device twin desired and reported properties Device dataCollector = new Device() { @Override public void PropertyCall(String propertyKey, Object propertyValue, Object context) { System.out.println("Received desired property change: " + propertyKey + " " + propertyValue); } };
Pour démarrer les services du client de l’appareil, ajoutez le code suivant à la méthode principale :
try { // Open the DeviceClient // Start the device twin services // Subscribe to direct method calls client.open(); client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null); client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(), null); } catch (Exception e) { System.out.println("Exception, shutting down \n" + " Cause: " + e.getCause() + " \n" + e.getMessage()); dataCollector.clean(); client.closeNow(); System.out.println("Shutting down..."); }
Pour attendre que l’utilisateur appuie sur la touche Entrée avant l’arrêt, ajoutez le code suivant à la fin de la méthode principal :
// Close the app System.out.println("Press any key to exit..."); Scanner scanner = new Scanner(System.in); scanner.nextLine(); dataCollector.clean(); client.closeNow(); scanner.close();
Enregistrez et fermez le fichier simulated-device\src\main\java\com\mycompany\app\App.java.
Générez l’application simulated-device et corrigez les erreurs. À l'invite de commandes, accédez au dossier simulated-device et exécutez la commande suivante :
mvn clean package -DskipTests
Exécuter les applications
Vous êtes maintenant prêt à exécuter les applications de console.
À l'invite de commande, dans le dossier simulated-device, exécutez la commande suivante afin de commencer à écouter les applications de l'appareil pour accéder aux modifications de propriété et aux appels de méthode directe souhaités :
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
À l’invite de commande du dossier
schedule-jobs
, exécutez la commande suivante pour faire fonctionner l’application de service schedule-jobs lors de l’exécution de deux travaux. Le premier définit les valeurs de propriété de votre choix et le second appelle la méthode directe :mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
L’application pour périphérique gère la modification de propriété souhaitée et l’appel de méthode directe :
Étapes suivantes
Dans cet article, vous avez planifié des travaux pour exécuter une méthode directe et mettre à jour les propriétés du jumeau d’appareil.
Pour continuer à explorer le hub IoT et les modèles de gestion des appareils, mettez à jour une image dans le Tutoriel sur le service Device Update pour IoT Hub : Utilisation de l’image de référence Raspberry Pi 3 B+.