Skip to content
This repository was archived by the owner on Oct 26, 2022. It is now read-only.

Implemented Moodle-REST connector #1

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
15 changes: 11 additions & 4 deletions connector-service/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
plugins {
id "org.sonarqube" version "2.1-rc1"
}

apply plugin: 'eclipse-wtp'
apply plugin: 'war'
apply plugin: 'jacoco'
apply plugin: 'sonar-runner'


jar {
manifest {
Expand All @@ -10,6 +14,7 @@ jar {
}

repositories {
jcenter()
mavenCentral()
mavenLocal()
}
Expand All @@ -33,6 +38,7 @@ dependencies {
compile group: 'org.apache.openjpa', name: 'openjpa', version: '2.3.0'
compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.10'
compile group: 'org.json', name: 'json', version: '20141113'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind',version: '2.0.1'

providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'

Expand All @@ -43,8 +49,8 @@ dependencies {

test { systemProperties 'property': 'value' }

sonarRunner {
sonarProperties {
sonarqube {
properties {
property "sonar.jacoco.reportPath", "$buildDir/jacoco/test.exec"
property "sonar.host.url", project.hasProperty('sonarServerUrl') ? sonarServerUrl : ''
property "sonar.jdbc.url", project.hasProperty('sonarDatabaseUrl') ? sonarDatabaseUrl : ''
Expand All @@ -54,4 +60,5 @@ sonarRunner {
}
}

tasks.compileJava.dependsOn(':connector-model:xjc')

tasks.compileJava.dependsOn(':connector-model:xjc')
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package de.thm.arsnova.connector.dao;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;

import de.thm.arsnova.connector.model.Course;
import de.thm.arsnova.connector.model.Membership;
import de.thm.arsnova.connector.model.UserRole;
import de.thm.arsnova.connector.model.moodle_rest.MoodleCourse;

public class MoodleRestConnectorDaoImpl implements ConnectorDao{

private static final String TYPE = "moodle";
private static final int MOODLE_COURSE_EDITINGTEACHER = 3;
private static final int MOODLE_COURSE_TEACHER = 4;
private static final int MOODLE_COURSE_MEMBER = 5;

private static String ENCODING="UTF-8";

@Value("${lms.http.token}") private String token ;
@Value("${lms.http.serverUrl}") private String domainName;

private static String getCourseUserURL;
private static String getMembersCoursesURL;
private static String getMembershipURL;

private final RestTemplate restTemplate = new RestTemplate();

@PostConstruct
public void initialize() {
getCourseUserURL = domainName + "/webservice/rest/server.php?wstoken=" + token + "&wsfunction=local_arsnova_connector_get_course_users&moodlewsrestformat=json";
getMembersCoursesURL = domainName + "/webservice/rest/server.php?wstoken=" + token + "&wsfunction=local_arsnova_connector_get_users_courses&moodlewsrestformat=json";
getMembershipURL = domainName + "/webservice/rest/server.php?wstoken=" + token + "&wsfunction=local_arsnova_connector_get_user_role_in_course&moodlewsrestformat=json";
}

/**
* It seems that this function is never used anywhere, therefore it isn't tested
*/
@Override
public List<String> getCourseUsers(String courseid) {
final List<String> result = new ArrayList<String>();
ResponseEntity<String> userWrapper=null;
try {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("courseid", URLEncoder.encode(courseid, ENCODING));
userWrapper=restTemplate.postForEntity(getCourseUserURL, map, String.class);
String[] users= new ObjectMapper().readValue(userWrapper.getBody(), String[].class);
for(String s : users)
{
result.add(s);
}
} catch (Exception e) {
System.out.println(userWrapper.getBody());
e.printStackTrace();
}

return result;
}

@Override
public List<Course> getMembersCourses(String username) {
List<Course> result = new ArrayList<Course>();
ResponseEntity<String> userWrapper=null;
try {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", URLEncoder.encode(username, ENCODING));
userWrapper=restTemplate.postForEntity(getMembersCoursesURL, map, String.class);
MoodleCourse[] courses=new ObjectMapper().readValue(userWrapper.getBody(), MoodleCourse[].class);
for(MoodleCourse mc : courses)
{
result.add(buildCourse(mc, getMembership(username, mc.getId())));
}
} catch (Exception e) {
System.out.println(userWrapper.getBody());
e.printStackTrace();
}

return result;
}

@Override
public Membership getMembership(String username, String courseid) {
Membership ms=new Membership();
ResponseEntity<String> userWrapper=null;
try {
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", URLEncoder.encode(username, ENCODING));
map.add("courseid", URLEncoder.encode(courseid, ENCODING));
userWrapper=restTemplate.postForEntity(getMembershipURL, map, String.class);
ms.setUserrole(getMembershipRole(Integer.parseInt(userWrapper.getBody())));
if(ms.getUserrole()!=UserRole.OTHER)
ms.setMember(true);
} catch (Exception e) {
e.printStackTrace();
System.out.println(userWrapper.getBody());
ms.setUserrole(UserRole.OTHER);
}
return ms;
}

//Copied from MoodleConnectorDao
private UserRole getMembershipRole(final int moodleRoleId) {
if (moodleRoleId == MOODLE_COURSE_EDITINGTEACHER || moodleRoleId == MOODLE_COURSE_TEACHER) {
return UserRole.TEACHER;
} else if (moodleRoleId == MOODLE_COURSE_MEMBER) {
return UserRole.MEMBER;
}

// User is course guest
return UserRole.OTHER;
}

private Course buildCourse(MoodleCourse mCourse, Membership membership) {
Course course = new Course();
course.setId(mCourse.getId());
course.setFullname(mCourse.getFullname());
course.setShortname(mCourse.getShortname());
course.setType(TYPE);
course.setMembership(membership);
return course;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package de.thm.arsnova.connector.model.moodle_rest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MoodleCourse {

private String id;
private String shortname;
private String fullname;
private int roleid;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}


public String getShortname() {
return shortname;
}


public void setShortname(String shortname) {
this.shortname = shortname;
}


public String getFullname() {
return fullname;
}


public void setFullname(String fullname) {
this.fullname = fullname;
}

public int getRoleid() {
return roleid;
}

public void setRoleid(int roleid) {
this.roleid = roleid;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package de.thm.arsnova.connector.model.moodle_rest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MoodleUser {

private int id;
private String username;
private Role[] roles;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public Role[] getRoles() {
return roles;
}

public void setRoles(Role[] roles) {
this.roles = roles;
}

public int getFirstMoodleRoleId(){
return getRoles()[0].getRoleid();
}

@JsonIgnoreProperties(ignoreUnknown = true)
private static class Role{

private int roleid;
private String name;

public int getRoleid() {
return roleid;
}
public void setRoleid(int roleid) {
this.roleid = roleid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ jdbc.username=root
jdbc.password=secret

lms.http.serverUrl=https://localhost/lms-api
lms.http.token=abc123
lms.http.username=connector-user
lms.http.password=secret

# Select the data access object implementation your target platform
# Uncomment the following line to access Moodle
dao.implementation=de.thm.arsnova.connector.dao.MoodleConnectorDaoImpl
# dao.implementation=de.thm.arsnova.connector.dao.MoodleConnectorDaoImpl
# Uncomment the following line to access Moodle via REST
dao.implementation=de.thm.arsnova.connector.dao.MoodleRestConnectorDaoImpl
# Uncomment the following line to access Stud.IP
# dao.implementation=de.thm.arsnova.connector.dao.StudipConnectorDaoImpl
# Uncomment the following line to access Stud.IP via REST
Expand Down