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

Calendar Improvements #281

Closed
wants to merge 67 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
25066c5
Correction to RawAcademicCalendar parsing.
rjcanto Jun 30, 2021
4a2af01
Academic Calendar Business Object Unitary test completed.
rjcanto Jul 2, 2021
90d9513
Renaming Details to Lectures and ensuring variable declaration consis…
rjcanto Jul 2, 2021
9db37cc
make startDate in IntegrationJobParameters nullable
grimord Jun 30, 2021
1ca3a33
make startDate in IntegrationJobParameters nullable
grimord Jun 30, 2021
0cd625f
Update IOnIntegration_Staging.yml
rjcanto Jul 1, 2021
dfac59b
Minor improvement with stating that integration data is available pub…
rjcanto Jul 2, 2021
a51956d
Update production pipeline to deploy to GHCR (#280)
grimord Jul 2, 2021
9c172f5
Update README.md
rjcanto Jul 3, 2021
fff797f
add InputProcessorTests
grimord Jul 3, 2021
e736d85
add OutputFormatTests
grimord Jul 3, 2021
3180d9f
add JobController tests
grimord Jul 3, 2021
6c8e89d
remove git-server binary data used to setup local env as it is no lon…
grimord Jul 4, 2021
b88dbbb
update README.md to match changes
grimord Jul 4, 2021
231d6d3
add context path to web API
grimord Jul 4, 2021
6b0794c
add ArgumentException error definition
grimord Jul 4, 2021
7a164e1
add JobNotFoundException definition
grimord Jul 4, 2021
0b0c418
add enddate field to job data
grimord Jul 5, 2021
bbcba11
add output representation for job details
grimord Jul 5, 2021
841add8
add output representation for running jobs
grimord Jul 5, 2021
dae45a3
add output representation for job creation requests
grimord Jul 5, 2021
12cf83e
fix unit tests
grimord Jul 5, 2021
0df056f
remove redundant 80 port from generated urls
grimord Jul 5, 2021
0c1ce62
small refactor to DateUtils.kt to allow formatting of LocalDateTime o…
grimord Jul 5, 2021
1bf6925
change SERVER_PORT variable to PORT
grimord Jul 5, 2021
5fa1ba4
Update IOnIntegration_PR.yml
grimord Jul 5, 2021
6ff3483
Update IOnIntegration_PR.yml
grimord Jul 5, 2021
cffa92c
Update Dockerfile
grimord Jul 5, 2021
0de095d
Update Dockerfile
grimord Jul 5, 2021
811ea06
Update Dockerfile
grimord Jul 5, 2021
0085c18
Update Dockerfile
grimord Jul 5, 2021
7f643b7
Update Dockerfile
grimord Jul 5, 2021
d59435d
Update Dockerfile
grimord Jul 5, 2021
62c877b
Update Dockerfile
grimord Jul 5, 2021
e6d0f46
Update Dockerfile
grimord Jul 5, 2021
529550d
Update Dockerfile
grimord Jul 5, 2021
0226ac5
Update Dockerfile
grimord Jul 5, 2021
d457455
Update Dockerfile
grimord Jul 5, 2021
c701b76
Update Dockerfile
grimord Jul 5, 2021
bed702e
Update Dockerfile
grimord Jul 5, 2021
7915376
Update Dockerfile
grimord Jul 5, 2021
95d0da6
Update Dockerfile
grimord Jul 5, 2021
4e4d9b5
Update Dockerfile
grimord Jul 5, 2021
7457aa3
Update Dockerfile
grimord Jul 5, 2021
640485d
Update Dockerfile
grimord Jul 6, 2021
d1cd8cd
fix env file
grimord Jul 6, 2021
481a15c
revert back PR pipeline
grimord Jul 6, 2021
3ccb257
revert .env local port map
grimord Jul 6, 2021
eef82b9
Rebase from master
rjcanto Jun 27, 2021
902a24a
Setting the structure for EvaluationsJob
rjcanto Jun 26, 2021
74f1a7c
Controller and JobEngine updated for Evaluations Job
rjcanto Jun 27, 2021
62e70ae
Business Object Creation
rjcanto Jun 27, 2021
2c249f3
Correction to Business Object generation for Academic Calendar genera…
rjcanto Jun 27, 2021
1fe0de4
First version of the Evaluations Business Objects tests. The creation…
rjcanto Jul 3, 2021
d910573
Changed Programme to Model.Common package.
rjcanto Jul 3, 2021
5a87ea8
Parser for Evaluation Date and Time done in DateUtils with getEvaluat…
rjcanto Jul 5, 2021
378e4e7
First version of exam list builder with unitary tests.
rjcanto Jul 6, 2021
59c7ef7
Added condition on the Evaluation Job to not delete the test pdf file…
rjcanto Jul 6, 2021
7f229f0
Build of CalendarTerm and retrieval of calendar Term
rjcanto Jul 6, 2021
9c15c5a
rebase on top of master
grimord Jul 6, 2021
952871b
add timeout to Downloader
grimord Jul 6, 2021
1c101aa
add timeout to Downloader
grimord Jul 6, 2021
409b8ed
add timeout to Downloader
grimord Jul 6, 2021
dd6d273
Creation of DTOs and respective tests.
rjcanto Jul 8, 2021
f658e6f
Completion of DTO tests and removal of any substring with hyphen in t…
rjcanto Jul 8, 2021
6f9e719
Improvement on calls to trimCourse.
rjcanto Jul 9, 2021
10d0549
Improvement on calls to trimCourse.
rjcanto Jul 9, 2021
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
35 changes: 32 additions & 3 deletions .github/workflows/IOnIntegration_Production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,47 @@ name: I-On Integration Production

on:
push:
branches: ['master']
tags:
- v*
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
push_production:
runs-on: ubuntu-latest
if: github.event_name == 'push' && contains(github.ref, 'tags')
permissions:
contents: read
packages: write

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Build image
id: production_build_image
run: ./gradlew buildDockerImage
- name: Login to Container Registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v3
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha

- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
4 changes: 2 additions & 2 deletions .github/workflows/IOnIntegration_Staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
heroku_app_name: ${{secrets.HEROKU_APP_NAME}}
heroku_email: ${{secrets.HEROKU_EMAIL}}
usedocker: true
docker_heroku_process_type: worker
docker_heroku_process_type: web
- run: |
echo "::add-mask::$HD_SQL_HOST"
echo "::add-mask::$HD_SQL_USER"
Expand All @@ -72,4 +72,4 @@ jobs:
if: ${{ env.ACT }}
run: |
echo GIT_SERVER_ADDRESS=$GIT_SERVER_ADDRESS
echo GIT_BRANCH=$GIT_BRANCH
echo GIT_BRANCH=$GIT_BRANCH
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,5 @@ ARG EXTRACT_DEPENDENCY_PATH=/src/build/dependency
COPY --from=build-env ${EXTRACT_DEPENDENCY_PATH}/BOOT-INF/classes /app
COPY --from=build-env ${EXTRACT_DEPENDENCY_PATH}/BOOT-INF/lib /app/lib

EXPOSE ${SERVER_PORT}

ENTRYPOINT [ "java", "-cp", "app:app/lib/*", "org.ionproject.integration.IOnIntegrationApplicationKt", "-XX:+UseContainerSupport" ]
ENTRYPOINT [ "java", "-cp", "app:app/lib/*", "org.ionproject.integration.IOnIntegrationApplicationKt", "-XX:+UseContainerSupport", "echo --server.port=$PORT" ]
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Academic information such as class schedules or academic calendars is often scat

![I-On Integration Architecture](img/ion_integration_architecture.png)

**I-On Integration** uses *batch processing* techniques to acquire and process all unstructured data and write it to the common **File Repository** (a Git repo whose sole purpose is to host this data).
**I-On Integration** uses *batch processing* techniques to acquire and process all unstructured data and write it to the common **File Repository** (a Git repo whose sole purpose is to host this data). The data is available for anyone that wishes to use this data on their own projects. It is available at [GitHub i-on Integration Data repository](https://github.com/i-on-project/integration-data).

The **Scheduler** component, as the name suggests, is responsible for periodically triggering job executions through Integration's Web API (not yet available).

Expand Down Expand Up @@ -62,10 +62,6 @@ By **default** the app containers will be accessible via the following ports:

If you wish to change these values please refer to the [Customizing Containers](#customizing-containers) section.

On Windows 10 you may see a **warning** about poor performance due to filesharing to a WSL container. This is due to the fact that we make use of [Docker Bind Mounts](https://docs.docker.com/storage/bind-mounts/) to share the necessary server files.

![Warning](img/bindmountwarning.jpg)

#### Using the containerized database
While the Integration app will be able to connect to the database out of the box without any human intervention you might also be interested in connecting directly to run your own queries.

Expand All @@ -89,6 +85,8 @@ The Git server currently deployed for local development is based on the [GitBuck

It's Web front-end can be accessed by pointing your browser to `localhost:8080` (default port, see the [Customizing Containers section](#customizing-containers) if you need to use a different port value).

On startup a repository named **"integration-data"** is created and initialized to mirror the existing production repository.

##### Git Credentials
The server is deployed with a single **account** that can be accessed by entering `root` for both username and password fields.

Expand Down
18 changes: 13 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ services:
- GIT_USER=${GIT_USER}
- GIT_PASSWORD=${GIT_PASSWORD}
- GIT_BRANCH=${GIT_BRANCH}
- SERVER_PORT=${SERVER_PORT}
- PORT=${SERVER_PORT}
volumes:
- db-data:/var/lib/postgresql/data
ports:
- "${SERVER_PORT}:${SERVER_PORT}"
depends_on:
ion-db:
condition: service_started
git-server:
condition: service_healthy
git-setup:
condition: service_started
ion-db:
image: postgres:13.2-alpine
ports:
Expand All @@ -38,11 +38,19 @@ services:
ports:
- "${GIT_PORT}:8080"
volumes:
- "./git-server:/gitbucket"
- git-data:/gitbucket
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:${GIT_PORT}" ]
interval: 30s
timeout: 10s
retries: 5
git-setup:
image: gitbucket/gitbucket:4.35.3
depends_on:
git-server:
condition: service_healthy
restart: "no"
entrypoint: [ "curl", "-X", "POST", "-u", "root:root", "git-server:${GIT_PORT}/api/v3/user/repos", "-d", "{\"name\":\"integration-data\", \"auto_init\": true}" ]
volumes:
db-data:
db-data:
git-data:
3 changes: 3 additions & 0 deletions docs/infrastructure/ArgumentException.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This **error** will occur in Integration's Web API associated with the status code [400: Bad Request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) and signals that either an expected argument is missing or incorrect.

The response body will be in the `application/json+problem` mediatype and its `detail` field will include more context-specific information about the error cause.
3 changes: 3 additions & 0 deletions docs/infrastructure/JobNotFoundException.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This **error** will occur in Integration's Web API associated with the status code [404: Not Found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404) and indicates that the request Job ID does not exist.

The response body will be in the `application/json+problem` mediatype and its `detail` field will include the given Job ID. The `instance` field will contain the requested path.
Binary file removed git-server/data.mv.db
Binary file not shown.
10 changes: 0 additions & 10 deletions git-server/database.conf

This file was deleted.

1 change: 0 additions & 1 deletion git-server/repositories/root/integration-data.git/HEAD

This file was deleted.

7 changes: 0 additions & 7 deletions git-server/repositories/root/integration-data.git/config

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

Binary file removed img/bindmountwarning.jpg
Binary file not shown.
Binary file modified img/ion_integration_architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package org.ionproject.integration.application
import org.ionproject.integration.application.config.AppProperties
import org.ionproject.integration.application.config.LAUNCHER_NAME
import org.ionproject.integration.application.job.CALENDAR_JOB_NAME
import org.ionproject.integration.infrastructure.file.OutputFormat
import org.ionproject.integration.domain.common.InstitutionModel
import org.ionproject.integration.domain.common.ProgrammeModel
import org.ionproject.integration.infrastructure.repository.IIntegrationJobRepository
import org.ionproject.integration.application.job.EVALUATIONS_JOB_NAME
import org.ionproject.integration.application.job.JobType
import org.ionproject.integration.application.job.TIMETABLE_JOB_NAME
import org.ionproject.integration.domain.common.InstitutionModel
import org.ionproject.integration.domain.common.ProgrammeModel
import org.ionproject.integration.infrastructure.exception.JobNotFoundException
import org.ionproject.integration.infrastructure.file.OutputFormat
import org.ionproject.integration.infrastructure.repository.IIntegrationJobRepository
import org.slf4j.LoggerFactory
import org.springframework.batch.core.Job
import org.springframework.batch.core.JobParameters
Expand Down Expand Up @@ -49,6 +50,7 @@ class JobEngine(
fun runJob(request: AbstractJobRequest): JobStatus {
return when (request) {
is TimetableJobRequest -> runTimetableJob(request)
is EvaluationsJobRequest -> runEvaluationsJob(request)
is CalendarJobRequest -> runCalendarJob(request)
}
}
Expand All @@ -62,6 +64,11 @@ class JobEngine(
return runJob(TIMETABLE_JOB_NAME, jobParams)
}

private fun runEvaluationsJob(request: EvaluationsJobRequest): JobStatus {
val jobParams = getJobParameters(request, EVALUATIONS_JOB_NAME)
return runJob(EVALUATIONS_JOB_NAME, jobParams)
}

private fun runCalendarJob(request: CalendarJobRequest): JobStatus {
val jobParams = getJobParameters(request, CALENDAR_JOB_NAME)
return runJob(CALENDAR_JOB_NAME, jobParams)
Expand All @@ -72,7 +79,11 @@ class JobEngine(

val uri = when (request) {
is TimetableJobRequest ->
request.programme.timetableUri.also {
request.programme.resources.timetableUri.also {
parametersBuilder.addString(PROGRAMME_PARAMETER, request.programme.acronym)
}
is EvaluationsJobRequest ->
request.programme.resources.evaluationsUri.also {
parametersBuilder.addString(PROGRAMME_PARAMETER, request.programme.acronym)
}
is CalendarJobRequest -> request.institution.academicCalendarUri
Expand Down Expand Up @@ -154,6 +165,30 @@ class JobEngine(
}
}

class EvaluationsJobRequest(
format: OutputFormat,
institution: InstitutionModel,
val programme: ProgrammeModel
) : AbstractJobRequest(format, institution, JobType.EXAM_SCHEDULE) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
if (!super.equals(other)) return false

other as EvaluationsJobRequest

if (programme != other.programme) return false

return true
}

override fun hashCode(): Int {
var result = super.hashCode()
result = 31 * result + programme.hashCode()
return result
}
}

data class IntegrationJob(
val type: JobType,
val status: JobStatus,
Expand All @@ -162,7 +197,8 @@ class JobEngine(

data class IntegrationJobParameters(
val creationDate: LocalDateTime,
val startDate: LocalDateTime,
val startDate: LocalDateTime? = null,
val endDate: LocalDateTime? = null,
val format: OutputFormat,
val institution: InstitutionModel,
val programme: ProgrammeModel? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.ionproject.integration.application.dto

import org.ionproject.integration.domain.calendar.AcademicCalendarDto
import org.ionproject.integration.domain.common.Term
import org.ionproject.integration.domain.evaluations.EvaluationsDto
import org.ionproject.integration.domain.timetable.dto.TimetableDto
import org.ionproject.integration.infrastructure.file.Filepath
import org.ionproject.integration.domain.calendar.AcademicCalendarDto

/**
* ParsedData will be used to "transport" the final data along with the required metadata.
Expand Down Expand Up @@ -74,4 +76,54 @@ data class AcademicCalendarData(

return staging + segments
}

data class EvaluationsData(
val programme: ProgrammeMetadata,
val term: CalendarTerm,
private val dto: EvaluationsDto
) : ParsedData(dto) {
companion object Factory {
private const val ACADEMIC_YEAR_LENGTH = 9
private const val ACADEMIC_YEARS_FOLDER_NAME = "academic_years"

fun from(evaluationsDto: EvaluationsDto, identifier: String): EvaluationsData =
EvaluationsData(
ProgrammeMetadata(
InstitutionMetadata(
evaluationsDto.school.name,
evaluationsDto.school.acr,
identifier
),
evaluationsDto.programme.name,
evaluationsDto.programme.acr
),
CalendarTerm(
evaluationsDto.calendarTerm.take(4).toInt(),
when (evaluationsDto.calendarTerm.takeLast(1).toInt()) {
1 -> Term.FALL
2 -> Term.SPRING
else -> throw IllegalArgumentException("Invalid Term ${evaluationsDto.calendarTerm}")
}
),
evaluationsDto
)
}

private val PROGRAMMES = "programmes"

override val identifier: String
get() = "${javaClass.simpleName}:${programme.acronym}:$term"

override fun getDirectory(repositoryName: String, staging: Filepath): Filepath {
val segments = listOf(
repositoryName,
programme.institution.domain,
PROGRAMMES,
programme.acronym,
term.toString()
)

return staging + segments
}
}
}
Loading