Refactoring and simplification of communication with rest API.

This commit is contained in:
Niklas Herder 2012-04-02 12:29:56 +02:00
parent 3a4ad9179c
commit f162037a5e
9 changed files with 499 additions and 524 deletions

@ -161,7 +161,6 @@
<scope>provided</scope>
</dependency>
<!-- JPA -->
<!-- Hibernate impl -->
<dependency>
@ -321,6 +320,11 @@
<artifactId>wicket-components</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.10</version>
</dependency>
</dependencies>
@ -471,6 +475,7 @@
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
<org.springframework.data.version>1.0.3.RELEASE</org.springframework.data.version>
<querydsl.version>2.3.3</querydsl.version>
<remote.lookup.url>https://api.dsv.su.se/rest</remote.lookup.url>
</properties>
<profiles>
@ -494,6 +499,7 @@
<database.showSql>true</database.showSql>
<database.generateDdl>true</database.generateDdl>
<wicket.mode>deployment</wicket.mode>
<remote.lookup.url>http://apitest.dsv.su.se:8080/rest</remote.lookup.url>
</properties>
</profile>
<profile>
@ -505,6 +511,7 @@
<database.showSql>false</database.showSql>
<database.generateDdl>false</database.generateDdl>
<wicket.mode>deployment</wicket.mode>
<remote.lookup.url>https://api.dsv.su.se/rest</remote.lookup.url>
</properties>
</profile>
</profiles>

@ -1,10 +1,8 @@
/**
*
*
*/
package se.su.dsv.scipro.admin.panels;
import java.io.Serializable;
import org.apache.log4j.Logger;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
@ -13,16 +11,16 @@ import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.springframework.context.annotation.ImportResource;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.io.ExternalImporter;
import se.su.dsv.scipro.io.exceptions.ExternalImportException;
import se.su.dsv.scipro.security.auth.roles.Roles;
import java.io.Serializable;
public class ManualImportExportPanel extends Panel {
private static final long serialVersionUID = 1L;
private Label statusMessage = new Label("statusMessage","");
private Label statusMessage = new Label("statusMessage", "");
@SpringBean
private ExternalImporter externalImporter;
@SpringBean
@ -31,25 +29,30 @@ public class ManualImportExportPanel extends Panel {
private ApplicationSettings applicationSettings;
private Form<ImportExportParams> importExportForm;
private static final Logger logger = Logger.getLogger(ManualImportExportPanel.class);
public ManualImportExportPanel(String id) {
super(id);
init();
}
private void init(){
private void init() {
statusMessage.setOutputMarkupId(true);
if(hasRemote())
setMessage("Using remote: "+getRemoteUrl());
else
if (hasRemote()) {
setMessage("Using remote: " + getRemoteUrl());
}
else {
setMessage("No remote configured");
}
add(statusMessage);
setupForm();
}
private void setupForm(){
importExportForm = new Form<ImportExportParams>("importExportForm",new CompoundPropertyModel<ImportExportParams>(new ImportExportParams())){
private void setupForm() {
importExportForm = new Form<ImportExportParams>("importExportForm", new CompoundPropertyModel<ImportExportParams>(new ImportExportParams())) {
private static final long serialVersionUID = 1L;
@Override
public void onSubmit(){
public void onSubmit() {
final ImportExportParams params = getModelObject();
final String userNameIn = params.getImportUserName();
final long userIdIn = params.getImportUserId();
@ -60,78 +63,85 @@ public class ManualImportExportPanel extends Panel {
final String projectTitleIn = params.getImportProjectTitle();
final long projectIdOut = params.getExportProjectId();
if(userNameIn != null && !userNameIn.equals("")){
logger.debug("Attempting remote import of user: "+userNameIn);
try{
externalImporter.importUser(userNameIn,params.isIncludeLinkedProjects());
setMessage("Succesfully imported user with username: "+userNameIn + " from "+getRemoteUrl());
}catch(final ExternalImportException eie){
logger.warn("Caught error while importing user from remote system: "+eie.getMessage());
setMessage("Failed to import user with username: "+userNameIn+ " from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
if (userNameIn != null && !userNameIn.equals("")) {
logger.debug("Attempting remote import of user: " + userNameIn);
try {
externalImporter.importUser(userNameIn, params.isIncludeLinkedProjects());
setMessage("Succesfully imported user with username: " + userNameIn + " from " + getRemoteUrl());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing user from remote system: " + eie.getMessage());
setMessage("Failed to import user with username: " + userNameIn + " from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(userIdIn > 0){
logger.debug("Attempting remote import of id: "+userIdIn);
try{
externalImporter.importUser(userIdIn,params.isIncludeLinkedProjects());
setMessage("Succesfully imported user with id: "+userIdIn + " from "+getRemoteUrl());
}catch(final ExternalImportException eie){
logger.warn("Caught error while importing user from remote system: "+eie.getMessage());
setMessage("Failed to import user with id: "+userIdIn+ " from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
if (userIdIn > 0) {
logger.debug("Attempting remote import of id: " + userIdIn);
try {
externalImporter.importUser(userIdIn, params.isIncludeLinkedProjects());
setMessage("Succesfully imported user with id: " + userIdIn + " from " + getRemoteUrl());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing user from remote system: " + eie.getMessage());
setMessage("Failed to import user with id: " + userIdIn + " from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(importSupervisors){
if (importSupervisors) {
logger.debug("Importing all listed supervisors");
try{
externalImporter.importUsersOfRole(Roles.EMPLOYEE,params.isIncludeLinkedProjects());
try {
externalImporter.importUsersOfRole(Roles.EMPLOYEE, params.isIncludeLinkedProjects());
setMessage("Successfully imported supervisors from " + getRemoteUrl());
}catch(final ExternalImportException eie){
logger.warn("Caught error while importing supervisors from remote system: "+eie.getMessage());
setMessage("Failed to import supervisors from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing supervisors from remote system: " + eie.getMessage());
setMessage("Failed to import supervisors from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(importSupervisorUnits){
if (importSupervisorUnits) {
logger.debug("Importing attached units for supervisors");
try {
externalImporter.importSupervisorUnits();
setMessage("Successfully imported attached units to supervisors from " + getRemoteUrl());
} catch (final ExternalImportException eie) {
logger.warn("Caught error while importing units to supervisors from remote system: "+eie.getMessage());
setMessage("Failed to import units from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing units to supervisors from remote system: " + eie.getMessage());
setMessage("Failed to import units from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(importResearchAreas){
if (importResearchAreas) {
logger.debug("Importing all research areas from remote host");
try {
externalImporter.importResearchAreas();
setMessage("Successfully imported research areas from " + getRemoteUrl());
} catch (final ExternalImportException eie){
logger.warn("Caught error while importing research areas from remote system: "+eie.getMessage());
setMessage("Failed to import research areas from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing research areas from remote system: " + eie.getMessage());
setMessage("Failed to import research areas from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(projectIdIn > 0){
logger.debug("Attempting remote import of project: "+projectIdIn);
try{
if (projectIdIn > 0) {
logger.debug("Attempting remote import of project: " + projectIdIn);
try {
externalImporter.importProject(projectIdIn);
setMessage("Successfully imported project with id "+projectIdIn+" from " + getRemoteUrl());
}catch (final ExternalImportException eie){
logger.warn("Caught error while importing project from remote system: "+eie.getMessage());
setMessage("Failed to import project with id "+projectIdIn+" from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
setMessage("Successfully imported project with id " + projectIdIn + " from " + getRemoteUrl());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing project from remote system: " + eie.getMessage());
setMessage("Failed to import project with id " + projectIdIn + " from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(projectTitleIn != null && !projectTitleIn.equals((""))){
logger.debug("Attempting remote import of projects matching: '"+projectTitleIn+"'");
try{
if (projectTitleIn != null && !projectTitleIn.equals((""))) {
logger.debug("Attempting remote import of projects matching: '" + projectTitleIn + "'");
try {
externalImporter.importProjects(projectTitleIn);
setMessage("Successfully imported all projects matching title '"+projectTitleIn+"' from " + getRemoteUrl());
}catch (final ExternalImportException eie){
logger.warn("Caught error while importing project from remote system: "+eie.getMessage());
setMessage("Failed to import projects matching title '"+projectTitleIn+"' from "+getRemoteUrl()+", error: "+eie.getWrappedErrorCode());
setMessage("Successfully imported all projects matching title '" + projectTitleIn + "' from " + getRemoteUrl());
}
catch (final ExternalImportException eie) {
logger.warn("Caught error while importing project from remote system: " + eie.getMessage());
setMessage("Failed to import projects matching title '" + projectTitleIn + "' from " + getRemoteUrl() + ", error: " + eie.getWrappedErrorCode());
}
}
if(projectIdOut > 0){
logger.debug("Attempting remote export of project: "+projectIdOut);
if (projectIdOut > 0) {
logger.debug("Attempting remote export of project: " + projectIdOut);
throw new UnsupportedOperationException("Not implemented yet");
}
}
@ -148,17 +158,21 @@ public class ManualImportExportPanel extends Panel {
importExportForm.add(new CheckBox("importResearchAreas"));
importExportForm.setVisible(hasRemote());
}
private boolean hasRemote(){
private boolean hasRemote() {
return externalImporter.supportsRemoteOperations();
}
private String getRemoteUrl(){
return applicationSettings.getRemoteLookupUrl();
private String getRemoteUrl() {
return externalImporter.getLookupUrl();
}
private void setMessage(final String message){
private void setMessage(final String message) {
statusMessage.setDefaultModelObject(message);
}
//Utility model-class
private class ImportExportParams implements Serializable{
private class ImportExportParams implements Serializable {
private static final long serialVersionUID = 5961088002006031317L;
private String importUserName;
private long importUserId;
@ -168,58 +182,76 @@ public class ManualImportExportPanel extends Panel {
private long importProjectId;
private String importProjectTitle;
private long exportProjectId;
private boolean includeLinkedProjects=false;
private boolean includeLinkedProjects = false;
public String getImportUserName() {
return importUserName;
}
public void setImportUserName(String importUserName) {
this.importUserName = importUserName;
}
public long getImportProjectId() {
return importProjectId;
}
public void setImportProjectId(long importProjectId) {
this.importProjectId = importProjectId;
}
public String getImportProjectTitle() {
return importProjectTitle;
}
public void setImportProjectTitle(String importProjectTitle) {
this.importProjectTitle = importProjectTitle;
}
public long getExportProjectId() {
return exportProjectId;
}
public void setExportProjectId(long exportProjectId) {
this.exportProjectId = exportProjectId;
}
public boolean isImportSupervisors() {
return importSupervisors;
}
public void setImportSupervisors(boolean importSupervisors) {
this.importSupervisors = importSupervisors;
}
public boolean isImportSupervisorUnits() {
return importSupervisorUnits;
}
public void setImportSupervisorUnits(boolean importSupervisorUnits) {
this.importSupervisorUnits = importSupervisorUnits;
}
public long getImportUserId() {
return importUserId;
}
public void setImportUserId(long importUserId) {
this.importUserId = importUserId;
}
public boolean isIncludeLinkedProjects() {
return includeLinkedProjects;
}
public void setIncludeLinkedProjects(boolean includeLinkedProjects) {
this.includeLinkedProjects = includeLinkedProjects;
}
public void setImportResearchAreas(boolean importResearchAreas) {
this.importResearchAreas = importResearchAreas;
}
public boolean isImportResearchAreas() {
return importResearchAreas;
}

@ -7,12 +7,21 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
* Specifies interaction of an importing service component.
*/
public interface ExternalImporter {
String getLookupUrl();
void importUser(final String userName, boolean includeLinkedEntities) throws ExternalImportException;
void importUser(final long externalIdentifier, boolean includeLinkedEntities) throws ExternalImportException;
void importUsersOfRole(final Roles role,boolean includeLinkedEntities) throws ExternalImportException;
void importUsersOfRole(final Roles role, boolean includeLinkedEntities) throws ExternalImportException;
void importProject(final long externalIdentifier) throws ExternalImportException;
void importProjects(final String matchingTitle) throws ExternalImportException;
void importSupervisorUnits() throws ExternalImportException;
void importResearchAreas() throws ExternalImportException;
boolean supportsRemoteOperations();
}

@ -0,0 +1,79 @@
package se.su.dsv.scipro.io.http;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import org.apache.log4j.Logger;
import se.su.dsv.scipro.io.exceptions.HttpRemoteRespondedWithFailureException;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ApiClient {
public static final int CONN_TIMEOUT = 1000 * 60;
public static final int READ_TIMEOUT = 1000 * 120;
public static final String ENC_TYPE = "UTF8";
public enum REQUEST_TYPE {POST, GET}
private final Logger logger = Logger.getLogger(ApiClient.class);
private final Map<String, String> parameters = new HashMap<String, String>();
private String baseUrl;
private String user;
private String password;
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public String getBaseUrl() {
return baseUrl;
}
private ApiClient() {
}
public void setUser(String user) {
this.user = user;
}
public void setPassword(String password) {
this.password = password;
}
/**
* Start to process the request
*
* @throws IOException if a connection error occurred
*/
public void processRequest(String urlPath, DtoResponseHandler responseHandler, Map<String, String> parameters, REQUEST_TYPE requestType) throws HttpRemoteRespondedWithFailureException {
logger.debug("Sending remote request (" + requestType + "): " + urlPath + "?" + parameters);
try {
WebResource resource = new Client().resource(baseUrl + urlPath);
resource.addFilter(new HTTPBasicAuthFilter(user, password));
String result = null;
switch (requestType) {
case GET:
for (Map.Entry<String, String> stringStringEntry : parameters.entrySet()) {
resource = resource.queryParam(stringStringEntry.getKey(), stringStringEntry.getValue());
}
result = resource.accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
break;
case POST:
result = resource.entity(parameters).accept(MediaType.APPLICATION_JSON).post(String.class);
}
responseHandler.handleResponse(result);
}
catch (UniformInterfaceException e) {
logger.error(e.getMessage(), e);
throw new HttpRemoteRespondedWithFailureException(e.getResponse().getStatus());
}
}
}

@ -1,152 +0,0 @@
package se.su.dsv.scipro.io.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import se.su.dsv.scipro.io.exceptions.HttpRemoteRespondedWithFailureException;
public class HttpRequestSender {
public static final int CONN_TIMEOUT = 1000*60;
public static final int READ_TIMEOUT = 1000*120;
public static final String ENC_TYPE = "UTF8";
public enum REQUEST_TYPE{POST,GET};
private final REQUEST_TYPE requestType;
private final Logger logger = Logger.getLogger(HttpRequestSender.class);
private final DtoResponseHandler responseHandler;
private final Map<String, String> parameters = new HashMap<String,String>();
private final String url;
private final String user;
private final String password;
public HttpRequestSender(final DtoResponseHandler responseHandler, final String url, final String user, final String password, final Map<String, String> parameters, final REQUEST_TYPE requestType){
if(responseHandler == null){
logger.error("Could not send request, no response handler was provided");
throw new IllegalArgumentException("You need to provide a handler for the response");
}
if(url == null){
logger.error("Can't create request for null url");
throw new IllegalArgumentException("url parameter must be non-null");
}
this.responseHandler = responseHandler;
this.url = url;
this.user = user;
this.password = password;
if(parameters!=null)
this.parameters.putAll(parameters);
this.requestType = requestType;
}
/**
* Start to process the request
* @throws IOException if a connection error occurred
*/
public void processRequest() throws IOException, HttpRemoteRespondedWithFailureException {
logger.debug("Sending remote request ("+requestType+"): " + url + "?"+parameters);
String parameterData = "";
int count = 0;
//Format request
for(Map.Entry<String, String> me : parameters.entrySet()){
if(count > 0){
parameterData += "&";
}
parameterData += me.getKey() + "=" + me.getValue();
count++;
}
//Add to request as appropriate
String urlString = url;
if(requestType == REQUEST_TYPE.GET && parameters.size() > 0){
urlString += "?" + parameterData;
}
HttpURLConnection conn = null;
OutputStreamWriter osr = null;
BufferedReader br = null;
try{
//This will throw an MalformedURLException if the url is not valid
URL u = new URL(urlString);
conn = (HttpURLConnection) getConnection(u);
conn.setRequestMethod(requestType.name());
//Set connection timeouts
conn.setConnectTimeout(CONN_TIMEOUT);
conn.setReadTimeout(READ_TIMEOUT);
if(user != null && password != null)
conn.setRequestProperty("Authorization", getBasicEncodedAuthData());
conn.setRequestProperty("Accept", getAcceptContentType());
//Handle POST-style requests
if(requestType == REQUEST_TYPE.POST){
conn.setDoOutput(true);
osr = new OutputStreamWriter(conn.getOutputStream());
osr.write(parameterData);
osr.flush();
}
//Handle response errors early on
if(conn.getResponseCode() != HttpServletResponse.SC_OK){
logger.error("Request URL: "+ u + " responded with failure, status code: " + conn.getResponseCode());
dispatchError(conn.getResponseCode());
}
br = new BufferedReader(new InputStreamReader(conn.getInputStream(),ENC_TYPE));
String line = "";
StringBuffer response = new StringBuffer();
while((line = br.readLine()) != null){
response.append(line);
}
responseHandler.handleResponse(response.toString());
}catch(final MalformedURLException mue){
logger.warn("Malformed url: " + urlString + " caused exception");
throw mue;
}catch(final SocketTimeoutException ste){
logger.warn("Socket timeout while talking to remote host on URL: " + urlString);
throw ste;
}catch(final UnknownHostException uhe){
logger.warn("Unknown host: " + urlString + " caused exception");
throw uhe;
}finally{
if(conn != null){
conn.disconnect();
}
if(osr != null){
try{
osr.close();
}catch(final IOException ioe){
logger.warn("Close on output stream caused an exception, not much to do about that");
}
}
if(br != null){
try{
br.close();
}catch(final IOException ioe){
logger.warn("Close on input stream caused an exception, not much to do about that");
}
}
}
}
private void dispatchError(int responseCode) {
throw new HttpRemoteRespondedWithFailureException(responseCode);
}
private String getBasicEncodedAuthData() {
String userpassword = user + ":" + password;
String encodedAuthorization = Base64.encodeBase64String(userpassword.getBytes());
return ("Basic "+encodedAuthorization);
}
private String getAcceptContentType() {
return "application/json";
}
protected HttpURLConnection getConnection(final URL url) throws IOException{
return (HttpURLConnection)url.openConnection();
}
}

@ -1,24 +0,0 @@
package se.su.dsv.scipro.io.http;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import org.apache.log4j.Logger;
public class HttpsRequestSender extends HttpRequestSender{
private Logger logger = Logger.getLogger(HttpsRequestSender.class);
public HttpsRequestSender(final DtoResponseHandler responseHandler, final String url, final String user, final String password, final Map<String, String> parameters, final REQUEST_TYPE requestType){
super(responseHandler,url,user,password,parameters,requestType);
}
@Override
protected HttpURLConnection getConnection(final URL url) throws IOException{
HttpsURLConnection con = (HttpsURLConnection)url.openConnection();
return con;
}
}

@ -1,44 +1,25 @@
package se.su.dsv.scipro.io.impl;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.io.ExternalImporter;
import se.su.dsv.scipro.io.dto.AbstractDtoResponseHandler;
import se.su.dsv.scipro.io.dto.ProjectDTO;
import se.su.dsv.scipro.io.dto.ProjectDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.ProjectParticipantDTO;
import se.su.dsv.scipro.io.dto.ProjectParticipantDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.ResearchAreaDTO;
import se.su.dsv.scipro.io.dto.ResearchAreaDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.PersonDTO;
import se.su.dsv.scipro.io.dto.PersonDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.UnitDTO;
import se.su.dsv.scipro.io.dto.UnitDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.UserDTO;
import se.su.dsv.scipro.io.dto.UserDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.UserRoleDTO;
import se.su.dsv.scipro.io.dto.UsernameDTO;
import se.su.dsv.scipro.io.dto.UsernameDTOCollectionWrapper;
import se.su.dsv.scipro.io.dto.*;
import se.su.dsv.scipro.io.exceptions.ExternalImportException;
import se.su.dsv.scipro.io.exceptions.HttpRemoteRespondedWithFailureException;
import se.su.dsv.scipro.io.facade.ImporterFacade;
import se.su.dsv.scipro.io.http.HttpRequestSender;
import se.su.dsv.scipro.io.http.HttpsRequestSender;
import se.su.dsv.scipro.io.http.ApiClient;
import se.su.dsv.scipro.security.auth.roles.Roles;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Importer implementation, uses standard HTTP requests and Json-wrappers.
* To use this class as the importer, configure it via applicationContext.xml.
@ -53,355 +34,383 @@ public class ExternalImporterDaisyImpl implements ExternalImporter {
@Autowired
private ProjectDao projectDao;
private final Logger logger = Logger.getLogger(ExternalImporterDaisyImpl.class);
private ApiClient client;
public void setClient(ApiClient client) {
this.client = client;
}
public ApiClient getClient() {
return client;
}
@Override
public String getLookupUrl() {
return client.getBaseUrl();
}
@Override
@Transactional
public void importUser(final String userName, boolean includeLinkedEntities) throws ExternalImportException{
final Map<String,String> parameters = new HashMap<String,String>();
public void importUser(final String userName, boolean includeLinkedEntities) throws ExternalImportException {
final Map<String, String> parameters = new HashMap<String, String>();
final UserDTOPreProcessor userDTODecorator = getDefaultUserProcessor(includeLinkedEntities);
//parameters.put("showTheses", Boolean.valueOf(includeLinkedEntities).toString());
sendDefaultUserRequest(parameters,HttpRequestSender.REQUEST_TYPE.GET,userDTODecorator,new UrlProcessor(){
sendDefaultUserRequest(parameters, ApiClient.REQUEST_TYPE.GET, userDTODecorator, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/person/username/"+userName);
String process(final String url) {
return (url + "/person/username/" + userName);
}
});
}
@Override
@Transactional
public void importUser(final long externalIdentifier, boolean includeLinkedEntities) throws ExternalImportException{
final Map<String,String> parameters = new HashMap<String,String>();
public void importUser(final long externalIdentifier, boolean includeLinkedEntities) throws ExternalImportException {
final Map<String, String> parameters = new HashMap<String, String>();
final UserDTOPreProcessor userDTODecorator = getDefaultUserProcessor(includeLinkedEntities);
sendDefaultUserRequest(parameters,HttpRequestSender.REQUEST_TYPE.GET,userDTODecorator,new UrlProcessor(){
sendDefaultUserRequest(parameters, ApiClient.REQUEST_TYPE.GET, userDTODecorator, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/person/"+externalIdentifier);
String process(final String url) {
return (url + "/person/" + externalIdentifier);
}
});
}
@Override
@Transactional
public void importUsersOfRole(final Roles role, boolean includeLinkedEntities) throws ExternalImportException{
final Map<String,String> parameters = new HashMap<String,String>();
public void importUsersOfRole(final Roles role, boolean includeLinkedEntities) throws ExternalImportException {
final Map<String, String> parameters = new HashMap<String, String>();
final UserDTOPreProcessor employeeDTODecorator = getDefaultEmployeeUserProcessor(includeLinkedEntities);//Force all returned users to be assigned the local "Supervisor" role
if(!role.equals(Roles.EMPLOYEE)) //Only supports employees currently
if (!role.equals(Roles.EMPLOYEE)) //Only supports employees currently
{
throw new UnsupportedOperationException("Sorry, only the EMPLOYEE role is currently supported");
sendDefaultUserRequest(parameters,HttpRequestSender.REQUEST_TYPE.GET, employeeDTODecorator,new UrlProcessor(){
}
sendDefaultUserRequest(parameters, ApiClient.REQUEST_TYPE.GET, employeeDTODecorator, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/orgunit/4/supervisors");//Hehe
String process(final String url) {
return (url + "/orgunit/4/supervisors");//Hehe
}
});
}
@Override
public void importProjects(final String title) throws ExternalImportException {
final Map<String,String> parameters = new HashMap<String,String>();
final Map<String, String> parameters = new HashMap<String, String>();
parameters.put("title", title);
Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(parameters,HttpRequestSender.REQUEST_TYPE.GET,null, new UrlProcessor(){
Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(parameters, ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/thesis");
String process(final String url) {
return (url + "/thesis");
}
});
final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(externalProjectSet);
for(ProjectDTO projectDTO : projectsWithParticipants){
for (ProjectDTO projectDTO : projectsWithParticipants) {
final Project project = projectDao.getProjectByIdentifier(projectDTO.id);
if(project == null)
logger.info("Importing new project: '" + projectDTO+"'");
else
logger.info("Updating existing project: '" + projectDTO+"'");
if (project == null) {
logger.info("Importing new project: '" + projectDTO + "'");
}
else {
logger.info("Updating existing project: '" + projectDTO + "'");
}
importerFacade.mergeProject(project, projectDTO);
}
}
@Override
public void importProject(final long externalIdentifier) throws ExternalImportException {
Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(new HashMap<String,String>(),HttpRequestSender.REQUEST_TYPE.GET,null, new UrlProcessor(){
Set<ProjectDTO> externalProjectSet = fetchRemoteProjects(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/thesis/"+externalIdentifier);
String process(final String url) {
return (url + "/thesis/" + externalIdentifier);
}
});
final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(externalProjectSet);
for(ProjectDTO projectDTO : projectsWithParticipants){
for (ProjectDTO projectDTO : projectsWithParticipants) {
final Project project = projectDao.getProjectByIdentifier(projectDTO.id);
if(project == null)
logger.info("Importing new project: '" + projectDTO+"'");
else
logger.info("Updating existing project: '" + projectDTO+"'");
if (project == null) {
logger.info("Importing new project: '" + projectDTO + "'");
}
else {
logger.info("Updating existing project: '" + projectDTO + "'");
}
importerFacade.mergeProject(project, projectDTO);
}
}
@Override
@Transactional
public void importSupervisorUnits() throws ExternalImportException {
Set<UnitDTO> unitSet = fetchRemoteUnits(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor() {
Set<UnitDTO> unitSet = fetchRemoteUnits(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/orgunit/4/subunits");
String process(final String url) {
return (url + "/orgunit/4/subunits");
}
});
importerFacade.addUnexistingUnitsAsKeywords(unitSet);
Set<PersonDTO> allSupervisorsOnUnits = new HashSet<PersonDTO>();
for (final UnitDTO unitDTO : unitSet){
Set<PersonDTO> supervisorSet = fetchSupervisorsOnUnit(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor() {
for (final UnitDTO unitDTO : unitSet) {
Set<PersonDTO> supervisorSet = fetchSupervisorsOnUnit(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/orgunit/"+unitDTO.id+"/supervisors");
String process(final String url) {
return (url + "/orgunit/" + unitDTO.id + "/supervisors");
}
});
allSupervisorsOnUnits.addAll(supervisorSet);
if(!supervisorSet.isEmpty()){
if (!supervisorSet.isEmpty()) {
for (PersonDTO supervisorDTO : supervisorSet) {
importerFacade.addUnitToSupervisor(supervisorDTO, unitDTO);
}
} else
logger.info("Unit: " + unitDTO.name + " has no supervisors attached.");
importerFacade.addUnitToSupervisor(supervisorDTO, unitDTO);
}
}
else {
logger.info("Unit: " + unitDTO.name + " has no supervisors attached.");
}
}
// Compare the list of supervisors with remote units with the list of
// all supervisors in scipro, to make sure to remove units from the
// users that doesn't have one in daisy.
logger.debug("Number of supervisors on remote units: " + allSupervisorsOnUnits.size());
importerFacade.removeUnitFromSupervisorsNotInSet(allSupervisorsOnUnits);
}
@Override
@Transactional
public void importResearchAreas() throws ExternalImportException {
Set<ResearchAreaDTO> areaSet = fetchResearchAreas(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor() {
Set<ResearchAreaDTO> areaSet = fetchResearchAreas(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(final String url){
return (url+"/orgunit/4/researchAreas");
String process(final String url) {
return (url + "/orgunit/4/researchAreas");
}
});
logger.info("Received " + areaSet.size() + " research areas from remote and adding those who not exist to database");
if(!areaSet.isEmpty()){
if (!areaSet.isEmpty()) {
importerFacade.addUnexistingResearchAreas(areaSet);
}
}
}
private Set<PersonDTO> fetchSupervisorsOnUnit(final Map<String, String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
private Set<PersonDTO> fetchSupervisorsOnUnit(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
final Set<PersonDTO> dtoCache = new HashSet<PersonDTO>();
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response received (from: "+ requestUrl+"): " + response);
final PersonDTOCollectionWrapper supervisorCollection = asSupervisorCollection(response);
if(supervisorCollection.size() == 0){
throw new ExternalImportException("No supervisors found in remote");
} else {
dtoCache.addAll(supervisorCollection.getPersons());
try {
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response received (from: " + requestUrl + "): " + response);
final PersonDTOCollectionWrapper supervisorCollection = asSupervisorCollection(response);
if (supervisorCollection.size() == 0) {
throw new ExternalImportException("No supervisors found in remote");
}
else {
dtoCache.addAll(supervisorCollection.getPersons());
}
logger.info("Received " + supervisorCollection.size() + " supervisor" + (supervisorCollection.size() == 1 ? "" : "s") + " from remote");
}
logger.info("Received " + supervisorCollection.size() + " supervisor"+(supervisorCollection.size()==1?"":"s")+" from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
try{
process(senderProxy);
} catch (final ExternalImportException eie){
}, parameters, requestType);
}
catch (final ExternalImportException eie) {
logger.warn("No supervisors found");
}
return dtoCache;
}
private Set<UnitDTO> fetchRemoteUnits(final Map<String,String> parameters,final HttpRequestSender.REQUEST_TYPE requestType,
UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
private Set<UnitDTO> fetchRemoteUnits(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType,
UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
final Set<UnitDTO> dtoCache = new HashSet<UnitDTO>();
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
@Override
public void handleResponse(String response) {
logger.info("Response received (from: "+requestUrl+"): " + response);
final UnitDTOCollectionWrapper unitCollection = asUnitCollection(response);//The query will always returns a collection, regardless of backing data
if(unitCollection.size() == 0){//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No units found in remote");
}else{
dtoCache.addAll(unitCollection.getUnits());
try {
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response received (from: " + requestUrl + "): " + response);
final UnitDTOCollectionWrapper unitCollection = asUnitCollection(response);//The query will always returns a collection, regardless of backing data
if (unitCollection.size() == 0) {//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No units found in remote");
}
else {
dtoCache.addAll(unitCollection.getUnits());
}
logger.info("Received " + unitCollection.size() + " unit" + (unitCollection.size() == 1 ? "" : "s") + " from remote");
}
logger.info("Received " + unitCollection.size() + " unit"+(unitCollection.size()==1?"":"s")+" from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
try{
process(senderProxy);
}catch(final ExternalImportException eie){
}, parameters, requestType);
}
catch (final ExternalImportException eie) {
logger.warn("No units found");
}
return dtoCache;
return dtoCache;
}
@Override
public boolean supportsRemoteOperations() {
return true;
}
/**
* Private utility method, sends request and signals failure via exceptions.
*
* @param parameters
* @param requestType
*/
private void sendDefaultUserRequest(final Map<String,String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UserDTOPreProcessor preProcessor, final UrlProcessor urlProcessor){
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
private void sendDefaultUserRequest(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UserDTOPreProcessor preProcessor, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: "+requestUrl+"): " + response);
logger.info("Response recieved (from: " + requestUrl + "): " + response);
final UserDTOCollectionWrapper userCollection = asUserCollectionWrapper(response);//The query will always returns a collection, regardless of backing data
if(userCollection.size() == 0){//If at this point we have nothing, we have to throw.
if (userCollection.size() == 0) {//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No users found in remote");
}else{
for(final UserDTO userDTO:userCollection){
}
else {
for (final UserDTO userDTO : userCollection) {
final User user = userDao.getUserByIdentifier(userDTO.id);
if(user == null)
logger.info("Importing new user: '" + userDTO+"'");
else
logger.info("Updating existing user: '" + userDTO+"'");
importerFacade.mergeUser(user, (preProcessor!=null?preProcessor.process(userDTO):userDTO));
if (user == null) {
logger.info("Importing new user: '" + userDTO + "'");
}
else {
logger.info("Updating existing user: '" + userDTO + "'");
}
importerFacade.mergeUser(user, (preProcessor != null ? preProcessor.process(userDTO) : userDTO));
}
}
logger.info("Recieved " + userCollection.size() + " user"+(userCollection.size()==1?"":"s")+" from remote");
logger.info("Recieved " + userCollection.size() + " user" + (userCollection.size() == 1 ? "" : "s") + " from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
process(senderProxy);
}, parameters, requestType);
}
private Set<ProjectDTO> fetchRemoteProjects(final Map<String,String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final ProjectDTOPreProcessor preProcessor, final UrlProcessor urlProcessor){
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
private Set<ProjectDTO> fetchRemoteProjects(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
final Set<ProjectDTO> dtoCache = new HashSet<ProjectDTO>();
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: "+requestUrl+"): " + response);
final ProjectDTOCollectionWrapper projectCollection = asProjectCollection(response);//The query will always returns a collection, regardless of backing data
if(projectCollection.size() == 0){//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No projects found in remote");
}else{
dtoCache.addAll(projectCollection.getProjects());
try {
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: " + requestUrl + "): " + response);
final ProjectDTOCollectionWrapper projectCollection = asProjectCollection(response);//The query will always returns a collection, regardless of backing data
if (projectCollection.size() == 0) {//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No projects found in remote");
}
else {
dtoCache.addAll(projectCollection.getProjects());
}
logger.info("Recieved " + projectCollection.size() + " project" + (projectCollection.size() == 1 ? "" : "s") + " from remote");
}
logger.info("Recieved " + projectCollection.size() + " project"+(projectCollection.size()==1?"":"s")+" from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
try{
process(senderProxy);
}catch(final ExternalImportException eie){
}, parameters, requestType);
}
catch (final ExternalImportException eie) {
logger.warn("No projects found, this may or may not indicate a problem");
}
return dtoCache;
}
private Set<UsernameDTO> fetchRemoteUsernames(final Map<String,String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
private Set<UsernameDTO> fetchRemoteUsernames(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
final Set<UsernameDTO> dtoCache = new HashSet<UsernameDTO>();
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: "+requestUrl+"): " + response);
final UsernameDTOCollectionWrapper usernameCollection = asUsernameCollection(response);
if(usernameCollection.size() == 0){
throw new ExternalImportException("No usernames found in remote");
}else{
dtoCache.addAll(usernameCollection.getUsernames());
try {
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: " + requestUrl + "): " + response);
final UsernameDTOCollectionWrapper usernameCollection = asUsernameCollection(response);
if (usernameCollection.size() == 0) {
throw new ExternalImportException("No usernames found in remote");
}
else {
dtoCache.addAll(usernameCollection.getUsernames());
}
logger.info("Received " + usernameCollection.size() + " usernames" + (usernameCollection.size() == 1 ? "" : "s") + " from remote");
}
logger.info("Received " + usernameCollection.size() + " usernames"+(usernameCollection.size()==1?"":"s")+" from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
try{
process(senderProxy);
} catch (final ExternalImportException eie){
}, parameters, requestType);
}
catch (final ExternalImportException eie) {
logger.warn("No usernames found");
}
return dtoCache;
}
private Set<ResearchAreaDTO> fetchResearchAreas(final Map<String, String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
private Set<ResearchAreaDTO> fetchResearchAreas(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
final Set<ResearchAreaDTO> dtoCache = new HashSet<ResearchAreaDTO>();
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: "+requestUrl+"): " + response);
final ResearchAreaDTOCollectionWrapper areaCollection = asAreaCollection(response);//The query will always returns a collection, regardless of backing data
if(areaCollection.size() == 0){//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No research areas found in remote");
}else{
dtoCache.addAll(areaCollection.getAreas());
try {
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: " + requestUrl + "): " + response);
final ResearchAreaDTOCollectionWrapper areaCollection = asAreaCollection(response);//The query will always returns a collection, regardless of backing data
if (areaCollection.size() == 0) {//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No research areas found in remote");
}
else {
dtoCache.addAll(areaCollection.getAreas());
}
logger.info("Recieved " + areaCollection.size() + " research area" + (areaCollection.size() == 1 ? "" : "s") + " from remote");
}
logger.info("Recieved " + areaCollection.size() + " research area"+(areaCollection.size()==1?"":"s")+" from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
try{
process(senderProxy);
}catch(final ExternalImportException eie){
}, parameters, requestType);
}
catch (final ExternalImportException eie) {
logger.warn("No research areas found, this may or may not indicate a problem");
}
return dtoCache;
}
private Set<ProjectParticipantDTO> fetchParticipants(final Map<String, String> parameters, final HttpRequestSender.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor==null?getRequestUrl():urlProcessor.process(getRequestUrl()));
private Set<ProjectParticipantDTO> fetchParticipants(final Map<String, String> parameters, final ApiClient.REQUEST_TYPE requestType, final UrlProcessor urlProcessor) {
final String requestUrl = (urlProcessor == null ? getRequestUrl() : urlProcessor.process(getRequestUrl()));
final Set<ProjectParticipantDTO> dtoCache = new HashSet<ProjectParticipantDTO>();
final HttpsRequestSender senderProxy = new HttpsRequestSender(new AbstractDtoResponseHandler(){
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: "+requestUrl+"): " + response);
final ProjectParticipantDTOCollectionWrapper participantCollection = asParticipantCollection(response);//The query will always returns a collection, regardless of backing data
if(participantCollection.size() == 0){//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No project participants found in remote");
}else{
dtoCache.addAll(participantCollection.getParticipants());
try {
client.processRequest(requestUrl, new AbstractDtoResponseHandler() {
@Override
public void handleResponse(String response) {
logger.info("Response recieved (from: " + requestUrl + "): " + response);
final ProjectParticipantDTOCollectionWrapper participantCollection = asParticipantCollection(response);//The query will always returns a collection, regardless of backing data
if (participantCollection.size() == 0) {//If at this point we have nothing, we have to throw.
throw new ExternalImportException("No project participants found in remote");
}
else {
dtoCache.addAll(participantCollection.getParticipants());
}
logger.info("Recieved " + participantCollection.size() + " project participant" + (participantCollection.size() == 1 ? "" : "s") + " from remote");
}
logger.info("Recieved " + participantCollection.size() + " project participant"+(participantCollection.size()==1?"":"s")+" from remote");
}
}, requestUrl, getRequestUser(), getRequestPassword(), parameters, requestType);
try{
process(senderProxy);
}catch(final ExternalImportException eie){
}, parameters, requestType);
}
catch (final ExternalImportException eie) {
logger.warn("No project participants found, this may or may not indicate a problem");
}
return dtoCache;
}
private String getRequestUrl(){
return applicationSettings.getRemoteLookupUrl();
}
private String getRequestUser() {
return applicationSettings.getRemoteLookupUser();
}
private String getRequestPassword() {
return applicationSettings.getRemoteLookupPassword();
}
private void process(final HttpRequestSender proxy) throws ExternalImportException{
try{
proxy.processRequest();
}catch(final IOException ioe){
logger.error("A fatal IO exception has occured while contacting remote host at: " + getRequestUrl());
throw new ExternalImportException(ioe);
}catch(final HttpRemoteRespondedWithFailureException hrrwfe){
logger.error("Remote host: " + getRequestUrl() + " responded with failure: "+ hrrwfe.getMessage());
throw new ExternalImportException(hrrwfe);//Use getCause etc to find out the response code and act on it in some meaningful way
}
/**
* @return
* @deprecated Should be removed. This is set in the client config in applicationContext.xml
*/
private String getRequestUrl() {
return "";
}
private UserDTOPreProcessor getDefaultUserProcessor(boolean includeLinkedEntities) {
if(!includeLinkedEntities)
if (!includeLinkedEntities) {
return new UserDTOPreProcessor();
return new UserDTOPreProcessor(){
}
return new UserDTOPreProcessor() {
@Override
UserDTO process(final UserDTO userDTO){
final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, null, new UrlProcessor(){
UserDTO process(final UserDTO userDTO) {
final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return (url+"/person/"+userDTO.id+"/theses");
String process(String url) {
return (url + "/person/" + userDTO.id + "/theses");
}
});
//Fetch authors and supervisors for each project
final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(fetchedProjects);
final Set<UsernameDTO> fetchedUsernames = fetchRemoteUsernames(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
final Set<UsernameDTO> fetchedUsernames = fetchRemoteUsernames(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return(url+"/person/"+userDTO.id+"/usernames");
String process(String url) {
return (url + "/person/" + userDTO.id + "/usernames");
}
});
userDTO.projects = projectsWithParticipants;
@ -410,88 +419,85 @@ public class ExternalImporterDaisyImpl implements ExternalImporter {
}
};
}
private UserDTOPreProcessor getDefaultEmployeeUserProcessor(final boolean includeLinkedEntities) {
return new UserDTOPreProcessor(){
return new UserDTOPreProcessor() {
@Override
UserDTO process(final UserDTO userDTO){
if(includeLinkedEntities){
final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, null, new UrlProcessor(){
UserDTO process(final UserDTO userDTO) {
if (includeLinkedEntities) {
final Set<ProjectDTO> fetchedProjects = fetchRemoteProjects(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return (url+"/person/"+userDTO.id+"/theses");
String process(String url) {
return (url + "/person/" + userDTO.id + "/theses");
}
});
final Set<ProjectDTO> projectsWithParticipants = projectDTOWithParticipants(fetchedProjects);
userDTO.projects = projectsWithParticipants;
}
final Set<UsernameDTO> fetchedUsernames = fetchRemoteUsernames(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
final Set<UsernameDTO> fetchedUsernames = fetchRemoteUsernames(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return(url+"/person/"+userDTO.id+"/usernames");
String process(String url) {
return (url + "/person/" + userDTO.id + "/usernames");
}
});
userDTO.usernames = fetchedUsernames;
final Set<ResearchAreaDTO> fetchedResearchAreas = fetchResearchAreas(new HashMap<String,String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
final Set<ResearchAreaDTO> fetchedResearchAreas = fetchResearchAreas(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return (url+"/person/"+userDTO.id+"/researchAreas");
String process(String url) {
return (url + "/person/" + userDTO.id + "/researchAreas");
}
});
userDTO.researchAreas = fetchedResearchAreas;
//Force employee role data to be on the DTO
UserRoleDTO employeeRole = new UserRoleDTO();
employeeRole.role = UserRoleDTO.EXTERNAL_USER_ROLES.SUPERVISOR_ROLE.asExternal();
if(!userDTO.roles.contains(employeeRole)){
if (!userDTO.roles.contains(employeeRole)) {
userDTO.roles.add(employeeRole);
}
return userDTO;
}
};
}
private Set<ProjectDTO> projectDTOWithParticipants(Set<ProjectDTO> fetchedProjects){
private Set<ProjectDTO> projectDTOWithParticipants(Set<ProjectDTO> fetchedProjects) {
Set<ProjectDTO> projects = new HashSet<ProjectDTO>(fetchedProjects);
for (final ProjectDTO projectDTO : projects) {
Set<ProjectParticipantDTO> combinedSet = new HashSet<ProjectParticipantDTO>();
final Set<ProjectParticipantDTO> fetchedAuthors = fetchParticipants(new HashMap<String, String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
final Set<ProjectParticipantDTO> fetchedAuthors = fetchParticipants(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return(url+"/thesis/"+projectDTO.id+"/student");
String process(String url) {
return (url + "/thesis/" + projectDTO.id + "/student");
}
});
combinedSet.addAll(fetchedAuthors);
final Set<ProjectParticipantDTO> fetchedOtherParticipants = fetchParticipants(new HashMap<String, String>(), HttpRequestSender.REQUEST_TYPE.GET, new UrlProcessor(){
final Set<ProjectParticipantDTO> fetchedOtherParticipants = fetchParticipants(new HashMap<String, String>(), ApiClient.REQUEST_TYPE.GET, new UrlProcessor() {
@Override
String process(String url){
return(url+"/thesis/"+projectDTO.id+"/contributor");
String process(String url) {
return (url + "/thesis/" + projectDTO.id + "/contributor");
}
});
combinedSet.addAll(fetchedOtherParticipants);
projectDTO.participants = combinedSet;
}
return projects;
}
/**
* Small utility interface/default implementation used to preprocess DTO objects, intended for anonymous inner class-usage.
*/
private class UserDTOPreProcessor{
UserDTO process(UserDTO userDTO){
private class UserDTOPreProcessor {
UserDTO process(UserDTO userDTO) {
return userDTO;
}
}
private class ProjectDTOPreProcessor{
ProjectDTO process(ProjectDTO projectDTO){
return projectDTO;
}
}
private class UrlProcessor{
String process(String url){
private class UrlProcessor {
String process(String url) {
return url;
}
}
}

@ -1,7 +1,6 @@
package se.su.dsv.scipro.io.impl;
import org.apache.log4j.Logger;
import se.su.dsv.scipro.io.ExternalImporter;
import se.su.dsv.scipro.io.exceptions.ExternalImportException;
import se.su.dsv.scipro.security.auth.roles.Roles;
@ -12,38 +11,51 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
*/
public class ExternalImporterDefaultImpl implements ExternalImporter {
private final Logger logger = Logger.getLogger(ExternalImporterDefaultImpl.class);
@Override
public String getLookupUrl() {
return "<not specified>";
}
@Override
public void importUser(final String userName, boolean includeLinkedEntities) {
logger.debug("Dummy implementation, the user: "+userName+" will not be imported");
logger.debug("Dummy implementation, the user: " + userName + " will not be imported");
}
@Override
public void importUser(final long externalIdentifier, boolean includeLinkedEntities) {
logger.debug("Dummy implementation, the user with identifier: "+externalIdentifier+" will not be imported");
logger.debug("Dummy implementation, the user with identifier: " + externalIdentifier + " will not be imported");
}
@Override
public void importUsersOfRole(final Roles role, boolean includeLinkedEntities) {
logger.debug("Dummy implementation, no users of role: " + role + " will be imported");
}
@Override
public void importProject(long externalIdentifier){
public void importProject(long externalIdentifier) {
logger.debug("Dummy implementation, no project with the id: " + externalIdentifier + " will be imported");
}
@Override
public void importProjects(String title) throws ExternalImportException {
logger.debug("Dummy implementation, no project matching the title: " + title + " will be imported");
}
@Override
public boolean supportsRemoteOperations() {
return false;
}
@Override
public void importSupervisorUnits() throws ExternalImportException {
// TODO Auto-generated method stub
}
@Override
public void importResearchAreas() throws ExternalImportException {
// TODO Auto-generated method stub
}
}

@ -12,7 +12,7 @@
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-autowire="byType">
<jpa:repositories base-package="se.su.dsv.scipro.springdata" />
<jpa:repositories base-package="se.su.dsv.scipro.springdata"/>
<!-- Sets up spring autowire configuration based on annotations -->
<context:annotation-config/>
@ -63,13 +63,19 @@
<!-- Load data initializer for default table-data -->
<bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit"/>
<!-- Importer used for remote importing work, use "ExternalImporterDefaultImpl" if you have no remote-import implementation capable of satisfying "ExternalImporter" interface. -->
<bean id="externalImporter" class="se.su.dsv.scipro.io.impl.ExternalImporterDaisyImpl"/>
<bean id="externalImporter" class="se.su.dsv.scipro.io.impl.ExternalImporterDaisyImpl">
<property name="client" ref="dsvApiClient"/>
</bean>
<bean id="dsvApiClient" class="se.su.dsv.scipro.io.http.ApiClient">
<!-- This property points to the location of the remote system used for json requests -->
<property name="baseUrl" value="${remote.lookup.url}"/>
<property name="user" value="thesis"/>
<property name="password" value="dqyhIM8LU5LQ53T3aJNz4SVXeTQ95dLGkN7JlLOv7X7jeTR2NR"/>
</bean>
<!-- Defines global settings for the application -->
<bean id="applicationSettings" class="se.su.dsv.scipro.ApplicationSettings">
<property name="remoteLookupUrl" value="https://api.dsv.su.se/rest"/>
<property name="remoteLookupUser" value="thesis"/>
<property name="remoteLookupPassword" value="dqyhIM8LU5LQ53T3aJNz4SVXeTQ95dLGkN7JlLOv7X7jeTR2NR"/>
<!-- This property points to the location of the remote system used for json requests -->
<!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.-->
<property name="acceptExternalAuthentication" value="true"/>
</bean>