Skip to content

Commit 413280a

Browse files
authored
Merge pull request #59 from CDLUC3/development
Initial sync of development to main
2 parents e697be2 + 1d722ef commit 413280a

File tree

101 files changed

+17248
-1318
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+17248
-1318
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.editorconfig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# https://editorconfig.org
2+
3+
# Taken from Facebook's config
4+
5+
# top-most EditorConfig file
6+
root = true
7+
8+
[*]
9+
charset = utf-8
10+
# Unix-style newlines with a newline ending every file
11+
end_of_line = lf
12+
insert_final_newline = true
13+
indent_size = 2
14+
indent_style = space
15+
max_line_length = 80
16+
trim_trailing_whitespace = true
17+
18+
[*.md]
19+
max_line_length = 0
20+
trim_trailing_whitespace = false
21+
22+
[COMMIT_EDITMSG]
23+
max_line_length = 0

.env-example

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Basic config used whether running in the local Docker env or in the cloud
2+
LOG_LEVEL=debug
3+
DMSP_BASE_URL=https://doi.org/10.11111/ZZ
4+
5+
# If you are running this system locally and want to run "offline" you should
6+
# set this variable to `true`
7+
USE_MOCK_DATA=false
8+
9+
# If you want access to live data you will need to set the above variable to `false`
10+
# and then provide fill out the following variables
11+
AWS_REGION=us-west-2
12+
13+
# JSON Web Token (JWT) settings
14+
JWT_SECRET=ihef93hgf9-u3hgfi3hfte4g4tg4tg4
15+
JWT_TTL=1hr
16+
17+
# DMPHub API
18+
DMPHUB_AUTH_URL=https://auth.mydomain.edu
19+
DMPHUB_API_BASE_URL=https://api.mydomain.edu
20+
DMPHUB_API_CLIENT_ID=1234567890
21+
DMPHUB_API_CLIENT_SECRET=zyxwvutsrq
22+
23+
# MySQL database connections
24+
MYSQL_CONNECTION_LIMIT=5
25+
MYSQL_HOST=localhost
26+
MYSQL_PORT=3306
27+
MYSQL_DATABASE=dmsp
28+
MYSQL_USER=root
29+
MYSQL_PASSWORD=

.gitignore

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
# Ignore the Dotenv file
22
.env
33

4+
# Ignore the local data-migration log.
5+
data-migrations/processed.log
6+
47
# Skip all of the dependencies in node_modules
58
node_modules/
69

710
# Skip the compile distribution files
811
dist/
912

10-
# testing
11-
/coverage
13+
# Skip the Jest code coverage folder
14+
coverage/
15+
16+
# Ignore the persisted data sources for the local Docker dev env
17+
docker/
18+
19+
# Ignore VS Code files, like the launch.json file
20+
.vscode/
1221

13-
# Visual Studio Code
14-
.vscode
22+
# OS specific files
23+
.DS_Store

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
### Added
3+
- Schema, Mocks, Models and Resolvers for Affiliations and tests for the Models and Resolvers
4+
- Added new DataSource for the DmptoolApi with endpoints for Affiliations and a new mock for this data source for use in tests
5+
6+
### Updated
7+
- Updated schemas.ts, resolvers.ts, mocks.ts and codegen.ts to use new Affiliation files
8+
- Updated express.ts middleware file to pull in and initialize the new DmptoolApi datasource
9+
10+
## v0.1
11+
Initial Apollo Server build
12+
13+
### Added
14+
- Added unit tests for User model and contributorRole resolver, and added @types/pino
15+
- Added editor config
16+
- initial Apollo server config
17+
- Initial Schema for ContributorRole
18+
- Initial Schema for DMSP
19+
- Resolvers for ContributorRole
20+
- Initial resolver to fetch a single DMSP from the DMPHub API
21+
- Initial DMPHub API data source
22+
- Initial MySQL data source
23+
- Custom GraphQL scalars for ROR, ORCID and DMSP IDs
24+
- Mechanism for Apollo to use mocks when a resolver has not yet been implemented
25+
- Mocks for User
26+
- Data migration mechanism `./data-migrations/process.sh`
27+
- Documentation!
28+
- Local Docker Compose config
29+
- Pino logger with ECS formatter
30+
- Plugin to log request/response lifecycle events
31+
- Add Logger to the context and then used it in the resolvers
32+
33+
### Updated
34+
- Made some updates to auth code based on testing out recent changes with frontend [#34]

Dockerfile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Dockerfile
2+
# preferred node version chosen here (22.1.0-alpine3.19 as of 05/04/2024)
3+
FROM public.ecr.aws/docker/library/node:22.1.0-alpine3.19
4+
5+
# Create the directory on the node image
6+
# where our Next.js app will live
7+
RUN mkdir -p /app
8+
9+
# Set /app as the working directory in container
10+
WORKDIR /app
11+
12+
# Copy package.json and package-lock.json
13+
# to the /app working directory
14+
COPY package*.json tsconfig.json codegen.ts .env ./
15+
16+
# Copy the rest of our Apollo Server folder into /app
17+
COPY . .
18+
19+
# Install dependencies in /app
20+
RUN npm install
21+
22+
# Ensure port 3000 is accessible to our system
23+
EXPOSE 4000
24+
25+
# Command to run the Next.js app in development mode
26+
CMD ["npm", "run", "dev"]

Dockerfile.aws

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# syntax = docker/dockerfile:1
2+
3+
# This version of the Dockerfile is used by the buildspec.yaml within the AWS environment
4+
FROM public.ecr.aws/docker/library/node:current-alpine
5+
6+
# Create the directory on the node image where our Apollo server will live
7+
RUN mkdir -p /dist
8+
9+
# Copy package.json and package-lock.json to the /app working directory
10+
COPY package*.json ./
11+
12+
# Build the node_modules for production mode
13+
RUN npm install
14+
15+
# The app was built in the CodeBuild buildspec.yaml, so just copy dist/ in
16+
COPY dist/ ./dist
17+
18+
EXPOSE 4000
19+
20+
CMD ["node", "dist/index.js"]

README.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,65 @@
22

33
Apollo Server to support GraphQL interactions with the UI and external partners.
44

5-
To run locally: `npm start`
5+
Our Apollo server installation consists of:
6+
- Data Sources: Code used to communicate with external APIs, databases, file systems, etc.
7+
- GraphQL Schemas: The definition of our Graph including types, queries and mutations
8+
- Resolvers: The code that processes incoming queries and uses the available data sources to generate the results
9+
- Mocks: Stub or placeholder data that can be returned when a resolver has not yet been developed
10+
11+
## Installation
12+
- Make a local copy of the example dotenv file: `cp .env-example .env`
13+
- Setup MySQL:
14+
- If you are running on a Mac:
15+
- If you have homebrew installed, run `brew install mysql` and then start it `brew services start mysql`
16+
- Initialize the Database and the dataMigrations table: `./data-migrations/database-init.sh`
17+
- Run all database migrations: `./data-migrations/process.sh`
18+
- Install all of the dependencies: `npm install`
19+
- Generate the Typescript types: `npm run generate`
20+
- Startup the application in development mode: `npm run dev`
21+
- Navigate to `http://localhost:4000` in your browser
22+
23+
## Running current database migrations
24+
- See the readme file in the `data-migrations` directory for instructions on running data migrations in your local environment.
25+
26+
## Adding a new query/mutation
27+
You should always start by updating an existing GraphQL Schema file or adding a new one to the `src/schemas` directory.
28+
29+
Please include comments everywhere. These comments appear in the GraphQL explorer and help others undertand how to interact with the query or mutation.
30+
31+
If you added a new schema file, make sure you update the `src/schemas.ts` file to pull in the new file when the server starts up.
32+
33+
Once the schema has been added, you will need to run `npm run generate` this kicks off a script that builds out Typescript Types for the new schema and queries.
34+
35+
### Create a new Model
36+
You will need to create a Model if your new query/mutation will need to transform the response from the data source in any way prior to sending it to the caller or to the data source.
37+
38+
For example:
39+
- If my data source returns a property called `funder_id` and I want to send a boolean flag called `isFunder` to the caller, I perform the logic in a Model.
40+
- If I simply want to rename a property prior to returning it to the client like the data source returning `identifier` but needing to send `DMPId` to the caller.
41+
42+
Make sure that you transform the raw response from the data source into your Model in your new resolver.
43+
For example:
44+
```
45+
const response = await someDataSource.query('test');
46+
return new MyModel(response);
47+
```
48+
49+
### Create a Mock
50+
If you will be unable to create the corresponding resolver(s) at this point because of time constraints or because the data source is not yet ready, then you should add a new Mock file to the `src/schemas/` directory (or update and existing one with your changes). If you add a new mock be sure to update the `src/mocks.ts` to pull in your new mock when the server starts up.
51+
52+
Note that mocks should represent the data structure that will be returned from your resolver to the caller. NOT the dtat structure that the resolver receives from the data source!
53+
54+
### Create a Resolver
55+
If your data source is ready and you have the bandwidth, add a new Resolver to the `src/resolvers/` directory (or update one with your new query/mutation). If you add a new Resolver be sure to update the `src/resolvers.ts` file to make sure it is included when the server starts up.
56+
57+
### Add tests
58+
You MUST add tests if you added or modified a Model! To do so, find the corresponding file (or add a new one) in the `src/models/__tests_/` directory.
59+
60+
Resolver tests are not yet particularly useful. We will be updating this to add these integration tests in the near future.
61+
62+
## Useful commands
63+
- To run the Codegen utility to generate our Typescript types: `npm run generate`
64+
- To run the server in development mode: `npm run dev`
65+
- To run the server normally: `npm start`
66+
- To build the application: `npm run build`

buildspec.yaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Build specifications for AWS CodeBuild
2+
# See: https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
3+
4+
# Each input artifact is extracted to its own directory by CodePipeline, the locations of which
5+
# are stored in environment variables. The directory for the primary source artifact (this repo)
6+
# is made available with $CODEBUILD_SRC_DIR. The directory for the DMPTool push artifacts is
7+
# made available with $CODEBUILD_SRC_DIR_dmptool-commit.
8+
# Do not change version. This is the version of aws buildspec, not the version of your buldspec file.
9+
version: 0.2
10+
11+
phases:
12+
install:
13+
runtime-versions:
14+
# Apollo gives error when building on < 21
15+
nodejs: 21
16+
commands:
17+
# Install any libraries necessary for testing and compilation
18+
# - echo Installing Mocha...
19+
# - npm install -g mocha
20+
pre_build:
21+
commands:
22+
# Set some ENV variables here because CF only allows a limit of 1000 characters in the
23+
# EnvironmentVariable config for the Pipeline action :(
24+
- export AWS_VERSION=$(aws --version)
25+
26+
# Fetch the ECR repository name
27+
- echo $ECR_REPOSITORY_URI >> .ecr
28+
- export SHORT_ECR_URI=$(awk '{gsub("$ECR_REPOSITORY_NAME", "");print}' .ecr)
29+
- rm .ecr
30+
31+
# Set the repository URI to your ECR image and add an image tag with the first seven characters of the Git
32+
# commit ID of the source.
33+
- echo Logging in to Amazon ECR ...
34+
- aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $SHORT_ECR_URI
35+
- IMAGE_TAG=${COMMIT_HASH:=apollo-latest}
36+
37+
# Install MySQL so we can run DB migrations
38+
# - dnf -y install mariadb105
39+
build:
40+
commands:
41+
- echo "Running build in ${NODE_ENV} mode - started on `date`"
42+
- cd $CODEBUILD_SRC_DIR
43+
44+
# - echo Checking for DB migrations
45+
# - cd $CODEBUILD_SRC_DIR
46+
# - cd data-migrations && ./process-aws.sh $NODE_ENV && cd ..
47+
48+
# Install all of the dependencies (including dev so we can compile TS)
49+
- npm install --production=false
50+
51+
# Generate all of the GraphQL schema types
52+
- npm run generate
53+
54+
# Run any tests here
55+
# - npm run test
56+
57+
# Build the Apollo server which writes to the ./dist dir
58+
- npm run build
59+
60+
- echo Building the Docker image...
61+
- docker build -f Dockerfile.aws -t $SHORT_ECR_URI:apollo-latest .
62+
- docker tag $ECR_REPOSITORY_URI:apollo-latest $SHORT_ECR_URI:$IMAGE_TAG
63+
post_build:
64+
commands:
65+
# Push the Docker image to the ECR repository. Fargate will pick it up an deploy automatically
66+
- echo Build completed on `date`
67+
- echo Pushing the Docker images...
68+
- cd $CODEBUILD_SRC_DIR
69+
- docker push $SHORT_ECR_URI:apollo-latest
70+
- docker push $SHORT_ECR_URI:$IMAGE_TAG
71+
72+
- echo Writing image definitions file...
73+
- printf '[{"name":"%s","imageUri":"%s"}]' $TASK_DEFINITION_CONTAINER_NAME $ECR_REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
74+
75+
- echo Build completed on `date`
76+
77+
artifacts:
78+
# The Deploy step is expecting this name
79+
files: imagedefinitions.json

codegen.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { CodegenConfig } from "@graphql-codegen/cli";
2+
3+
const config: CodegenConfig = {
4+
schema: "./src/schemas/*.ts",
5+
generates: {
6+
"./src/types.ts": {
7+
plugins: ["typescript", "typescript-resolvers"],
8+
config: {
9+
contextType: "./context#MyContext",
10+
enumsAsTypes: true,
11+
mappers: {
12+
Dmsp: "./models/Dmsp#DmspModel",
13+
ContributorRole: "./models/ContributorRole#ContributorRoleModel",
14+
},
15+
},
16+
},
17+
},
18+
};
19+
20+
export default config;

0 commit comments

Comments
 (0)