Distribuzione del traffico in entrata - AWS Panorama

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Distribuzione del traffico in entrata

È possibile monitorare o eseguire il debug delle applicazioni localmente eseguendo un server HTTP insieme al codice dell'applicazione. Per servire il traffico esterno, è possibile mappare le porte di AWS Panorama Appliance alle porte del contenitore dell'applicazione.

Importante

Per impostazione predefinita, AWS Panorama Appliance non accetta traffico in entrata su nessuna porta. L'apertura di porte sull'accessorio comporta rischi impliciti per la sicurezza. Quando si utilizza questa funzionalità, è necessario adottare ulteriori misure perproteggere il tuo elettrodomestico dal traffico esternoe comunicazioni sicure tra i clienti autorizzati e l'apparecchio.

Il codice di esempio incluso in questa guida è a scopo dimostrativo e non implementa l'autenticazione, l'autorizzazione o la crittografia.

È possibile aprire porte nell'intervallo 8000—9000 sull'accessorio. Queste porte, una volta aperte, possono ricevere traffico da qualsiasi client instradabile. Quando si distribuisce l'applicazione, è necessario specificare quali porte aprire e mappare le porte dell'accessorio alle porte del contenitore dell'applicazione. Il software dell'appliance inoltra il traffico al container e invia le risposte al richiedente. Le richieste vengono ricevute sulla porta dell'accessorio specificata e le risposte vengono inviate su una porta effimera casuale.

Configurazione delle porte in entrata

È possibile specificare le mappature delle porte in tre punti nella configurazione dell'applicazione. Il pacchetto di codicipackage.json, si specifica la porta su cui il nodo di codice è in ascolto in unnetworkblocco. L'esempio seguente dichiara che il nodo è in ascolto sulla porta 80.

Esempio Packages/123456789012-debug_server-1.0/package.json
"outputs": [ { "description": "Video stream output", "name": "video_out", "type": "media" } ], "network": { "inboundPorts": [ { "port": 80, "description": "http" } ] }

Nel manifesto dell'applicazione, si dichiara una regola di routing che associa una porta dell'accessorio a una porta del contenitore del codice dell'applicazione. L'esempio seguente aggiunge una regola che associa la porta 8080 del dispositivo alla porta 80 delcode_nodecontainer.

Esempio grafi/my-app/graph.json
{ "producer": "model_input_width", "consumer": "code_node.model_input_width" }, { "producer": "model_input_order", "consumer": "code_node.model_input_order" } ], "networkRoutingRules": [ { "node": "code_node", "containerPort": 80, "hostPort": 8080, "decorator": { "title": "Listener port 8080", "description": "Container monitoring and debug." } } ]

Quando si distribuisce l'applicazione, si specificano le stesse regole nella console di AWS Panorama o con un documento di sostituzione passato alCreateApplicationInstanceAPI. È necessario fornire questa configurazione al momento della distribuzione per confermare che si desidera aprire le porte sull'accessorio.

Esempio grafi/my-app/override.json
{ "replace": "camera_node", "with": [ { "name": "exterior-north" } ] } ], "networkRoutingRules":[ { "node": "code_node", "containerPort": 80, "hostPort": 8080 } ], "envelopeVersion": "2021-01-01" } }

Se la porta del dispositivo specificata nel manifesto dell'applicazione è utilizzata da un'altra applicazione, è possibile utilizzare il documento di sostituzione per scegliere una porta diversa.

Traffico serv

Con le porte aperte sul contenitore, è possibile aprire un socket o eseguire un server per gestire le richieste in arrivo. Ladebug-serveresempio mostra un'implementazione di base di un server HTTP in esecuzione insieme al codice dell'applicazione di visione artificiale.

Importante

L'implementazione di esempio non è sicura per l'uso in produzione. Per evitare di rendere il dispositivo vulnerabile agli attacchi, è necessario implementare controlli di sicurezza appropriati nel codice e nella configurazione di rete.

Esempio Pacchetti/123456789012-debug_server-1.0/application.py— Server HTTP
# HTTP debug server def run_debugger(self): """Process debug commands from local network.""" class ServerHandler(SimpleHTTPRequestHandler): # Store reference to application application = self # Get status def do_GET(self): """Process GET requests.""" logger.info('Get request to {}'.format(self.path)) if self.path == '/status': self.send_200('OK') else: self.send_error(400) # Restart application def do_POST(self): """Process POST requests.""" logger.info('Post request to {}'.format(self.path)) if self.path == '/restart': self.send_200('OK') ServerHandler.application.stop() else: self.send_error(400) # Send response def send_200(self, msg): """Send 200 (success) response with message.""" self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(msg.encode('utf-8')) try: # Run HTTP server self.server = HTTPServer(("", self.CONTAINER_PORT), ServerHandler) self.server.serve_forever(1) # Server shut down by run_cv loop logger.info("EXITING SERVER THREAD") except: logger.exception('Exception on server thread.')

Il server accetta richieste GET al/statuspercorso per recuperare alcune informazioni sull'applicazione. Accetta anche una richiesta POST a/restartper riavviare l'applicazione.

Per dimostrare questa funzionalità, l'applicazione di esempio esegue un client HTTP su un thread separato. Il cliente chiama il/statuspercorso sulla rete locale poco dopo l'avvio e riavvia l'applicazione pochi minuti dopo.

Esempio Pacchetti/123456789012-debug_server-1.0/application.py— Client HTTP
# HTTP test client def run_client(self): """Send HTTP requests to device port to demnostrate debug server functions.""" def client_get(): """Get container status""" r = requests.get('http://{}:{}/status'.format(self.device_ip, self.DEVICE_PORT)) logger.info('Response: {}'.format(r.text)) return def client_post(): """Restart application""" r = requests.post('http://{}:{}/restart'.format(self.device_ip, self.DEVICE_PORT)) logger.info('Response: {}'.format(r.text)) return # Call debug server while not self.terminate: try: time.sleep(30) client_get() time.sleep(300) client_post() except: logger.exception('Exception on client thread.') # stop signal received logger.info("EXITING CLIENT THREAD")

Il ciclo principale gestisce i thread e riavvia l'applicazione all'uscita.

Esempio Pacchetti/123456789012-debug_server-1.0/application.py— Loop principale
def main(): panorama = panoramasdk.node() while True: try: # Instantiate application logger.info('INITIALIZING APPLICATION') app = Application(panorama) # Create threads for stream processing, debugger, and client app.run_thread = threading.Thread(target=app.run_cv) app.server_thread = threading.Thread(target=app.run_debugger) app.client_thread = threading.Thread(target=app.run_client) # Start threads logger.info('RUNNING APPLICATION') app.run_thread.start() logger.info('RUNNING SERVER') app.server_thread.start() logger.info('RUNNING CLIENT') app.client_thread.start() # Wait for threads to exit app.run_thread.join() app.server_thread.join() app.client_thread.join() logger.info('RESTARTING APPLICATION') except: logger.exception('Exception during processing loop.')

Per distribuire l'applicazione di esempio, vedere laistruzioni in questa guida GitHub repository.