/** * $Id: SakaiExternalIntegrationProvider.java 123125 2013-04-23 01:03:34Z azeckoski@unicon.net $ * $URL: https://source.sakaiproject.org/svn/entitybroker/trunk/impl/src/java/org/sakaiproject/entitybroker/impl/external/SakaiExternalIntegrationProvider.java $ * ExternalIntegrationProvider.java - entity-broker - Jan 12, 2009 6:24:04 PM - azeckoski ********************************************************************************** * Copyright (c) 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **********************************************************************************/ package org.sakaiproject.entitybroker.impl.external; import java.io.PrintWriter; import java.io.StringWriter; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.email.api.EmailService; import org.sakaiproject.entity.api.EntityManager; import org.sakaiproject.entitybroker.DeveloperHelperService; import org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider; import org.sakaiproject.entitybroker.util.servlet.DirectServlet; import org.sakaiproject.event.api.Event; import org.sakaiproject.event.api.EventTrackingService; import org.sakaiproject.event.api.LearningResourceStoreService; import org.sakaiproject.event.api.NotificationService; import org.sakaiproject.event.api.UsageSession; import org.sakaiproject.event.api.UsageSessionService; import org.sakaiproject.event.api.LearningResourceStoreService.LRS_Statement; import org.sakaiproject.tool.api.Session; import org.sakaiproject.tool.api.SessionManager; /** * This allows EB to integrate with external systems, * this combines with the implementation of {@link DeveloperHelperService} and {@link DirectServlet} * to allow external systems to plugin their own handling without * having to modify the core EB codebase * * @author Aaron Zeckoski (azeckoski @ gmail.com) */ public class SakaiExternalIntegrationProvider implements ExternalIntegrationProvider { private static final Log log = LogFactory.getLog(SakaiExternalIntegrationProvider.class); // SAKAI private EntityManager entityManager; // for find entity by reference public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } private EventTrackingService eventTrackingService; // for fire event public void setEventTrackingService(EventTrackingService eventTrackingService) { this.eventTrackingService = eventTrackingService; } private LearningResourceStoreService learningResourceStoreService; public void setLearningResourceStoreService(LearningResourceStoreService learningResourceStoreService) { this.learningResourceStoreService = learningResourceStoreService; } private ServerConfigurationService serverConfigurationService; public void setServerConfigurationService(ServerConfigurationService serverConfigurationService) { this.serverConfigurationService = serverConfigurationService; } private EmailService emailService; public void setEmailService(EmailService emailService) { this.emailService = emailService; } private UsageSessionService usageSessionService; public void setUsageSessionService(UsageSessionService usageSessionService) { this.usageSessionService = usageSessionService; } private SessionManager sessionManager; public void setSessionManager(SessionManager sessionManager) { this.sessionManager = sessionManager; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider#findService(java.lang.Class) */ @SuppressWarnings("unchecked") public <T> T findService(Class<T> type) { return (T) ComponentManager.getInstance().get(type); } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.impl.ExternalIntegrationProvider#fireEvent(java.lang.String, java.lang.String) */ public void fireEvent(String eventName, String reference) { // had to take out the exists check because it makes firing events for removing entities very annoying -AZ Event event = eventTrackingService.newEvent(eventName, reference, true, NotificationService.PREF_IMMEDIATE); eventTrackingService.post(event); } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.impl.ExternalIntegrationProvider#getServerUrl() */ public String getServerUrl() { return serverConfigurationService.getServerUrl(); } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider#getMaxJSONLevel() */ public String getMaxJSONLevel() { return serverConfigurationService.getString("entitybroker.maxJSONLevel","7"); // default 7 } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider#fetchEntity(java.lang.String) */ public Object fetchEntity(String reference) { Object entity = null; try { // cannot test this in a meaningful way so the tests are designed to not get here -AZ entity = entityManager.newReference(reference).getEntity(); } catch (Exception e) { log.warn("Failed to look up reference '" + reference + "' to an entity in Sakai legacy entity system", e); } return entity; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider#handleUserSessionKey(javax.servlet.http.HttpServletRequest) */ public void handleUserSessionKey(HttpServletRequest req) { // SAKAI // http://jira.sakaiproject.org/jira/browse/SAK-14899 - added support for setting the sakai session id final String SAKAI_SESSION = "sakai.session"; if (req.getParameter(SAKAI_SESSION) != null || req.getParameter(SESSION_ID) != null) { // set the session to the given id if possible or die String sessionId = req.getParameter(SAKAI_SESSION); if (sessionId == null) { sessionId = req.getParameter(SESSION_ID); } try { // this also protects us from null pointer where session service is not set or working Session s = sessionManager.getSession(sessionId); if (s != null) { sessionManager.setCurrentSession(s); } else { throw new IllegalArgumentException("Invalid sakai session id ("+sessionId+") supplied, could not find a valid session with that id to set"); } } catch (Exception e) { throw new IllegalArgumentException("Failure attempting to set sakai session id ("+sessionId+"): " + e.getMessage()); } } } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.providers.ExternalIntegrationProvider#handleEntityError(javax.servlet.http.HttpServletRequest, java.lang.Throwable) */ public String handleEntityError(HttpServletRequest req, Throwable error) { String subject = "Direct request failure: " + error.getClass().getSimpleName() + ":" + error.getMessage(); String sakaiVersion = "Sakai version: " + serverConfigurationService.getString("version.sakai") + "("+serverConfigurationService.getString("version.service")+")\n "; String serverInfo = "Server: " + serverConfigurationService.getServerName() + "("+serverConfigurationService.getServerId()+") ["+serverConfigurationService.getServerIdInstance()+"]\n "; String usageSessionInfo = ""; if (usageSessionService != null) { UsageSession usageSession = usageSessionService.getSession(); if (usageSession != null) { usageSessionInfo = "Server: " + usageSession.getServer() + "\n " //+ "Hostname: " + usageSession.getHostName() + "\n " // removed since this is incompatible with older sakai + "User agent: " + usageSession.getUserAgent() + "\n " + "Browser ID: " + usageSession.getBrowserId() + "\n " + "IP address: " + usageSession.getIpAddress() + "\n " + "User ID: " + usageSession.getUserId() + "\n " + "User EID: " + usageSession.getUserEid() + "\n " + "User Display ID: " + usageSession.getUserDisplayId() + "\n "; } } String requestInfo = ""; if (req != null) { requestInfo = "Request URI: "+req.getRequestURI()+"\n " + "Path Info: "+req.getPathInfo()+"\n " + "Context path: "+req.getContextPath()+"\n " + "Method: "+req.getMethod()+"\n "; } // get the stacktrace out StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); error.printStackTrace(pw); String stacktrace = "Full stacktrace:\n" + error.getClass().getSimpleName() + ":" + error.getMessage() + ":\n" + sw.toString(); String body = subject + ":\n " + sakaiVersion + "\n" + serverInfo + "\n" + requestInfo + "\n" + usageSessionInfo; // attempt to get the email address, if it is not there then we will not send an email String emailAddr = serverConfigurationService.getString("direct.error.email", serverConfigurationService.getString("portal.error.email")); if (emailAddr != null && !"".equals(emailAddr)) { String from = "\"<no-reply@" + serverConfigurationService.getServerName() + ">"; if (emailService != null) { emailService.send(from, emailAddr, subject, body + "\n" + stacktrace, emailAddr, null, null); } else { log.error("Could not send email, no emailService"); } } String errorMessage = subject + ":" + body; log.error(errorMessage + "\n" + stacktrace); return errorMessage; } /** * String type: gets the printable name of this server */ protected static final String SETTING_SERVER_NAME = "server.name"; /** * String type: gets the unique id of this server (safe for clustering if used) */ protected static final String SETTING_SERVER_ID = "server.cluster.id"; /** * String type: gets the URL to this server */ protected static final String SETTING_SERVER_URL = "server.main.URL"; /** * String type: gets the URL to the portal on this server (or just returns the server URL if no * portal in use) */ protected static final String SETTING_PORTAL_URL = "server.portal.URL"; /** * Boolean type: if true then there will be data preloads and DDL creation, if false then data * preloads are disabled (and will cause exceptions if preload data is missing) */ protected static final String SETTING_AUTO_DDL = "auto.ddl"; @SuppressWarnings("unchecked") public <T> T getConfigurationSetting(String settingName, T defaultValue) { T returnValue = defaultValue; if (SETTING_SERVER_NAME.equals(settingName)) { returnValue = (T) serverConfigurationService.getServerName(); } else if (SETTING_SERVER_URL.equals(settingName)) { returnValue = (T) serverConfigurationService.getServerUrl(); } else if (SETTING_PORTAL_URL.equals(settingName)) { returnValue = (T) serverConfigurationService.getPortalUrl(); } else if (SETTING_SERVER_ID.equals(settingName)) { returnValue = (T) serverConfigurationService.getServerIdInstance(); } else { if (defaultValue == null) { returnValue = (T) serverConfigurationService.getString(settingName); if ("".equals(returnValue)) { returnValue = null; } } else { if (defaultValue instanceof Number) { int num = ((Number) defaultValue).intValue(); int value = serverConfigurationService.getInt(settingName, num); returnValue = (T) Integer.valueOf(value); } else if (defaultValue instanceof Boolean) { boolean bool = ((Boolean) defaultValue).booleanValue(); boolean value = serverConfigurationService.getBoolean(settingName, bool); returnValue = (T) Boolean.valueOf(value); } else if (defaultValue instanceof String) { returnValue = (T) serverConfigurationService.getString(settingName, (String) defaultValue); } } } return returnValue; } /* (non-Javadoc) * @see org.sakaiproject.entitybroker.entityprovider.extension.LearningTrackingProvider#registerStatement(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, java.lang.Float) */ public void registerStatement(String prefix, String actorEmail, String verbStr, String objectURI, Boolean resultSuccess, Float resultScaledScore) { if (prefix == null || "".equals(prefix)) { throw new IllegalArgumentException("prefix must be set"); } LRS_Statement statement = new LRS_Statement(actorEmail, verbStr, objectURI); if (resultSuccess != null && resultScaledScore != null) { statement = new LRS_Statement(actorEmail, verbStr, objectURI, resultSuccess.booleanValue(), resultScaledScore.floatValue()); } else { statement = new LRS_Statement(actorEmail, verbStr, objectURI); } learningResourceStoreService.registerStatement(statement, prefix); } }