@Override public Mono processLaunchRequest(LaunchJwt launchJwt, String organizationId) { return provisionLaunchUsers(launchJwt, organizationId) .flatMap(provisioningPojo -> getNamesRolesAndContext(launchJwt) .map(namesRoleResponse -> Tuples.of(namesRoleResponse, provisioningPojo))) .flatMap(tuple -> processContextFromNamesRolesResponse(tuple.getT1().getContext(), tuple.getT2()) .map(provisioningPojo -> Tuples.of(tuple.getT1(), provisioningPojo))) .flatMap(tuple -> this.provisionClass(tuple.getT1().getMembers(), tuple.getT2())); } /** * Gets the names roles and context. * * @param launchJwt the launch jwt * @return the names roles and context */ private Mono getNamesRolesAndContext(LaunchJwt launchJwt) { NamesRoleService namesRoleService = launchJwt.getNamesRoleService(); if(Objects.nonNull(namesRoleService) && StringUtils.isNotBlank(namesRoleService.getContextMembershipsUrl())) { String contextUrl = namesRoleService.getContextMembershipsUrl(); return configurationClient.getPlatformAccessToken(constructAuthInfo(launchJwt)) .flatMap(oAuth2AccessToken -> namesAndRolesClient.getNamesAndRolesInfo(contextUrl, oAuth2AccessToken.getValue())); } else if (Objects.nonNull(launchJwt.getContext())) { NamesRoleResponse namesRoleResponse = new NamesRoleResponse(); namesRoleResponse.setMembers(new ArrayList()); namesRoleResponse.setContext(constructCourseContext(launchJwt)); return Mono.just(namesRoleResponse); } return Mono.empty(); } private Mono processContextFromNamesRolesResponse(CourseContext namesRoleCourseContext, ProvisioningPojo provisioningPojo) { LOGGER.debug("processing context from names and roles API"); Roster roster = constructRosterPojo(namesRoleCourseContext, provisioningPojo.getOrganizationId()); provisioningPojo.setRoster(roster); return Mono.just(provisioningPojo); } private Mono provisionClass(List namesRoleMembers, ProvisioningPojo provisioningPojo) { return this.checkIfClassExists(provisioningPojo) .flatMap(isClassPresent -> { if (isClassPresent) { return Mono.just(provisioningPojo); } else { return processMembersFromNamesRolesResponse(namesRoleMembers, provisioningPojo) .flatMap(this::createClassAndMapping); } }); } private Mono checkIfClassExists(ProvisioningPojo provisioningPojo) { Mono cmsClassIdMono = emsClassMappingClient.classExistsForExternalClassId(provisioningPojo.getRoster().getExternalClassId()) .map(ExternalClassMappingData::getData) .map(map -> map.entrySet().stream()) .map(Stream::findFirst) .map(Optional::get) .map(Entry::getValue) .map(ExternalClassMapping::getClassId); return cmsClassIdMono .flatMap(rosterServiceClient::getClassBySectionId) .map(CMSClass::getData) .map(ClassData::getSection) .map(Section::getId) .flatMap(cmsClassId -> { provisioningPojo.getRoster().setToolSectionId(cmsClassId); return Mono.just(Boolean.TRUE); }) .switchIfEmpty(Mono.defer(() -> Mono.just(Boolean.FALSE))); } private Mono processMembersFromNamesRolesResponse(List namesRoleMembers, ProvisioningPojo provisioningPojo) { LOGGER.debug("provisioning additional Teacher users from names and roles API "); Optional instructor = namesRoleMembers.stream() .filter(member -> RumbaRole.T.name() .equalsIgnoreCase(classProvisoningHelper.obtainRumbaRoleFromLTIRoles(member.getRoles()))) .findFirst(); if(provisioningPojo.getRole().equals(RumbaRole.S.name()) && instructor.isPresent()) { MemberData memberData = constructMemberData(instructor.get(), provisioningPojo); return provisioningService.enableUserProvisioning(memberData) .map(rumbaTeacherId -> { RosterMember rosterMember = new RosterMember(); rosterMember.setUserId(instructor.get().getUserId()); rosterMember.setRole(memberData.getRole()); rosterMember.setExternalUserId(memberData.getExternalUserId()); rosterMember.setToolUserId(rumbaTeacherId); provisioningPojo.getMembers().add(rosterMember); LOGGER.debug("provisioningPojo : {}", provisioningPojo); return provisioningPojo; }); } return Mono.just(provisioningPojo); }