diff --git a/README.md b/README.md index ef9ad02..acc646e 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,34 @@ ![Context Mapper](https://raw.githubusercontent.com/wiki/ContextMapper/context-mapper-dsl/logo/cm-logo-github-small.png) -# Context Mapper Demo for Online IDE +# Demostración de Context Mapper para IDE en línea [![Build](https://github.com/ContextMapper/web-ide-demo/actions/workflows/build.yml/badge.svg)](https://github.com/ContextMapper/web-ide-demo/actions) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/ContextMapper/web-ide-demo) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -Welcome to Context Mapper's demo repository. It illustrates how you can configure your own repository for the usage of Context Mapper in the online IDE [Gitpod](https://www.gitpod.io/). +Bienvenido al repositorio de demostración de Context Mapper. Ilustra cómo puede configurar su propio repositorio para el uso de Context Mapper en el IDE en línea. [Gitpod](https://www.gitpod.io/). -## Start Using Context Mapper Now -Start the online IDE and use Context Mapper right now: +## Comience a utilizar Context Mapper ahora +Inicie el IDE en línea y use Context Mapper ahora mismo: Push

-## Open the Demo File -In the folder `src/main/cml` you find a small **[CML demo](./src/main/cml/demo.cml)** (DDD sample application) where you can start to familiarize yourself with our DSL and our tools. -You can find more info's about the tool and a complete documentation on our website [https://contextmapper.org/](https://contextmapper.org/). +## Abra el archivo de demostración +En la carpeta `src/main/cml` encontrarás una pequeña **[CML demo](./src/main/cml/demo.cml)** (aplicación de muestra DDD) donde podrás empezar a familiarizarte con nuestro DSL. y nuestras herramientas. +Puede encontrar más información sobre la herramienta y una documentación completa en nuestro sitio web [https://contextmapper.org/](https://contextmapper.org/). -## Create Your Own Context Mapping Repository -You can simply fork this repository and click the button above to start the online IDE for your repo. +## Cree su propio repositorio de mapas de contexto +Simplemente puede bifurcar este repositorio y hacer clic en el botón de arriba para iniciar el IDE en línea para su repositorio. -## Useful Links +## Enlaces útiles * [More example models](https://github.com/ContextMapper/context-mapper-examples) * [CML language reference](https://contextmapper.org/docs/language-reference/) * [Rapid prototyping tutorial](https://contextmapper.org/docs/rapid-ooad/) * [Architectural Refactorings](https://contextmapper.org/docs/architectural-refactorings/) * [Generators](https://contextmapper.org/docs/generators/) + +## Context Mapper +En la carpeta `src/main/resources/cml` se podrán encontrar los archivos `cml` para el AS IS y el TO BE del proyecto; como también las imágenes generadas por la herramienta en la carpeta `src/main/src-gen`, con el nombre `as_is_ContextMap.png` y `to_be_ContextMap.png`. + +## Lenguaje ubicuo +En la carpeta `src/main/src-gen` se podrá encontrar las imágenes con el nombre `EventStorming AS IS.jpg` y `EventStorming TO BE.jpg` diff --git a/src/bff/bff/__init__.py b/src/bff/bff/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/bff/bff/__pycache__/__init__.cpython-312.pyc b/src/bff/bff/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..3d2e3c1 Binary files /dev/null and b/src/bff/bff/__pycache__/__init__.cpython-312.pyc differ diff --git a/src/bff/bff/__pycache__/despachadores.cpython-312.pyc b/src/bff/bff/__pycache__/despachadores.cpython-312.pyc new file mode 100644 index 0000000..6b36d8d Binary files /dev/null and b/src/bff/bff/__pycache__/despachadores.cpython-312.pyc differ diff --git a/src/bff/bff/__pycache__/utils.cpython-312.pyc b/src/bff/bff/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000..67772da Binary files /dev/null and b/src/bff/bff/__pycache__/utils.cpython-312.pyc differ diff --git a/src/bff/bff/api/__init__.py b/src/bff/bff/api/__init__.py new file mode 100644 index 0000000..8284735 --- /dev/null +++ b/src/bff/bff/api/__init__.py @@ -0,0 +1,16 @@ +from flask import Flask + +from src.bff.api import ingesta_automatizada + + +def create_app(): + aplicacion = Flask(__name__) + + aplicacion.debug = True + aplicacion.register_blueprint(ingesta_automatizada.blueprint) + + @aplicacion.route("/health") + def health(): + return {"status": "up"} + + return aplicacion diff --git a/src/bff/bff/api/__pycache__/__init__.cpython-312.pyc b/src/bff/bff/api/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..82d27fc Binary files /dev/null and b/src/bff/bff/api/__pycache__/__init__.cpython-312.pyc differ diff --git a/src/bff/bff/api/__pycache__/ingesta_automatizada.cpython-312.pyc b/src/bff/bff/api/__pycache__/ingesta_automatizada.cpython-312.pyc new file mode 100644 index 0000000..a974ef1 Binary files /dev/null and b/src/bff/bff/api/__pycache__/ingesta_automatizada.cpython-312.pyc differ diff --git a/src/bff/bff/api/ingesta_automatizada.py b/src/bff/bff/api/ingesta_automatizada.py new file mode 100644 index 0000000..4bc95af --- /dev/null +++ b/src/bff/bff/api/ingesta_automatizada.py @@ -0,0 +1,34 @@ +import os +import uuid + +import requests +from flask import Blueprint, request + +from src.bff import utils +from src.bff.despachadores import Despachador + +blueprint = Blueprint('ingesta_automatizada', __name__, url_prefix="/bff/ingesta_automatizada") + +STA_HOST = os.getenv("STA_HOST", default="localhost") + + +@blueprint.route('/imagen_medica', methods=['POST']) +def agregar_imagen_medica(): + comando = dict( + id=str(uuid.uuid4()), + time=utils.time_millis(), + specversion="v1", + type="ComandoImagenMedica", + ingestion=utils.time_millis(), + datacontenttype="AVRO", + service_name="BFF", + data=request.json + ) + despachador = Despachador() + despachador.publicar_mensaje(comando, "comandos-imagen-medica") + return [{'message': 'Su imagen esta siendo agregada'}], 203 + + +@blueprint.route('/imagen_medica/', methods=['GET']) +def dar_imagen_medica(id=None): + return requests.get(f'http://{STA_HOST}:5000/ingesta_automatizada/imagen_medica-query/{id}').json() diff --git a/src/bff/bff/despachadores.py b/src/bff/bff/despachadores.py new file mode 100644 index 0000000..cf6ab9f --- /dev/null +++ b/src/bff/bff/despachadores.py @@ -0,0 +1,17 @@ +import pulsar + +from src.bff import utils + + +class Despachador(): + def __init__(self): + ... + + def publicar_mensaje(self, mensaje, topico): + json_schema = utils.consultar_schema_registry(topico) + avro_schema = utils.obtener_schema_avro_de_diccionario(json_schema) + + cliente = pulsar.Client(f'pulsar://{utils.broker_host()}:6650') + publicador = cliente.create_producer(topico, schema=avro_schema) + publicador.send(mensaje) + cliente.close() diff --git a/src/bff/bff/utils.py b/src/bff/bff/utils.py new file mode 100644 index 0000000..3463e04 --- /dev/null +++ b/src/bff/bff/utils.py @@ -0,0 +1,28 @@ +import json +import time + +import requests +import os + +from fastavro.schema import parse_schema +from pulsar.schema import AvroSchema + +PULSAR_ENV: str = 'BROKER_HOST' + + +def broker_host(): + return os.getenv(PULSAR_ENV, default="localhost") + + +def consultar_schema_registry(topico: str) -> dict: + json_registry = requests.get(f'http://{broker_host()}:8080/admin/v2/schemas/public/default/{topico}/schema').json() + return json.loads(json_registry.get('data', {})) + + +def obtener_schema_avro_de_diccionario(json_schema: dict) -> AvroSchema: + definicion_schema = parse_schema(json_schema) + return AvroSchema(None, schema_definition=definicion_schema) + + +def time_millis(): + return int(time.time() * 1000) diff --git a/src/main/cml/demo.cml b/src/main/cml/demo.cml deleted file mode 100644 index 5ba9275..0000000 --- a/src/main/cml/demo.cml +++ /dev/null @@ -1,79 +0,0 @@ -/* The DDD Cargo sample application modeled in CML. Note that we split the application into multiple bounded contexts. */ -ContextMap DDDSampleMap { - contains CargoBookingContext - contains VoyagePlanningContext - contains LocationContext - - /* As Evans mentions in his book (Bounded Context chapter): The voyage planning can be seen as - * separated bounded context. However, it still shares code with the booking application (CargoBookingContext). - * Thus, they are in a 'Shared-Kernel' relationship. - */ - CargoBookingContext [SK]<->[SK] VoyagePlanningContext - - /* Note that the splitting of the LocationContext is not mentioned in the original DDD sample of Evans. - * However, locations and the management around them, can somehow be seen as a separated concept which is used by other - * bounded contexts. But this is just an example, since we want to demonstrate our DSL with multiple bounded contexts. - */ - CargoBookingContext [D]<-[U,OHS,PL] LocationContext - - VoyagePlanningContext [D]<-[U,OHS,PL] LocationContext - -} - -/* The original booking application context */ -BoundedContext CargoBookingContext { - Module cargo { - basePackage = se.citerus.dddsample.domain.model - - Aggregate CargoItineraryLegDeliveryRouteSpecification { - Entity Cargo - ValueObject Delivery - ValueObject HandlingActivity - ValueObject Itinerary - ValueObject Leg - ValueObject RouteSpecification - enum TransportStatus { - NOT_RECEIVED, IN_PORT, ONBOARD_CARRIER, CLAIMED, UNKNOWN - } - enum RoutingStatus { - NOT_ROUTED, ROUTED, MISROUTED - } - } - } - - Module handling { - basePackage = se.citerus.dddsample.domain.model - - Aggregate Handling { - DomainEvent HandlingEvent - ValueObject HandlingHistory - } - } -} - -/* We split the Voyage Planning into a separate bounded context as Evans proposes it in his book. */ -BoundedContext VoyagePlanningContext { - Module voyage { - basePackage = se.citerus.dddsample.domain.model - - Aggregate Voyage { - Entity Voyage - ValueObject CarrierMovement - ValueObject Schedule - ValueObject VoyageNumber - } - } -} - -/* Separate bounded context for managing the locations. */ -BoundedContext LocationContext { - Module location { - basePackage = se.citerus.dddsample.domain.model - - Aggregate Location { - Entity Location - ValueObject UnLocode - ValueObject LocationShared - } - } -} diff --git a/src/main/resources/cml/as_is.cml b/src/main/resources/cml/as_is.cml new file mode 100644 index 0000000..f4e9333 --- /dev/null +++ b/src/main/resources/cml/as_is.cml @@ -0,0 +1,73 @@ +// Dominio Principal de SaludTech +Domain SaludTech { + domainVisionStatement = "Recaudar, procesar, distribuir y anonimizar imágenes y diagnósticos médicos." + + // Subdominios principales + Subdomain Recoleccion { + type = CORE_DOMAIN + domainVisionStatement = "Recolectan, estandarizan y anonimizan las imágenes y diagnosticos medicos." + } + + Subdomain Procesamiento { + type = CORE_DOMAIN + domainVisionStatement = "Aplican modelos de IA para clasificar y extraer información de las imágenes médicas y diagnosticos medicos." + } + + Subdomain Distribucion { + type = CORE_DOMAIN + domainVisionStatement = "Habilitan la consulta y descarga de las imágenes médicas y diagnosticos medicos anonimizados." + } + + // Subdominios de soporte + Subdomain Proveedores { + type = SUPPORTING_DOMAIN + domainVisionStatement = "Organizan la adquisicion de las imágenes médicas y diagnosticos medicos desde la infraestructura de los proveedores." + } + + Subdomain Clientes { + type = SUPPORTING_DOMAIN + domainVisionStatement = "Gestionan los clientes, suscripciones, comercialización y entrenamientos de productos IA." + } + + // Subdominios generales + Subdomain Notificaciones { + type = GENERIC_SUBDOMAIN + domainVisionStatement = "Gestionan las notificaciones de todos los flujos de trabajo." + } + + Subdomain Facturacion { + type = GENERIC_SUBDOMAIN + domainVisionStatement = "Gestionan la facturacion, cobros y pagos de todos los flujos de trabajo." + } +} + +// Contextos +BoundedContext ContextoGestionDeImagenesYDiagnosticosMedicos implements Recoleccion, Procesamiento, Distribucion { + responsibilities = "Recolectar, estandarizar y anonimizar imágenes y diagnósticos médicos." +} + +BoundedContext ContextosProveedores implements Proveedores { + responsibilities = "Organizar la adquisición de imágenes médicas y diagnósticos médicos desde la infraestructura de los proveedores." +} + +BoundedContext ContextosClientes implements Clientes { + responsibilities = "Distribución, comercializacion y entrenamiento de IA de las imágenes médicas y diagnósticos médicos anonimizados a los clientes." +} + +BoundedContext ContextoTransaccional implements Notificaciones, Facturacion { + responsibilities = "Gestionar las notificaciones, facturacion, cobros y pagos de todos los flujos de trabajo." +} + +// Mapa de Contextos +ContextMap ImagenesClinicasSaludTechAlpes { + state = AS_IS + contains ContextoGestionDeImagenesYDiagnosticosMedicos + contains ContextosProveedores + contains ContextosClientes + contains ContextoTransaccional + + ContextosProveedores -> ContextoGestionDeImagenesYDiagnosticosMedicos + ContextoGestionDeImagenesYDiagnosticosMedicos -> ContextosClientes + ContextoTransaccional -> ContextosProveedores + ContextoTransaccional -> ContextosClientes +} diff --git a/src/main/resources/cml/to_be.cml b/src/main/resources/cml/to_be.cml new file mode 100644 index 0000000..47f3b90 --- /dev/null +++ b/src/main/resources/cml/to_be.cml @@ -0,0 +1,98 @@ +// Dominio Principal de SaludTech +Domain SaludTech { + domainVisionStatement = "Recaudar, procesar, distribuir y anonimizar imágenes y diagnósticos médicos." + + // Subdominios principales + Subdomain Recoleccion { + type = CORE_DOMAIN + domainVisionStatement = "Recolectan, estandarizan y anonimizan las imágenes y diagnosticos medicos." + } + + Subdomain Procesamiento { + type = CORE_DOMAIN + domainVisionStatement = "Aplican modelos de IA para clasificar y extraer información de las imágenes médicas y diagnosticos medicos." + } + + Subdomain Distribucion { + type = CORE_DOMAIN + domainVisionStatement = "Habilitan la consulta y descarga de las imágenes médicas y diagnosticos medicos anonimizados." + } + + // Subdominios de soporte + Subdomain Proveedores { + type = SUPPORTING_DOMAIN + domainVisionStatement = "Organizan la adquisicion de las imágenes médicas y diagnosticos medicos desde la infraestructura de los proveedores." + } + + Subdomain Clientes { + type = SUPPORTING_DOMAIN + domainVisionStatement = "Gestionan los clientes, suscripciones, comercialización y entrenamientos de productos IA." + } + + // Subdominios generales + Subdomain Notificaciones { + type = GENERIC_SUBDOMAIN + domainVisionStatement = "Gestionan las notificaciones de todos los flujos de trabajo." + } + + Subdomain Facturacion { + type = GENERIC_SUBDOMAIN + domainVisionStatement = "Gestionan la facturacion, cobros y pagos de todos los flujos de trabajo." + } +} + +// Contextos +BoundedContext ContextoIngestaAutomatizada implements Recoleccion { + responsibilities = "Automatizar la recolección de imágenes médicas desde hospitales y proveedores. Estandarizar y validar los datos antes de su procesamiento." +} + +BoundedContext ContextoProcesamientoInteligenteDeImagenes implements Procesamiento { + responsibilities = "Aplicación de modelos de IA para clasificar y extraer información de las imágenes médicas. Optimización del rendimiento de los modelos para escalar con grandes volúmenes de datos." +} + +BoundedContext ContextoAnonimizacionYCanonizacion implements Recoleccion { + responsibilities = "Limpieza y eliminación de información sensible en imágenes médicas. Canonización de datos para asegurar formatos estándar y cumplir normativas." +} + +BoundedContext ContextoDistribucionDeDatos implements Distribucion { + responsibilities = "Facilitar la consulta y descarga de imágenes médicas anonimizadas. Manejar accesos de clientes en función de sus planes de suscripción." +} + +BoundedContext ContextoInfraestructuraDistribuida implements Recoleccion, Procesamiento, Distribucion { + responsibilities = "Manejar la segmentación de datos por país y la infraestructura en la nube. Asegurar la residencia de datos conforme a normativas de cada región." +} + +BoundedContext ContextoSeguridadYRegulacion implements Recoleccion, Procesamiento, Distribucion { + responsibilities = "Supervisar el cumplimiento de normativas de seguridad de los datos en cada región. Implementar controles de acceso y monitoreo en la plataforma." +} + +BoundedContext ContextoTransaccional implements Notificaciones, Facturacion { + responsibilities = "Gestionar las notificaciones, facturacion, cobros y pagos de todos los flujos de trabajo." +} + +// Mapa de Contextos +ContextMap ImagenesClinicasSaludTechAlpes { + state = TO_BE + + contains ContextoIngestaAutomatizada + contains ContextoProcesamientoInteligenteDeImagenes + contains ContextoAnonimizacionYCanonizacion + contains ContextoDistribucionDeDatos + contains ContextoInfraestructuraDistribuida + contains ContextoSeguridadYRegulacion + contains ContextoTransaccional + + ContextoIngestaAutomatizada [OHS] -> ContextoAnonimizacionYCanonizacion + ContextoAnonimizacionYCanonizacion [OHS] -> ContextoProcesamientoInteligenteDeImagenes + ContextoProcesamientoInteligenteDeImagenes [OHS] -> ContextoDistribucionDeDatos + ContextoInfraestructuraDistribuida [OHS] -> ContextoIngestaAutomatizada + ContextoInfraestructuraDistribuida [OHS] -> ContextoAnonimizacionYCanonizacion + ContextoInfraestructuraDistribuida [OHS] -> ContextoProcesamientoInteligenteDeImagenes + ContextoInfraestructuraDistribuida [OHS] -> ContextoDistribucionDeDatos + ContextoSeguridadYRegulacion [OHS] -> ContextoIngestaAutomatizada + ContextoSeguridadYRegulacion [OHS] -> ContextoAnonimizacionYCanonizacion + ContextoSeguridadYRegulacion [OHS] -> ContextoProcesamientoInteligenteDeImagenes + ContextoSeguridadYRegulacion [OHS] -> ContextoDistribucionDeDatos + ContextoTransaccional [OHS] -> ContextoIngestaAutomatizada + ContextoTransaccional [OHS] -> ContextoDistribucionDeDatos +} diff --git a/src/main/src-gen/EventStorming AS IS.jpg b/src/main/src-gen/EventStorming AS IS.jpg new file mode 100644 index 0000000..d6d499c Binary files /dev/null and b/src/main/src-gen/EventStorming AS IS.jpg differ diff --git a/src/main/src-gen/EventStorming TO BE.jpg b/src/main/src-gen/EventStorming TO BE.jpg new file mode 100644 index 0000000..c3723c3 Binary files /dev/null and b/src/main/src-gen/EventStorming TO BE.jpg differ diff --git a/src/main/src-gen/as_is_ContextMap.png b/src/main/src-gen/as_is_ContextMap.png new file mode 100644 index 0000000..b72c134 Binary files /dev/null and b/src/main/src-gen/as_is_ContextMap.png differ diff --git a/src/main/src-gen/to_be_ContextMap.png b/src/main/src-gen/to_be_ContextMap.png new file mode 100644 index 0000000..082afdb Binary files /dev/null and b/src/main/src-gen/to_be_ContextMap.png differ