Commit 4dc871d9 authored by FORESTIER Fabien's avatar FORESTIER Fabien
Browse files

Add config module, set the configuration in gitlab-ci and docker in order to...

Add config module, set the configuration in gitlab-ci and docker in order to be able to build the service for dev end rec env
parent 026349c9
Pipeline #2507 failed with stages
in 9 seconds
......@@ -17,3 +17,7 @@
coverage
node_modules
npm-debug.log
*.env
!template.env
......@@ -2,18 +2,48 @@ stages:
- build
- deploy
build:
build_development:
stage: build
only:
- master
- sandbox
script:
- docker-compose build --no-cache
- export NODE_ENV=DEV
- export SERVICE_EMAIL_PORT=3001
- export RABBITMQ_STANDARD_PORT=5672
- export RABBITMQ_INTERFACE_PORT=15672
- docker-compose --project-name service-email-dev build
deploy:
deploy_development:
stage: deploy
only:
- master
- sandbox
script:
- docker-compose up -d
- export NODE_ENV=DEV
- export SERVICE_EMAIL_PORT=3001
- export RABBITMQ_STANDARD_PORT=5672
- export RABBITMQ_INTERFACE_PORT=15672
- docker-compose --project-name service-email-dev up -d
build_staging:
stage: build
only:
- staging
script:
- export NODE_ENV=REC
- export SERVICE_EMAIL_PORT=3101
- export RABBITMQ_STANDARD_PORT=5673
- export RABBITMQ_INTERFACE_PORT=15673
- sed -i 's/DEV_/REC_/g' docker-compose.yml
- docker-compose --project-name service-email-rec build
deploy_staging:
stage: deploy
only:
- staging
script:
- export NODE_ENV=REC
- export SERVICE_EMAIL_PORT=3101
- export RABBITMQ_STANDARD_PORT=5673
- export RABBITMQ_INTERFACE_PORT=15673
- sed -i 's/DEV_/REC_/g' docker-compose.yml
- docker-compose --project-name service-email-rec up -d
......@@ -3,21 +3,23 @@ version: '3.1'
services:
service-email:
build: .
container_name: service-email
container_name: service-email-${NODE_ENV}
ports:
- 3001:3000
- ${SERVICE_EMAIL_PORT}:3000
environment:
- ADMIN_EMAIL=${ADMIN_EMAIL}
- ADMIN_EMAILS=${DEV_ADMIN_EMAILS}
- RABBITMQ_USER=${DEV_RABBITMQ_USER}
- RABBITMQ_PASSWORD=${DEV_RABBITMQ_PASSWORD}
restart: unless-stopped
rabbitmq:
image: 'rabbitmq:3-management-alpine'
container_name: rabbitmq
ports:
- 5672:5672 # standar port for communication
- 15672:15672 # graphique interface
- ${RABBITMQ_STANDARD_PORT}:5672 # standar port for communication
- ${RABBITMQ_INTERFACE_PORT}:15672 # graphique interface
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_USERNAME}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}
- RABBITMQ_DEFAULT_USER=${DEV_RABBITMQ_USER}
- RABBITMQ_DEFAULT_PASS=${DEV_RABBITMQ_PASSWORD}
volumes:
- rabbitmqPersistence:/var/lib/rabbitmq
restart: unless-stopped
......
......@@ -2499,6 +2499,11 @@
"is-obj": "^1.0.0"
}
},
"dotenv": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.1.0.tgz",
"integrity": "sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw=="
},
"duplexer": {
"version": "0.1.1",
"resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
......@@ -3396,14 +3401,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
......@@ -3418,20 +3421,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"core-util-is": {
"version": "1.0.2",
......@@ -3548,8 +3548,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"ini": {
"version": "1.3.5",
......@@ -3561,7 +3560,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
......@@ -3576,7 +3574,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
......@@ -3584,14 +3581,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
......@@ -3610,7 +3605,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
......@@ -3691,8 +3685,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",
......@@ -3704,7 +3697,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
......@@ -3826,7 +3818,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
......
import { Module } from '@nestjs/common';
import { EmailModule } from 'email/email.module';
import { ConfigModule } from 'configuration/config.module';
@Module({
imports: [EmailModule],
imports: [ConfigModule, EmailModule],
controllers: [],
providers: [],
})
......
import { Module, Global } from '@nestjs/common';
import { ConfigService } from './config.service';
@Global()
@Module({
providers: [
{
provide: ConfigService,
useValue: new ConfigService(),
},
],
exports: [ConfigService],
})
export class ConfigModule {}
\ No newline at end of file
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { config } from './config';
export class ConfigService {
private _config = config;
constructor() {
// Only for development purpose, set environment variable based on the env file provided
if (process.env.NODE_ENV === 'LOCAL') {
const envConfig = dotenv.parse(fs.readFileSync(`./src/configuration/${process.env.NODE_ENV}.env`));
for (const k in envConfig) {
if (envConfig.hasOwnProperty(k)) {
process.env[k] = envConfig[k];
}
}
}
// Initializing conf with values from var env
this._config.rabbitMQ.user = process.env.RABBITMQ_USER;
this._config.rabbitMQ.password = process.env.RABBITMQ_PASSWORD;
this._config.adminEmails = process.env.ADMIN_EMAILS.split(',');
}
get config() {
return this._config;
}
}
\ No newline at end of file
export const config = {
rabbitMQ: {
user: null,
password: null,
host: 'rabbitmq',
port: '5672',
},
mailerQueue: 'portail-data-send-email',
adminEmails: [],
};
\ No newline at end of file
RABBITMQ_USER=
RABBITMQ_PASSWORD=
ADMIN_EMAILS=
\ No newline at end of file
import { Controller, Post, Body, Res } from '@nestjs/common';
import { ContactForm } from './email';
import { EmailService } from './email.service';
import { ApiBadRequestResponse, ApiOkResponse } from '@nestjs/swagger';
import { ApiBadRequestResponse, ApiOkResponse, ApiUseTags } from '@nestjs/swagger';
@ApiUseTags('email')
@Controller('email')
export class EmailController {
......@@ -16,7 +17,7 @@ export class EmailController {
create(@Body() contactForm: ContactForm, @Res() res) {
this.emailService.send(contactForm, (err, result) => {
if (err !== null || result !== true) {
res.status(400).send({error: err});
res.status(err.status).send({error: err.message});
} else {
res.status(200).send();
}
......
import { Injectable, Logger } from '@nestjs/common';
import * as amqp from 'amqplib/callback_api';
import { ContactForm, Email } from './email';
import { config } from 'configuration/config';
@Injectable()
export class EmailService {
send(contactForm: ContactForm, done) {
const rabbitmqUrl = 'amqp://user:password123@rabbitmq:5672';
const mailerQueue = 'portail-data-send-email';
const rabbitmqUrl = `amqp://${config.rabbitMQ.user}:${config.rabbitMQ.password}@${config.rabbitMQ.host}:${config.rabbitMQ.port}`;
const mailerQueue = config.mailerQueue;
const email = new Email();
email.from = `${contactForm.firstname} ${contactForm.lastname} ${contactForm.from}`;
email.to = [process.env.ADMIN_EMAIL];
email.to = config.adminEmails;
email.subject = contactForm.subject;
email.text = contactForm.text;
Logger.log('[-] send method');
Logger.log(email);
// Connect to rabbitmq
amqp.connect(rabbitmqUrl, (err, conn) => {
if (err != null) {
Logger.log(err);
done('Couldn\'t connect to rabbitMQ.');
Logger.error(' [x] Error connecting to RabbitMQ: ', err);
done({ message: 'Could not connect to rabbitMQ.', status: 500});
} else {
// Create a communication channel
conn.createChannel((error, ch) => {
if (error != null) {
Logger.log(error);
done('Couldn\'t create channel.');
Logger.error(' [x] Error creating channel: ', error);
done({ message: 'Could not create channel.', status: 500});
} else {
// Stringify and bufferise message
const buffer = Buffer.from(JSON.stringify(email));
......@@ -37,7 +39,7 @@ export class EmailService {
ch.sendToQueue(mailerQueue, buffer, { persistent: true });
Logger.log(`sent to queue ${mailerQueue}: ${JSON.stringify(email)}`);
Logger.log(`Sent to queue ${mailerQueue}: ${JSON.stringify(email)}`);
done(null, true);
......
import { IsDefined } from 'class-validator';
import { IsDefined, Length, IsEmail } from 'class-validator';
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';
export class ContactForm {
@ApiModelProperty()
@IsDefined()
@IsEmail()
from: string;
@ApiModelProperty()
......@@ -13,10 +14,12 @@ export class ContactForm {
@ApiModelProperty()
@IsDefined()
@Length(1)
firstname: string;
@ApiModelProperty()
@IsDefined()
@Length(1)
lastname: string;
@ApiModelProperty()
......
......@@ -12,6 +12,7 @@ async function bootstrap() {
.setTitle('Portail Data Email MicroService API')
.setDescription('APIs description for the Email API')
.setVersion('0.1')
.addTag('email')
.build();
const document = SwaggerModule.createDocument(app, options);
fs.writeFileSync('./swagger-spec.json', JSON.stringify(document));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment