Tin Can Integration Walkthrough

Concepts

Auth

Authentication can be handled in Tin Can via Basic Auth or OAuth and is a necessity if you wish to handle Tin Can Statements from an activity not launched by your LMS. Going forward it's expected LMSs will want to track learning happening in places they were never able to track before. An example might be a learner's interactions with a forum inside the LMS. In order to record those interactions as statements in the LRS you will need to have some authentication set up. Integration methods are provided to allow you to tie both of these concepts into your existing system. An example scenario would be allowing a user's Single Sign On credentials to authenticate against your system, through the integration method. This will allow them to use those same credentials for LRS access as they use for other parts of the system. Additionally, you may want to provide special accounts to Activity Providers (like the forum software) so that you can always verify who is making the statement.

Permissions

You'll want to consider what permission level each individual account should have. The default permissions level allows customization across two primary areas:

Additionally, there is a Root permissions level. This level is what you'll want to use for third party applications you want to have the ability to both read and write any statements to or from the LMS. While it's unlikely you'll apply this permissions level to many, if any, third parties we've made the option available for your own systems.

Reporting

Understanding how you want to handle reporting on Tin Can data requires you to understand how you want to use Tin Can. For our customers that will be only using Tin Can content created as traditional courses launched by an LMS you don't need to do anything special. We will aggregate the data from those statements and send it to you via the same RollupRegistration Method we always have. The caveat with this approach is that this approach will focus entirely on the result object within the statement. This means we'll report on completion, success, score, and time as reflected in the result object and we will not depend on the verb for any meaning.

For people looking to record results data for Tin Can Content not launched by the LMS you'll want to copy the statements out to a separate location via our TinCanStatementsStored Integration Method for in depth analysis.

If you just want to get the big 4 data (Pass, Completion, Score, Time) for those things we provide an extension to the Tin Can API to allow you to pull that aggregate data directly from the SCORM Engine. You can read more about this in the Tin Can /results API documentation.

Content Auth

When we talk about Content Authorization and its relationship to Tin Can we're actually talking about the Tin Can addendum launch spec. The short version is that some Activity Providers may be launched, or initiated, by an LMS but end up taking place outside of the browser where handling content authorization for the content's resources becomes tricky. The easiest example would be a course that launched in a browser, detected it was on a mobile device, and then redirected to a mobile app. The mobile app needs to download the various resources inside the package such as images and videos. For most LMSs these resources are protected by a cookie, or some other authorization scheme, and the authorization mechanic is available to the browser. Once we've left the confines of the browser we have no way to pass cookies to something like a mobile application, and we wouldn't want to.

What we do pass, however, is the endpoint and credentials for accessing the LRS. With that data, and the full implementation of the spec referenced above, we're able to use the Tin Can endpoint as a way to proxy content files to the mobile application. This means that your content is still protected by your authentication scheme but can be made available to people with valid LRS credentials while they take your course.

Multi-Tenant

To make multi tenant setups work correctly with Tin Can you'll want to use a different TCAPI endpoint for each of your tenants. The SCORM Engine makes this easy to do. The SCORM Engine is prepared to parse out any value appears between TCAPI and the method name being called and present that to the Integration as a way to distinguish which tenant is accessing the system and creating the correct external configuration object.

an example might be:

http://example.com/ScormEngine/TCAPI/examplecompany/statements

When accessing the resource above "examplecompany" will be passed to TinCanPostProcessContext where the Integration should convert the string "examplecompany" to both a unique value that can be used internally to fill the appId variable in the context object as well as a valid External configuration object. This value can then be used in all other integration methods where tenancy will be important. Internally, the SCORM Engine will use the concept of "AppId" as a way to track tenancy amongst the various Tin Can tables. Externally, you'll continue to use the External Configuration object to represent the data your system uses to determine individual tenants.

Some optional Tin Can extensions, such as the /results API, will require implementation of the integration method TinCanGetMultiTenantContexts. TinCanPostProcessContext can be used to construct this list of contexts, using the list of TCAPI endpoints. This will be used to perform background processing using all of the possible ExternalConfiguration Obejcts your system depends on to inspect and transform the data for each of your customers/connection strings.

Config

In order to use Tin Can successfully in Engine, you’ll need to do a few things:

You can read the lengthy comment for this value in the SCORMEngineSettings.config that came with your 2013.x distribution for more information. More than likely, you can copy the default from the new config into your existing config and uncomment it, and it should work. That should be enough to get you up and running with Tin Can in console. If your setup is multi-tenant and you want an endpoint per, say, ClientId, then we might have a little more work to do.

Key Integration Methods


public TCAPIContext TinCanBuildContext(TinCanVersion version, ExternalConfiguration cfg, boolean isLaunchLink) throws Exception {
  MyExternalConfiguration myConfig = (MyExternalConfiguration)cfg);
  TCAPIContext ctx = super.TinCanBuildContext(version, cfg, isLaunchLink);
  ctx.setAppId(myConfig.TenantID);
  ctx.setSandbox(false);
  ctx.setOriginalAppId(myConfig.TenantID);
  return ctx;
}

public TCAPIContext TinCanPostProcessContext(TCAPIContext ctx, Map requestParameters, String extraEndpointInfo) throws Exception{
    String tenantID = extraEndpointInfo;
    MyExternalConfiguration myConfig = (MyExternalConfiguration)ctx.getExternalConfiguration();
    myConfig.TenantID = tenantID;
    ctx.setAppId(myConfig.TenantID);
    ctx.setSandbox(false);
    ctx.setOriginalAppId(myConfig.TenantID);
    return ctx;
}