© Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @...

38
© Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

Transcript of © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @...

Page 1: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

© Blackboard, Inc. All rights reserved.

CourseCopy NT (CoCoNuT)

Customized Course Copy operation

@ K.U.Leuven (Belgium)

Page 2: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

2/38

Presentation overview

» Toledo team - KULeuven Association » Toledo in numbers» Blackboard implementation» Data integration» Blackboard Copy Operations» Archive – Restore» Customized Procedure – overview» Customized Procedure – pre processing» Customized Procedure – archive and restore» Customized Procedure – post processing

Page 3: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

3/38

Toledo team - KULeuven Association

Page 4: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

4/38

Page 5: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

5/38

Page 6: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

6/38

Toledo team - KULeuven Association

» KULeuven Association» 1 university +10 higher

education institutions

» K12» 140 k12 education

schools

2 production environments

» 1 project leader» 2 application managers (training and

support)» 3 software developers» 2 data managers (data integration)» 2 system administrators

Page 7: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

7/38

Toledo in numbers

» KULeuven Association» Active users: 69.932 » Courses: 37.624

(+50% actively used)

» K12» Active users: 29.970 » Courses: 7.459

app server 2

app server 1

app server 3

Load balancer 1

Load balancer 2

Oracle DB server

Collab server

app server 1

Oracle DB server

NFS-cluster

Page 8: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

8/38

Blackboard implementation

Users» Only two types of users: students and instructors » Primary institutionrole > reflects the Institution

users belong to (defines branding and tab pages)» Secondary institutionrole > reflects the users

permissions (defines modules on the tab pages)» 10 Blackboard system admins (Toledo Team)» 1 Local admin pro department, institution or k12 school» Staff » Student

Page 9: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

9/38

Blackboard implementation

Courses

» 2 concurrent versions of one course» One copy of the previous academic year» One copy of the current academic year (set unavaileble @

copy)» Instructor decides when to set his course (un)available

Previous Current

CourseId a-courseid-0506 a-courseid-0607

Course Title course title [0506] course title

Page 10: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

10/38

Toledo Server

IMS-XMLIMS-XML

Data integration

Institution a

Institution b

... Institution

k

Enterprise Information Systems

IMS-XML

perl

Nightly rsync

Toledo databa

seNightly parsed

Java BbJava/Bb-API

Java/php

5 min

Toledo applications•Enrollment module•Communities module...

Need extra storage of •organisational structure•User roles

Bb

Page 11: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

11/38

Requirements for Course Copy @ K.U.Leuven

» The program has to be able to

» run in “batch” mode » be started from within blackboard for one or more courses,

as well as be started from bash» ignore “non-used” courses» add a “copied” flag to copied courses» check whether the target course already exists (created

with IMS-XML) and whether it ‘s not copied before (“copied” flag)

» unenroll student memberships, but keep staff memberships» set the target courses unavailable » change title of the source course (add [0506])» add an announcement in source and target courses» move the archive and its logfiles to a specific location» create symlinks at filesystem level (max #files/dir reached)

Page 12: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

12/38

Blackboard Copy Operations

Control Panel

Batch Target course not required

Keeps users / interactions

Creates an archive

Copy Snapshot / batch copy

/ API -Clone() Export / import Archive / Restore

Page 13: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

13/38

Archive

/usr/local/blackboard/apps/content-exchange/bin/batch_ImportExport.sh -f /path_to/A.dummyfile.txt -l 1 -t archive

a-courseid1-0506, /usr/local/blackboard/archives/

a-courseid2-0506, /usr/local/blackboard/archives/

a-courseid3-0506, /usr/local/blackboard/archives/

a-courseid4-0506, /usr/local/blackboard/archives/

a-courseid5-0506, /usr/local/blackboard/archives/

a-courseid6-0506, /usr/local/blackboard/archives/

A.dummyfile.txt

•-f path_to_file

•-l (delimiter) 1(,) 2(;) 3(tab)

•-t (type) import export archive restore

•-n virtual hostname

Options:

Page 14: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

14/38

Restore

/usr/local/blackboard/apps/content-exchange/bin/batch_ImportExport.sh -f /path_to/R.dummyfile.txt -l 1 -t restore

a-courseid1-0607, /usr/local/blackboard/server/archives/ArchiveFile_a-courseid1-0506.zip

a-courseid1-0607, /usr/local/blackboard/server/archives/ArchiveFile_a-courseid2-0506.zip

a-courseid1-0607, /usr/local/blackboard/server/archives/ArchiveFile_a-courseid3-0506.zip

a-courseid1-0607, /usr/local/blackboard/server/archives/ArchiveFile_a-courseid4-0506.zip

a-courseid1-0607, /usr/local/blackboard/server/archives/ArchiveFile_a-courseid5-0506.zip

a-courseid1-0607, /usr/local/blackboard/server/archives/ArchiveFile_a-courseid6-0506.zip

R.dummyfile.txt

•-f path_to_file

•-l (delimiter) 1(,) 2(;) 3(tab)

•-t (type) import export archive restore

•-n virtual hostname

Options:

Page 15: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

15/38

Customized Procedure – overviewif source has content if target existsif no copy flagremove targetcreate a/r filescreate symlinkarchiverestore

add annoucements add title suffixset target unavailableunenroll studentsadd copyflagmove logs and archive

Pre processing

Archive / Restore

Post processing

a-courseid1-0506, a-courseid1-0607

a-courseid2-0506, a-courseid2-0607

...

a-courseid1-0506, /path_to/archives/

a-courseid2-0506, /path_to/archives/

...a-courseid1-0607, /path_to/archives/ArchiveFile_a-courseid1-0506.zip

a-courseid2-0607, /path_to/archives/ArchiveFile_a-courseid2-0506.zip

...

mail (short) errorlog

Page 16: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

16/38

Customized Procedure – overviewif source has content if target existsif no copy flagremove targetcreate a/r filescreate symlink

Pre processing

a-courseid1-0506, a-courseid1-0607

a-courseid2-0506, a-courseid2-0607

...

a-courseid1-0506, /path_to/archives/

a-courseid2-0506, /path_to/archives/

...a-courseid1-0607, /path_to/archives/ArchiveFile_a-courseid1-0506.zip

a-courseid2-0607, /path_to/archives/ArchiveFile_a-courseid2-0506.zip

...

Page 17: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

17/38

Customized Procedure - pre processing» CourseCheck (GoF Strategy + GoF Composite Pattern)

ICourseCheck

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckAnnouncementString getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckCopyFlag

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckLink

String getMessage()

setMessage(String)

boolean hasitem(course)

Responsablility of each class: •checking for its own citerium•setting a MessageString if the criterium is met

CourseCheckDiscussionBoardString getMessage()

setMessage(String)

boolean hasitem(course)

Page 18: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

18/38

BbList announcementList = AnnouncementDbLoader.Default.getInstance().loadByCourseId(course.getId());

if (announcementList.size() > 1) {

setMessage(course.getBatchUid()+ " has at least one Announcement");

return true;

}

setMessage(course.getBatchUid()+ " has one or less Announcements");

return false;

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

Get AnnouncementList from its loader

Check list size

Page 19: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

19/38

If TOC has contentId, load its children with ContentDbLoader

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

ContentDbLoader contentLoader = ContentDbLoader.Default.getInstance();

BbList courseTocList = CourseTocDbLoader.Default.getInstance().loadByCourseId(course.getId());

for (Iterator i = courseTocList.iterator(); i.hasNext();) {

CourseToc courseToc = (CourseToc) i.next();

if (courseToc.getContentId().isSet()) {

courseToc.getContentId()).size());

if (contentLoader.loadChildren(courseToc.getContentId()).size() > 0) {

setMessage(course.getBatchUid()+ " has one or more Course Informations, Course Documents, Assignments or external links");

return true;

} } }

setMessage(course.getBatchUid()+ " has no Course Information, Course Documents, Assignments or external links");

return false;

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

Get the Table Of ContentsIterate Table Of Contents and check for valid ContendIds

Page 20: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

20/38

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

BbList linkList = LinkDbLoader.Default.getInstance().loadByCourseId(course.getId());

if (linkList.size() > 0) {

setMessage(course.getBatchUid() + " has one or more links");

return true;

} else {

setMessage(course.getBatchUid() + " has no link");

return false; }

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckLink

String getMessage()

setMessage(String)

boolean hasitem(course)

Get LinkList from its loaderCheck list size

Page 21: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

21/38

Iterate Conferences and check for fora

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

boolean hasDiscussionBoard=false;

BbList confManagers = ConferenceDbLoader.Default.getInstance().loadAllByCourseId(course.getId());

for (Iterator iter = confManagers.iterator(); iter.hasNext();) {Conference conf = (Conference) iter.next();BbList fora =

ForumDbLoader.Default.getInstance().loadByConferenceId(conf.getId()); if (fora.size()>0)hasDiscussionBoard=true;

}

if (hasDiscussionBoard) {setMessage(course.getBatchUid()+" has one or more DiscussionBoard");return true;

} else {setMessage(course.getBatchUid()+" has no DiscussionBoard");return false;

}

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckLink

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckDiscussionBoardString getMessage()

setMessage(String)

boolean hasitem(course)

BB6 Get ConferenceList from its loader

Page 22: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

22/38

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

boolean hasDiscussionBoard=false;

List fManagers = DiscussionBoardManager.getForumManager().loadByCourseId(course.getId());

if (fManagers.size() > 0)hasDiscussionBoard=true;

if (hasDiscussionBoard) {

setMessage(course.getBatchUid()+" has one or more DiscussionBoard");

return true;

} else {

setMessage(course.getBatchUid()+" has no DiscussionBoard");

return false;

}

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckLink

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckDiscussionBoardString getMessage()

setMessage(String)

boolean hasitem(course)

BB7 Get ForumManagerlist from its

loaderCheck list size

Page 23: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

23/38

Registry creg = CourseRegistryEntryDbLoader.Default.getInstance().loadRegistryByCourseId(course.getId());

Enumeration regenum = creg.entries();

while (regenum.hasMoreElements()) {

CourseRegistryEntry cregentry = (CourseRegistryEntry) regenum.nextElement();

if (cregentry.getKey().equals(copyFlag)) {setMessage(course.getBatchUid()+ " is already copied before");return true;}

}

setMessage(course.getBatchUid()+" is not copied before");return false;

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckLink

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckDiscussionBoardString getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckCopyFlag

String getMessage()

setMessage(String)

boolean hasitem(course)

Hidden API !Get CourseRegistry from its loaderIterate its entries and check for

key

Page 24: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

24/38

Customized Procedure - pre processing» CourseCheck (GoF Strategy + GoF Composite Pattern)

ICourseCheck

String getMessage()

setMessage(String)

boolean hasitem(course)

AbstractCourseValidator

String getMessage()

setMessage(String)

boolean hasitem(course)

Add(ICourseCheck)

DestinationCourseValidatorboolean hasitem(course)

SourceCourseValidator

boolean hasitem(course)

Map<ICouseCheck>

Map with actual strategy in

implementing class

Page 25: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

25/38

Customized Procedure - pre processingCourseCheckAnnounce

mentString getMessage()

setMessage(String)

boolean hasitem(course)

for (Iterator iter = validations.iterator(); iter.hasNext();) {

ICourseCheck cc = (ICourseCheck) iter.next();

if (cc.hasItem(c)) {

setMessage(cc.getMessage());

return true;

}

}

setMessage(c.getBatchUid()+" has no content items ");

return false;

CourseCheckContent

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckLink

String getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckDiscussionBoardString getMessage()

setMessage(String)

boolean hasitem(course)

CourseCheckCopyFlag

String getMessage()

setMessage(String)

boolean hasitem(course)

SourceCourseValidator

boolean hasitem(course)

public SourceCourseValidator() {

add(new CourseCheckAnnouncements());

add(new CourseCheckContent());

add(new CourseCheckDiscussionBoard());

add(new CourseCheckLink());

}

Page 26: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

26/38

Customized Procedure - pre processingBufferedwriter awriter = new BufferedWriter(new FileWriter(CCIO.getArchiveFile()));

DestinationCourseValidator destCourseValidator = new DestinationCourseValidator(copyFlag);

SourceCourseValidator sourceCourseValidator = new SourceCourseValidator();

// if destination course has no copyflag

if (!(destCourseValidator.hasItem(trgCourse))) {

// if source course has contentif

((sourceCourseValidator.hasItem(srcCourse))) {

CourseDbPersister.Default.getInstance().deleteById(trgCourse.getId());

awriter.write(sourceCourseId + ", "+ archivePath + "\n");

}

}

if source has content if target existsif no copy flagremove targetcreate a/r filescreate symlink

CCIO : CourseCopy I/O

Bean (getters/setters) with all input, output and properties files

Page 27: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

27/38

Customized Procedure – archive and restore

archiverestore

Archive / Restore

a-courseid1-0506, /path_to/archives/

a-courseid2-0506, /path_to/archives/

...a-courseid1-0607, /path_to/archives/ArchiveFile_a-courseid1-0506.zip

a-courseid2-0607, /path_to/archives/ArchiveFile_a-courseid2-0506.zip

...

Page 28: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

28/38

Process archProcess = Runtime.getRuntime().exec( "/usr/local/blackboard/apps/content-exchange/bin/batch_ImportExport.sh -" + "f " + CCIO.getArchiveFile().getAbsolutePath()+ " -l 1 -t archive“);

InputStreamReader isr = new InputStreamReader(archProcess.getInputStream());BufferedReader br = new BufferedReader(isr);String line = null;

while ((line = br.readLine()) != null) {logger.info(line);

}

Customized Procedure – archive and restore

Execute the shell command with the Runtime classMonitor the process by reading its InputStreamManipulate logging here

Page 29: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

29/38

Customized Procedure – post processing

add annoucements add title suffixset target unavailableunenroll studentsadd copyflagmove logs and archive

Post processing

a-courseid1-0506, /path_to/archives/

a-courseid2-0506, /path_to/archives/

...a-courseid1-0607, /path_to/archives/ArchiveFile_a-courseid1-0506.zip

a-courseid2-0607, /path_to/archives/ArchiveFile_a-courseid2-0506.zip

...

Page 30: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

30/38

Post processing – add announcementAnnouncementDbPersister aPersister = (AnnouncementDbPersister) pManager.getPersister(AnnouncementDbPersister.TYPE);

CourseDbLoader cLoader = CourseDbLoader.Default.getInstance();UserDbLoader uLoader = UserDbLoader.Default.getInstance();idAboutCourse = cLoader.loadByBatchUid(sAboutCourse).getId();

String bodyText = MessageFormat.format(aBody, new Object[] { " <b><a href='" + bbPath+ idAboutCourse.toExternalString()+ "' target='blank'>" + sAboutCourse + "</a></b>" });

FormattedText body = new FormattedText(bodyText, FormattedText.Type.HTML);

Announcement a = new Announcement();

a.setIsPermanent(true);a.setRestrictionStartDate(calendar);

a.setType(Announcement.Type.COURSE);

a.setCourseId(cLoader.loadByBatchUid(sInCourse).getId());a.setTitle(aTitle);a.setBody(body);

a.setCreatorUserId(uLoader.loadByBatchUid(aPostedBy).getId());

aPersister.persist(a);

Get the appropriate loaders

Create HTML-formatted bodySet various annoucement properties

Save announcement

Page 31: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

31/38

Post processing – add title suffix

if (copyProps.getProperty("doSetTitleSuffix").equalsIgnoreCase("Y")) {

if (!srcBBCourse.getTitle().contains(copyProps.getProperty("titleSuffix"))) {

srcBBCourse.setTitle(srcBBCourse.getTitle() + " " + copyProps.getProperty("titleSuffix"));

coursePersister.persist(srcBBCourse);

} else {logger.info("year suffix existed already in "+

srcBBCourse.getBatchUid());

}

} If specified in the properties, add titlesuffixIf the title doesn ‘t already contains suffix, add it

Save course

Page 32: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

32/38

Set Enabled (admin apis only) Get appropriate loaders and persistersCheck whether the Course is an “Organization” or a “Course”

Use the correct loaderSave course

BbPersistenceManager pManager = BbServiceManager.getPersistenceService().getDbPersistenceManager();CourseSiteDbPersister cPersister = (CourseSiteDbPersister) pManager.getPersister(CourseSiteDbPersister.TYPE);CourseSiteDbLoader cLoader = (CourseSiteDbLoader)

if (trgBBCourse.getServiceLevelType().compareTo(ServiceLevel.DEFAULT) == 0) {

CourseSite trgDICourse = cLoader.load(trgBBCourse.getBatchUid());

if (copyProps.getProperty("doSetUnavailable").equalsIgnoreCase("Y")) {

trgDICourse.setIsAvailable(false);

trgDICourse.setRowStatus(IAdminObject.RowStatus.ENABLED);

cPersister.save(trgDICourse);}

....

Post processing – set course unavailalbe

Set unavailable (!= Disabled !!)

Page 33: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

33/38

.....

pManager.getLoader(CourseSiteDbLoader.TYPE);EnrollmentLoader eLoader = EnrollmentLoader.Default.getInstance();EnrollmentPersister ePersister = EnrollmentPersister.Default.getInstance();

if (copyProps.getProperty("doUnenrollStudents").equalsIgnoreCase("Y")) {

BbList enrollmentList = new BbList();Enrollment tempEnrollment = new Enrollment();

tempEnrollment.setCourseSiteBatchUid(trgDICourse.getBatchUid());tempEnrollment.setRole(Enrollment.Role.STUDENT);

enrollmentList = eLoader.load(tempEnrollment);

for (Iterator i = enrollmentList.iterator(); i.hasNext();) {

Enrollment enrollment = (Enrollment) i.next();ePersister.remove(enrollment);

}}}

Post processing – unenroll students

Get appropriate loaders and persistersCreate an example enrollment with role == STUDENT and current courseid

Load all enrollments “by example”Remove selected enrollments

Page 34: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

34/38

CourseRegistryEntry courseRegEntry = new CourseRegistryEntry(copyFlag, copyFlagValue);

courseRegEntry.setCourseId(trgBBCourse.getId());

CourseRegistryEntryDbPersister.Default.getInstance().persist(courseRegEntry);

Post processing – add copyflag

Create a new CoursRegistryEntry (String key, String value)Set the CourseIdSave the CourseRegistryEntry

Page 35: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

35/38

ExtendedFile archivedFile = new ExtendedFile(srcPath);ExtendedFile reposFile = new ExtendedFile(reposPath+ archivedFile.getName());

if (!reposFile.exists()) reposFile.createNewFile();

if (archivedFile.renameTo(reposFile)) {logger.info("MOVE : " + archivedFile.getAbsolutePath() +

" --> "+reposFile.getAbsolutePath());} else {

logger.error("MOVE FAILED : "+ archivedFile.getAbsolutePath()+ " --> "+reposFile.getAbsolutePath());}

if (logFile.moveTo(reposLogFile)) {logger.info("MOVE : " + logFile.getAbsolutePath() + " --> "+ reposLogFile.getAbsolutePath());}

else {logger.error("MOVE FAILED : "+ logFile.getAbsolutePath() + " --> "+reposLogFile.getAbsolutePath());}

Post processing – move logs and archive

ExtendedFile

boolean copyTo(File)

boolean moveTo(File)

md5()

renameTo > ok for same filesystem

moveTo > bytestream copy for different filesystems

Page 36: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

36/38

Current issues > future developments

Current issues: » In case of failure lots of manual setup work (due

to sequential batch structure) > use blackboard.platform.ApplicationLauncher.main ?

» Archive/restore phase relatively slow > Clone() ?» Fileserver crashes at large numbers > ?

Page 37: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

37/38

Source Code

» http://perswww.kuleuven.be/~u0034877/coursecopy/coconut.zip

Page 38: © Blackboard, Inc. All rights reserved. CourseCopy NT (CoCoNuT) Customized Course Copy operation @ K.U.Leuven (Belgium)

38/38

Questions – remarks – suggestions ?if source has content if target existsif no copy flagremove targetcreate a/r filescreate symlinkarchiverestore

add annoucements add title suffixset target unavailableunenroll studentsadd copyflagmove logs and archive

a-courseid1-0506, a-courseid1-0607

a-courseid2-0506, a-courseid2-0607

...

a-courseid1-0506, /path_to/archives/

a-courseid2-0506, /path_to/archives/

...a-courseid1-0607, /path_to/archives/ArchiveFile_a-courseid1-0506.zip

a-courseid2-0607, /path_to/archives/ArchiveFile_a-courseid2-0506.zip

...

mail (short) errorlog