| 1 | package edu.ucsb.cs156.frontiers.services; | |
| 2 | ||
| 3 | import com.fasterxml.jackson.databind.JsonNode; | |
| 4 | import com.fasterxml.jackson.databind.ObjectMapper; | |
| 5 | import edu.ucsb.cs156.frontiers.entities.Course; | |
| 6 | import edu.ucsb.cs156.frontiers.entities.RosterStudent; | |
| 7 | import edu.ucsb.cs156.frontiers.models.CanvasStudent; | |
| 8 | import edu.ucsb.cs156.frontiers.validators.HasLinkedCanvasCourse; | |
| 9 | import java.util.List; | |
| 10 | import org.springframework.graphql.client.HttpSyncGraphQlClient; | |
| 11 | import org.springframework.stereotype.Service; | |
| 12 | import org.springframework.validation.annotation.Validated; | |
| 13 | import org.springframework.web.client.RestClient; | |
| 14 | ||
| 15 | @Service | |
| 16 | @Validated | |
| 17 | public class CanvasService { | |
| 18 | ||
| 19 | private HttpSyncGraphQlClient graphQlClient; | |
| 20 | private ObjectMapper mapper; | |
| 21 | ||
| 22 | private static final String CANVAS_GRAPHQL_URL = "https://ucsb.instructure.com/api/graphql"; | |
| 23 | ||
| 24 | public CanvasService(ObjectMapper mapper, RestClient.Builder builder) { | |
| 25 | this.graphQlClient = | |
| 26 | HttpSyncGraphQlClient.builder(builder.baseUrl(CANVAS_GRAPHQL_URL).build()).build(); | |
| 27 | this.mapper = mapper; | |
| 28 | } | |
| 29 | ||
| 30 | /** | |
| 31 | * Fetches the roster of students from Canvas for the given course. | |
| 32 | * | |
| 33 | * @param course the Course entity containing canvasApiToken and canvasCourseId | |
| 34 | * @return list of RosterStudent objects from Canvas | |
| 35 | */ | |
| 36 | public List<RosterStudent> getCanvasRoster(@HasLinkedCanvasCourse Course course) { | |
| 37 | String query = | |
| 38 | """ | |
| 39 | query GetRoster($courseId: ID!) { | |
| 40 | course(id: $courseId) { | |
| 41 | usersConnection(filter: {enrollmentTypes: StudentEnrollment}) { | |
| 42 | edges { | |
| 43 | node { | |
| 44 | firstName | |
| 45 | lastName | |
| 46 | sisId | |
| 47 | email | |
| 48 | integrationId | |
| 49 | } | |
| 50 | } | |
| 51 | } | |
| 52 | } | |
| 53 | } | |
| 54 | """; | |
| 55 | ||
| 56 | HttpSyncGraphQlClient authedClient = | |
| 57 | graphQlClient | |
| 58 | .mutate() | |
| 59 | .header("Authorization", "Bearer " + course.getCanvasApiToken()) | |
| 60 | .build(); | |
| 61 | ||
| 62 | List<CanvasStudent> students = | |
| 63 | authedClient | |
| 64 | .document(query) | |
| 65 | .variable("courseId", course.getCanvasCourseId()) | |
| 66 | .retrieveSync("course.usersConnection.edges") | |
| 67 | .toEntityList(JsonNode.class) | |
| 68 | .stream() | |
| 69 |
1
1. lambda$getCanvasRoster$0 : replaced return value with null for edu/ucsb/cs156/frontiers/services/CanvasService::lambda$getCanvasRoster$0 → KILLED |
.map(node -> mapper.convertValue(node.get("node"), CanvasStudent.class)) |
| 70 | .toList(); | |
| 71 | ||
| 72 |
1
1. getCanvasRoster : replaced return value with Collections.emptyList for edu/ucsb/cs156/frontiers/services/CanvasService::getCanvasRoster → KILLED |
return students.stream() |
| 73 | .map( | |
| 74 | student -> | |
| 75 |
1
1. lambda$getCanvasRoster$1 : replaced return value with null for edu/ucsb/cs156/frontiers/services/CanvasService::lambda$getCanvasRoster$1 → KILLED |
RosterStudent.builder() |
| 76 | .firstName(student.getFirstName()) | |
| 77 | .lastName(student.getLastName()) | |
| 78 | .studentId(student.getStudentId()) | |
| 79 | .email(student.getEmail()) | |
| 80 | .build()) | |
| 81 | .toList(); | |
| 82 | } | |
| 83 | } | |
Mutations | ||
| 69 |
1.1 |
|
| 72 |
1.1 |
|
| 75 |
1.1 |