Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial commit #34

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
# API ports
BAP_PORT=5010
BG_PORT=5001
BPP_PORT=5002
PROXY_PORT=3000
MOCK_API_PORT=6000
PORT=4021
BAP_PORT=4021

# API URLS
BAP_URI=http://localhost:5010
BG_URI=http://localhost:5001
BPP_URI=http://localhost:5002
PROXY_URI=http://localhost:3000
MOCK_API_URI=http://localhost:6000/courses

# DB Vars
HASURA_URI=
SECRET=

## auth header builder
PRIVATE_KEY=<NETWORK_PARTICIPANT_PRIVATE_KEY_HERE> # (Right the official beckn gateway uses the public key only to sign)
SUBSCRIBER_ID=<YOUR_BPP_ID_HERE>
UNIQUE_ID=<NETWORK_PARTICIPANT_SIGNING_KEY_NAME_HERE>
BAP_URI='https://bap-compass.loca.lt/'
BAP_ID='bap.sandbox.compass.samagra.io'
# BG_URI='https://gateway.becknprotocol.io/bg/'
BG_URI='https://sandbox.onest.network/gateway/'
COURSE_MANAGER_URL='http://0.0.0.0:4030'
REDIS_HOST='0.0.0.0'
REDIS_PORT=6379
MARKETPLACE_PORTAL_SERVICE_URL=
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

# Use the official Node.js 18 image as a base
FROM node:18.16.1-alpine

# Install bash for debugging purposes (optional)
RUN apk add --no-cache bash

# Install global Node.js packages for NestJS development
RUN npm i -g @nestjs/cli typescript ts-node

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install project dependencies
RUN npm install

# Copy the rest of the application code to the container
COPY . .
COPY ./.env.sample ./.env
ENV REDIS_HOST redis
ENV REDIS_PORT 6379
# Build your Nest.js application
RUN npm run build

# Expose the PORT environment variable (default to 4000 if not provided)
ARG PORT=4021
ENV PORT=$PORT
EXPOSE $PORT

# Start the Nest.js application using the start:prod script
CMD ["npm", "run", "start:prod"]
12 changes: 6 additions & 6 deletions apps/bap/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,33 @@ import { AppController } from './app.controller';
import { AppService } from './app.service';
import { OnSearchModule } from './on_search/on_search.module';
import { OnSelectModule } from './on_select/on_select.module';
import { OnInitModule } from './on_init/on_init.module';
import { OnConfirmModule } from './on_confirm/on_confirm.module';
import { OnTrackModule } from './on_track/on_track.module';
import { OnCancelModule } from './on_cancel/on_cancel.module';
import { OnUpdateModule } from './on_update/on_update.module';
import { OnStatusModule } from './on_status/on_status.module';
import { OnRatingModule } from './on_rating/on_rating.module';
import { OnSupportModule } from './on_support/on_support.module';
import { HttpModule } from '@nestjs/axios';
import { ConfigModule } from '@nestjs/config';
import { RedisStoreModule } from './redis-store/redis-store.module';
import { FilterModule } from './filter/filter.module';
import { CoursesModule } from './courses/courses.module';

@Module({
imports: [
OnSearchModule,
OnSelectModule,
OnInitModule,
OnConfirmModule,
OnTrackModule,
OnCancelModule,
OnUpdateModule,
OnStatusModule,
OnRatingModule,
OnSupportModule,
ConfigModule.forRoot({
isGlobal: true,
}),
HttpModule,
RedisStoreModule,
FilterModule,
CoursesModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
18 changes: 18 additions & 0 deletions apps/bap/src/courses/courses.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CoursesController } from './courses.controller';

describe('CoursesController', () => {
let controller: CoursesController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [CoursesController],
}).compile();

controller = module.get<CoursesController>(CoursesController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
218 changes: 218 additions & 0 deletions apps/bap/src/courses/courses.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import {
Body,
Controller,
Get,
HttpStatus,
Logger,
Param,
ParseUUIDPipe,
Post,
Query,
Res,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CourseResponseDto } from '../filter/dto/course-response.dto';
import { RedisStoreService } from '../redis-store/redis-store.service';
import { CoursesService } from './courses.service';
import {
ConfirmRequestDto,
CourseDefaultResponseDto,
CourseRatingRequestDto,
UpdateRequestDto,
} from './dto';

@Controller('courses')
@ApiTags('courses')
export class CoursesController {
private readonly logger = new Logger(CoursesController.name);
constructor(
private readonly coursesService: CoursesService,
private readonly redisStoreService: RedisStoreService,
) {}

@Get('/search')
@ApiOperation({
summary: 'search request from consumer and forward it to the onest network',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Acknowledgement of confirm request',
type: CourseDefaultResponseDto,
})
async search(
@Res() res,
@Query('searchText') searchText: string,
): Promise<CourseDefaultResponseDto> {
try {
this.logger.log(
`Initiated triggering backen gateway for searching courses on onest network for:- ${searchText}`,
);

const response = await this.coursesService.search(searchText);

this.logger.log(
`Successfully triggered backen gateway to search courses on onest network for:- ${searchText}`,
);

return res.status(HttpStatus.OK).json(response);
} catch (error) {
this.logger.error(
`Failed to trigger backen gateway to search courses on onest network for:- ${searchText}`,
error,
);

return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
message: error.message,
});
}
}

@Get('/poll/:messageId')
@ApiOperation({
summary:
'Api to poll search results for a specific search query(a particular messageId)',
})
@ApiResponse({
status: HttpStatus.OK,
type: CourseResponseDto,
isArray: true,
})
async pollSearchResults(
@Param('messageId', ParseUUIDPipe) messageId: string,
@Res() res,
): Promise<CourseResponseDto[]> {
try {
this.logger.log(
`Initiated polling search result for message id #${messageId} on redis`,
);
const results = await this.redisStoreService.pollValue(messageId);

this.logger.log(
`Successfully polled search result for message id #${messageId} on redis`,
);

return res.status(HttpStatus.OK).json({
message: 'New Search responses fetched',
data: results,
});
} catch (error) {
this.logger.error(
`Failed to poll search result for message id #${messageId} on redis`,
error,
);

return res
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.json({ message: error.message });
}
}

@Post('/confirm')
@ApiOperation({
summary: 'confirm request from consumer and forward it to the bpp',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Acknowledgement of confirm request',
type: CourseDefaultResponseDto,
})
async confirmOrder(
@Res() res,
@Body() confirmDto: ConfirmRequestDto,
): Promise<CourseDefaultResponseDto> {
try {
this.logger.log(
`Initiated triggering bpp uri for confirmation of course with id #${confirmDto.courseId} and provider id #${confirmDto.providerId}`,
);
const response = await this.coursesService.confirmOrder(confirmDto);

this.logger.log(
`Successfully triggered bpp uri for confirmation course with id #${confirmDto.courseId} and provider id #${confirmDto.providerId}`,
);

return res.status(HttpStatus.OK).json(response);
} catch (error) {
this.logger.error(
`Failed to trigger bpp uri for confirmation of course with id #${confirmDto.courseId} and provider id #${confirmDto.providerId}`,
error,
);

return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
message: error.message,
});
}
}

@Post('/update')
@ApiOperation({
summary: 'update request from consumer and forward it to the bpp',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Acknowledgement of confirm request',
type: CourseDefaultResponseDto,
})
async updateOrder(
@Res() res,
@Body() updateRequestDto: UpdateRequestDto,
): Promise<CourseDefaultResponseDto> {
try {
this.logger.log(
`Initiated triggering bpp uri for status updating of purchased course with message id #${updateRequestDto.messageId} and transactionId id #${updateRequestDto.transactionId}`,
);
const response = await this.coursesService.updateOrder(updateRequestDto);
this.logger.log(
`Successfully triggered bpp uri for status updating of purchased course with message id #${updateRequestDto.messageId} and transactionId id #${updateRequestDto.transactionId}`,
);

return res.status(HttpStatus.OK).json(response);
} catch (error) {
this.logger.error(
`Failed to trigger bpp uri for status updating of purchased course with message id #${updateRequestDto.messageId} and transactionId id #${updateRequestDto.transactionId}`,
error,
);
return res
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.json({ message: error.message });
}
}

@Post('/rating')
@ApiOperation({
summary: 'course rating request from consumer and forward it to the bpp',
})
@ApiResponse({
status: HttpStatus.OK,
description: 'Acknowledgement of confirm request',
type: CourseDefaultResponseDto,
})
async courseRating(
@Res() res,
@Body() courseRatingRequestDto: CourseRatingRequestDto,
): Promise<CourseDefaultResponseDto> {
try {
this.logger.log(
`Initiated triggering bpp uri for rating of course with id #${courseRatingRequestDto.courseId}`,
);

const response = await this.coursesService.courseRating(
courseRatingRequestDto,
);

this.logger.log(
`Successfully to trigger bpp uri for rating of course with id #${courseRatingRequestDto.courseId}`,
);

return res.status(HttpStatus.OK).json(response);
} catch (error) {
this.logger.error(
`Failed to trigger bpp uri for rating of course with id #${courseRatingRequestDto.courseId}`,
error,
);

return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
message: error.message,
});
}
}
}
13 changes: 13 additions & 0 deletions apps/bap/src/courses/courses.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { CoursesService } from './courses.service';
import { CoursesController } from './courses.controller';
import { HttpModule } from '@nestjs/axios';
import { FilterService } from '../filter/filter.service';
import { RedisStoreService } from '../redis-store/redis-store.service';

@Module({
imports: [HttpModule],
providers: [CoursesService, FilterService, RedisStoreService],
controllers: [CoursesController],
})
export class CoursesModule {}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CancelService } from './cancel.service';
import { CoursesService } from './courses.service';

describe('CancelService', () => {
let service: CancelService;
describe('CoursesService', () => {
let service: CoursesService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CancelService],
providers: [CoursesService],
}).compile();

service = module.get<CancelService>(CancelService);
service = module.get<CoursesService>(CoursesService);
});

it('should be defined', () => {
Expand Down
Loading