Aaron Benton es un arquitecto experimentado especializado en soluciones creativas para desarrollar aplicaciones móviles innovadoras. Tiene más de 10 años de experiencia en desarrollo full stack, incluyendo ColdFusion, SQL, NoSQL, JavaScript, HTML y CSS. Aaron es actualmente Arquitecto de Aplicaciones para Shop.com en Greensboro, Carolina del Norte y es un Campeón de la comunidad Couchbase.

Para nuestro último post en el FakeIt serie vamos a explorar cómo podemos aprovechar FakeIt + Servidor Couchbase + Pasarela de sincronización para poner en marcha nuestro entorno local para el desarrollo móvil. Para ello utilizaremos Docker y docker-compose. Descargo de responsabilidad: No soy en absoluto un experto en Docker, esto es simplemente un ejemplo de lo que he hecho para configurar rápidamente un entorno de desarrollo y un conjunto de datos.
Docker
Utilizaremos dos contenedores Docker, uno para Servidor Couchbase y uno para Pasarela de sincronización. Podríamos definir un archivo docker-compose.yaml que simplemente tirara de couchbase:latest y couchbase/sync-gateway:latest pero aún habría necesidad de configuración manual y queremos ser capaces de automatizar tanto como sea posible para nuestra aplicación. Para ello tendremos que construir nuestros propios contenedores a partir de ambos añadiendo nuestros propios scripts y configuración.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
./docker-componer.yaml versión: '2' servicios: fakeit-couchbase: construya: contexto: ./.docker/couchbase/ nombre_contenedor: fakeit-couchbase puertos: - "8091-8094:8091-8094" - "11210:11210" volúmenes: - ./:/aplicación fakeit-syncgatway: construya: contexto: ./.docker/sincronizar-pasarela/ nombre_contenedor: fakeit-syncgateway depende_de: - fakeit-couchbase puertos: - "4984-4985:4984-4985" volúmenes: - ./:/aplicación |
Nuestro archivo docker-compose.yaml primero construye un contenedor en el Dockerfile desde ./.docker/couchbase/Dockerfile que se ve así.
|
1 2 3 4 5 6 7 8 9 10 |
./.docker/couchbase/Dockerfile # empezar con couchbase DESDE couchbase:última # copia el script de configuración COPIA guiones/configure-nodo.sh /op/couchbase # ejecuta el script configure-node.sh CMD ["/opt/couchbase/configure-node.sh"] |
Este Dockerfile en realidad sólo hace dos cosas, copiar un script de configuración y ejecutar ese script. El script configure-node.sh tiene este aspecto.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
./.docker/couchbase/guiones/configure-nodo.sh configure -m /punto de entrada.sh couchbase-servidor & echo Esperando 20 segundos para que se inicie el servicio Couchbase". dormir 20 # configurar el clúster echo Configuración del clúster /op/couchbase/papelera/couchbase-cli grupo-init -c localhost:8091 --grupo-nombre de usuario=Administrador --grupo-contraseña=contraseña --grupo-puerto=8091 --grupo-ramsize=500 --servicio=datos # crear el cubo de comercio electrónico echo Crear un cubo de comercio electrónico /op/couchbase/papelera/couchbase-cli cubo-crear -c localhost:8091 -u Administrador -p contraseña --cubo=comercio electrónico --cubo-desahucio-política=fullEviction --cubo-tipo=membrana --cubo-prioridad=alta --active-índice-réplica=0 --cubo-puerto=11211 --active-descarga=1 --cubo-réplica=1 --cubo-ramsize=200 echo El servidor Couchbase está listo fg 1 |
El script configure-node.sh está haciendo un par de cosas:
- Esperando a que se inicie el servicio Couchbase para poder configurarlo.
- Inicializar la configuración del Cluster
- Crear nuestro cubo de comercio electrónico
El contenedor Couchbase ya está construido, el siguiente contenedor que necesita ser construido es el contenedor Sync Gateway. Por defecto el contenedor Sync Gateway utiliza el bucket sync gateway de sólo memoria walrus. Tendremos que actualizar esta configuración proporcionando nuestro propio archivo sync-gateway.json para que podamos actualizar la configuración de almacenamiento y acceso. Por último, el contenedor Sync Gateway sólo expone el puerto 4984, que es el puerto público, como esto es para fines de desarrollo vamos a seguir adelante y exponer el puerto 4985 que es el puerto de administrador.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
./.docker/sincronizar-pasarela/Dockerfile # Comienza con la pasarela de sincronización base DESDE couchbase/sincronizar-pasarela:última # Copia el sync-gateway.json en el contenedor COPIA sincronizar-pasarela.json /op/sync_gateway/sincronizar-pasarela.json # Crear volumen para que los datos persistan RUN mkdir -p /op/sync_gateway/datos # Punto de entrada de copias COPIA guiones/punto de entrada.sh / PUNTO DE ENTRADA ["/entrypoint.sh"] # Copia el script de configuración COPIA guiones/configure-nodo.sh /op/sincronizar_pasarela # Configurar la pasarela de sincronización e iniciarla CMD ["/opt/sync_gateway/configure-node.sh"] # puerto 4984: puerto público # puerto 4985: puerto admin EXPONE 4984 4985 ./.docker/sincronizar-pasarela/sincronizar-pasarela.json { "interfaz": "0.0.0.0:4984", "adminInterface": "0.0.0.0:4985", "log": ["CRUD+", "REST+", "Cambios+", "Adjuntar+"], "CORS": { "Origen":[ "http://localhost:8000", "*" ], "LoginOrigin":[ "http://localhost:8000", "*" ], "Cabeceras":["Tipo de contenido"], "MaxAge": 1728000 }, "bases de datos": { "comercio electrónico": { "servidor": "http://fakeit-couchbase:8091", "cubo": "comercio electrónico", "usuarios": { "INVITADO": { "desactivado": falso } }, "sync": "function(doc, oldDoc) { channel(doc.channels); }" } } } ./.docker/sincronizar-pasarela/guiones/configure-nodo.sh #!/bin/bash configure -m echo Esperando 20 segundos para que el servicio Couchbase se inicie y caliente' dormir 20 echo Inicio del servicio Sync Gateway /punto de entrada.sh sync_gateway /op/sync_gateway/sincronizar-pasarela.json echo 'Couchbase Sync Gateway está listo' |
Una vez más, esto es sólo para fines de desarrollo. Usted nunca debe permitir el acceso desde cualquier lugar a su adminInterface o habilitar INVITADO acceso a tu sync-gateway a menos que haya una muy buena razón para hacerlo.
La estructura de nuestra aplicación tiene ahora este aspecto:

Ahora que hemos configurado nuestros contenedores Docker y nuestro archivo docker-compose.yaml necesitamos construir e iniciar los contenedores. Para ello, ejecutamos el siguiente comando desde nuestro directorio de aplicaciones:
|
1 |
docker-componer arriba -d |
Nota: para los propósitos del screencast, se omite el parámetro -d para ejecutar los contenedores en modo separado.

Modelos
Nuestros contenedores ya están iniciados, lo siguiente que tenemos que hacer antes de generar nuestro conjunto de datos es actualizar los modelos para que admitan el atributo channels.
|
1 |
usuarios.yaml |
Este modelo sólo se sincronizará con canales específicos del usuario.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
nombre: Usuarios tipo: objeto clave: _id datos: min: 1000 max: 2000 entradas: ./países.json propiedades: _id: tipo: cadena descripción: En documento id construido por el prefijo "usuario_" y el usuarios id datos: post_build: `usuario_${este.usuario_id}` canales: tipo: matriz datos: post_build: | devolver [ `canal-usuario-${este.usuario_id}` ]; tipo_doc: tipo: cadena descripción: En documento tipo datos: valor: "usuario" ... productos.yaml |
Sólo por diversión publicaremos este modelo en un canal global al que estarán suscritos todos nuestros usuarios.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
nombre: Productos tipo: objeto clave: _id datos: min: 500 max: 1000 entradas: - ./categorías.csv pre_build: globales.categoría_actual = farsante.al azar.arrayElement(entradas.categorías); propiedades: _id: tipo: cadena descripción: En documento id datos: post_build: `producto_${este.producto_id}` canales: tipo: matriz datos: construya: | devolver [ `canal-productos` ]; tipo_doc: tipo: cadena descripción: En documento tipo datos: valor: producto ... pedidos.yaml |
Este modelo sólo se sincronizará con canales específicos del usuario.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
nombre: Pedidos tipo: objeto clave: _id datos: dependencias: - productos.yaml - usuarios.yaml min: 5000 max: 6000 propiedades: _id: tipo: cadena descripción: En documento id datos: post_build: `orden_${este.orden_id}` canales: tipo: matriz datos: construya: | devolver [ `canal-usuario-${este.usuario_id}` ]; tipo_doc: tipo: cadena descripción: En documento tipo datos: valor: "orden" ... |
Ahora que nuestros modelos han sido actualizados para soportar canales, podemos generar nuestro conjunto de datos aleatorios e introducirlo en Servidor Couchbase a través de la Pasarela de sincronización API REST. Le decimos FakeIt para ello, utilice el siguiente comando:
|
1 |
fakeit sincronizar-pasarela --servidor http://localhost:4984 --bucket ecommerce --verbose models/* |
Para fines de desarrollo hemos permitido el acceso de invitados a nuestro Pasarela de sincronización. Sin embargo, si tiene desactivado el acceso de invitados, puede seguir utilizando FakeIt especificando un nombre de usuario y una contraseña a un usuario existente mediante el siguiente comando:
|
1 |
fakeit sincronizar-pasarela --servidor http://localhost:4984 --bucket ecommerce --username YOURUSERNAME --password YOURPASSWORD --verbose models/* |
Antes de dar salida al conjunto de datos generado, FakeIt se autenticará contra el Pasarela de sincronización para recuperar la información de sesión necesaria.

Pruebas
Lo siguiente que tenemos que hacer es crear un usuario de pasarela de sincronización para que podamos sincronizar sus documentos localmente. Para esta prueba, vamos a coger un documento de usuario aleatorio de nuestro modelo Users y crearemos un usuario a partir de ese documento. En este ejemplo será user_1001, y crearemos el usuario usando el comando curl:
|
1 2 3 4 5 6 |
rizo --silencioso --Mostrar-error \ -H "Content-Type: application/json; charset=UTF-8" \ -H "Content-type: application/json" \ -X PUT \ -d '{"name": "Domenic81", "password": "pgid_Tubn0qoEtZ", "admin_channels":["channel-user-1001", "channel-products"]}' \ http://localhost:4985/ecommerce/_user/Domenic81 |

Aplicación
Hemos creado un pequeño VueJS proyecto que utiliza PouchDB para conectarse al Sync Gateway y extraer los documentos de un usuario autenticado. Nuestra aplicación sólo va a mostrar los diferentes tipos de documentos disponibles, sus IDs y contenido.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
// registrar el componente vue highlight.js Vue.utilice(VueHighlightJS) // crear base de datos local de comercio electrónico var db = nuevo PouchDB(comercio_local, { auto_compactación: verdadero, límite_rev: 3 }); // crear base de datos remota de comercio electrónico var remote_db = nuevo PouchDB(http://localhost:4984/ecommerce/, { auth: { nombre de usuario: Domenic81, contraseña: 'pgid_Tubn0qoEtZ' }, skip_setup: verdadero }); // fusionar la base de datos remota con la local PouchDB.sincronizar(db, remote_db, { en directo: verdadero, reintentar: verdadero }) var aplicación = nuevo Vue({ el: #app, datos: { tipo_actual: '', artículos: [], id: '', actual: JSON.stringify({}), tipos: [], }, ver: { id(id) { si (id) { db.consiga(id).entonces((actual) => este.actual = JSON.stringify(actual, null, 2)) } }, tipo_actual(tipo) { este.id = '' // actualizar el elemento actual para que esté en blanco este.actual = JSON.stringify({}) // cuando `current_type` cambia actualiza la lista de elementos con la lista de tipos actual este.updateItems(tipo) .entonces(() => { si (!este.id) { este.id = este.artículos[0] } }) } }, métodos: { updateItems(tipo) { devolver db.consulta(ecommerce/by_doc_type, { clave: tipo, reducir: falso }) .entonces((resultado) => { este.artículos = resultado.filas.mapa((artículo) => artículo.id) }) }, removeStyle(el) { setTimeout(() => { el.estilo = '' }, 1000) } }, creado() { // crear la vista a consultar var ddoc = { _id: _design/ecommerce, vistas: { por_tipo_doc: { mapa: función(doc) { si (doc.tipo_doc) { emite(doc.tipo_doc); } }.toString(), reducir: '_count' } } } db.poner(ddoc) // documento de diseño creado // llamar al índice de la vista del documento de diseño inmediatamente para lanzar una construcción .entonces(() => db.consulta(ecommerce/by_doc_type, { límite: 0 })) .captura((err) => { // está bien si esto falla y devuelve un conflicto de documento que sólo significa que no necesita ser creado si (err.estado !== 409) { tirar err; } }) // obtener todos los tipos de documentos disponibles .entonces(() => db.consulta(ecommerce/by_doc_type, { reducir: verdadero, grupo: verdadero })) .entonces((tipos) => { este.tipos = tipos.filas.mapa((tipo) => tipo.clave) este.tipo_actual = este.tipos[0] }) } }) |

La aplicación de muestra completa puede consultarse en https://github.com/bentonam/fakeit-couchbase-mobile-example
Conclusión
A lo largo de esta serie han visto cómo FakeIt puede tomar simples modelos YAML y generar grandes cantidades de datos falsos y enviar esos datos a múltiples destinos diferentes. Por favor, consulte el repositorio, pull requests son bienvenidos, siempre estamos buscando mejoras y mejoras para hacer la herramienta más útil para la comunidad. También me gustaría aprovechar este momento para agradecer a aquellos que han hecho contribuciones al proyecto. La versión 1.0 no se habría publicado sin la ayuda de Tyler Benton (@tjbenton21), también Trevor Brindle (@VinceKerrazzi), Jessica Kennedy (@mistersender), Adam Burdette (@RavenStorms619) y Brant Burnett (@btburnett3)
Anterior
- FakeIt Serie 1 de 5: Generación de datos falsos
- FakeIt Serie 2 de 5: Datos compartidos y dependencias
- FakeIt Series 3 de 5: Modelos Lean a través de definiciones
- FakeIt Series 4 de 5: Trabajar con datos existentes
