Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit aafd91a

Browse files
Merge pull request #3 from hesibo/develop
Directly using Informix database
2 parents ddcacfd + 96cd479 commit aafd91a

17 files changed

+1757
-5041
lines changed

ReadMe.md

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
## Dependencies
44

5-
- nodejs https://nodejs.org/en/ (v10+)
5+
- nodejs https://nodejs.org/en/ (v8)
66
- Kafka
7+
- Informix
8+
- Docker, Docker Compose
79

810
## Configuration
911

@@ -26,11 +28,9 @@ The following parameters can be set in config files or in env variables:
2628
- AUTH0_CLIENT_ID: Auth0 client id, used to get TC M2M token
2729
- AUTH0_CLIENT_SECRET: Auth0 client secret, used to get TC M2M token
2830
- AUTH0_PROXY_SERVER_URL: Proxy Auth0 URL, used to get TC M2M token
29-
- V4_CHALLENGE_API_URL: V4 challenge api url, default value is 'https://api.topcoder-dev.com/v4/challenges'
30-
- V4_PLATFORMS_API_URL: v4 platforms api url, default value is 'https://api.topcoder-dev.com/v4/platforms'
31-
- V4_TECHNOLOGIES_API_URL:v4 technologies api url, default value is 'https://api.topcoder-dev.com/v4/technologies'
3231
- V5_CHALLENGE_API_URL: v5 challenge api url, default value is 'http://localhost:4000/v5/challenges'
3332
- V5_CHALLENGE_TYPE_API_URL: v5 challenge type api url, default value is 'http://localhost:4000/v5/challengeTypes'
33+
- INFORMIX: Informix database configuration parameters, refer `config/default.js` for more information
3434

3535
There is a `/health` endpoint that checks for the health of the app. This sets up an expressjs server and listens on the environment variable `PORT`. It's not part of the configuration file and needs to be passed as an environment variable
3636

@@ -67,33 +67,40 @@ Configuration for the tests is at `config/test.js`, only add such new configurat
6767
`bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic challenge.notification.create --from-beginning`
6868
- writing/reading messages to/from other topics are similar
6969

70+
## Topcoder Informix Database Setup
71+
We will use Topcoder Informix database setup on Docker.
72+
73+
Go to `docker-ifx` folder and run `docker-compose up`
74+
After the database has initialized, You can use a database GUI tool(example [DBeaver](https://dbeaver.io)) to run the sql script `docker-ifx/update.sql`.
75+
7076
## Mock V5 Challenge API
7177
Mock V5 challenge api is under `test/mock` folder. You can use command `npm run mock-api` to start the server.
7278

7379
## Local deployment
74-
1. Make sure that Kafka is running as per instructions above.
75-
2. From the project root directory, run the following command to install the dependencies
76-
```
77-
npm install
78-
```
79-
3. To run linters if required
80-
```
81-
npm run lint
80+
- Given the fact that the library used to access Informix DB depends on Informix Client SDK.
81+
We will run the application on Docker using a base image with Informix Client SDK installed and properly configured.
82+
For deployment, please refer to next section 'Local Deployment with Docker'
8283

83-
npm run lint:fix # To fix possible lint errors
84-
```
85-
4. Start the mock server
84+
## Local Deployment with Docker
85+
86+
1. Make sure that Kafka, mock server and Informix are running as per instructions above.
87+
88+
2. Go to `docker` folder
89+
90+
3. Rename the file `sample.api.env` to `api.env` And properly update the IP addresses to match your environment for the variables : KAFKA_URL, INFORMIX_HOST and V5_CHALLENGE_TYPE_API_URL( make sure to use IP address instead of hostname ( i.e localhost will not work)).Here is an example:
8691
```
87-
npm run mock-api
92+
KAFKA_URL=192.168.31.8:9092
93+
INFORMIX_HOST=192.168.31.8
94+
V5_CHALLENGE_TYPE_API_URL=http://192.168.31.8:4000/v5/challengeTypes
8895
```
89-
5. Start the processor and health check dropin
96+
97+
4. Once that is done, go to run the following command
98+
9099
```
91-
npm start
100+
docker-compose up
92101
```
93102

94-
## Testing
95-
- Run `npm run test` to execute unit tests and generate coverage report.
96-
- RUN `npm run e2e` to execute e2e tests and generate coverage report.
103+
5. When you are running the application for the first time, It will take some time initially to download the image and install the dependencies
97104

98105
## Verification
99106
Refer `Verification.md`

Verification.md

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,40 @@
1-
# Topcoder - Legacy Groups Processor
1+
# Topcoder - Legacy Challenge Processor
22

33
## Verification
4-
start Kafka server, start mock api server and start the processor
4+
start Kafka server, start Informix database, start mock api server and start the processor
55

66
1. start kafka-console-producer to write messages to `challenge.notification.create` topic:
77
`bin/kafka-console-producer.sh --broker-list localhost:9092 --topic challenge.notification.create`
88
2. write message:
9-
`{ "topic": "challenge.notification.create","originator": "challenge-api","timestamp": "2019-05-14T00:00:00.000Z","mime-type": "application/json","payload": { "id": "1a4ef3a8-ed35-40d1-b8a6-7371a700d011","typeId": "2f4ef3a8-ed35-40d1-b8a6-7371a700d098","track": "CODE","name": "test-for-legacy-challenge-processor","description": "<p>test</p>","phases": [{ "id": "id-1","name": "registration","isActive": true, "duration": 345600000 }, { "id": "id-2","name": "submission","isActive": true, "duration": 345600000 }, { "id": "id-3","name": "checkpoint","isActive": true, "duration": 172800000 } ], "prizeSets": [{ "type": "Code","prizes": [{ "type": "first-place", "value": 1000 }, { "type": "second-place","value": 500 }] }, { "type": "Check Point", "prizes": [{ "type": "first-place","value": 200 }, { "type": "second-place","value": 200 }, { "type": "third-place","value": 200 }] }],"reviewType": "COMMUNITY","markdown": false,"tags": ["Node.js","NodeJS","MongoDB","AWS"],"projectId": 5087,"forumId": 33059 } }`
10-
3. Watch the app console, It will show message successfully handled. And has info log `Create challenge entity in legacy system, the legacy id is XXX`. Now mark down the legacy id.
11-
4. Wait for a short period(1 minute), Then go to `https://api.topcoder-dev.com/v4/challenges/<legacy_id>` to verify the challenge has been created in legacy system. Note CODE challenge doesn't have checkpoint prize/phase, so the checkpoint prize is 0 in the legacy system.
9+
`{ "topic": "challenge.notification.create","originator": "challenge-api","timestamp": "2019-05-14T00:00:00.000Z","mime-type": "application/json","payload": { "id": "1a4ef3a8-ed35-40d1-b8a6-7371a700d011","typeId": "2f4ef3a8-ed35-40d1-b8a6-7371a700d098","track": "CODE","name": "test-for-legacy-challenge-processor","description": "<p>test</p>","phases": [{ "id": "id-1","name": "registration","isActive": true, "duration": 345600000 }, { "id": "id-2","name": "submission","isActive": true, "duration": 345600000 }, { "id": "id-3","name": "checkpoint","isActive": true, "duration": 172800000 } ], "prizeSets": [{ "type": "Code","prizes": [{ "type": "first-place", "value": 1000 }, { "type": "second-place","value": 500 }] }, { "type": "Check Point", "prizes": [{ "type": "first-place","value": 200 }, { "type": "second-place","value": 200 }, { "type": "third-place","value": 200 }] }],"reviewType": "COMMUNITY","markdown": false,"tags": ["Java","JUnit","MongoDB","AWS"],"projectId": 5087,"forumId": 33059 } }`
10+
3. Use database GUI tool to execute following statements to verify AssetDTO data.
11+
```sql
12+
select * from tcs_catalog:comp_catalog where component_id >= 2010;
13+
select * from tcs_catalog:comp_categories where comp_categories_id >= 2010;
14+
select * from tcs_catalog:comp_versions where comp_vers_id >= 2010;
15+
select * from tcs_catalog:comp_version_dates where comp_version_dates_id >= 3000;
16+
select * from tcs_catalog:comp_technology where comp_tech_id >= 2200;
17+
```
18+
4. Use database GUI tool to insert the following test data(Only AssetDTO data has been persisted right now, so you can't retrieve the corresponding AssetDTO using the legacyId provided by message payload). project_info table will contain component version id of challenge, you can use the comp_vers_id retrieve from step 3 to replace the `value` column.
19+
```sql
20+
insert into tcs_catalog:project(project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) values(2000, 2, 39, 132456, current, 132456, current);
21+
insert into tcs_catalog:project_info(project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) values(2000, 1, 2020, 132456, current, 132456, current);
22+
```
1223
5. start kafka-console-producer to write messages to `challenge.notification.update` topic:
1324
`bin/kafka-console-producer.sh --broker-list localhost:9092 --topic challenge.notification.update`
14-
6. write message(Use the legacy id you mark down in step 3, as a number):
15-
`{ "topic": "challenge.notification.update","originator": "challenge-api","timestamp": "2019-05-14T00:00:00.000Z","mime-type": "application/json","payload": { "legacyId": <legacy_id>, "id": "1a4ef3a8-ed35-40d1-b8a6-7371a700d011","typeId": "2f4ef3a8-ed35-40d1-b8a6-7371a700d098","track": "CODE","name": "update-for-legacy-challenge-processor","description": "#Title\n##sub title 1\ntext\n##sub title2\nanother text\n","phases": [{ "id": "id-1","name": "registration","isActive": true, "duration": 345600000 }, { "id": "id-2","name": "submission","isActive": true, "duration": 345600000 }], "prizeSets": [{ "type": "Code","prizes": [{ "type": "first-place", "value": 800 }, { "type": "second-place","value": 400 }]}],"reviewType": "COMMUNITY","markdown":true,"tags": ["Node.js","NodeJS"],"projectId": 5087,"forumId": 33059 } }`
16-
7. Wait for a short period(1 minute), Then go to `https://api.topcoder-dev.com/v4/challenges/<legacy_id>` to verify the challenge has been updated in legacy system.
17-
8. Repeat step 1 to 7, to create other type of challenge. Here is the message payload for creating a Design challenge with checkpoint prizes:
18-
`{ "topic": "challenge.notification.create","originator": "challenge-api","timestamp": "2019-05-14T00:00:00.000Z","mime-type": "application/json","payload": { "id": "1a4ef3a8-ed35-40d1-b8a6-7371a700d011","typeId": "3f4ef3a8-ed35-40d1-b8a6-7371a700d098","track": "WEB_DESIGNS","name": "test-design-demo","description": "<p>test design</p>","phases": [{ "id": "id-1","name": "registration","isActive": true, "duration": 345600000 }, { "id": "id-2","name": "submission","isActive": true, "duration": 345600000 }, { "id": "id-3","name": "checkpoint","isActive": true, "duration": 172800000 } ], "prizeSets": [{ "type": "Code","prizes": [{ "type": "first-place", "value": 1000 }, { "type": "second-place","value": 500 }] }, { "type": "Check Point", "prizes": [{ "type": "first-place","value": 200 }, { "type": "second-place","value": 200 }, { "type": "third-place","value": 200 }] }],"reviewType": "COMMUNITY","markdown": false,"tags": ["Node.js","NodeJS","MongoDB","AWS"],"projectId": 5087,"forumId": 33059 } }`
19-
25+
6. write message
26+
`{ "topic": "challenge.notification.update","originator": "challenge-api","timestamp": "2019-05-14T00:00:00.000Z","mime-type": "application/json","payload": { "legacyId": 2000, "id": "1a4ef3a8-ed35-40d1-b8a6-7371a700d011","typeId": "2f4ef3a8-ed35-40d1-b8a6-7371a700d098","track": "CODE","name": "update-for-legacy-challenge-processor","description": "#Title\n##sub title 1\ntext\n##sub title2\nanother text\n","phases": [{ "id": "id-1","name": "registration","isActive": true, "duration": 345600000 }, { "id": "id-2","name": "submission","isActive": true, "duration": 345600000 }], "prizeSets": [{ "type": "Code","prizes": [{ "type": "first-place", "value": 800 }, { "type": "second-place","value": 400 }]}],"reviewType": "COMMUNITY","markdown":true,"tags": ["Node.js","NodeJS", "PostgreSQL"],"projectId": 5087,"forumId": 33059 } }`
27+
7. Use database GUI tool to execute following statements to verify AssetDTO data.
28+
```sql
29+
select * from tcs_catalog:comp_catalog where component_id >= 2010;
30+
select * from tcs_catalog:comp_technology where comp_tech_id >= 2200;
31+
```
32+
8. Try to change track, write the following message
33+
`{ "topic": "challenge.notification.update","originator": "challenge-api","timestamp": "2019-05-14T00:00:00.000Z","mime-type": "application/json","payload": { "legacyId": 2000, "id": "1a4ef3a8-ed35-40d1-b8a6-7371a700d011","typeId": "2f4ef3a8-ed35-40d1-b8a6-7371a700d098","track": "WEB_DESIGNS","name": "update-for-legacy-challenge-processor","description": "#Title\n##sub title 1\ntext\n##sub title2\nanother text\n","phases": [{ "id": "id-1","name": "registration","isActive": true, "duration": 345600000 }, { "id": "id-2","name": "submission","isActive": true, "duration": 345600000 }], "prizeSets": [{ "type": "Code","prizes": [{ "type": "first-place", "value": 800 }, { "type": "second-place","value": 400 }]}],"reviewType": "COMMUNITY","markdown":true,"tags": ["Node.js","NodeJS", "PostgreSQL"],"projectId": 5087,"forumId": 33059 } }`
34+
9. You would see error message in app console.
2035

2136
## Unit test Coverage
22-
51 passing (23s)
23-
24-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
25-
----------------------|----------|----------|----------|----------|-------------------|
26-
All files | 94.05 | 86.21 | 96.67 | 93.75 | |
27-
config | 100 | 100 | 100 | 100 | |
28-
default.js | 100 | 100 | 100 | 100 | |
29-
test.js | 100 | 100 | 100 | 100 | |
30-
src | 100 | 100 | 100 | 100 | |
31-
bootstrap.js | 100 | 100 | 100 | 100 | |
32-
constants.js | 100 | 100 | 100 | 100 | |
33-
src/common | 87.34 | 50 | 94.74 | 87.34 | |
34-
helper.js | 73.33 | 0 | 83.33 | 73.33 | 16,17,18,20 |
35-
logger.js | 90.63 | 60 | 100 | 90.63 |32,55,60,84,98,118 |
36-
src/services | 100 | 100 | 100 | 100 | |
37-
ProcessorService.js | 100 | 100 | 100 | 100 | |
37+
It is not available right now
3838

3939
## E2E test Coverage
40-
41-
54 passing (2m)
42-
43-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
44-
----------------------|----------|----------|----------|----------|-------------------|
45-
All files | 95.37 | 87.88 | 97.5 | 95.17 | |
46-
config | 100 | 100 | 100 | 100 | |
47-
default.js | 100 | 100 | 100 | 100 | |
48-
test.js | 100 | 100 | 100 | 100 | |
49-
src | 94.12 | 66.67 | 90 | 94 | |
50-
app.js | 93.75 | 66.67 | 90 | 93.62 | 48,61,86 |
51-
bootstrap.js | 100 | 100 | 100 | 100 | |
52-
constants.js | 100 | 100 | 100 | 100 | |
53-
src/common | 91.14 | 66.67 | 100 | 91.14 | |
54-
helper.js | 93.33 | 50 | 100 | 93.33 | 18 |
55-
logger.js | 90.63 | 70 | 100 | 90.63 |32,55,60,84,98,118 |
56-
src/services | 100 | 100 | 100 | 100 | |
57-
ProcessorService.js | 100 | 100 | 100 | 100 | |
40+
It is not available right now

config/default.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ module.exports = {
2020
AUTH0_URL: process.env.AUTH0_URL || 'https://topcoder-dev.auth0.com/oauth/token',
2121
AUTH0_AUDIENCE: process.env.AUTH0_AUDIENCE || 'https://m2m.topcoder-dev.com/',
2222
TOKEN_CACHE_TIME: process.env.TOKEN_CACHE_TIME || 90,
23-
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID || 'e6oZAxnoFvjdRtjJs1Jt3tquLnNSTs0e',
24-
AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET || 'OGCzOnQkhYTQpZM3NI0sD--JJ_EPcm2E7707_k6zX11m223LrRK1-QZL4Pon4y-D',
23+
AUTH0_CLIENT_ID: process.env.AUTH0_CLIENT_ID || 'EkE9qU3Ey6hdJwOsF1X0duwskqcDuElW',
24+
AUTH0_CLIENT_SECRET: process.env.AUTH0_CLIENT_SECRET || 'Iq7REiEacFmepPh0UpKoOmc6u74WjuoJriLayeVnt311qeKNBvhRNBe9BZ8WABYk',
2525
AUTH0_PROXY_SERVER_URL: process.env.AUTH0_PROXY_SERVER_URL,
2626

27-
V4_CHALLENGE_API_URL: process.env.V4_CHALLENGE_API_URL || 'https://api.topcoder-dev.com/v4/challenges',
28-
V4_PLATFORMS_API_URL: process.env.V4_PLATFORMS_API_URL || 'https://api.topcoder-dev.com/v4/platforms',
29-
V4_TECHNOLOGIES_API_URL: process.env.V4_TECHNOLOGIES_API_URL || 'https://api.topcoder-dev.com/v4/technologies',
3027
V5_CHALLENGE_API_URL: process.env.V5_CHALLENGE_API_URL || 'http://localhost:4000/v5/challenges',
31-
V5_CHALLENGE_TYPE_API_URL: process.env.V5_CHALLENGE_TYPE_API_URL || 'http://localhost:4000/v5/challengeTypes'
28+
V5_CHALLENGE_TYPE_API_URL: process.env.V5_CHALLENGE_TYPE_API_URL || 'http://localhost:4000/v5/challengeTypes',
29+
30+
// informix database configuration
31+
INFORMIX: {
32+
SERVER: process.env.IFX_SERVER || 'informixoltp_tcp', // informix server
33+
DATABASE: process.env.IFX_DATABASE || 'tcs_catalog', // informix database
34+
HOST: process.env.INFORMIX_HOST || 'localhost', // host
35+
PROTOCOL: process.env.IFX_PROTOCOL || 'onsoctcp',
36+
PORT: process.env.IFX_PORT || '2021', // port
37+
DB_LOCALE: process.env.IFX_DB_LOCALE || 'en_US.57372',
38+
USER: process.env.IFX_USER || 'informix', // user
39+
PASSWORD: process.env.IFX_PASSWORD || '1nf0rm1x', // password
40+
POOL_MAX_SIZE: parseInt(process.env.IFX_POOL_MAX_SIZE) || 10 // use connection pool in processor, the pool size
41+
}
3242
}

docker-ifx/docker-compose.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: "3"
2+
services:
3+
informix:
4+
image: "appiriodevops/informix:cbbd0fa"
5+
ports:
6+
- "2021:2021"

docker-ifx/update.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
update tcs_catalog:id_sequences set next_block_start = 3000 where name = 'COMPVERSIONDATES_SEQ';

docker/Dockerfile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
FROM ibmcom/informix-innovator-c:12.10.FC12W1IE
2+
3+
ARG servername=informix
4+
5+
USER root
6+
RUN mkdir /app
7+
WORKDIR /home/informix
8+
9+
RUN sed -i '/jessie-updates/d' /etc/apt/sources.list
10+
RUN apt-get -qq update && apt-get -qq install -y \
11+
wget gcc g++ make xz-utils python2.7 git curl
12+
13+
RUN wget -q -O node8.tar.xz https://nodejs.org/dist/v8.11.3/node-v8.11.3-linux-x64.tar.xz \
14+
&& tar xfJ node8.tar.xz && rm -rf node8.tar.xz
15+
16+
ENV SERVERNAME=$servername
17+
18+
COPY docker/esql /opt/ibm/informix/bin/
19+
20+
RUN chmod +x /opt/ibm/informix/bin/esql
21+
RUN echo "informixoltp_tcp onsoctcp $SERVERNAME sqlexec" \
22+
> /opt/ibm/informix/etc/sqlhosts.informixoltp_tcp
23+
24+
ENV INFORMIXDIR /opt/ibm/informix
25+
ENV INFORMIX_HOME /home/informix
26+
ENV INFORMIXSERVER informixoltp_tcp
27+
ENV INFORMIXTERM terminfo
28+
ENV CLIENT_LOCALE=en_US.utf8
29+
ENV DB_LOCALE=en_US.utf8
30+
ENV DBDATE Y4MD-
31+
ENV DBDELIMITER "|"
32+
ENV PATH /home/informix/node-v8.11.3-linux-x64/bin:${INFORMIXDIR}/bin:${INFORMIXDIR}/lib:${INFORMIXDIR}/lib/esql:${PATH}
33+
ENV LD_LIBRARY_PATH ${INFORMIXDIR}/lib:${INFORMIXDIR}/lib/esql:${INFORMIXDIR}/lib/cli
34+
ENV INFORMIXSQLHOSTS /opt/ibm/informix/etc/sqlhosts.informixoltp_tcp
35+
ENV USER root
36+
ENV LICENSE accept
37+
38+
RUN ln -s /usr/bin/python2.7 /usr/bin/python
39+
RUN echo "sqlexec 2021/tcp" >> /etc/services
40+
41+
COPY . /app
42+
43+
WORKDIR /app
44+
RUN rm -rf node_modules && npm install --unsafe-perm
45+
46+
ENTRYPOINT [ "npm" ]

docker/api.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
KAFKA_URL=192.168.31.8:9092
2+
INFORMIX_HOST=192.168.31.8
3+
V5_CHALLENGE_TYPE_API_URL=http://192.168.31.8:4000/v5/challengeTypes

docker/docker-compose.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: '3'
2+
services:
3+
legacy-challenge-processor:
4+
image: legacy-challenge-processor:latest
5+
container_name: legacy-challenge-processor
6+
build:
7+
context: ../
8+
dockerfile: docker/Dockerfile
9+
env_file:
10+
- api.env
11+
network_mode: "host"
12+
command: run start

0 commit comments

Comments
 (0)