diff --git a/src/main/java/org/olat/core/logging/activity/LoggingObject.hbm.xml b/src/main/java/org/olat/core/logging/activity/LoggingObject.hbm.xml deleted file mode 100644 index 9d5c84901c7f7b3b6960d291ca703016064236c8..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/logging/activity/LoggingObject.hbm.xml +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD//EN" - "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping default-lazy="false"> - <class name="org.olat.core.logging.activity.LoggingObject" - table="o_loggingtable"> - - -<!-- ================================================================================== --> -<!-- Technical fields --> -<!-- ================================================================================== --> - <id name="key" column="log_id" type="long" unsaved-value="null"> - <generator class="enhanced-sequence"> - <param name="sequence_name">hibernate_unique_key</param> - <param name="force_table_use">true</param> - <param name="optimizer">legacy-hilo</param> - <param name="value_column">next_hi</param> - <param name="increment_size">32767</param> - <param name="initial_value">32767</param> - </generator> - </id> - <property name="creationDate" column="creationdate" type="timestamp"/> - <property name="sourceClass" type="string"> - <column name="sourceclass" length="512" sql-type="varchar(512)" not-null="false" /> - </property> -<!-- ================================================================================== --> - - -<!-- ================================================================================== --> -<!-- Session and User Reference --> -<!-- ================================================================================== --> - <property name="sessionId" column="sessionid" type="string" length="255" not-null="true" /> - <property name="userId" column="user_id" type="long"/> -<!-- ================================================================================== --> - - -<!-- ================================================================================== --> -<!-- Action Fields --> -<!-- ================================================================================== --> - <property name="actionCrudType" column="actioncrudtype" type="string" length="1" not-null="true" /> - <property name="actionVerb" column="actionverb" type="string" length="16" not-null="true" /> - <property name="actionObject" column="actionobject" type="string" length="32" not-null="true" /> - <property name="resourceAdminAction" column="resourceadminaction" type="boolean" length="1" not-null="true"/> - <property name="simpleDuration" column="simpleduration" type="long" /> -<!-- ================================================================================== --> - -<!-- ================================================================================== --> -<!-- Scope Fields --> -<!-- ================================================================================== --> - <property name="businessPath" type="string" > - <column name="businesspath" length="2048" not-null="false" sql-type="varchar(2048)"/> - </property> - <property name="greatGrandParentResType" column="greatgrandparentrestype" type="string" length="32" not-null="false" /> - <property name="greatGrandParentResId" column="greatgrandparentresid" type="string" length="64" not-null="false" /> - <property name="greatGrandParentResName" column="greatgrandparentresname" type="string" length="255" not-null="false" /> - <property name="grandParentResType" column="grandparentrestype" type="string" length="32" not-null="false" /> - <property name="grandParentResId" column="grandparentresid" type="string" length="64" not-null="false" /> - <property name="grandParentResName" column="grandparentresname" type="string" length="255" not-null="false" /> - <property name="parentResType" column="parentrestype" type="string" length="32" not-null="false" /> - <property name="parentResId" column="parentresid" type="string" length="64" not-null="false" /> - <property name="parentResName" column="parentresname" type="string" length="255" not-null="false" /> - <property name="targetResType" column="targetrestype" type="string" length="32" not-null="false" /> - <property name="targetResId" column="targetresid" type="string" length="64" not-null="false" /> - <property name="targetResName" column="targetresname" type="string" length="255" not-null="false" /> -<!-- ================================================================================== --> - -<!-- A NOTE ON THE sql-update check none BELOW: - - OLAT-4109 - - What we want to achieve with the statement below is to DISABLE THE HIBERNATE "EXPECTATION CHECK" - - i.e. when you do a normal update with hibernate, it checks the number of changed rows to match - the number it expected - with update on single objects the expected number is 1. - Now with the Logging-DB setup we have @ UZH - where we have a master mysql database which has - BLACKHOLE configured as the table engine for the o_loggingtable and a slave mysql database which - is configured in a replication setup to retrieve all updates from the master, we only have - the o_loggingtable on the slave - it is completely empty (BLACKHOLE) on the master. - This will conflict with insert/update combinations - since after the insert, the logging entry - is not really in the master's o_loggingtable but only in the slave - hence the update check would fail. - Hence we want to disable it. - - Now there are not many ways in hibernate (at least they haven't been discovered) to do this. One is - to use FlushMode.MANUAL (but that can't be used with multiple logging events per transaction) and - below check="none". - - The only implication/limitation of check="none" is that you CANT USE - - DBFactory.getInstance().updateObject(logObj); - - because it will fail with the BLACKHOLE@UZH setup! - - Instead you must do manual updating via something like this: - - DBQuery update = DBFactory.getInstance().createQuery( - "update org.olat.core.logging.activity.LoggingObject set simpleDuration = :duration where log_id = :logid"); - update.setLong("duration", duration); - update.setLong("logid", lastLogObj.getKey()); - update.executeUpdate(FlushMode.AUTO); - --> - <sql-update check="none"/> - - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/src/main/java/org/olat/core/logging/activity/LoggingObject.java b/src/main/java/org/olat/core/logging/activity/LoggingObject.java index 8d3c43839a75bf6d1c3bedaa66a30dcc63658e62..ea32fc9b2fadf48b75c2e3c0fc6c0c7925eeab37 100644 --- a/src/main/java/org/olat/core/logging/activity/LoggingObject.java +++ b/src/main/java/org/olat/core/logging/activity/LoggingObject.java @@ -26,7 +26,20 @@ package org.olat.core.logging.activity; -import org.olat.core.commons.persistence.PersistentObject; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; +import org.olat.core.id.CreateInfo; +import org.olat.core.id.Persistable; /** * Hibernate class representing a <i>log line</i> - @@ -35,36 +48,76 @@ import org.olat.core.commons.persistence.PersistentObject; * Initial Date: 20.10.2009 <br> * @author Stefan */ -public class LoggingObject extends PersistentObject { +@Entity(name="loggingobject") +@Table(name="o_loggingtable") +public class LoggingObject implements CreateInfo, Persistable { private static final long serialVersionUID = -7960024949707705523L; + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "enhanced-sequence", parameters={ + @Parameter(name="sequence_name", value="hibernate_unique_key"), + @Parameter(name="force_table_use", value="true"), + @Parameter(name="optimizer", value="legacy-hilo"), + @Parameter(name="value_column", value="next_hi"), + @Parameter(name="increment_size", value="32767"), + @Parameter(name="initial_value", value="32767") + }) + @Column(name="log_id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + // technical fields + @Column(name="sourceclass", nullable=true, insertable=true, updatable=true) private String sourceClass; // session and user fields + @Column(name="sessionid", nullable=true, insertable=true, updatable=true) private String sessionId; + @Column(name="user_id", nullable=true, insertable=true, updatable=true) private long userId; // action fields + @Column(name="actioncrudtype", nullable=true, insertable=true, updatable=true) private String actionCrudType; + @Column(name="actionverb", nullable=true, insertable=true, updatable=true) private String actionVerb; + @Column(name="actionobject", nullable=true, insertable=true, updatable=true) private String actionObject; + @Column(name="resourceadminaction", nullable=true, insertable=true, updatable=true) private Boolean resourceAdminAction; + @Column(name="simpleduration", nullable=true, insertable=true, updatable=true) private long simpleDuration; // scope fields + @Column(name="businesspath", nullable=true, insertable=true, updatable=true) private String businessPath; + @Column(name="greatgrandparentrestype", nullable=true, insertable=true, updatable=true) private String greatGrandParentResType; + @Column(name="greatgrandparentresid", nullable=true, insertable=true, updatable=true) private String greatGrandParentResId; + @Column(name="greatgrandparentresname", nullable=true, insertable=true, updatable=true) private String greatGrandParentResName; + @Column(name="grandparentrestype", nullable=true, insertable=true, updatable=true) private String grandParentResType; + @Column(name="grandparentresid", nullable=true, insertable=true, updatable=true) private String grandParentResId; + @Column(name="grandparentresname", nullable=true, insertable=true, updatable=true) private String grandParentResName; + @Column(name="parentrestype", nullable=true, insertable=true, updatable=true) private String parentResType; + @Column(name="parentresid", nullable=true, insertable=true, updatable=true) private String parentResId; + @Column(name="parentresname", nullable=true, insertable=true, updatable=true) private String parentResName; + @Column(name="targetrestype", nullable=true, insertable=true, updatable=true) private String targetResType; + @Column(name="targetresid", nullable=true, insertable=true, updatable=true) private String targetResId; + @Column(name="targetresname", nullable=true, insertable=true, updatable=true) private String targetResName; public LoggingObject(){ @@ -181,35 +234,53 @@ public class LoggingObject extends PersistentObject { // Following are generated setters and getters // - public final String getSourceClass() { + @Override + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + @Override + public Date getCreationDate() { + return creationDate; + } + + public String getSourceClass() { return sourceClass; } - public final void setSourceClass(String sourceClass) { + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public void setSourceClass(String sourceClass) { this.sourceClass = sourceClass; } - public final String getSessionId() { + public String getSessionId() { return sessionId; } - public final void setSessionId(String sessionId) { + public void setSessionId(String sessionId) { this.sessionId = sessionId; } - public final long getUserId() { + public long getUserId() { return userId; } - public final void setUserId(long userId) { + public void setUserId(long userId) { this.userId = userId; } - public final String getActionCrudType() { + public String getActionCrudType() { return actionCrudType; } - public final String getActionCrudTypeVerbose() { + public String getActionCrudTypeVerbose() { if ("c".equals(actionCrudType)) { return "create"; } else if ("r".equals(actionCrudType)) { @@ -226,146 +297,168 @@ public class LoggingObject extends PersistentObject { } } - public final void setActionCrudType(String actionCrudType) { + public void setActionCrudType(String actionCrudType) { if (actionCrudType.length()>1) { throw new IllegalArgumentException("actionCrudType must be of length 1"); } this.actionCrudType = actionCrudType; } - public final String getActionVerb() { + public String getActionVerb() { return actionVerb; } - public final void setActionVerb(String actionverb) { + public void setActionVerb(String actionverb) { this.actionVerb = actionverb; } - public final String getActionObject() { + public String getActionObject() { return actionObject; } - public final void setActionObject(String actionobject) { + public void setActionObject(String actionobject) { this.actionObject = actionobject; } - public final Boolean getResourceAdminAction() { + public Boolean getResourceAdminAction() { return resourceAdminAction; } - public final void setResourceAdminAction(Boolean resourceAdminAction) { + public void setResourceAdminAction(Boolean resourceAdminAction) { this.resourceAdminAction = resourceAdminAction; } - public final long getSimpleDuration() { + public long getSimpleDuration() { return simpleDuration; } - public final void setSimpleDuration(long duration) { + public void setSimpleDuration(long duration) { this.simpleDuration = duration; } - public final String getBusinessPath() { + public String getBusinessPath() { return businessPath; } - public final void setBusinessPath(String businessPath) { + public void setBusinessPath(String businessPath) { this.businessPath = businessPath; } - public final String getGreatGrandParentResType() { + public String getGreatGrandParentResType() { return greatGrandParentResType; } - public final void setGreatGrandParentResType(String greatGrandParentResType) { + public void setGreatGrandParentResType(String greatGrandParentResType) { this.greatGrandParentResType = greatGrandParentResType; } - public final String getGreatGrandParentResId() { + public String getGreatGrandParentResId() { return greatGrandParentResId; } - public final void setGreatGrandParentResId(String greatGrandParentResId) { + public void setGreatGrandParentResId(String greatGrandParentResId) { this.greatGrandParentResId = greatGrandParentResId; } - public final String getGreatGrandParentResName() { + public String getGreatGrandParentResName() { return greatGrandParentResName; } - public final void setGreatGrandParentResName(String greatGrandParentResName) { + public void setGreatGrandParentResName(String greatGrandParentResName) { this.greatGrandParentResName = greatGrandParentResName; } - public final String getGrandParentResType() { + public String getGrandParentResType() { return grandParentResType; } - public final void setGrandParentResType(String grandParentResType) { + public void setGrandParentResType(String grandParentResType) { this.grandParentResType = grandParentResType; } - public final String getGrandParentResId() { + public String getGrandParentResId() { return grandParentResId; } - public final void setGrandParentResId(String grandParentResId) { + public void setGrandParentResId(String grandParentResId) { this.grandParentResId = grandParentResId; } - public final String getGrandParentResName() { + public String getGrandParentResName() { return grandParentResName; } - public final void setGrandParentResName(String grandParentResName) { + public void setGrandParentResName(String grandParentResName) { this.grandParentResName = grandParentResName; } - public final String getParentResType() { + public String getParentResType() { return parentResType; } - public final void setParentResType(String parentResType) { + public void setParentResType(String parentResType) { this.parentResType = parentResType; } - public final String getParentResId() { + public String getParentResId() { return parentResId; } - public final void setParentResId(String parentResId) { + public void setParentResId(String parentResId) { this.parentResId = parentResId; } - public final String getParentResName() { + public String getParentResName() { return parentResName; } - public final void setParentResName(String parentResName) { + public void setParentResName(String parentResName) { this.parentResName = parentResName; } - public final String getTargetResType() { + public String getTargetResType() { return targetResType; } - public final void setTargetResType(String targetResType) { + public void setTargetResType(String targetResType) { this.targetResType = targetResType; } - public final String getTargetResId() { + public String getTargetResId() { return targetResId; } - public final void setTargetResId(String targetResId) { + public void setTargetResId(String targetResId) { this.targetResId = targetResId; } - public final String getTargetResName() { + public String getTargetResName() { return targetResName; } - public final void setTargetResName(String targetResName) { + public void setTargetResName(String targetResName) { this.targetResName = targetResName; } + + @Override + public int hashCode() { + return getKey() == null ? -9265 : getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof LoggingObject) { + LoggingObject logObject = (LoggingObject)obj; + return getKey() != null && getKey().equals(logObject.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } } diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java index 8cddc63f3c9f6e13daad770cf28f1fc9ebb098aa..085618d41a9a3779907780eb152c61dd9fc09e35 100644 --- a/src/main/java/org/olat/course/CourseFactory.java +++ b/src/main/java/org/olat/course/CourseFactory.java @@ -695,15 +695,10 @@ public class CourseFactory { // make an intermediate commit here to make sure long running course log export doesn't // cause db connection timeout to be triggered - //@TODO transactions/backgroundjob: // rework when backgroundjob infrastructure exists DBFactory.getInstance().intermediateCommit(); - AsyncExportManager.getInstance().asyncArchiveCourseLogFiles(archiveOnBehalfOf, new Runnable() { - @Override - public void run() { - // that's fine, I dont need to do anything here - }; - }, course.getResourceableId(), exportDirectory.getPath(), null, null, aLogV, uLogV, sLogV, charset, null, null); + CoreSpringFactory.getImpl(AsyncExportManager.class).asyncArchiveCourseLogFiles(archiveOnBehalfOf, () -> { /* nothing to do */ }, + course.getResourceableId(), exportDirectory.getPath(), null, null, aLogV, uLogV, sLogV, null, null); course.getCourseEnvironment().getCourseGroupManager().archiveCourseGroups(exportDirectory); diff --git a/src/main/java/org/olat/course/archiver/CourseLogsArchiveController.java b/src/main/java/org/olat/course/archiver/CourseLogsArchiveController.java index 28438fb1ac420a8db90f75ea3de6794c1d417f5f..0f5fd5a5867e847ce228ab261bc1cddc959e1110 100644 --- a/src/main/java/org/olat/course/archiver/CourseLogsArchiveController.java +++ b/src/main/java/org/olat/course/archiver/CourseLogsArchiveController.java @@ -54,7 +54,6 @@ import org.olat.course.statistic.AsyncExportManager; import org.olat.home.HomeMainController; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; -import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; /** @@ -68,14 +67,16 @@ public class CourseLogsArchiveController extends BasicController { private Panel myPanel; private VelocityContainer myContent; - private LogFileChooserForm logFileChooserForm; private Link showFileButton; private OLATResourceable ores; private CloseableModalController cmc; + private LogFileChooserForm logFileChooserForm; @Autowired private RepositoryManager repositoryManager; + @Autowired + private AsyncExportManager asyncExportManager; /** * Constructor for the course logs archive controller @@ -102,7 +103,7 @@ public class CourseLogsArchiveController extends BasicController { boolean uLogV = isOLATAdmin; boolean sLogV = isOresOwner || isOresInstitutionalManager; - if (AsyncExportManager.getInstance().asyncArchiveCourseLogOngoingFor(ureq.getIdentity())) { + if (asyncExportManager.asyncArchiveCourseLogOngoingFor(getIdentity())) { // then show the ongoing feedback showExportOngoing(false); } else if (isOLATAdmin || aLogV || uLogV || sLogV){ @@ -118,10 +119,10 @@ public class CourseLogsArchiveController extends BasicController { if (exportDir!=null && exportDir.exists() && exportDir.isDirectory()) { exportDirExists = true; } - myContent.contextPut("hascourselogarchive", new Boolean(exportDirExists)); + myContent.contextPut("hascourselogarchive", Boolean.valueOf(exportDirExists)); myPanel.setContent(myContent); } else { - myContent.contextPut("hasLogArchiveAccess", new Boolean(false)); + myContent.contextPut("hasLogArchiveAccess", Boolean.valueOf(false)); myPanel.setContent(myContent); } @@ -131,87 +132,75 @@ public class CourseLogsArchiveController extends BasicController { @Override public void event(UserRequest ureq, Component source, Event event) { if (source == showFileButton){ - ICourse course = CourseFactory.loadCourse(ores); - String personalFolderDir = CourseFactory.getPersonalDirectory(ureq.getIdentity()).getPath(); - String targetDir = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), course.getCourseTitle()).getPath(); - - String relPath = ""; - - if (targetDir.startsWith(personalFolderDir)) { - // that should always be the case - - relPath = targetDir.substring(personalFolderDir.length()).replace("\\", "/"); - targetDir = targetDir.substring(0, personalFolderDir.length()); - } - - VFSContainer targetFolder = new LocalFolderImpl(new File(targetDir)); - FolderRunController bcrun = new FolderRunController(targetFolder, true, ureq, getWindowControl()); - Component folderComponent = bcrun.getInitialComponent(); - if (relPath.length()!=0) { - if (!relPath.endsWith("/")) { - relPath = relPath + "/"; - } - bcrun.activatePath(ureq, relPath); - } - - String personalFolder = Util.createPackageTranslator(HomeMainController.class, ureq.getLocale(), null).translate("menu.bc"); - - removeAsListenerAndDispose(cmc); - cmc = new CloseableModalController( - getWindowControl(), translate("close"), folderComponent, true, personalFolder - ); - listenTo(cmc); - - cmc.activate(); + doShowFiles(ureq); } } @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == logFileChooserForm) { - if (event == Event.DONE_EVENT) { - final boolean logAdminChecked = logFileChooserForm.logAdminChecked(); - final boolean logUserChecked = logFileChooserForm.logUserChecked(); - final boolean logStatisticChecked = logFileChooserForm.logStatChecked(); - - final Date begin = logFileChooserForm.getBeginDate(); - final Date end = logFileChooserForm.getEndDate(); - - if (end != null) { - //shift time from beginning to end of day - end.setTime(end.getTime() + 24 * 60 * 60 * 1000); - } - - UserManager um = UserManager.getInstance(); - final String charset = um.getUserCharset(ureq.getIdentity()); - - ICourse course = CourseFactory.loadCourse(ores); - final String courseTitle = course.getCourseTitle(); - final String targetDir = CourseFactory.getOrCreateDataExportDirectory(ureq.getIdentity(), courseTitle).getPath(); - - final Long resId = ores.getResourceableId(); - final Locale theLocale = ureq.getLocale(); - final String email = ureq.getIdentity().getUser().getProperty(UserConstants.EMAIL, ureq.getLocale()); - - - AsyncExportManager.getInstance().asyncArchiveCourseLogFiles(ureq.getIdentity(), new Runnable() { - - @Override - public void run() { - showExportFinished(); - } - - }, - resId, targetDir, begin, end, logAdminChecked, logUserChecked, logStatisticChecked, charset, theLocale, email); + if (event == Event.DONE_EVENT) { + doStartLog(); + showExportOngoing(true); + } + } + } + + private void doStartLog() { + final boolean logAdminChecked = logFileChooserForm.logAdminChecked(); + final boolean logUserChecked = logFileChooserForm.logUserChecked(); + final boolean logStatisticChecked = logFileChooserForm.logStatChecked(); + final Date begin = logFileChooserForm.getBeginDate(); + final Date end = logFileChooserForm.getEndDate(); + + if (end != null) { + //shift time from beginning to end of day + end.setTime(end.getTime() + 24 * 60 * 60 * 1000); + } + + ICourse course = CourseFactory.loadCourse(ores); + final String courseTitle = course.getCourseTitle(); + final String targetDir = CourseFactory.getOrCreateDataExportDirectory(getIdentity(), courseTitle).getPath(); + + final Long resId = ores.getResourceableId(); + final Locale theLocale = getLocale(); + final String email = getIdentity().getUser().getProperty(UserConstants.EMAIL, getLocale()); - showExportOngoing(true); - } else if (event == Event.DONE_EVENT) { - myPanel.setContent(myContent); + asyncExportManager.asyncArchiveCourseLogFiles(getIdentity(), this::showExportFinished, + resId, targetDir, begin, end, logAdminChecked, logUserChecked, logStatisticChecked, theLocale, email); + } + + private void doShowFiles(UserRequest ureq) { + ICourse course = CourseFactory.loadCourse(ores); + String personalFolderDir = CourseFactory.getPersonalDirectory(getIdentity()).getPath(); + String targetDir = CourseFactory.getOrCreateDataExportDirectory(getIdentity(), course.getCourseTitle()).getPath(); + + String relPath = ""; + if (targetDir.startsWith(personalFolderDir)) { + // that should always be the case + relPath = targetDir.substring(personalFolderDir.length()).replace("\\", "/"); + targetDir = targetDir.substring(0, personalFolderDir.length()); + } + + VFSContainer targetFolder = new LocalFolderImpl(new File(targetDir)); + FolderRunController bcrun = new FolderRunController(targetFolder, true, ureq, getWindowControl()); + Component folderComponent = bcrun.getInitialComponent(); + if (relPath.length()!=0) { + if (!relPath.endsWith("/")) { + relPath = relPath + "/"; } + bcrun.activatePath(ureq, relPath); } + + String personalFolder = Util.createPackageTranslator(HomeMainController.class, ureq.getLocale(), null).translate("menu.bc"); + + removeAsListenerAndDispose(cmc); + cmc = new CloseableModalController(getWindowControl(), translate("close"), folderComponent, true, personalFolder); + listenTo(cmc); + cmc.activate(); } - private void showExportOngoing(final boolean thisCourse) { + private void showExportOngoing(boolean thisCourse) { VelocityContainer vcOngoing = createVelocityContainer("courselogs_ongoing"); if (thisCourse) { vcOngoing.contextPut("body", translate("course.logs.ongoing")); @@ -236,10 +225,9 @@ public class CourseLogsArchiveController extends BasicController { showInfo("course.logs.finished", course.getCourseTitle()); } - + @Override protected void doDispose() { //has nothing to dispose so far } - } diff --git a/src/main/java/org/olat/course/statistic/AsyncExportManager.java b/src/main/java/org/olat/course/statistic/AsyncExportManager.java index dc97d933cbbe0ecb50a3f09cd4ac26d2e3ab21a6..a6ae771dd525319988e2185041a76fb39bb81ed3 100644 --- a/src/main/java/org/olat/course/statistic/AsyncExportManager.java +++ b/src/main/java/org/olat/course/statistic/AsyncExportManager.java @@ -29,10 +29,15 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; +import org.olat.basesecurity.BaseSecurity; +import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.commons.services.taskexecutor.TaskExecutorManager; import org.olat.core.id.Identity; +import org.olat.core.id.Roles; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * Handles asynchronous aspects of log export - including limiting the @@ -41,56 +46,31 @@ import org.olat.core.logging.Tracing; * Initial Date: 13.01.2010 <br> * @author Stefan */ +@Service public class AsyncExportManager { - /** the logging object used in this class **/ - private static final OLog log_ = Tracing.createLoggerFor(AsyncExportManager.class); + private static final OLog log = Tracing.createLoggerFor(AsyncExportManager.class); - /** AsyncExportManager is a singleton, configured by spring **/ - private static AsyncExportManager INSTANCE; + private static final int concurrentExportsPerNode = 2; - /** set via spring **/ - private int concurrentExportsPerNode_ = 1; - + @Autowired + private ExportManager exportManager; + @Autowired + private BaseSecurity securityManager; + @Autowired + private BaseSecurityModule securityModule; + @Autowired private TaskExecutorManager taskExecutorManager; /** the identities currently executing an export **/ - private final Set<Identity> identitiesOfJobsCurrentlyRunning_ = new HashSet<Identity>(); + private final Set<Identity> identitiesOfJobsCurrentlyRunning = new HashSet<>(); /** DEBUG ONLY: how many runnables are queued up - are we overloading the ThreadPoolTaskExecutor ? **/ - private int waitingCnt_ = 0; - - /** created via spring **/ - private AsyncExportManager() { - // this empty constructor is okay - INSTANCE = this; - } - - /** - * [used by Spring] - * @param taskExecutorManager - */ - public void setTaskExecutorManager(TaskExecutorManager taskExecutorManager) { - this.taskExecutorManager = taskExecutorManager; - } + private int waitingCnt = 0; - /** - * @return Singleton. - */ - public static final AsyncExportManager getInstance() { - if (INSTANCE==null) { - throw new IllegalStateException("AsyncExportManager bean not created via spring. Configuration error!"); - } - return INSTANCE; - } - - /** called via spring, sets the number of concurrent exports within one node, default is 2 **/ - public void setConcurrentExportsPerNode(int concurrentExportsPerNode) { - this.concurrentExportsPerNode_ = concurrentExportsPerNode; - } - public void asyncArchiveCourseLogFiles(final Identity identity, final Runnable callback, - final Long oresID, final String exportDir, final Date begin, final Date end, final boolean adminLog, final boolean userLog, final boolean statisticLog, final String charset, final Locale locale, final String email){ + public void asyncArchiveCourseLogFiles(Identity identity, Runnable callback, Long oresID, String exportDir, + Date begin, Date end, boolean adminLog, boolean userLog, boolean statisticLog, Locale locale, String email){ // argument checks if (identity==null) { throw new IllegalArgumentException("identity must not be null"); @@ -100,11 +80,13 @@ public class AsyncExportManager { } // DEBUG ONLY - synchronized(this) { - log_.info("asyncArchiveCourseLogFiles: user "+identity.getName()+" wants to archive a course log. Already pending jobs: "+waitingCnt_); - } + log.info("asyncArchiveCourseLogFiles: user " + identity.getKey() + " wants to archive a course log. Already pending jobs: " + waitingCnt); + + Roles roles = securityManager.getRoles(identity); + boolean isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); - CourseLogRunnable run = new CourseLogRunnable(identity, callback, oresID, exportDir, begin, end, adminLog, userLog, statisticLog, charset, locale, email); + CourseLogRunnable run = new CourseLogRunnable(identity, callback, oresID, exportDir, begin, end, adminLog, userLog, statisticLog, + locale, email, isAdministrativeUser, this, exportManager); taskExecutorManager.execute(run); } @@ -119,12 +101,15 @@ public class AsyncExportManager { private final boolean adminLog; private final boolean userLog; private final boolean statisticLog; - private final String charset; private final Locale locale; private final String email; + private final boolean isAdministrativeUser; + private final ExportManager exportManager; + private final AsyncExportManager asyncExportManager; public CourseLogRunnable(Identity identity, Runnable callback, Long oresID, String exportDir, Date begin, Date end, - boolean adminLog, boolean userLog, boolean statisticLog, String charset, Locale locale, String email) { + boolean adminLog, boolean userLog, boolean statisticLog, Locale locale, String email, boolean isAdministrativeUser, + AsyncExportManager asyncExportManager, ExportManager exportManager) { this.identity = identity; this.callback = callback; this.oresID = oresID; @@ -134,50 +119,52 @@ public class AsyncExportManager { this.adminLog = adminLog; this.userLog = userLog; this.statisticLog = statisticLog; - this.charset = charset; this.locale = locale; this.email = email; + this.isAdministrativeUser = isAdministrativeUser; + this.asyncExportManager = asyncExportManager; + this.exportManager = exportManager; } @Override public void run() { try{ - log_.info("asyncArchiveCourseLogFiles: user "+identity.getName()+" aquires lock for archiving course log"); - AsyncExportManager.getInstance().waitForSlot(identity); - log_.info("asyncArchiveCourseLogFiles: user "+identity.getName()+" starts archiving..."); - ExportManager.getInstance().archiveCourseLogFiles(oresID, exportDir, begin, end, adminLog, userLog, statisticLog, charset, locale, email); - log_.info("asyncArchiveCourseLogFiles: user "+identity.getName()+" finished archiving..."); + log.info("asyncArchiveCourseLogFiles: user " + identity.getKey() + " aquires lock for archiving course log"); + asyncExportManager.waitForSlot(identity); + log.info("asyncArchiveCourseLogFiles: user " + identity.getKey() + " starts archiving..."); + exportManager.archiveCourseLogFiles(oresID, exportDir, begin, end, adminLog, userLog, statisticLog, locale, email, isAdministrativeUser); + log.info("asyncArchiveCourseLogFiles: user " + identity.getKey() + " finished archiving..."); } finally { - AsyncExportManager.getInstance().returnSlot(identity); - log_.info("asyncArchiveCourseLogFiles: user "+identity.getName()+" releases lock for archiving course log"); + asyncExportManager.returnSlot(identity); + log.info("asyncArchiveCourseLogFiles: user " + identity.getKey() + " releases lock for archiving course log"); callback.run(); } } } public synchronized boolean asyncArchiveCourseLogOngoingFor(Identity identity) { - return identitiesOfJobsCurrentlyRunning_.contains(identity); + return identitiesOfJobsCurrentlyRunning.contains(identity); } /** internal counter method **/ private synchronized void waitForSlot(Identity identity) { - waitingCnt_++; - while(identitiesOfJobsCurrentlyRunning_.size()>concurrentExportsPerNode_ || identitiesOfJobsCurrentlyRunning_.contains(identity)) { + waitingCnt++; + while(identitiesOfJobsCurrentlyRunning.size()>concurrentExportsPerNode || identitiesOfJobsCurrentlyRunning.contains(identity)) { try{ - log_.info("waitForSlot: user "+identity.getName()+" wants to archive a course log, but the queue is full. Running count: "+identitiesOfJobsCurrentlyRunning_.size()+". Total pending jobs: "+waitingCnt_); + log.info("waitForSlot: user "+identity.getName()+" wants to archive a course log, but the queue is full. Running count: "+identitiesOfJobsCurrentlyRunning.size()+". Total pending jobs: "+waitingCnt); wait(); } catch(InterruptedException ie) { // this empty catch is ok } } - waitingCnt_--; - identitiesOfJobsCurrentlyRunning_.add(identity); + waitingCnt--; + identitiesOfJobsCurrentlyRunning.add(identity); } /** internal counter method **/ private synchronized void returnSlot(Identity identity) { - identitiesOfJobsCurrentlyRunning_.remove(identity); - log_.info("returnSlot: user "+identity.getName()+" returns a slot. Running count: "+identitiesOfJobsCurrentlyRunning_.size()+", Total pending jobs: "+waitingCnt_); + identitiesOfJobsCurrentlyRunning.remove(identity); + log.info("returnSlot: user "+identity.getName()+" returns a slot. Running count: "+identitiesOfJobsCurrentlyRunning.size()+", Total pending jobs: "+waitingCnt); notifyAll(); } } diff --git a/src/main/java/org/olat/course/statistic/ExportManager.java b/src/main/java/org/olat/course/statistic/ExportManager.java index 7e66a14a86be04dda2243e5e9d33adc3c1248273..0291a33aa59c7dd340b88b7799a93807963d35f2 100644 --- a/src/main/java/org/olat/course/statistic/ExportManager.java +++ b/src/main/java/org/olat/course/statistic/ExportManager.java @@ -31,25 +31,24 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.Set; +import java.util.stream.Collectors; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.translator.Translator; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.manager.BasicManager; import org.olat.core.util.ExportUtil; +import org.olat.core.util.FileUtils; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.mail.MailBundle; import org.olat.core.util.mail.MailManager; -import org.olat.core.util.vfs.LocalFileImpl; -import org.olat.core.util.vfs.LocalFolderImpl; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.VFSLeaf; import org.olat.course.statistic.export.ICourseLogExporter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -59,27 +58,25 @@ import org.olat.course.statistic.export.ICourseLogExporter; * Initial Date: 19.11.2009 <br> * @author bja */ -public class ExportManager extends BasicManager { +@Service +public class ExportManager { - /** the logging object used in this class **/ - private static final OLog log_ = Tracing.createLoggerFor(ExportManager.class); + private static final OLog log = Tracing.createLoggerFor(ExportManager.class); - /** ExportManager is a singleton, configured by spring **/ - private static ExportManager INSTANCE; /** * filename used to store courseauthor's activities (personalized) */ - private static final String FILENAME_ADMIN_LOG = "course_admin_log.csv"; + private static final String FILENAME_ADMIN_LOG = "course_admin_log.xlsx"; /** * filename used to store all user's activities (personalized) in the course * only visible for OLAT-admins */ - private static final String FILENAME_USER_LOG = "course_user_log.csv"; + private static final String FILENAME_USER_LOG = "course_user_log.xlsx"; /** * filename used to store all user's activities (anonymized) in the course */ - private static final String FILENAME_STATISTIC_LOG = "course_statistic_log.csv"; + private static final String FILENAME_STATISTIC_LOG = "course_statistic_log.xlsx"; /** * zip filename substring (archive log files) */ @@ -89,29 +86,9 @@ public class ExportManager extends BasicManager { */ public static final String COURSE_STATISTIC = "CourseStatistic"; - /** injected via spring **/ + @Autowired private ICourseLogExporter courseLogExporter; - /** created via spring **/ - private ExportManager() { - INSTANCE = this; - } - - /** injected via spring **/ - public void setCourseLogExporter(ICourseLogExporter courseLogExporter) { - this.courseLogExporter = courseLogExporter; - } - - /** - * @return Singleton. - */ - public static final ExportManager getInstance() { - if (INSTANCE==null) { - throw new IllegalStateException("ExportManager bean not created via spring. Configuration error!"); - } - return INSTANCE; - } - /** * Archives the course log files * @param oresID @@ -125,26 +102,29 @@ public class ExportManager extends BasicManager { * @param locale * @param email */ - public void archiveCourseLogFiles(Long oresID, String exportDir, Date begin, Date end, boolean adminLog, boolean userLog, boolean statisticLog, String charset, Locale locale, String email){ + public void archiveCourseLogFiles(Long oresID, String exportDir, Date begin, Date end, boolean adminLog, boolean userLog, boolean statisticLog, + Locale locale, String email, boolean isAdministrativeUser){ String zipName = ExportUtil.createFileNameWithTimeStamp(ExportManager.COURSE_LOG_FILES, "zip"); Date date = new Date(); String tmpDirName = oresID + "-" + date.getTime(); - final VFSContainer tmpDirVFSContainer = new LocalFolderImpl(new File(WebappHelper.getTmpDir(), tmpDirName)); - final File tmpDir = new File(WebappHelper.getTmpDir(), tmpDirName); + File tmpDir = new File(WebappHelper.getTmpDir(), tmpDirName); + if(!tmpDir.exists()) { + tmpDir.mkdirs(); + } - List<VFSItem> logFiles = new ArrayList<VFSItem>(); + List<File> logFiles = new ArrayList<>(); if (adminLog) { - logFiles.add(createLogFile(oresID, begin, end, charset, tmpDirVFSContainer, tmpDir, FILENAME_ADMIN_LOG, true, false)); + logFiles.add(createLogFile(oresID, begin, end, tmpDir, FILENAME_ADMIN_LOG, true, false, isAdministrativeUser)); } if (userLog) { - logFiles.add(createLogFile(oresID, begin, end, charset, tmpDirVFSContainer, tmpDir, FILENAME_USER_LOG, false, false)); + logFiles.add(createLogFile(oresID, begin, end, tmpDir, FILENAME_USER_LOG, false, false, isAdministrativeUser)); } if (statisticLog) { - logFiles.add(createLogFile(oresID, begin, end, charset, tmpDirVFSContainer, tmpDir, FILENAME_STATISTIC_LOG, false, true)); + logFiles.add(createLogFile(oresID, begin, end, tmpDir, FILENAME_STATISTIC_LOG, false, true, isAdministrativeUser)); } - saveFile(exportDir, zipName, tmpDirVFSContainer, logFiles, email, "email.archive", locale); + saveFile(exportDir, zipName, tmpDir, logFiles, email, "email.archive", locale); } /** @@ -167,31 +147,24 @@ public class ExportManager extends BasicManager { * @param anonymize * @return */ - private VFSItem createLogFile(Long oresID, Date begin, Date end, String charset, VFSContainer vfsContainer, File dir, String filename, boolean resourceAdminAction, boolean anonymize) { + private File createLogFile(Long oresID, Date begin, Date end, File dir, String filename, + boolean resourceAdminAction, boolean anonymize, boolean isAdministrativeUser) { File outFile = new File(dir, filename); // trigger the course log exporter - it will store the file to outFile - log_.info("createLogFile: start exporting course log file "+outFile.getAbsolutePath()); - courseLogExporter.exportCourseLog(outFile, charset, oresID, begin, end, resourceAdminAction, anonymize); - log_.info("createLogFile: finished exporting course log file "+outFile.getAbsolutePath()); - VFSItem logFile = vfsContainer.resolve(filename); - if (logFile==null) { - log_.warn("createLogFile: could not resolve "+filename); - } - return logFile; + log.info("createLogFile: start exporting course log file "+outFile.getAbsolutePath()); + courseLogExporter.exportCourseLog(outFile, oresID, begin, end, resourceAdminAction, anonymize, isAdministrativeUser); + log.info("createLogFile: finished exporting course log file "+outFile.getAbsolutePath()); + return outFile; } - private void saveFile(String targetDir, String fileName, VFSContainer tmpDir, List<VFSItem> files, String email, String emailI18nSubkey, Locale locale) { - File file = new File(targetDir, fileName); - VFSLeaf exportFile = new LocalFileImpl(file); - if (!ZipUtil.zip(files, exportFile, true)) { - // cleanup zip file - exportFile.delete(); - } else { - // success + private void saveFile(String targetDir, String zipName, File tmpDir, List<File> files, String email, String emailI18nSubkey, Locale locale) { + File zipFile = new File(targetDir, zipName); + Set<String> filenames = files.stream().map(File::getName).collect(Collectors.toSet()); + if (ZipUtil.zip(filenames, tmpDir, zipFile)) { sendEMail(email, locale, emailI18nSubkey); } - removeTemporaryFolder(tmpDir); + FileUtils.deleteDirsAndFiles(tmpDir, true, true); } private void sendEMail(String email, Locale locale, String emailI18nSubkey) { @@ -211,38 +184,13 @@ public class ExportManager extends BasicManager { CoreSpringFactory.getImpl(MailManager.class).sendMessage(bundle); } catch (Exception e) { - log_.error("Error sending information email to user that file was saved successfully.", e); - } - } - -/* private VFSItem createCourseStatisticFile(Long resourceableId, VFSContainer tmpDir, Date begin, Date end, List<ExtendedCondition> conditions, String groupByKey, boolean hasANDConnection, String charset, Locale locale) { - VFSLeaf statisticFile = tmpDir.createChildLeaf(FILENAME_COURSE_STATISTIC); - if(statisticFile == null) { - statisticFile = (VFSLeaf) tmpDir.resolve(FILENAME_COURSE_STATISTIC); + log.error("Error sending information email to user that file was saved successfully.", e); } - // Translator - Translator translator = new PackageTranslator(this.getClass().getPackage().getName(), locale); - - IStatistic simpleCourseStatistic = new SimpleCourseStatistic(begin, end, conditions, groupByKey, hasANDConnection, translator, resourceableId); - FileUtils.save(statisticFile.getOutputStream(true), simpleCourseStatistic.getResult(), charset); - - return statisticFile; } - - public void createCourseStatistic(Long resourceableId, String targetDir, Date begin, Date end, List<ExtendedCondition> conditions, String groupByKey, boolean hasANDConnection, String charset, Locale locale, String email) { - String zipName = ExportUtil.createFileNameWithTimeStamp(ExportManager.COURSE_STATISTIC, "zip"); - Date date = new Date(); - String tmpDirName = resourceableId + "-" + date.getTime(); - VFSContainer tmpDir = new OlatRootFolderImpl(FolderConfig.getRelativeTmpDir() + File.separator + tmpDirName, null); - List<VFSItem> statisticFiles = new ArrayList<VFSItem>(); - statisticFiles.add(createCourseStatisticFile(resourceableId, tmpDir, begin, end, conditions, groupByKey, hasANDConnection, charset, locale)); - saveFile(targetDir, zipName, tmpDir, statisticFiles, email, "email.statistic", locale); - } */ public File getLatestCourseStatisticFile(String targetDir) { File courseStatisticsDir = new File(targetDir); File[] exportedCourseStatisticZipFiles = courseStatisticsDir.listFiles(new FilenameFilter() { - @Override public boolean accept(File dir, String name) { return name.startsWith(ExportManager.COURSE_STATISTIC) && name.endsWith(".zip"); @@ -268,13 +216,4 @@ public class ExportManager extends BasicManager { return newestFile; } - - /** - * remove temporary folder - * @param tmpDir - */ - private void removeTemporaryFolder(VFSContainer tmpDir) { - tmpDir.delete(); - } - } diff --git a/src/main/java/org/olat/course/statistic/_spring/statisticContext.xml b/src/main/java/org/olat/course/statistic/_spring/statisticContext.xml index 95c386231bb2e052da1e1c7d60f74dee726e111f..f4c92bea454744d1fecf4a8c337ddfd8e5f4fe18 100644 --- a/src/main/java/org/olat/course/statistic/_spring/statisticContext.xml +++ b/src/main/java/org/olat/course/statistic/_spring/statisticContext.xml @@ -5,61 +5,6 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - <!-- - ......................................................... - Configuration of ExportManager - required for any version - ......................................................... - - Cluster-Node: - An ExportManager must be configured on every host in a cluster, - plus an AsyncExportManager - --> - - <bean id="logExportManager" - class="org.olat.course.statistic.ExportManager"> - - <property name="courseLogExporter"> - <ref bean="courseLogExporter"/> - </property> - </bean> - - <bean id="asyncLogExportManager" - class="org.olat.course.statistic.AsyncExportManager"> - <property name="taskExecutorManager" ref="taskExecutorManager"/> - <property name="concurrentExportsPerNode" value="2"/> - </bean> - - - <!-- - ........................................................................ - Sample remaining configuration for SimpleLogExporter - ........................................................................ - --> - <bean id="courseLogExporter" class="org.olat.course.statistic.export.SimpleLogExporter"> - <property name="dbInstance" ref="database"/> - <property name="logLineConverter" ref="logLineConverter"/> - </bean> - - <bean id="logLineConverter" - class="org.olat.course.statistic.export.LogLineConverter"> - <property name="orderedExportedProperties"> - <list> - <value>creationDate</value> - <value>userName</value> - <value>actionCrudType</value> - <value>actionVerb</value> - <value>actionObject</value> - <value>parentResName</value> - <value>targetResName</value> - </list> - </property> - <property name="anonymizedProperties"> - <list> - <value>userName</value> - </list> - </property> - </bean> - <!-- STATISTICS BEANS --> <bean id="statisticsJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> diff --git a/src/main/java/org/olat/course/statistic/export/ICourseLogExporter.java b/src/main/java/org/olat/course/statistic/export/ICourseLogExporter.java index 354b638a6aab9b017d2836b39580d25d09287e8e..b0a0fe9d8b29f74e034b5118d932166280f80c22 100644 --- a/src/main/java/org/olat/course/statistic/export/ICourseLogExporter.java +++ b/src/main/java/org/olat/course/statistic/export/ICourseLogExporter.java @@ -56,6 +56,6 @@ public interface ICourseLogExporter { * @param resourceAdminAction * @return */ - public void exportCourseLog(File outFile, String charset, Long resourceableId, Date begin, Date end, boolean resourceAdminAction, boolean anonymize); + public void exportCourseLog(File outFile, Long resourceableId, Date begin, Date end, boolean resourceAdminAction, boolean anonymize, boolean isAdministrativeUser); } diff --git a/src/main/java/org/olat/course/statistic/export/LogLineConverter.java b/src/main/java/org/olat/course/statistic/export/LogLineConverter.java index ffd04b000c072b66dec6d35ed31600edf6fd84b0..3386bd31ded849a78268d9c96c5017b9cc0fde38 100644 --- a/src/main/java/org/olat/course/statistic/export/LogLineConverter.java +++ b/src/main/java/org/olat/course/statistic/export/LogLineConverter.java @@ -24,22 +24,19 @@ */ package org.olat.course.statistic.export; -import static java.util.Locale.ENGLISH; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Set; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; +import org.olat.core.id.Identity; +import org.olat.core.id.User; import org.olat.core.logging.activity.LoggingObject; import org.olat.core.util.Encoder; -import org.olat.core.util.StringHelper; +import org.olat.core.util.openxml.OpenXMLWorkbook; +import org.olat.core.util.openxml.OpenXMLWorksheet; +import org.olat.core.util.openxml.OpenXMLWorksheet.Row; +import org.olat.user.UserManager; +import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * Converter class to take a LoggingObject and convert it into a (csv) line @@ -49,69 +46,14 @@ import org.olat.core.util.StringHelper; * Initial Date: 06.01.2010 <br> * @author Stefan */ +@Service("logLineConverter") public class LogLineConverter { - /** the logging object used in this class **/ - private static final OLog log_ = Tracing.createLoggerFor(LogLineConverter.class); - - /** spring property defining all properties - including the order in which they will be exported **/ - private List<String> orderedExportedProperties = new ArrayList<>(); + public static final String USAGE_IDENTIFIER = LogLineConverter.class.getCanonicalName(); - /** spring property defining all properties which should be anonymized - they must also be in orderedExportedProperties **/ - private Set<String> anonymizedProperties = new HashSet<>(); - - /** internal property which contains (javax.bean) PropertyDescriptors of each of the above property - - * given the properties are available - */ - private List<PropertyDescriptor> orderedExportedPropertyDescriptors = new ArrayList<>(); - - /** - * spring property setter for orderedExportedProperties - which is the list of all properties to be extracted - * from the LoggingObject and exported in the csv format - * @param orderedExportedProperties - */ - public void setOrderedExportedProperties(List<String> orderedExportedProperties) { - this.orderedExportedProperties = orderedExportedProperties; - initPropertyDescriptor(); - } + @Autowired + private UserManager userManager; - /** - * spring property setter for anonymizedProperties - all of these must also be in the orderedExportedProperties list - */ - public void setAnonymizedProperties(Set<String> anonymizedProperties) { - this.anonymizedProperties = anonymizedProperties; - } - - /** - * Returns a String which capitalizes the first letter of the string. - * (c) from java.beans.NameGenerator (which unfortunatelly is not a public class) - */ - public static String capitalize(String name) { - if (name == null || name.length() == 0) { - return name; - } - return name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1); - } - - /** - * Initialize the (java.bean) PropertyDescriptors for the properties - */ - private void initPropertyDescriptor() { - for (Iterator<String> it = orderedExportedProperties.iterator(); it.hasNext();) { - String propertyName = it.next(); - try { - // we're using this specialized constructor since we want to allow properties that are read-only (such as creationDate). - // with the simpler constructor (String,Class) that would result in an Exception. - // also note that we're using "is"+propertyName rather than get - that's the way the PropertyDescriptor itself - // does it in the constructor (String,Class) - resulting in a lookup of an is Method first and then the get Method - // this seems to be the correct standard here. - PropertyDescriptor pd = new PropertyDescriptor(propertyName, LoggingObject.class, "is" + capitalize(propertyName), null); - orderedExportedPropertyDescriptors.add(pd); - } catch (IntrospectionException e) { - log_.error("initPropertyDescriptor: Could not retrieve property "+propertyName+" from LoggingObject, configuration error?", e); - } - } - } /** * Returns the CSV Header line containing all property names in the exact same way as in the config file - @@ -119,13 +61,27 @@ public class LogLineConverter { * @return the CSV Header line containing all property names in the exact same way as in the config file - * excluding those properties which could not be retrieved, i.e. for which no PropertyDescriptor could be created */ - public String getCSVHeader() { - List<String> propertyNames = new ArrayList<>(); - for (Iterator<PropertyDescriptor> it = orderedExportedPropertyDescriptors.iterator(); it.hasNext();) { - PropertyDescriptor pd = it.next(); - propertyNames.add(pd.getName()); + public void setHeader(OpenXMLWorksheet sheet, boolean anonymize, boolean isAdministrativeUser) { + Row row = sheet.newRow(); + + int col = 0; + row.addCell(col++, "creationDate"); + if(isAdministrativeUser) { + row.addCell(col++, "userName"); + } + + if(!anonymize) { + List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(USAGE_IDENTIFIER, isAdministrativeUser); + for (UserPropertyHandler userPropertyHandler:userPropertyHandlers) { + row.addCell(col++, userPropertyHandler.getName()); + } } - return StringHelper.formatAsEscapedCSVString(propertyNames); + + row.addCell(col++, "actionCrudType"); + row.addCell(col++, "actionVerb"); + row.addCell(col++, "actionObject"); + row.addCell(col++, "parentResName"); + row.addCell(col, "targetResName"); } /** @@ -135,28 +91,31 @@ public class LogLineConverter { * @param loggingObject the LoggingObject for which a CSV line should be created * @return the CSV line representing the given LoggingObject */ - public String getCSVRow(LoggingObject loggingObject, boolean anonymize, Long resourceableId) { - List<String> loggingObjectList = new ArrayList<>(); - for (Iterator<PropertyDescriptor> it = orderedExportedPropertyDescriptors.iterator(); it.hasNext();) { - PropertyDescriptor pd = it.next(); + public void setRow(OpenXMLWorkbook workbook, OpenXMLWorksheet sheet, LoggingObject loggingObject, Identity identity, User user, + boolean anonymize, Long resourceableId, boolean isAdministrativeUser) { + Row row = sheet.newRow(); + + int col = 0; + row.addCell(col++, loggingObject.getCreationDate(), workbook.getStyles().getDateTimeStyle()); + if(anonymize) { + row.addCell(col++, makeAnonymous(identity.getName(), resourceableId)); + } else if(isAdministrativeUser) { - String strValue = ""; - try { - Object value = pd.getReadMethod().invoke(loggingObject, (Object[])null); - if (value!=null) { - strValue = String.valueOf(value); - } - if (anonymize && anonymizedProperties.contains(pd.getName())) { - // do anonymization - strValue = makeAnonymous(String.valueOf(value), resourceableId); - } - } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { - // nothing to do - } - loggingObjectList.add(strValue); + row.addCell(col++, identity.getName()); } - return StringHelper.formatAsEscapedCSVString(loggingObjectList); + if(!anonymize) { + List<UserPropertyHandler> userPropertyHandlers = userManager.getUserPropertyHandlersFor(USAGE_IDENTIFIER, isAdministrativeUser); + for (UserPropertyHandler userPropertyHandler:userPropertyHandlers) { + row.addCell(col++, user.getProperty(userPropertyHandler.getName(), null)); + } + } + + row.addCell(col++, loggingObject.getActionCrudType()); + row.addCell(col++, loggingObject.getActionVerb()); + row.addCell(col++, loggingObject.getActionObject()); + row.addCell(col++, loggingObject.getParentResName()); + row.addCell(col, loggingObject.getTargetResName()); } /** @@ -170,5 +129,4 @@ public class LogLineConverter { // encode with MD5 return Encoder.md5hash(encodeValue); } - } diff --git a/src/main/java/org/olat/course/statistic/export/SimpleLogExporter.java b/src/main/java/org/olat/course/statistic/export/SimpleLogExporter.java index 024cbf8083be026dbd8f5a46f353f04bb1655624..3a27d86201d8c9444692793d4a8485aed1a6526e 100644 --- a/src/main/java/org/olat/course/statistic/export/SimpleLogExporter.java +++ b/src/main/java/org/olat/course/statistic/export/SimpleLogExporter.java @@ -27,8 +27,7 @@ package org.olat.course.statistic.export; import java.io.File; -import java.io.Writer; -import java.nio.charset.Charset; +import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.util.Calendar; @@ -39,10 +38,17 @@ import javax.persistence.EntityManager; import javax.persistence.TemporalType; import javax.persistence.TypedQuery; +import org.olat.basesecurity.IdentityImpl; import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.core.id.User; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.LoggingObject; +import org.olat.core.util.openxml.OpenXMLWorkbook; +import org.olat.core.util.openxml.OpenXMLWorksheet; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -57,51 +63,38 @@ import org.olat.core.logging.activity.LoggingObject; * Initial Date: 09.12.2009 <br> * @author bja */ +@Service("courseLogExporter") public class SimpleLogExporter implements ICourseLogExporter { private static final OLog log = Tracing.createLoggerFor(SimpleLogExporter.class); - private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + @Autowired private DB dbInstance; - private LogLineConverter logLineConverter_; + @Autowired + private LogLineConverter logLineConverter; - private SimpleLogExporter() { - // this empty constructor is ok - instantiated via spring - } - - /** injected by spring **/ - public void setLogLineConverter(LogLineConverter logLineConverter) { - logLineConverter_ = logLineConverter; - } - - public void setDbInstance(DB dbInstance) { - this.dbInstance = dbInstance; - } @Override - public void exportCourseLog(File outFile, String charset, Long resourceableId, Date begin, Date end, boolean resourceAdminAction, boolean anonymize) { - - //FIXME DSGVO join with user, config rows via user property context - - String query = "select v from org.olat.core.logging.activity.LoggingObject v " + "where v.resourceAdminAction = :resAdminAction " - + "AND ( " - + "(v.targetResId = :resId) OR " - + "(v.parentResId = :resId) OR " - + "(v.grandParentResId = :resId) OR " - + "(v.greatGrandParentResId = :resId) " - + ")"; + public void exportCourseLog(File outFile, Long resourceableId, Date begin, Date end, boolean resourceAdminAction, + boolean anonymize, boolean isAdministrativeUser) { + StringBuilder sb = new StringBuilder(512); + sb.append("select v, ident, identUser from loggingobject as v") + .append(" left join ").append(IdentityImpl.class.getCanonicalName()).append(" as ident on (ident.key=v.userId)") + .append(" left join ident.user as identUser") + .append(" where v.resourceAdminAction=:resAdminAction") + .append(" and ((v.targetResId = :resId) or (v.parentResId = :resId) or (v.grandParentResId = :resId) or (v.greatGrandParentResId = :resId))"); if (begin != null) { - query = query.concat(" AND (v.creationDate >= :createdAfter)"); + sb.append(" and (v.creationDate >= :createdAfter)"); } if (end != null) { - query = query.concat(" AND (v.creationDate <= :createdBefore)"); + sb.append(" and (v.creationDate <= :createdBefore)"); } EntityManager em = dbInstance.getCurrentEntityManager(); em.clear(); - TypedQuery<LoggingObject> dbQuery = em.createQuery(query, LoggingObject.class) + TypedQuery<Object[]> dbQuery = em.createQuery(sb.toString(), Object[].class) .setParameter("resAdminAction", resourceAdminAction) .setParameter("resId", Long.toString(resourceableId)); if (begin != null) { @@ -115,16 +108,20 @@ public class SimpleLogExporter implements ICourseLogExporter { dbQuery.setParameter("createdBefore", end, TemporalType.DATE); } - try(Writer out = Files.newBufferedWriter(outFile.toPath(), Charset.forName("UTF-8"), StandardOpenOption.CREATE_NEW)) { - out.append(logLineConverter_.getCSVHeader()); - out.append(LINE_SEPARATOR); + try(OutputStream out = Files.newOutputStream(outFile.toPath(), StandardOpenOption.CREATE_NEW); + OpenXMLWorkbook workbook = new OpenXMLWorkbook(out, 1)) { + OpenXMLWorksheet sheet = workbook.nextWorksheet(); + logLineConverter.setHeader(sheet, anonymize, isAdministrativeUser); int count = 0; - List<LoggingObject> queryResult = dbQuery.getResultList(); - for (LoggingObject loggingObject : queryResult) { - out.append(logLineConverter_.getCSVRow(loggingObject, anonymize, resourceableId)); - out.append(LINE_SEPARATOR); - if(count % 1000 == 0) { + List<Object[]> queryResult = dbQuery.getResultList(); + for (Object[] rawObject : queryResult) { + LoggingObject loggingObject = (LoggingObject)rawObject[0]; + Identity identity = (Identity)rawObject[1]; + User user = (User)rawObject[2]; + + logLineConverter.setRow(workbook, sheet, loggingObject, identity, user, anonymize, resourceableId, isAdministrativeUser); + if(count++ % 1000 == 0) { out.flush(); em.clear(); } diff --git a/src/main/java/org/olat/repository/manager/RepositoryDeletionManager.java b/src/main/java/org/olat/repository/manager/RepositoryDeletionManager.java index 72fd48f1e097b63b5c3b171597c7ee290c4df5b6..ab225ae9dda99d71118a208548a4f97640716ca8 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryDeletionManager.java +++ b/src/main/java/org/olat/repository/manager/RepositoryDeletionManager.java @@ -26,7 +26,6 @@ package org.olat.repository.manager; import java.io.File; -import java.util.Iterator; import java.util.List; import org.olat.basesecurity.GroupRoles; @@ -57,15 +56,12 @@ public class RepositoryDeletionManager implements UserDataDeletable { public static final String SEND_DELETE_EMAIL_ACTION = "sendDeleteEmail"; - private final RepositoryDeletionModule deletionModule; - + @Autowired + private RepositoryManager repositoryManager; @Autowired private RepositoryService repositoryService; - @Autowired - public RepositoryDeletionManager(RepositoryDeletionModule deletionModule) { - this.deletionModule = deletionModule; - } + private RepositoryDeletionModule deletionModule; /** * Remove identity as owner and initial author. Used in user-deletion. @@ -76,24 +72,28 @@ public class RepositoryDeletionManager implements UserDataDeletable { @Override public void deleteUserData(Identity identity, String newDeletedUserName, File archivePath) { // Remove as owner - List<RepositoryEntry> repoEntries = RepositoryManager.getInstance().queryByOwner(identity, new String[] {}/*no type limit*/); - for (Iterator<RepositoryEntry> iter = repoEntries.iterator(); iter.hasNext();) { - RepositoryEntry repositoryEntry = iter.next(); - + Identity adminIdentity = deletionModule.getAdminUserIdentity(); + List<RepositoryEntry> ownedRepoEntries = repositoryManager.queryByOwner(identity); + for (RepositoryEntry repositoryEntry: ownedRepoEntries) { repositoryService.removeRole(identity, repositoryEntry, GroupRoles.owner.name()); - if (repositoryService.countMembers(repositoryEntry, GroupRoles.owner.name()) == 0 ) { + if (adminIdentity != null && repositoryService.countMembers(repositoryEntry, GroupRoles.owner.name()) == 0) { // This group has no owner anymore => add OLAT-Admin as owner repositoryService.addRole(deletionModule.getAdminUserIdentity(), repositoryEntry, GroupRoles.owner.name()); log.info("Delete user-data, add Administrator-identity as owner of repositoryEntry=" + repositoryEntry.getDisplayname()); } } // Remove as initial author - repoEntries = RepositoryManager.getInstance().queryByInitialAuthor(identity.getName()); - for (Iterator<RepositoryEntry> iter = repoEntries.iterator(); iter.hasNext();) { - RepositoryEntry repositoryEntry = iter.next(); - repositoryEntry.setInitialAuthor(deletionModule.getAdminUserIdentity().getName()); - //FIXME DSGVO - log.info("Delete user-data, add Administrator-identity as initial-author of repositoryEntry=" + repositoryEntry.getDisplayname()); + List<RepositoryEntry> repoEntries = repositoryManager.queryByInitialAuthor(identity.getName()); + if(!repoEntries.isEmpty()) { + String replacement = "administrator"; + if(adminIdentity != null) { + replacement = adminIdentity.getName(); + } + for (RepositoryEntry repositoryEntry: repoEntries) { + repositoryEntry.setInitialAuthor(replacement); + repositoryService.update(repositoryEntry); + log.info("Delete user-data, add Administrator-identity as initial-author of repositoryEntry=" + repositoryEntry.getDisplayname()); + } } log.debug("All owner and initial-author entries in repository deleted for identity=" + identity); } diff --git a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml index f6c3176a96075eb9079ce163793d84a3a76a4268..a7be4fdc1380027f8a1bb54867a1ada707b87494 100644 --- a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml @@ -128,6 +128,10 @@ <constructor-arg index="0" value="OLAT_12.4.1" /> <property name="alterDbStatements" value="alter_12_4_0_to_12_4_1.sql" /> </bean> + <bean id="database_upgrade_12_5_0" class="org.olat.upgrade.DatabaseUpgrade"> + <constructor-arg index="0" value="OLAT_12.5.0" /> + <property name="alterDbStatements" value="alter_12_4_x_to_12_5_0.sql" /> + </bean> <bean id="database_upgrade_13_0_0" class="org.olat.upgrade.DatabaseUpgrade"> <constructor-arg index="0" value="OLAT_13.0.0" /> <property name="alterDbStatements" value="alter_12_4_x_to_13_0_0.sql" /> diff --git a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml index 654c90666c4b8329333659ecc0d536641b90041e..d305f7bbf211a97cf35d116457a44cac28c9c1ee 100644 --- a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml +++ b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml @@ -1515,6 +1515,24 @@ </bean> </entry> + <entry key="org.olat.course.statistic.export.LogLineConverter"> + <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> + <property name="description" value="Properties used in the course log archive" /> + <property name="propertyHandlers"> + <list> + <ref bean="userPropertyFirstName" /> + <ref bean="userPropertyLastName" /> + <ref bean="userPropertyInstitutionalUserIdentifier" /> + </list> + </property> + <property name="adminViewOnlyProperties"> + <set> + <ref bean="userPropertyInstitutionalUserIdentifier" /> + </set> + </property> + </bean> + </entry> + <!-- User properties added to o_info JS variable --> <entry key="org.olat.core.commons.fullWebApp.BaseFullWebappController"> <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index da33e6673055b759b5c0999cb61c0834ef172e70..cddfa774a0646e149f31a568a7ddafbd2a30beb8 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -46,7 +46,6 @@ <mapping-file>org/olat/core/util/mail/model/DBMail.hbm.xml</mapping-file> <mapping-file>org/olat/core/util/mail/model/DBMailAttachment.hbm.xml</mapping-file> <mapping-file>org/olat/core/util/mail/model/DBMailRecipient.hbm.xml</mapping-file> - <mapping-file>org/olat/core/logging/activity/LoggingObject.hbm.xml</mapping-file> <mapping-file>org/olat/course/db/impl/CourseDBEntryImpl.hbm.xml</mapping-file> <!-- Start upgraders mapping --> @@ -73,6 +72,7 @@ <class>org.olat.basesecurity.model.OrganisationTypeToTypeImpl</class> <class>org.olat.basesecurity.model.OrganisationImpl</class> <class>org.olat.core.dispatcher.mapper.model.PersistedMapper</class> + <class>org.olat.core.logging.activity.LoggingObject</class> <class>org.olat.commons.calendar.model.ImportedCalendar</class> <class>org.olat.commons.calendar.model.ImportedToCalendar</class> <class>org.olat.commons.calendar.model.CalendarUserConfiguration</class> diff --git a/src/main/resources/database/mysql/alter_12_4_x_to_12_5_0.sql b/src/main/resources/database/mysql/alter_12_4_x_to_12_5_0.sql index 672354a9e018a10058c201e80e25982e098e3f4c..6b530fca0c213293e6da4d6332a2fbf1d9bb7d67 100644 --- a/src/main/resources/database/mysql/alter_12_4_x_to_12_5_0.sql +++ b/src/main/resources/database/mysql/alter_12_4_x_to_12_5_0.sql @@ -2,73 +2,73 @@ alter table o_loggingtable drop username, drop userproperty1, drop userproperty2 update o_bs_identity set name=id where status=199; -update o_user set u_firstname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_lastname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_email=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_birthday=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_graduation=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_gender=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_telprivate=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_telmobile=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_teloffice=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_skype=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_msn=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_xing=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_icq=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_homepage=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_street=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_extendedaddress=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_pobox=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_zipcode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_region=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_city=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_country=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_countrycode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionalname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionaluseridentifier=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionalemail=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_orgunit=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_studysubject=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_emchangekey=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_emaildisabled=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_typeofuser=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_socialsecuritynumber=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty4=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty5=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericemailproperty1=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_rank=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_degree=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_position=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_userinterests=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_usersearchedinterests=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officestreet=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_extendedofficeaddress=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officepobox=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officezipcode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officecity=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officecountry=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officemobilephone=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_department=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_privateemail=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_edupersonaffiliation=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonhomeorg=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudylevel=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonhomeorgtype=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_employeenumber=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstaffcategory=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_organizationalunit=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch1=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch3=null from o_bs_identity where user_id=fk_user_id and status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_firstname=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_lastname=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_email=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_birthday=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_graduation=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_gender=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_telprivate=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_telmobile=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_teloffice=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_skype=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_msn=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_xing=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_icq=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_homepage=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_street=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_extendedaddress=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_pobox=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_zipcode=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_region=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_city=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_country=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_countrycode=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_institutionalname=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_institutionaluseridentifier=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_institutionalemail=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_orgunit=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_studysubject=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_emchangekey=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_emaildisabled=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_typeofuser=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_socialsecuritynumber=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericselectionproperty=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericselectionproperty2=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericselectionproperty3=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_generictextproperty=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_generictextproperty2=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_generictextproperty3=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_generictextproperty4=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_generictextproperty5=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericuniquetextproperty=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericuniquetextproperty2=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericuniquetextproperty3=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericemailproperty1=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericcheckboxproperty=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericcheckboxproperty2=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_genericcheckboxproperty3=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_rank=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_degree=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_position=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_userinterests=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_usersearchedinterests=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_officestreet=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_extendedofficeaddress=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_officepobox=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_officezipcode=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_officecity=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_officecountry=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_officemobilephone=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_department=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_privateemail=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_edupersonaffiliation=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonhomeorg=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonstudylevel=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonhomeorgtype=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_employeenumber=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonstaffcategory=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_organizationalunit=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonstudybranch1=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonstudybranch2=null where status=199; +update o_user inner join o_bs_identity on (id=fk_identity) set u_swissedupersonstudybranch3=null where status=199; diff --git a/src/main/resources/database/oracle/alter_12_4_x_to_12_5_0.sql b/src/main/resources/database/oracle/alter_12_4_x_to_12_5_0.sql index 43615f3d53c3cf658eae79fd9ef0f480346f7328..89a8074b5fba87d2eb19e6d1d58e4359792fd1e3 100644 --- a/src/main/resources/database/oracle/alter_12_4_x_to_12_5_0.sql +++ b/src/main/resources/database/oracle/alter_12_4_x_to_12_5_0.sql @@ -2,73 +2,74 @@ alter table o_loggingtable drop (username, userproperty1, userproperty2, userpro update o_bs_identity set name=id where status=199; -update o_user set u_firstname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_lastname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_email=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_birthday=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_graduation=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_gender=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_telprivate=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_telmobile=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_teloffice=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_skype=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_msn=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_xing=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_icq=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_homepage=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_street=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_extendedaddress=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_pobox=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_zipcode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_region=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_city=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_country=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_countrycode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionalname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionaluseridentifier=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionalemail=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_orgunit=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_studysubject=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_emchangekey=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_emaildisabled=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_typeofuser=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_socialsecuritynumber=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty4=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty5=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericemailproperty1=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_rank=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_degree=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_position=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_userinterests=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_usersearchedinterests=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officestreet=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_extendedofficeaddress=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officepobox=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officezipcode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officecity=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officecountry=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officemobilephone=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_department=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_privateemail=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_edupersonaffiliation=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonhomeorg=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudylevel=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonhomeorgtype=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_employeenumber=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstaffcategory=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_organizationalunit=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch1=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch3=null from o_bs_identity where user_id=fk_user_id and status=199; +update o_user set u_firstname=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_firstname=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_lastname=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_email=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_birthday=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_graduation=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_gender=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_telprivate=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_telmobile=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_teloffice=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_skype=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_msn=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_xing=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_icq=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_homepage=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_street=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_extendedaddress=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_pobox=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_zipcode=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_region=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_city=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_country=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_countrycode=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_institutionalname=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_institutionaluseridentifier=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_institutionalemail=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_orgunit=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_studysubject=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_emchangekey=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_emaildisabled=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_typeofuser=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_socialsecuritynumber=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericselectionproperty=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericselectionproperty2=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericselectionproperty3=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_generictextproperty=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_generictextproperty2=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_generictextproperty3=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_generictextproperty4=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_generictextproperty5=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericuniquetextproperty=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericuniquetextproperty2=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericuniquetextproperty3=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericemailproperty1=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericcheckboxproperty=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericcheckboxproperty2=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_genericcheckboxproperty3=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_rank=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_degree=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_position=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_userinterests=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_usersearchedinterests=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_officestreet=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_extendedofficeaddress=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_officepobox=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_officezipcode=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_officecity=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_officecountry=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_officemobilephone=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_department=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_privateemail=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_edupersonaffiliation=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonhomeorg=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonstudylevel=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonhomeorgtype=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_employeenumber=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonstaffcategory=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_organizationalunit=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonstudybranch1=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonstudybranch2=null where exists (select id from o_bs_identity where id=fk_identity and status=199); +update o_user set u_swissedupersonstudybranch3=null where exists (select id from o_bs_identity where id=fk_identity and status=199); diff --git a/src/main/resources/database/postgresql/alter_12_4_x_to_12_5_0.sql b/src/main/resources/database/postgresql/alter_12_4_x_to_12_5_0.sql index 33b8ab7797c86a6c890eab615f884907dc5ade33..1745ccee7d6b26e70a1a5223eee701960cda5a9a 100644 --- a/src/main/resources/database/postgresql/alter_12_4_x_to_12_5_0.sql +++ b/src/main/resources/database/postgresql/alter_12_4_x_to_12_5_0.sql @@ -2,73 +2,73 @@ alter table o_loggingtable drop column username, drop column userproperty1, drop update o_bs_identity set name=id where status=199; -update o_user set u_firstname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_lastname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_email=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_birthday=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_graduation=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_gender=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_telprivate=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_telmobile=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_teloffice=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_skype=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_msn=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_xing=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_icq=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_homepage=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_street=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_extendedaddress=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_pobox=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_zipcode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_region=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_city=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_country=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_countrycode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionalname=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionaluseridentifier=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_institutionalemail=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_orgunit=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_studysubject=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_emchangekey=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_emaildisabled=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_typeofuser=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_socialsecuritynumber=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericselectionproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty4=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_generictextproperty5=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericuniquetextproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericemailproperty1=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_genericcheckboxproperty3=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_rank=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_degree=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_position=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_userinterests=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_usersearchedinterests=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officestreet=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_extendedofficeaddress=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officepobox=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officezipcode=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officecity=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officecountry=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_officemobilephone=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_department=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_privateemail=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_edupersonaffiliation=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonhomeorg=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudylevel=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonhomeorgtype=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_employeenumber=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstaffcategory=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_organizationalunit=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch1=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch2=null from o_bs_identity where user_id=fk_user_id and status=199; -update o_user set u_swissedupersonstudybranch3=null from o_bs_identity where user_id=fk_user_id and status=199; +update o_user set u_firstname=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_lastname=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_email=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_birthday=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_graduation=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_gender=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_telprivate=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_telmobile=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_teloffice=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_skype=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_msn=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_xing=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_icq=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_homepage=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_street=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_extendedaddress=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_pobox=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_zipcode=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_region=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_city=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_country=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_countrycode=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_institutionalname=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_institutionaluseridentifier=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_institutionalemail=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_orgunit=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_studysubject=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_emchangekey=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_emaildisabled=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_typeofuser=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_socialsecuritynumber=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericselectionproperty=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericselectionproperty2=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericselectionproperty3=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_generictextproperty=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_generictextproperty2=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_generictextproperty3=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_generictextproperty4=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_generictextproperty5=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericuniquetextproperty=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericuniquetextproperty2=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericuniquetextproperty3=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericemailproperty1=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericcheckboxproperty=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericcheckboxproperty2=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_genericcheckboxproperty3=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_rank=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_degree=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_position=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_userinterests=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_usersearchedinterests=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_officestreet=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_extendedofficeaddress=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_officepobox=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_officezipcode=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_officecity=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_officecountry=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_officemobilephone=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_department=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_privateemail=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_edupersonaffiliation=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonhomeorg=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonstudylevel=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonhomeorgtype=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_employeenumber=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonstaffcategory=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_organizationalunit=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonstudybranch1=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonstudybranch2=null from o_bs_identity where id=fk_identity and status=199; +update o_user set u_swissedupersonstudybranch3=null from o_bs_identity where id=fk_identity and status=199; diff --git a/src/test/java/org/olat/admin/user/delete/service/UserDeletionManagerTest.java b/src/test/java/org/olat/admin/user/delete/service/UserDeletionManagerTest.java index 6ef3dba7abc0d3769e46e94554273ed7d5eccaf1..75e7104e3fd281e0ef9cadb4ee23e888f2c8da31 100644 --- a/src/test/java/org/olat/admin/user/delete/service/UserDeletionManagerTest.java +++ b/src/test/java/org/olat/admin/user/delete/service/UserDeletionManagerTest.java @@ -29,7 +29,6 @@ package org.olat.admin.user.delete.service; import static org.junit.Assert.assertTrue; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CountDownLatch; @@ -39,6 +38,7 @@ import org.junit.Assert; import org.junit.Test; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; +import org.olat.basesecurity.GroupRoles; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; @@ -54,6 +54,8 @@ import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.structel.ElementType; import org.olat.portfolio.model.structel.PortfolioStructure; import org.olat.portfolio.model.structel.PortfolioStructureMap; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryService; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.olat.user.UserManager; @@ -73,6 +75,8 @@ public class UserDeletionManagerTest extends OlatTestCase { @Autowired private BaseSecurity securityManager; @Autowired + private RepositoryService repositoryService; + @Autowired private EPFrontendManager epFrontendManager; @Autowired private EPStructureManager epStructureManager; @@ -104,11 +108,15 @@ public class UserDeletionManagerTest extends OlatTestCase { AbstractArtefact artefact = epFrontendManager.createAndPersistArtefact(identity, "Forum"); dbInstance.commit(); Assert.assertNotNull(artefact); - //a group BusinessGroup group = businessGroupService.createBusinessGroup(identity, "Group", "Group", -1, -1, false, false, null); Assert.assertNotNull(group); + dbInstance.commit(); + //a course + RepositoryEntry course = JunitTestHelper.deployBasicCourse(identity); dbInstance.commitAndCloseSession(); + Assert.assertEquals(username, course.getInitialAuthor()); + Assert.assertTrue(repositoryService.hasRole(identity, false, GroupRoles.owner.name())); //delete the identity userDeletionManager.deleteIdentity(identity); @@ -132,6 +140,10 @@ public class UserDeletionManagerTest extends OlatTestCase { //check membership of group boolean isMember = businessGroupService.isIdentityInBusinessGroup(deletedIdentity, group); Assert.assertFalse(isMember); + RepositoryEntry reloadedCourse = repositoryService.loadByKey(course.getKey()); + Assert.assertFalse(reloadedCourse.getInitialAuthor().equals(username)); + boolean isOwner = repositoryService.hasRole(identity, false, GroupRoles.owner.name()); + Assert.assertFalse(isOwner); User deletedUser = deletedIdentity.getUser(); String institutionalName = deletedUser.getProperty(UserConstants.INSTITUTIONALNAME, null); @@ -143,35 +155,35 @@ public class UserDeletionManagerTest extends OlatTestCase { } @Test - public void testSetIdentityAsActiv() { + public void testSetIdentityAsActiv() throws InterruptedException { Identity ident = JunitTestHelper.createAndPersistIdentityAsUser("anIdentity"); final int maxLoop = 2000; // => 2000 x 11ms => 22sec => finished in 120sec // Let two thread call UserDeletionManager.setIdentityAsActiv - final List<Exception> exceptionHolder = Collections.synchronizedList(new ArrayList<Exception>(1)); CountDownLatch latch = new CountDownLatch(4); ActivThread[] threads = new ActivThread[4]; for(int i=0; i<threads.length;i++) { - threads[i] = new ActivThread(ident, maxLoop, latch, exceptionHolder); + threads[i] = new ActivThread(ident, maxLoop, latch); } for(int i=0; i<threads.length;i++) { threads[i].start(); } - - try { - latch.await(120, TimeUnit.SECONDS); - } catch (InterruptedException e) { - exceptionHolder.add(e); + + latch.await(120, TimeUnit.SECONDS); + + List<Exception> exceptionsHolder = new ArrayList<>(); + for(int i=0; i<threads.length;i++) { + exceptionsHolder.addAll(threads[i].exceptionHolder); } // if not -> they are in deadlock and the db did not detect it - for (Exception exception : exceptionHolder) { + for (Exception exception : exceptionsHolder) { System.err.println("exception: "+exception.getMessage()); exception.printStackTrace(); } - assertTrue("Exceptions #" + exceptionHolder.size(), exceptionHolder.size() == 0); + assertTrue("Exceptions #" + exceptionsHolder.size(), exceptionsHolder.isEmpty()); } private static class ActivThread extends Thread { @@ -179,15 +191,15 @@ public class UserDeletionManagerTest extends OlatTestCase { private final int maxLoop; private final Identity identity; private final CountDownLatch countDown; - private final List<Exception> exceptionHolder; + private final List<Exception> exceptionHolder = new ArrayList<>(); - public ActivThread(Identity identity, int maxLoop, CountDownLatch countDown, List<Exception> exceptionHolder) { + public ActivThread(Identity identity, int maxLoop, CountDownLatch countDown) { this.identity = identity; this.maxLoop = maxLoop; this.countDown = countDown; - this.exceptionHolder = exceptionHolder; } + @Override public void run() { try { sleep(10);