Fornecimento de tráfego de entrada - AWS Panorama

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Fornecimento de tráfego de entrada

Você pode monitorar ou depurar aplicações localmente executando um servidor HTTP junto com o código da aplicação. Para fornecer tráfego externo, mapeie as portas no AWS Panorama Appliance para portas no contêiner do sua aplicação.

Importante

Por padrão, o AWS Panorama Appliance não aceita tráfego de entrada em nenhuma porta. A abertura de portas no dispositivo tem um risco de segurança implícito. Ao usar esse atributo, você deve tomar medidas adicionais para proteger seu dispositivo contra tráfego externo e proteger as comunicações entre clientes autorizados e o dispositivo.

O código de exemplo incluído neste guia serve para fins de demonstração e não implementa autenticação, autorização ou criptografia.

Você pode abrir portas na faixa de 8.000 a 9.000 no dispositivo. Essas portas, quando abertas, podem receber tráfego de qualquer cliente roteável. Ao implantar sua aplicação, você especifica quais portas abrir e mapeia as portas do dispositivo para as portas do contêiner da aplicação. O software do dispositivo encaminha o tráfego para o contêiner e envia as respostas de volta ao solicitante. As solicitações são recebidas na porta do dispositivo que você especificar, e as respostas são enviadas em uma porta efêmera aleatória.

Configuração de portas de entrada

Você especifica mapeamentos de portas em três locais na configuração da sua aplicação. No pacote de código package.json, você especifica a porta que o nó de código escuta em um bloco network. O exemplo a seguir declara que o nó escuta na porta 80.

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

No manifesto da aplicação, você declara uma regra de roteamento que mapeia uma porta no dispositivo para uma porta no contêiner de código da aplicação. O exemplo a seguir adiciona uma regra que mapeia a porta 8080 no dispositivo para a porta 80 no contêiner code_node.

exemplo graphs/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." } } ]

Ao implantar a aplicação, você especifica as mesmas regras no console do AWS Panorama, ou com um documento de substituição passado para a API CreateApplicationInstance. Você deve fornecer essa configuração no momento da implantação para confirmar que deseja abrir portas no dispositivo.

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

Se a porta do dispositivo especificada no manifesto da aplicação estiver sendo usada por outra aplicação, você poderá usar o documento de substituição para escolher uma porta diferente.

Fornecimento de tráfego

Com as portas abertas no contêiner, você pode abrir um soquete ou executar um servidor para processar as solicitações recebidas. O exemplo debug-server mostra uma implementação básica de um servidor HTTP em execução junto com o código da aplicação de visão computacional.

Importante

A implementação de exemplo não é segura para uso em produção. Para evitar tornar seu dispositivo vulnerável a ataques, você deve implementar controles de segurança apropriados em seu código e na configuração de rede.

exemplo packages/123456789012-DEBUG_SERVER-1.0/application.py: servidor 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.')

O servidor aceita solicitações GET no caminho /status para recuperar algumas informações sobre a aplicação. Ele também aceita uma solicitação POST para /restart para reiniciar a aplicação.

Para demonstrar essa funcionalidade, a aplicação de exemplo executa um cliente HTTP em um thread separado. O cliente chama o caminho /status pela rede local logo após a inicialização e reinicia a aplicação alguns minutos depois.

exemplo packages/123456789012-DEBUG_SERVER-1.0/application.py: cliente 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")

O loop principal gerencia os threads e reinicia a aplicação quando eles saem.

exemplo packages/123456789012-DEBUG_SERVER-1.0/application.py: loop principal
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.')

Para implantar a aplicação de exemplo, consulte as instruções no repositório do GitHub deste guia.