switch to redis
This commit is contained in:
parent
3505d2a520
commit
da82d0f289
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
14
ci/.env.ci
14
ci/.env.ci
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
15
package.json
15
package.json
|
@ -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",
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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],
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
Loading…
Reference in New Issue