switch to redis

This commit is contained in:
sbriat 2023-10-25 09:09:45 +02:00
parent 3505d2a520
commit da82d0f289
15 changed files with 33 additions and 118 deletions

View File

@ -2,5 +2,7 @@
SERVICE_URL=0.0.0.0 SERVICE_URL=0.0.0.0
SERVICE_PORT=5003 SERVICE_PORT=5003
# PRISMA # REDIS
DATABASE_URL="postgresql://mobicoop:mobicoop@localhost:5432/mobicoop-test?schema=configuration" REDIS_HOST=v3-redis-test
REDIS_PASSWORD=redis
REDIS_PORT=6380

View File

@ -12,12 +12,8 @@ WORKDIR /usr/src/app
# Copying this first prevents re-running npm install on every code change. # Copying this first prevents re-running npm install on every code change.
COPY --chown=node:node package*.json ./ COPY --chown=node:node package*.json ./
# Copy prisma (needed for prisma error types)
COPY --chown=node:node ./prisma prisma
# Install app dependencies using the `npm ci` command instead of `npm install` # Install app dependencies using the `npm ci` command instead of `npm install`
RUN npm ci RUN npm ci
RUN npx prisma generate
# Bundle app source # Bundle app source
COPY --chown=node:node . . COPY --chown=node:node . .
@ -43,9 +39,6 @@ COPY --chown=node:node --from=development /usr/src/app/node_modules ./node_modul
COPY --chown=node:node . . COPY --chown=node:node . .
# Copy prisma (needed for migrations)
COPY --chown=node:node ./prisma prisma
# Run the build command which creates the production bundle # Run the build command which creates the production bundle
RUN npm run build RUN npm run build
@ -70,7 +63,6 @@ COPY --chown=node:node package*.json ./
# Copy the bundled code from the build stage to the production image # Copy the bundled code from the build stage to the production image
COPY --chown=node:node --from=build /usr/src/app/node_modules ./node_modules COPY --chown=node:node --from=build /usr/src/app/node_modules ./node_modules
COPY --chown=node:node --from=build /usr/src/app/prisma ./prisma
COPY --chown=node:node --from=build /usr/src/app/dist ./dist COPY --chown=node:node --from=build /usr/src/app/dist ./dist
# Start the server using the production build # Start the server using the production build

View File

@ -2,14 +2,6 @@
SERVICE_URL=0.0.0.0 SERVICE_URL=0.0.0.0
SERVICE_PORT=5003 SERVICE_PORT=5003
# PRISMA # REDIS
DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=public" REDIS_IMAGE=redis:7.0-alpine
REDIS_PASSWORD=redis
# RABBIT MQ
RMQ_URI=amqp://v3-broker:5672
# MESSAGE BROKER
BROKER_IMAGE=rabbitmq:3-alpine
# POSTGRES
POSTGRES_IMAGE=postgres:15.0

View File

@ -16,9 +16,6 @@ RUN npm ci
# Bundle app source # Bundle app source
COPY . . COPY . .
# Generate prisma client
RUN npx prisma generate
# Create a "dist" folder # Create a "dist" folder
RUN npm run build RUN npm run build

View File

@ -1,12 +1,12 @@
#!/bin/bash #!/bin/bash
testlog() { testlog() {
docker logs v3-db | grep -q "database system is ready to accept connections" docker logs v3-redis | grep -q "Ready to accept connections"
} }
testlog 2> /dev/null testlog 2> /dev/null
while [ $? -ne 0 ]; while [ $? -ne 0 ];
do do
sleep 5 sleep 5
echo "Waiting for Test DB to be up..." echo "Waiting for Test Redis to be up..."
testlog 2> /dev/null testlog 2> /dev/null
done done

View File

@ -1,23 +1,12 @@
version: '3.8' version: '3.8'
services: services:
db: redis:
container_name: v3-db container_name: v3-redis
image: ${POSTGRES_IMAGE} image: ${REDIS_IMAGE}
environment: command: redis-server --requirepass ${REDIS_PASSWORD}
POSTGRES_DB: mobicoop
POSTGRES_USER: mobicoop
POSTGRES_PASSWORD: mobicoop
ports: ports:
- 5432:5432 - 6379:6379
networks:
- v3-network
broker:
container_name: v3-broker
image: ${BROKER_IMAGE}
ports:
- 5672:5672
networks: networks:
- v3-network - v3-network

View File

@ -17,18 +17,13 @@
"lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix-dry-run --ignore-path .gitignore", "lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix-dry-run --ignore-path .gitignore",
"pretty:check": "./node_modules/.bin/prettier --check .", "pretty:check": "./node_modules/.bin/prettier --check .",
"pretty": "./node_modules/.bin/prettier --write .", "pretty": "./node_modules/.bin/prettier --write .",
"test": "npm run migrate:test && dotenv -e .env.test jest", "test": "dotenv -e .env.test jest",
"test:unit": "jest --testPathPattern 'tests/unit/' --verbose", "test:unit": "jest --testPathPattern 'tests/unit/' --verbose",
"test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage", "test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage",
"test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose", "test:integration": "dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose",
"test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/'", "test:integration:ci": "dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/'",
"test:cov": "jest --testPathPattern 'tests/unit/' --coverage", "test:cov": "jest --testPathPattern 'tests/unit/' --coverage",
"test:e2e": "jest --config ./test/jest-e2e.json", "test:e2e": "jest --config ./test/jest-e2e.json"
"generate": "docker exec v3-configuration-api sh -c 'npx prisma generate'",
"migrate": "docker exec v3-configuration-api sh -c 'npx prisma migrate dev'",
"migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy",
"migrate:test:ci": "dotenv -e ci/.env.ci -- npx prisma migrate deploy",
"migrate:deploy": "npx prisma migrate deploy"
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "^1.9.6", "@grpc/grpc-js": "^1.9.6",
@ -44,7 +39,6 @@
"@nestjs/microservices": "^10.2.7", "@nestjs/microservices": "^10.2.7",
"@nestjs/platform-express": "^10.2.7", "@nestjs/platform-express": "^10.2.7",
"@nestjs/terminus": "^10.1.1", "@nestjs/terminus": "^10.1.1",
"@prisma/client": "^5.4.2",
"@songkeys/nestjs-redis": "^10.0.0", "@songkeys/nestjs-redis": "^10.0.0",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.0", "class-validator": "^0.14.0",
@ -71,7 +65,6 @@
"eslint-plugin-prettier": "^5.0.1", "eslint-plugin-prettier": "^5.0.1",
"jest": "29.7.0", "jest": "29.7.0",
"prettier": "^3.0.3", "prettier": "^3.0.3",
"prisma": "^5.4.2",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"supertest": "^6.3.3", "supertest": "^6.3.3",
"ts-jest": "29.1.1", "ts-jest": "29.1.1",

View File

@ -5,12 +5,6 @@ export const SERVICE_NAME = 'configuration';
export const GRPC_PACKAGE_NAME = 'configuration'; export const GRPC_PACKAGE_NAME = 'configuration';
export const GRPC_SERVICE_NAME = 'ConfigurationService'; export const GRPC_SERVICE_NAME = 'ConfigurationService';
// messaging
export const CONFIGURATION_SET_ROUTING_KEY = 'configuration.set';
export const CONFIGURATION_DELETED_ROUTING_KEY = 'configuration.deleted';
export const CONFIGURATION_PROPAGATED_ROUTING_KEY = 'configuration.propagated';
// health // health
export const GRPC_HEALTH_PACKAGE_NAME = 'health'; export const GRPC_HEALTH_PACKAGE_NAME = 'health';
export const HEALTH_CONFIGURATION_REPOSITORY = 'ConfigurationRepository';
export const HEALTH_CRITICAL_LOGGING_KEY = 'logging.configuration.health.crit'; export const HEALTH_CRITICAL_LOGGING_KEY = 'logging.configuration.health.crit';

View File

@ -1,19 +1,10 @@
import { import { HealthModule, HealthModuleOptions } from '@mobicoop/health-module';
HealthModule,
HealthModuleOptions,
HealthRepositoryPort,
} from '@mobicoop/health-module';
import { MessagerModule } from '@modules/messager/messager.module'; import { MessagerModule } from '@modules/messager/messager.module';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config'; import { ConfigModule, ConfigService } from '@nestjs/config';
import { import { HEALTH_CRITICAL_LOGGING_KEY, SERVICE_NAME } from './app.constants';
HEALTH_CONFIGURATION_REPOSITORY,
HEALTH_CRITICAL_LOGGING_KEY,
SERVICE_NAME,
} from './app.constants';
import { MessagePublisherPort } from '@mobicoop/ddd-library'; import { MessagePublisherPort } from '@mobicoop/ddd-library';
import { MESSAGE_PUBLISHER } from '@modules/messager/messager.di-tokens'; import { MESSAGE_PUBLISHER } from '@modules/messager/messager.di-tokens';
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
import { ConfigurationModule } from '@modules/configuration/configuration.module'; import { ConfigurationModule } from '@modules/configuration/configuration.module';
import { EventEmitterModule } from '@nestjs/event-emitter'; import { EventEmitterModule } from '@nestjs/event-emitter';
import brokerConfig from './config/broker.config'; import brokerConfig from './config/broker.config';
@ -22,6 +13,7 @@ import paginationConfig from './config/pagination.config';
import serviceConfig from './config/service.config'; import serviceConfig from './config/service.config';
import { RedisModule, RedisModuleOptions } from '@songkeys/nestjs-redis'; import { RedisModule, RedisModuleOptions } from '@songkeys/nestjs-redis';
import redisConfig from './config/redis.config'; import redisConfig from './config/redis.config';
import { Transport } from '@nestjs/microservices';
@Module({ @Module({
imports: [ imports: [
@ -37,21 +29,24 @@ import redisConfig from './config/redis.config';
}), }),
EventEmitterModule.forRoot(), EventEmitterModule.forRoot(),
HealthModule.forRootAsync({ HealthModule.forRootAsync({
imports: [ConfigurationModule, MessagerModule], imports: [MessagerModule, ConfigModule],
inject: [CONFIGURATION_REPOSITORY, MESSAGE_PUBLISHER], inject: [MESSAGE_PUBLISHER, ConfigService],
useFactory: async ( useFactory: async (
configurationRepository: HealthRepositoryPort,
messagePublisher: MessagePublisherPort, messagePublisher: MessagePublisherPort,
configService: ConfigService,
): Promise<HealthModuleOptions> => ({ ): Promise<HealthModuleOptions> => ({
serviceName: SERVICE_NAME, serviceName: SERVICE_NAME,
criticalLoggingKey: HEALTH_CRITICAL_LOGGING_KEY, criticalLoggingKey: HEALTH_CRITICAL_LOGGING_KEY,
checkRepositories: [ messagePublisher,
checkMicroservices: [
{ {
name: HEALTH_CONFIGURATION_REPOSITORY, host: configService.get<string>('redis.host') as string,
repository: configurationRepository, port: configService.get<string>('redis.port') as string,
password: configService.get<string>('redis.password'),
name: 'Redis',
transport: Transport.REDIS,
}, },
], ],
messagePublisher,
}), }),
}), }),
RedisModule.forRootAsync({ RedisModule.forRootAsync({

View File

@ -1,4 +1 @@
export const CONFIGURATION_MESSAGE_PUBLISHER = Symbol(
'CONFIGURATION_MESSAGE_PUBLISHER',
);
export const CONFIGURATION_REPOSITORY = Symbol('CONFIGURATION_REPOSITORY'); export const CONFIGURATION_REPOSITORY = Symbol('CONFIGURATION_REPOSITORY');

View File

@ -5,11 +5,7 @@ import { SetConfigurationGrpcController } from './interface/grpc-controllers/set
import { SetConfigurationService } from './core/application/commands/set-configuration/set-configuration.service'; import { SetConfigurationService } from './core/application/commands/set-configuration/set-configuration.service';
import { GetConfigurationQueryHandler } from './core/application/queries/get-configuration/get-configuration.query-handler'; import { GetConfigurationQueryHandler } from './core/application/queries/get-configuration/get-configuration.query-handler';
import { ConfigurationMapper } from './configuration.mapper'; import { ConfigurationMapper } from './configuration.mapper';
import { import { CONFIGURATION_REPOSITORY } from './configuration.di-tokens';
CONFIGURATION_MESSAGE_PUBLISHER,
CONFIGURATION_REPOSITORY,
} from './configuration.di-tokens';
import { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
import { PopulateService } from './core/application/services/populate.service'; import { PopulateService } from './core/application/services/populate.service';
import { ConfigurationRepository } from './infrastructure/configuration.repository'; import { ConfigurationRepository } from './infrastructure/configuration.repository';
@ -33,13 +29,6 @@ const repositories: Provider[] = [
}, },
]; ];
const messagePublishers: Provider[] = [
{
provide: CONFIGURATION_MESSAGE_PUBLISHER,
useExisting: MessageBrokerPublisher,
},
];
@Module({ @Module({
imports: [CqrsModule], imports: [CqrsModule],
controllers: [...grpcControllers], controllers: [...grpcControllers],
@ -49,7 +38,6 @@ const messagePublishers: Provider[] = [
...mappers, ...mappers,
...providers, ...providers,
...repositories, ...repositories,
...messagePublishers,
], ],
exports: [ConfigurationMapper, CONFIGURATION_REPOSITORY], exports: [ConfigurationMapper, CONFIGURATION_REPOSITORY],
}) })

View File

@ -3,7 +3,6 @@ import { v4 } from 'uuid';
import { import {
ConfigurationProps, ConfigurationProps,
CreateConfigurationProps, CreateConfigurationProps,
UpdateConfigurationProps,
} from './configuration.types'; } from './configuration.types';
export class ConfigurationEntity extends AggregateRoot<ConfigurationProps> { export class ConfigurationEntity extends AggregateRoot<ConfigurationProps> {
@ -16,10 +15,6 @@ export class ConfigurationEntity extends AggregateRoot<ConfigurationProps> {
return configuration; return configuration;
}; };
update(props: UpdateConfigurationProps): void {
this.props.value = props.value;
}
validate(): void { validate(): void {
// entity business rules validation to protect it's invariant before saving entity to a database // entity business rules validation to protect it's invariant before saving entity to a database
} }

View File

@ -10,10 +10,6 @@ export interface CreateConfigurationProps {
value: ConfigurationValue; value: ConfigurationValue;
} }
export interface UpdateConfigurationProps {
value: ConfigurationValue;
}
export enum ConfigurationDomain { export enum ConfigurationDomain {
CARPOOL = 'CARPOOL', CARPOOL = 'CARPOOL',
PAGINATION = 'PAGINATION', PAGINATION = 'PAGINATION',

View File

@ -2,7 +2,6 @@ import { ConfigurationEntity } from '@modules/configuration/core/domain/configur
import { import {
CreateConfigurationProps, CreateConfigurationProps,
ConfigurationDomain, ConfigurationDomain,
UpdateConfigurationProps,
} from '@modules/configuration/core/domain/configuration.types'; } from '@modules/configuration/core/domain/configuration.types';
const createConfigurationProps: CreateConfigurationProps = { const createConfigurationProps: CreateConfigurationProps = {
@ -13,10 +12,6 @@ const createConfigurationProps: CreateConfigurationProps = {
value: '3', value: '3',
}; };
const updateConfigurationProps: UpdateConfigurationProps = {
value: '2',
};
describe('Configuration entity create', () => { describe('Configuration entity create', () => {
it('should create a new configuration entity', async () => { it('should create a new configuration entity', async () => {
const configurationEntity: ConfigurationEntity = ConfigurationEntity.create( const configurationEntity: ConfigurationEntity = ConfigurationEntity.create(
@ -26,13 +21,3 @@ describe('Configuration entity create', () => {
expect(configurationEntity.getProps().value).toBe('3'); expect(configurationEntity.getProps().value).toBe('3');
}); });
}); });
describe('Configuration entity update', () => {
it('should update a configuration entity', async () => {
const configurationEntity: ConfigurationEntity = ConfigurationEntity.create(
createConfigurationProps,
);
configurationEntity.update(updateConfigurationProps);
expect(configurationEntity.getProps().value).toBe('2');
});
});

View File

@ -18,7 +18,7 @@ const mockConfigurationMapper = {
toDomain: jest.fn().mockImplementation( toDomain: jest.fn().mockImplementation(
() => () =>
new ConfigurationEntity({ new ConfigurationEntity({
id: ' 001199d4-7187-4e83-a044-12159cba2e33', id: '001199d4-7187-4e83-a044-12159cba2e33',
props: { props: {
identifier: { identifier: {
domain: ConfigurationDomain.CARPOOL, domain: ConfigurationDomain.CARPOOL,