Refactoring of the lookup/json-mess, this is slightly experimental and the code base is so messy

it will likely end up needing a total re-write at some point.
Note: this currently fails many unit-tests due to some weird stuff in the development branch, needs to be fixed.
This commit is contained in:
Robin Eklund 2011-08-05 16:58:47 +02:00
parent e9273a97eb
commit d15f25e509
22 changed files with 142 additions and 134 deletions

@ -22,6 +22,8 @@ import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.UserSettings; import se.su.dsv.scipro.data.dataobjects.UserSettings;
import se.su.dsv.scipro.json.IUserLookupFromUsername; import se.su.dsv.scipro.json.IUserLookupFromUsername;
import se.su.dsv.scipro.json.RemoteLookupOptions;
import se.su.dsv.scipro.json.RemoteLookupOptions.LOOKUP_DEPTH;
import se.su.dsv.scipro.security.auth.Authenticator; import se.su.dsv.scipro.security.auth.Authenticator;
import se.su.dsv.scipro.security.auth.roles.Admin; import se.su.dsv.scipro.security.auth.roles.Admin;
import se.su.dsv.scipro.security.auth.roles.DefaultRole; import se.su.dsv.scipro.security.auth.roles.DefaultRole;
@ -191,7 +193,6 @@ public class SciProSession extends WebSession {
// With this userSettings.created() will return a users first login date and userSettings.modified() will return last login // With this userSettings.created() will return a users first login date and userSettings.modified() will return last login
userSettings.setLastModified(new Date()); userSettings.setLastModified(new Date());
userSettings = userSettingsDao.save(userSettings); userSettings = userSettingsDao.save(userSettings);
logger.info("User: "+getLoggedInIdentity()+ " logged in to "+this.getApplication().getClass().getSimpleName()+ logger.info("User: "+getLoggedInIdentity()+ " logged in to "+this.getApplication().getClass().getSimpleName()+
" as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames()+ " at: "+new Date()); " as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames()+ " at: "+new Date());
loggedIn = true; loggedIn = true;
@ -265,7 +266,7 @@ public class SciProSession extends WebSession {
return false; return false;
} }
private User doUserLookup(final String username, final String realm) { private User doUserLookup(final String username, final String realm) {
final User u = userLookupFromUsername.lookup(new KeyValuePair<String>(username,realm)); final User u = userLookupFromUsername.lookup(new KeyValuePair<String>(username,realm), new RemoteLookupOptions(LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS));
if(u == null) if(u == null)
logger.warn(username + " authenticated successfully, but the user was not available from remote system."); logger.warn(username + " authenticated successfully, but the user was not available from remote system.");
return u; return u;

@ -22,6 +22,8 @@ public interface Dao<T extends DomainObject>
public T reLoad(T object); public T reLoad(T object);
public void refresh(T object);
public List<T> findAll(int first, int count); public List<T> findAll(int first, int count);
public List<T> findAll(int first, int count, String orderBy); public List<T> findAll(int first, int count, String orderBy);

@ -56,6 +56,11 @@ public abstract class AbstractDaoJPAImp<T extends DomainObject> extends JpaDaoSu
else else
return null; return null;
} }
@Transactional(readOnly=true)
public void refresh(T object){
if(object != null)
getJpaTemplate().refresh(object);
}
@Transactional( readOnly=false ) @Transactional( readOnly=false )
public T save(T object){ public T save(T object){

@ -8,7 +8,6 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
@ -102,6 +101,9 @@ public class User extends LazyDeletableDomainObject implements Comparable<User>,
return emailAddress; return emailAddress;
} }
public void addUserName(Username username){
this.usernames.add(username);
}
public void setUserNames(Set<Username> usernames) { public void setUserNames(Set<Username> usernames) {
this.usernames = usernames; this.usernames = usernames;

@ -73,6 +73,8 @@ public class Username extends DomainObject {
public void setUser(User user) { public void setUser(User user) {
this.user = user; this.user = user;
if(user!=null)
user.addUserName(this);
} }
@Override @Override

@ -16,13 +16,12 @@ abstract class DefaultUserLookupBase{
@Autowired @Autowired
protected UserDao userDao; protected UserDao userDao;
@Autowired @Autowired
protected JsonUserResponseHandler userResponseHandler; private JsonUserResponseHandler userResponseHandler;
@Autowired @Autowired
protected ApplicationSettings settings; private ApplicationSettings settings;
protected boolean doRemoteRequest(final Map<String,String> params){ protected boolean doRemoteRequest(final Map<String,String> params, final RemoteLookupOptions options){
userResponseHandler.setLogResult(true); RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, options, RequestSender.REQUEST_TYPE.POST);
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (final IOException e){ } catch (final IOException e){

@ -7,6 +7,7 @@ import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.json.RemoteLookupOptions.LOOKUP_DEPTH;
/** /**
* Default implementation of IUserLookupFromIdentifier queries remote defined by ApplicationSettings via JSon requests. * Default implementation of IUserLookupFromIdentifier queries remote defined by ApplicationSettings via JSon requests.
@ -15,18 +16,20 @@ import se.su.dsv.scipro.data.dataobjects.User;
public class DefaultUserLookupFromIdentifier extends DefaultUserLookupBase implements IUserLookupFromIdentifier { public class DefaultUserLookupFromIdentifier extends DefaultUserLookupBase implements IUserLookupFromIdentifier {
private Logger logger = Logger.getLogger(DefaultUserLookupFromIdentifier.class); private Logger logger = Logger.getLogger(DefaultUserLookupFromIdentifier.class);
public User lookup(final Long identifier){ public User lookup(final Long identifier, final RemoteLookupOptions options){
if(identifier == null){ if(identifier == null){
throw new IllegalStateException("null values for user parameter not allowed"); throw new IllegalStateException("null values for user parameter not allowed");
} }
logger.debug("Starting remote lookup for: " + identifier); logger.debug("Starting remote lookup for: " + identifier);
final Map<String, String> params = new HashMap<String, String>(); final Map<String, String> params = new HashMap<String, String>();
params.put("userid", identifier.toString()); params.put("userid", identifier.toString());
if(!doRemoteRequest(params)) if(!doRemoteRequest(params,options)){
logger.warn("Remote lookup failed for identifier: "+identifier);
return null; return null;
}
final User u = userDao.getUserByIdentifier(identifier); final User u = userDao.getUserByIdentifier(identifier);
if(u != null) if(u != null)
logger.info("Successfully imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+identifier+") id: " + u.getId()); logger.info("Successfully imported user/username from remote system: " + u.getId() + " " +u.getUserNames());
else else
logger.warn("Failed to import a valid user from remote system: "+identifier); logger.warn("Failed to import a valid user from remote system: "+identifier);
return u; return u;

@ -16,7 +16,7 @@ import se.su.dsv.scipro.util.KeyValuePair;
public class DefaultUserLookupFromUsername extends DefaultUserLookupBase implements IUserLookupFromUsername { public class DefaultUserLookupFromUsername extends DefaultUserLookupBase implements IUserLookupFromUsername {
private Logger logger = Logger.getLogger(DefaultUserLookupFromUsername.class); private Logger logger = Logger.getLogger(DefaultUserLookupFromUsername.class);
public User lookup(final KeyValuePair<String> userAtRealm){ public User lookup(final KeyValuePair<String> userAtRealm, final RemoteLookupOptions options){
if(userAtRealm == null || userAtRealm.getKey() == null){ if(userAtRealm == null || userAtRealm.getKey() == null){
throw new IllegalStateException("null values for user parameter not allowed"); throw new IllegalStateException("null values for user parameter not allowed");
} }
@ -26,11 +26,11 @@ public class DefaultUserLookupFromUsername extends DefaultUserLookupBase impleme
final Map<String, String> params = new HashMap<String, String>(); final Map<String, String> params = new HashMap<String, String>();
params.put("username", user); params.put("username", user);
params.put("realm", realm); params.put("realm", realm);
if(!doRemoteRequest(params)) if(!doRemoteRequest(params,options))
return null; return null;
final User u = userDao.getUserByUsername(user,realm); final User u = userDao.getUserByUsername(user,realm);
if(u != null) if(u != null)
logger.info("Successfully imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+user+"@"+realm+") id: " + u.getId()); logger.info("Successfully imported user/username from remote system: " + user+"@"+realm+ " (id: " + u.getId()+") "+u.getUserNames());
else else
logger.warn("Failed to import a valid user from remote system: "+userAtRealm); logger.warn("Failed to import a valid user from remote system: "+userAtRealm);
return u; return u;

@ -8,6 +8,6 @@ package se.su.dsv.scipro.json;
* @param <E> The lookup parameter, use compound types to support querying on multiple parameters. * @param <E> The lookup parameter, use compound types to support querying on multiple parameters.
*/ */
public interface ILookup<T, E> { public interface ILookup<T, E> {
public T lookup(E lookupParam); public T lookup(final E lookupParam, final RemoteLookupOptions options);
} }

@ -4,5 +4,5 @@ package se.su.dsv.scipro.json;
* Interface for delegated callback handling of response-strings. * Interface for delegated callback handling of response-strings.
*/ */
public interface IResponseHandler { public interface IResponseHandler {
public void handleResponse(String response); public void handleResponse(final String response,final RemoteLookupOptions options);
} }

@ -7,5 +7,5 @@ import se.su.dsv.scipro.data.dataobjects.User;
* See ILookup for more information on the implicit contract of this interface. * See ILookup for more information on the implicit contract of this interface.
*/ */
public interface IUserLookupFromIdentifier extends ILookup<User,Long>{ public interface IUserLookupFromIdentifier extends ILookup<User,Long>{
public User lookup(final Long identifier); public User lookup(final Long identifier, final RemoteLookupOptions options);
} }

@ -9,5 +9,5 @@ import se.su.dsv.scipro.util.KeyValuePair;
* See ILookup for more information on the implicit contract of this interface. * See ILookup for more information on the implicit contract of this interface.
*/ */
public interface IUserLookupFromUsername extends ILookup<User,KeyValuePair<String>>{ public interface IUserLookupFromUsername extends ILookup<User,KeyValuePair<String>>{
public User lookup(final KeyValuePair<String> userAtRealm); public User lookup(final KeyValuePair<String> userAtRealm, final RemoteLookupOptions options);
} }

@ -27,7 +27,7 @@ public class ImportUpdateStatsResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonUpdateStatsContainer statsContainer = null; JsonUpdateStatsContainer statsContainer = null;
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();

@ -13,10 +13,11 @@ import se.su.dsv.scipro.ApplicationSettings;
/** /**
* This class does a lookup on a username against the remote remoteLookupUrl specified in * This class does a lookup on a username against the remote remoteLookupUrl specified in
* the applicationContext, under ApplicationSettings. * the applicationContext, under ApplicationSettings.
* *
* *
* @author Dan Kjellman <dan-kjel@dsv.su.se> * @author Dan Kjellman <dan-kjel@dsv.su.se>
*/ */
//TODO Make sure this worker successfully fails when it should
@Component @Component
public class ImportWorkerLookup { public class ImportWorkerLookup {
public static final String USERS = "users"; public static final String USERS = "users";
@ -52,7 +53,7 @@ public class ImportWorkerLookup {
}else{ }else{
//logger.log(Level.INFO,"Starting lookup for completeGet=true & type="+type+" & updatedAfter=" + updatedAfter); //logger.log(Level.INFO,"Starting lookup for completeGet=true & type="+type+" & updatedAfter=" + updatedAfter);
} }
RequestSender request = new RequestSender(importWorkerResponseHandler, applicationSettings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST); RequestSender request = new RequestSender(importWorkerResponseHandler, applicationSettings.getRemoteLookupUrl(), params, new RemoteLookupOptions(), RequestSender.REQUEST_TYPE.POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (IOException e) { } catch (IOException e) {
@ -66,7 +67,7 @@ public class ImportWorkerLookup {
params.put("updateStats", "true"); params.put("updateStats", "true");
params.put("updatedAfter",""+updatedAfter.getTime()); params.put("updatedAfter",""+updatedAfter.getTime());
RequestSender request = new RequestSender(importUpdateStatsResponseHandler, applicationSettings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST); RequestSender request = new RequestSender(importUpdateStatsResponseHandler, applicationSettings.getRemoteLookupUrl(), params, new RemoteLookupOptions(), RequestSender.REQUEST_TYPE.POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (IOException e) { } catch (IOException e) {

@ -34,7 +34,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonCompleteGetContainer completeContainer = null; JsonCompleteGetContainer completeContainer = null;
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();
@ -101,7 +101,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
if(user == null){ if(user == null){
createThesisUser(jsonUser, false); createThesisUser(jsonUser, new RemoteLookupOptions());
}else{ }else{
lookForChangesInUserAndSave(jsonUser); lookForChangesInUserAndSave(jsonUser);
} }
@ -112,7 +112,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
if(project == null){ if(project == null){
//System.out.println("User does not exist... trying to create"); //System.out.println("User does not exist... trying to create");
if(null == checkAndCreateProject(jsonThesis)){ if(null == checkAndCreateProject(jsonThesis,options)){
thesesCreationsErrors++; thesesCreationsErrors++;
} else { } else {
thesesCreations++; thesesCreations++;

@ -1,13 +1,16 @@
package se.su.dsv.scipro.json; package se.su.dsv.scipro.json;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.ApplicationSettings; import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
@ -31,7 +34,7 @@ import se.su.dsv.scipro.jsonobjects.JsonUser;
import se.su.dsv.scipro.jsonobjects.JsonUserRole; import se.su.dsv.scipro.jsonobjects.JsonUserRole;
import se.su.dsv.scipro.jsonobjects.JsonUsername; import se.su.dsv.scipro.jsonobjects.JsonUsername;
/** /**
* Package-private sase class for JsonResponseHandlers. * Package-private base class for JsonResponseHandlers.
* Contains a number of utility methods to lessen boilerplate code inside implementations. * Contains a number of utility methods to lessen boilerplate code inside implementations.
*/ */
abstract class JsonResponseHandler implements IResponseHandler { abstract class JsonResponseHandler implements IResponseHandler {
@ -67,9 +70,10 @@ abstract class JsonResponseHandler implements IResponseHandler {
/** /**
* Creates and persists a User from a JsonUser * Creates and persists a User from a JsonUser
* @param jsonUser the JsonUser to use for creation * @param jsonUser the JsonUser to use for creation
* @param doFullCheck If true, checkAndCreateProject will be called on each project included in the query response.
* @return The created User or null if it cannot be persisted. * @return The created User or null if it cannot be persisted.
*/ */
protected User createThesisUser(JsonUser jsonUser, boolean doFullCheck){ protected User createThesisUser(final JsonUser jsonUser, final RemoteLookupOptions options){
User user = new User(); User user = new User();
user.setFirstName(jsonUser.firstName); user.setFirstName(jsonUser.firstName);
user.setLastName(jsonUser.lastName); user.setLastName(jsonUser.lastName);
@ -110,18 +114,21 @@ abstract class JsonResponseHandler implements IResponseHandler {
/* /*
* Create any projects of which the user is a member of * Create any projects of which the user is a member of
*/ */
if(doFullCheck){ if(options.getLookupDepth().equals(RemoteLookupOptions.LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS)){
for(JsonThesis jThesis : jsonUser.theses){ for(JsonThesis jThesis : jsonUser.theses){
checkAndCreateProject(jThesis); checkAndCreateProject(jThesis, options);
} }
} }
numUsersCreated++; numUsersCreated++;
return user; return user;
} }
/**
protected Project checkAndCreateProject(JsonThesis jThesis) { * Retrieve a Project matching the given JsonThesis ID, and create a project matching the supplied JsonThesis in full if it does not already exists.
* @param jThesis
* @return The retrieved (or newly created) project.
*/
protected Project checkAndCreateProject(JsonThesis jThesis, final RemoteLookupOptions options) {
Project project = null; Project project = null;
//System.out.println("Creating project:" + jThesis.thesisID);
project = projectDao.getProjectByIdentifier(jThesis.thesisID); project = projectDao.getProjectByIdentifier(jThesis.thesisID);
if(project == null){ if(project == null){
project = new Project(); project = new Project();
@ -139,48 +146,48 @@ abstract class JsonResponseHandler implements IResponseHandler {
if(jThesis.daisyStartDate > 0){ if(jThesis.daisyStartDate > 0){
Date daisyStartDate = new Date(jThesis.daisyStartDate); Date daisyStartDate = new Date(jThesis.daisyStartDate);
project.setDaisyStartDate(daisyStartDate); project.setDaisyStartDate(daisyStartDate);
} }
project = projectDao.save(project); project = projectDao.save(project);
//Synch participants //Synch participants
for(JsonThesisParticipant jtp : jThesis.participants){ if(options.getLookupDepth().equals(RemoteLookupOptions.LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS)){
User u = userDao.getUserByIdentifier(jtp.id); for(JsonThesisParticipant jtp : jThesis.participants){
//Attempt remote lookup if no user is found User u = userDao.getUserByIdentifier(jtp.id);
if(u == null){ //Attempt remote lookup if no user is found
final Long id = Long.valueOf(jtp.id); if(u == null){
if( (u = userLookupFromIdentifier.lookup(id)) == null){ final Long id = Long.valueOf(jtp.id);
throw new RuntimeException("Cannot save jsonuser with jsonuserid: " + jtp.id); if( (u = userLookupFromIdentifier.lookup(id, new RemoteLookupOptions(RemoteLookupOptions.LOOKUP_DEPTH.NONE))) == null){
} logger.warn("Cannot create jsonuser with jsonuserid: " + jtp.id+" while adding participants for the project: "+project.getIdentifier());
} continue;
//Move on }
if(jtp.role.equals("SUPERVISOR")){ }
Employee e = roleDao.makeEmployee(u); //Move on, set participant roles
project.setHeadSupervisor(e); if(jtp.role.equals("SUPERVISOR")){
}else if(jtp.role.equals("PARTICIPANT")){ Employee e = roleDao.makeEmployee(u);
Student s = roleDao.makeStudent(u); project.setHeadSupervisor(e);
project.getProjectParticipants().add(s); }else if(jtp.role.equals("PARTICIPANT")){
} Student s = roleDao.makeStudent(u);
else{ project.getProjectParticipants().add(s);
ProjectFollower pf = new ProjectFollower(); }else{
ProjectFollower pf = new ProjectFollower();
if(jtp.role.equals("ASSISTANT_SUPERVISOR")){ if(jtp.role.equals("ASSISTANT_SUPERVISOR")){
pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR); pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR);
pf.setFollower((Employee)roleDao.makeEmployee(u)); pf.setFollower((Employee)roleDao.makeEmployee(u));
}else if(jtp.role.equals("OPPONENT")){ }else if(jtp.role.equals("OPPONENT")){
//TODO: OPPONENT //TODO: OPPONENT
}else if (jtp.role.equals("EXAMINER")){ }else if (jtp.role.equals("EXAMINER")){
pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER); pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER);
pf.setFollower(roleDao.makeEmployee(u)); pf.setFollower(roleDao.makeEmployee(u));
} }
if(pf.getFollower() != null && pf.getProjectRole() != null){ if(pf.getFollower() != null && pf.getProjectRole() != null){
pf.setProject(project); pf.setProject(project);
pf = projectFollowerDao.save(pf); pf = projectFollowerDao.save(pf);
project.getProjectFollowers().add(pf); project.getProjectFollowers().add(pf);
}
} }
} }
project = projectDao.save(project);
} }
project = projectDao.save(project);
} }
project = projectDao.getProjectByIdentifier(jThesis.thesisID); project = projectDao.getProjectByIdentifier(jThesis.thesisID);
return project; return project;
@ -243,7 +250,7 @@ abstract class JsonResponseHandler implements IResponseHandler {
}else{ }else{
try { try {
checkAndCreateProject(jThesis); checkAndCreateProject(jThesis,new RemoteLookupOptions());
} catch (Exception e) { } catch (Exception e) {
logger.error("Error when creating project: daisyId=" + jThesis.thesisID + "when looking up user:" logger.error("Error when creating project: daisyId=" + jThesis.thesisID + "when looking up user:"
+jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage()); +jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage());
@ -376,9 +383,9 @@ abstract class JsonResponseHandler implements IResponseHandler {
if(u == null){ if(u == null){
final Long id = Long.valueOf(jtp.id); final Long id = Long.valueOf(jtp.id);
try { try {
u = userLookupFromIdentifier.lookup(id); u = userLookupFromIdentifier.lookup(id, new RemoteLookupOptions(RemoteLookupOptions.LOOKUP_DEPTH.NONE));
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed to save changes for project:" + current.getIdentifier() + " when looking up user whith idetifier:"+jtp.id+ logger.error("Failed to save changes for project:" + current.getIdentifier() + " when looking up user with identifier:"+jtp.id+
" Rolling back...\n" + e.getMessage()); " Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -458,7 +465,7 @@ abstract class JsonResponseHandler implements IResponseHandler {
/* /*
* Force subclasses to handle the response * Force subclasses to handle the response
*/ */
public abstract void handleResponse(String response); public abstract void handleResponse(final String response, final RemoteLookupOptions options);
/* /*
* Getters for logging * Getters for logging

@ -32,7 +32,7 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonUserContainer userContainer = null; JsonUserContainer userContainer = null;
try{ try{
@ -52,13 +52,11 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
//Loop all users in the response and look for changes... //Loop all users in the response and look for changes...
for(JsonUser jsonUser : userContainer.users){ for(JsonUser jsonUser : userContainer.users){
System.out.println("Checking: " + " id: " + jsonUser.id + " firstName: "+ jsonUser.firstName); logger.debug("Checking: " + jsonUser);
User thesisUser = userDao.getUserByIdentifier(new Long(jsonUser.id)); User thesisUser = userDao.getUserByIdentifier(new Long(jsonUser.id));
for(JsonUsername jsonUsername : jsonUser.usernames){ for(JsonUsername jsonUsername : jsonUser.usernames){
logger.debug("\t"+jsonUsername.username);
System.out.println(jsonUsername.username);
String usernameString = jsonUsername.username.toLowerCase().trim(); String usernameString = jsonUsername.username.toLowerCase().trim();
String userRealmString = jsonUsername.realm.toUpperCase().trim(); String userRealmString = jsonUsername.realm.toUpperCase().trim();
User potentialDuplicateUser = userDao.getUserByUsername(usernameString, userRealmString); User potentialDuplicateUser = userDao.getUserByUsername(usernameString, userRealmString);
@ -108,7 +106,7 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
if(thesisUser == null){ if(thesisUser == null){
//System.out.println("User does not exist... trying to create"); //System.out.println("User does not exist... trying to create");
if(null == createThesisUser(jsonUser,true)){ if(null == createThesisUser(jsonUser,options)){
userCreationErrors++; userCreationErrors++;
} else { } else {
createdUsers++; createdUsers++;

@ -29,16 +29,16 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonUserContainer userContainer = null; JsonUserContainer userContainer = null;
logger.debug(response); logger.debug(response);
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();
Type type = new TypeToken<JsonUserContainer>(){}.getType(); Type type = new TypeToken<JsonUserContainer>(){}.getType();
userContainer = gson.fromJson(response, type); userContainer = gson.fromJson(response, type);
} catch (Exception e) { } catch (Exception e) {
logger.error("Gson error when creating objects from json \n" + e.getMessage()); logger.error("Gson error when creating objects from json response" + e.getMessage());
logger.error("Full response from remote:" + response);
return; return;
} }
int createdUsers = 0; int createdUsers = 0;
@ -47,12 +47,11 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
//Loop all users in the response and look for changes... //Loop all users in the response and look for changes...
for(JsonUser jsonUser : userContainer.users){ for(JsonUser jsonUser : userContainer.users){
logger.debug("Checking identifier: " + jsonUser.id); logger.debug("Checking " + jsonUser.id);
User thesisUser = userDao.getUserByIdentifier(Long.valueOf(jsonUser.id)); User thesisUser = userDao.getUserByIdentifier(Long.valueOf(jsonUser.id));
if(thesisUser == null){ if(thesisUser == null){
logger.debug("User '"+jsonUser.id+ "' does not exist, trying to create"); logger.debug("User '"+jsonUser.id+ "' does not exist locally, trying to create");
if(null == createThesisUser(jsonUser,false)){ if(null == createThesisUser(jsonUser,options)){
userCreationErrors++; userCreationErrors++;
} else { } else {
createdUsers++; createdUsers++;

@ -0,0 +1,18 @@
package se.su.dsv.scipro.json;
/**
* Bla bla bla
*/
public final class RemoteLookupOptions {
public enum LOOKUP_DEPTH{NONE,PROJECT_AND_PARTICIPANTS};
private final LOOKUP_DEPTH depth;
public RemoteLookupOptions(){
this(LOOKUP_DEPTH.NONE);
}
public RemoteLookupOptions(final LOOKUP_DEPTH depth){
this.depth = depth;
}
public LOOKUP_DEPTH getLookupDepth(){
return depth;
}
}

@ -9,8 +9,6 @@ import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -20,66 +18,40 @@ import org.apache.log4j.Logger;
* @author Dan Kjellman * @author Dan Kjellman
* *
*/ */
public class RequestSender { public final class RequestSender {
public static final int REQUEST_TYPE_POST = 0; public enum REQUEST_TYPE{POST,GET};
public static final int REQUEST_TYPE_GET = 1; private final REQUEST_TYPE requestType;
public static final String[] REQUEST_METHODS = new String[]{ private Logger logger = Logger.getLogger(RequestSender.class);
"POST", "GET"
};
private Logger logger;
/* /*
* The Handler for the response * The Handler for the response
*/ */
protected IResponseHandler responseHandler; private IResponseHandler responseHandler;
/* /*
* The params * The params
*/ */
protected Map<String, String> parameters; private Map<String, String> parameters;
/* /*
* The url to call * The url to call
*/ */
protected String url; private String url;
//Options for performed lookups
private final RemoteLookupOptions remoteLookupOptions;
/* public RequestSender(final IResponseHandler responseHandler, final String url, final Map<String, String> parameters, final RemoteLookupOptions options, final REQUEST_TYPE requestType){
* Type of request, use the static variables REQUEST_TYPE_POST or REQUEST_TYPE_GET
*/
protected int requestType;
public RequestSender(IResponseHandler responseHandler, String url, Map<String, String> parameters, int requestType){
logger = Logger.getLogger(this.getClass());
if(requestType != REQUEST_TYPE_GET && requestType != REQUEST_TYPE_POST){
logger.log(Level.ERROR, "Could not send request, no request type specified");
throw new IllegalArgumentException("Bad request type");
}
if(responseHandler == null){ if(responseHandler == null){
logger.log(Level.ERROR, "Could not send request, no response handler was provided"); logger.log(Level.ERROR, "Could not send request, no response handler was provided");
throw new IllegalArgumentException("You need no provide a handler for the response"); throw new IllegalArgumentException("You need no provide a handler for the response");
} }
remoteLookupOptions = (options==null?new RemoteLookupOptions():options);
this.responseHandler = responseHandler; this.responseHandler = responseHandler;
this.url = url; this.url = url;
this.parameters = parameters; this.parameters = parameters;
this.requestType = requestType; this.requestType = requestType;
} }
public RequestSender(IResponseHandler responseHandler, String url){ public RequestSender(IResponseHandler responseHandler, String url){
this(responseHandler,url,new HashMap<String,String>(),null,REQUEST_TYPE.GET);
if(responseHandler == null){
throw new IllegalArgumentException("You need no provide a handler for the response");
}
this.responseHandler = responseHandler;
this.url = url;
this.parameters = new HashMap<String, String>();
this.requestType = REQUEST_TYPE_GET;
} }
/** /**
@ -100,7 +72,7 @@ public class RequestSender {
count++; count++;
} }
if(requestType == REQUEST_TYPE_GET && parameters.size() > 0){ if(requestType == REQUEST_TYPE.GET && parameters.size() > 0){
url += "?" + parameterData; url += "?" + parameterData;
} }
@ -112,7 +84,7 @@ public class RequestSender {
URL u = new URL(url); URL u = new URL(url);
conn = (HttpURLConnection) u.openConnection(); conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(REQUEST_METHODS[requestType]); conn.setRequestMethod(requestType.name());
/* /*
* Set connect timeout to 60 seconds and read timeout to 120 sec * Set connect timeout to 60 seconds and read timeout to 120 sec
@ -122,7 +94,7 @@ public class RequestSender {
conn.setConnectTimeout(1000 * 60); conn.setConnectTimeout(1000 * 60);
conn.setReadTimeout(1000 * 120); conn.setReadTimeout(1000 * 120);
if(requestType == REQUEST_TYPE_POST){ if(requestType == REQUEST_TYPE.POST){
conn.setDoOutput(true); conn.setDoOutput(true);
osr = new OutputStreamWriter(conn.getOutputStream()); osr = new OutputStreamWriter(conn.getOutputStream());
osr.write(parameterData); osr.write(parameterData);
@ -136,7 +108,7 @@ public class RequestSender {
while((line = br.readLine()) != null){ while((line = br.readLine()) != null){
response += line; response += line;
} }
responseHandler.handleResponse(response); responseHandler.handleResponse(response, remoteLookupOptions);
} catch (IOException e){ } catch (IOException e){
/* /*
@ -152,11 +124,9 @@ public class RequestSender {
if(conn != null){ if(conn != null){
conn.disconnect(); conn.disconnect();
} }
if(osr != null){ if(osr != null){
osr.close(); osr.close();
} }
if(br != null){ if(br != null){
br.close(); br.close();
} }

@ -33,7 +33,7 @@
By default it's turned off since we don't have access to the daisy search yet By default it's turned off since we don't have access to the daisy search yet
--> -->
<property name="enableRemoteUserLookup" value="true"></property> <property name="enableRemoteUserLookup" value="true"></property>
<!-- This property points to the location of the daisy json search --> <!-- This property points to the location of the remote system used for json requests -->
<property name="remoteLookupUrl" value="https://thesis.dsv.su.se/match/json" /> <property name="remoteLookupUrl" value="https://thesis.dsv.su.se/match/json" />
<!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.--> <!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.-->
<property name="acceptExternalAuthentication" value="true"/> <property name="acceptExternalAuthentication" value="true"/>

@ -34,6 +34,7 @@ import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username; import se.su.dsv.scipro.data.dataobjects.Username;
import se.su.dsv.scipro.json.IUserLookupFromIdentifier; import se.su.dsv.scipro.json.IUserLookupFromIdentifier;
import se.su.dsv.scipro.json.IUserLookupFromUsername; import se.su.dsv.scipro.json.IUserLookupFromUsername;
import se.su.dsv.scipro.json.RemoteLookupOptions;
import se.su.dsv.scipro.repository.util.RepositoryManager; import se.su.dsv.scipro.repository.util.RepositoryManager;
import se.su.dsv.scipro.util.KeyValuePair; import se.su.dsv.scipro.util.KeyValuePair;
@ -54,7 +55,7 @@ public class TestAuthRoutines {
//Fake a lookup mechanism //Fake a lookup mechanism
fixedLookupFromUsername = new IUserLookupFromUsername(){ fixedLookupFromUsername = new IUserLookupFromUsername(){
@Override @Override
public User lookup(final KeyValuePair<String> userAtRealm){ public User lookup(final KeyValuePair<String> userAtRealm, final RemoteLookupOptions options){
if(userAtRealm.getKey().equals("kalle-kula")) if(userAtRealm.getKey().equals("kalle-kula"))
return user; return user;
else else
@ -63,7 +64,7 @@ public class TestAuthRoutines {
}; };
fixedLookupFromIdentifier = new IUserLookupFromIdentifier(){ fixedLookupFromIdentifier = new IUserLookupFromIdentifier(){
@Override @Override
public User lookup(final Long identifier){ public User lookup(final Long identifier, final RemoteLookupOptions options){
if(identifier.equals(666)) if(identifier.equals(666))
return user; return user;
else else