Skip to content
Snippets Groups Projects
Commit c10d71d5 authored by FORESTIER Fabien's avatar FORESTIER Fabien
Browse files

Replace callback by async/await

parent aee9f90e
No related branches found
No related tags found
No related merge requests found
Pipeline #
......@@ -21,3 +21,5 @@ npm-debug.log
*.env
!template.env
swagger-spec.json
import { Controller, Post, Body, Res } from '@nestjs/common';
import { Controller, Post, Body, Res, HttpException, InternalServerErrorException, Logger, HttpCode } from '@nestjs/common';
import { ContactForm } from './email';
import { EmailService } from './email.service';
import { ApiBadRequestResponse, ApiOkResponse, ApiUseTags, ApiOperation } from '@nestjs/swagger';
import { ApiBadRequestResponse, ApiOkResponse, ApiUseTags, ApiOperation, ApiInternalServerErrorResponse } from '@nestjs/swagger';
@ApiUseTags('email')
@Controller('email')
......@@ -13,16 +13,16 @@ export class EmailController {
@Post('contact')
@ApiOperation({ title: 'Send email to admin (emails defined as var env of the project, see docker-compose.yml file).' })
@ApiOkResponse({ description: 'OK'})
@ApiBadRequestResponse({ description: 'Missing fields'})
create(@Body() contactForm: ContactForm, @Res() res) {
this.emailService.send(contactForm, (err, result) => {
if (err !== null || result !== true) {
res.status(err.status).send({error: err.message});
} else {
res.status(200).send();
}
});
@ApiOkResponse({ description: 'OK' })
@ApiBadRequestResponse({ description: 'Missing fields' })
@ApiInternalServerErrorResponse({ description: 'Internal error, this is probably a rabbitMQ related error (unreachable service...)'})
@HttpCode(200)
async create(@Body() contactForm: ContactForm) {
try {
return await this.emailService.send(contactForm);
} catch (error) {
Logger.log(error);
throw new InternalServerErrorException();
}
}
}
import { Injectable, Logger } from '@nestjs/common';
import * as amqp from 'amqplib/callback_api';
import { Injectable, Logger, InternalServerErrorException, BadRequestException } from '@nestjs/common';
import * as amqp from 'amqplib';
import { ContactForm, Email } from './email';
import { config } from 'configuration/config';
import { ConfigService } from 'configuration/config.service';
@Injectable()
export class EmailService {
config: any = {};
send(contactForm: ContactForm, done) {
const rabbitmqUrl = `amqp://${config.rabbitMQ.user}:${config.rabbitMQ.password}@${config.rabbitMQ.host}:${config.rabbitMQ.port}`;
const mailerQueue = config.mailerQueue;
constructor(private configService: ConfigService) {
this.config = this.configService.config;
}
async send(contactForm: ContactForm) {
let conn, ch;
// tslint:disable-next-line:max-line-length
const rabbitmqUrl = `amqp://${this.config.rabbitMQ.user}:${this.config.rabbitMQ.password}@${this.config.rabbitMQ.host}:${this.config.rabbitMQ.port}`;
const mailerQueue = this.config.mailerQueue;
const email = new Email();
email.from = `${contactForm.firstname} ${contactForm.lastname} ${contactForm.from}`;
email.to = config.adminEmails;
email.to = this.config.adminEmails;
email.subject = contactForm.subject;
email.text = contactForm.text;
......@@ -20,34 +27,43 @@ export class EmailService {
Logger.log(email);
// Connect to rabbitmq
amqp.connect(rabbitmqUrl, (err, conn) => {
if (err != null) {
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.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));
ch.assertQueue(mailerQueue, { durable: true });
ch.sendToQueue(mailerQueue, buffer, { persistent: true });
Logger.log(`Sent to queue ${mailerQueue}: ${JSON.stringify(email)}`);
done(null, true);
setTimeout(() => { conn.close(); }, 500);
}
});
}
});
try {
conn = await amqp.connect(rabbitmqUrl);
} catch (error) {
Logger.error(' [x] Error connecting to RabbitMQ: ', JSON.stringify(error));
throw new InternalServerErrorException('Could not connect to rabbitMQ.');
}
try {
// Create a communication channel
ch = await conn.createChannel();
} catch (error) {
Logger.error(' [x] Error creating channel: ', JSON.stringify(error));
throw new InternalServerErrorException('Could not create channel.');
}
// Stringify and bufferise message
const buffer = Buffer.from(JSON.stringify(email));
try {
await ch.assertQueue(mailerQueue, { durable: true });
} catch (error) {
Logger.error(' [x] Error creating channel: ', JSON.stringify(error));
throw new InternalServerErrorException('Could not assert channel.');
}
try {
await ch.sendToQueue(mailerQueue, buffer, { persistent: true });
} catch (error) {
Logger.error(' [x] Error sending to queue: ', JSON.stringify(error));
throw new InternalServerErrorException('Could not send to queue.');
}
Logger.log(`Sent to queue ${mailerQueue}: ${JSON.stringify(email)}`);
setTimeout(() => { conn.close(); }, 500);
return;
}
}
......@@ -17,7 +17,7 @@ async function bootstrap() {
const document = SwaggerModule.createDocument(app, options);
fs.writeFileSync('./swagger-spec.json', JSON.stringify(document));
SwaggerModule.setup('api', app, document);
SwaggerModule.setup('api-doc', app, document);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
......
{"swagger":"2.0","info":{"description":"APIs description for the Email API","version":"0.1","title":"Portail Data Email MicroService API"},"basePath":"/","tags":[],"schemes":["http"],"paths":{"/email/contact":{"post":{"parameters":[{"name":"ContactForm","required":true,"in":"body","schema":{"$ref":"#/definitions/ContactForm"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Missing fields"}},"produces":["application/json"],"consumes":["application/json"]}}},"definitions":{"ContactForm":{"type":"object","properties":{"from":{"type":"string"},"subject":{"type":"string"},"firstname":{"type":"string"},"lastname":{"type":"string"},"text":{"type":"string"}},"required":["from","subject","firstname","lastname","text"]}}}
\ No newline at end of file
{"swagger":"2.0","info":{"description":"Service providing the method to send emails.","version":"0.1","title":"Email service API"},"basePath":"/","tags":[{"name":"email","description":""}],"schemes":["http"],"paths":{"/email/contact":{"post":{"summary":"Send email to admin (emails defined as var env of the project, see docker-compose.yml file).","parameters":[{"name":"ContactForm","required":true,"in":"body","schema":{"$ref":"#/definitions/ContactForm"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Missing fields"},"500":{"description":"Internal error, this is probably a rabbitMQ related error (unreachable service...)"}},"tags":["email"],"produces":["application/json"],"consumes":["application/json"]}}},"definitions":{"ContactForm":{"type":"object","properties":{"from":{"type":"string"},"subject":{"type":"string"},"firstname":{"type":"string"},"lastname":{"type":"string"},"text":{"type":"string"}},"required":["from","subject","firstname","lastname","text"]}}}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment