Download - Code Your Own: Tool Integration using the Basic Learning Tools Interoperability (LTI) Standard
Code Your Own Tool Integration Using the Basic
Learning Tools Interoperability (LTI)
Standard
#blticodeJim Riecken & Dan Rinzel
Blackboard Learn Product Development
BasicLearning
ToolsInteroperability
with Blackboard Learn™, Release 9.1 SP4
Q’s we will try to A
• What is LTI?• What is Basic LTI?• What does being a Tool Provider mean?• What does being a Tool Consumer mean?• What does that look like in Learn?• What does it look like for Blackboard Building
Blocks?• Hungry yet? Code your own Tool Provider
What is LTI?
“a single framework or standard way of integrating rich learning applications...to allow the seamless connection of web-based, externally hosted applications and content…to platforms that present them to users”
http://www.imsglobal.org/toolsinteroperability2.cfm
What is Basic LTI?
Simplify, Simplify, Simplify• one launch mechanism with one security policy• no access to run-time services on the platform
What’s a Tool Provider?
A (typically centrally hosted) service that interacts with users who are “launched” from inside their platform
Launch mechanism and authN as specified, including extra data in the launch “payload”
What’s a Tool Consumer?
A LMS, VLE or portal environment
Sets policy about the payload privacy, who can provision links
What does that look like in Blackboard Learn?
Basic LTI & Blackboard Building Blocks™
Why use a Blackboard Building Block?
• More seamless integration– Tool placement– Content Handler placement
• Bypass global provider settings– Permissions declared in bb-manifest.xml
• Instructors don’t need to deal with URLs, Keys, and Secrets– They might not even know that the tool is running
on another server!
How to use Basic LTI in a Blackboard Building Block
• Two Parts– Declare permissions in bb-manifest.xml– Use blackboard.platform.blti.BasicLTILauncher
• In your Tool page or Content Handler view page
Basic LTI Permissions
• New “basiclti” permission type.– Name is the domain you intent to launch to.
• Use “*” if you want to launch to any domain• Specifying a domain allows subdomains as well
– Value is some combination of• “sendroles” – Allow user’s role to be sent.• “sendname” – Allow user’s full name to be sent.• “sendemail” – Allow user’s email address to be
sent.
– If the value is empty, you will just be able to launch to that domain.
Basic LTI PermissionsExample
<permission type="basiclti" name="example.com" actions="" /><permission type="basiclti" name="foo.example.com" actions="sendroles" /><permission type="basiclti" name="bar.example.com" actions="sendname,sendemail" /><permission type="basiclti" name="baz.example.com" actions="sendemail" />
BasicLTILauncher
• Encapsulates the logic for performing a Basic LTI launch.– blackboard.platform.blti.BasicLTILauncher– blackboard.platform.blti.BasicLTIConstants
• Simple API– Can add user/course information– Can add custom parameters– Does OAuth signing and redirects to an automatic
launch page.
BasicLTILauncher• Constructor
– BasicLTILauncher(String url, String key, String secret, String resourceLinkId)
• Data Population (all return BasicLTILauncher)– addResourceLinkInformation(String title, String
description)– addCurrentUserInformation(boolean includeRoles, boolean
includeName, boolean includeEmail)– addUserInformation(User user, CourseMembership membership,
boolean includeRoles, boolean includeName, boolean includeEmail)
– addCurrentCourseInformation()– addCourseInformation(Course course)– addLaunchPresentationInformation(Map<String,String> params)– addCustomToolParameters(Map<String,String> params)
• Launch– Map<String,String> prepareParameters()– void launch(HttpServletRequest req, HttpServletResponse
res, boolean useSplashScreen, FormattedText splashScreenMessage)
BasicLTILauncher - Examples
BasicLTILauncher launcher = new BasicLTILauncher( "http://url.to.my.tool", "my.key", "s3cr3t", "resourceId_1" );
launcher.launch( req, res, false, null );
Simple Launch
Launch with current user and current course (from Context) and a splash message
BasicLTILauncher launcher = new BasicLTILauncher( "http://url.to.my.tool", "my.key", "s3cr3t", "resourceId_1" ) //Send roles and name, but not email .addCurrentUserInformation( true, true, false ) .addCurrentCourseInformation();
launcher.launch( req, res, true, new FormattedText( "You are launching my tool. Click Submit.", FormattedText.Type.PLAIN_TEXT ) );
BasicLTILauncher - Examples
User user = ...; // Get user somehowCourse course = ...; // Get course somehowCourseMembership membership = ...; // Get user membership in course
Map<String, String> launchPresentation = new HashMap<String, String>();launchPresentation.put( BasicLTIConstants.PARAM_LAUNCH_PRESENTATION_DOCUMENT_TARGET, BasicLTIConstants.PARAM_LAUNCH_PRESENTATION_TARGET_WINDOW );launchPresentation.put( BasicLTIConstants.PARAM_LAUNCH_PRESENTATION_RETURN_URL, PlugInUtil.getUri( "vendor", "handle", "/path/to/my/return" ) ); Map<String,String> customParams = new HashMap<String,String>();customParams.put("param1", "value1");customParams.put("param2", "value2");
BasicLTILauncher launcher = new BasicLTILauncher( "http://url.to.my.tool", "my.key", "s3cr3t", "resourceId_1" ) .addResourceLinkInformation( "resourceTitle", "resourceDescription" ) .addUserInformation( user, membership, true, true, true ) .addCourseInformation( course ) .addCustomToolParameters( customParams ) .addLaunchPresentationInformation( launchPresentation );
launcher.launch( req, res, true, new FormattedText( "You are launching my tool. Click Submit.", FormattedText.Type.PLAIN_TEXT ) );
The kitchen sink
Hungry yet? Let’s make a sandwich Tool Provider
Tool Provider… Tool Provider?HOW DO I WRITE A TOOL PROVIDER!!!
• You could:– Go to http://www.imsglobal.org/lti – Download the Basic LTI spec– Read the spec– Implement the Tool Provider side of the spec– Find bugs, tear out hair, fix bugs.– Rinse, Repeat until working.
• Benefit:– You can use any language to do this– Like Ruby? Ok. Like PHP? Ok. Like Node.js? Ok.
BLTI-sandwich to the Rescue!
• But… If you like Java– I’ve done this for you!
• BLTI-sandwich– http://projects.oscelot.org/gf/project/blti-sandwich/– Simple Java library that implements the glue
between Tool Consumers and Tool Providers• Implements Basic LTI 1.0• Mostly for creating Tool Providers• Can also use to help create a Tool Consumer
BLTI-Sandwich
• Two main classes to deal with– BLTIMessage
• Contains all of the Basic LTI launch data in an easy to use format
– BLTIProvider• Allows you to pull a BLTIMessage off of an HttpServletRequest and validate it.
BLTIMessage
• Container for Basic LTI Launch Data– E.g.
• msg.getKey()• msg.getResourceLink().getId()• msg.getUser().getFullName()• msg.getUser().isInRole( Role.CONTEXT_NAMESPACE, Role.MENTOR )
• msg.getContext().getLabel()• msg.getLaunchPresentation().getReturnUrl()• msg.getCustomParameters().get("the-custom-param")
BLTIProvider
• Static methods to grab Basic LTI launch data and validate it.– BLTIMessage getMessage(HttpServletRequest request)
• Pulls launch data off the request.– boolean isValid(BLTIMessage msg, String secret)
• Checks whether the message contains all of the required Basic LTI fields and was signed using the specified shared secret.
Let’s make a tool
• Simple polling tool– Let instructor create an ad-hoc poll– Let students vote (and see results)– Let instructors see detailed results (who voted on
what)
• What we’ll use– blti-sandwich– Spring MVC– Google App Engine– Objectify (App Engine Datastore ORM)
Demo Time
• http://blti-sandwich.appspot.com – Running on App Engine
Code Walkthrough
/** * Performs the Basic LTI launch using blti-sandwich. */ @RequestMapping( "/blti/tool" ) public String launch( HttpServletRequest request ) { // Parse out the BLTI launch BLTIMessage msg = BLTIProvider.getMessage( request ); // Load the consumer that matches the key passed in the launch Consumer consumer = consumerDAO.get( Consumer.generateKey( msg.getKey() ) ); // Validate the message (make sure the message was signed by the shared secret) if ( consumer == null || !BLTIProvider.isValid( msg, consumer.getSharedSecret() ) ) { return errorRedirect( msg, "Error: Not Authorized!" ); } // [More validation edited out here...] else { // Provision a user object provisionUser( msg, consumer ); // Set up the HTTP session for the user HttpSession session = request.getSession( false ); if ( session != null ) { session.invalidate(); } session = request.getSession(); // Keep the BLTI message in session for use in other pages. session.setAttribute( "bltiSessionMsg", msg ); // Redirect to the tool (Poll) display page return "redirect:/blti/tool/index"; } }
Resources
• IMS http://www.imsglobal.org/toolsinteroperability2.cfm
• Learn Help Center http://help.blackboard.com
• blti-sandwich library on OSCELOT http://projects.oscelot.org/gf/project/blti-sandwich/
This presentation and example code will be available via http://edugarage.com at some point after the conference ends.
Please provide feedback for this session by [email protected].
The title of this session is:
Code Your Own: Tool Integration Using the Basic Learning Tools Interoperability (LTI) Standard