Skip to content

Commit cd43377

Browse files
author
Wes Williams
committed
initial release
0 parents  commit cd43377

21 files changed

+1907
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.classpath
2+
.project
3+
.settings
4+
target

LICENSE.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
LICENSE
2+
=======
3+
4+
LEARNINGSTUDIO EVENTING SAMPLE APPLICATION - CHAIN-OF-LEARNING
5+
--------------------------------------
6+
7+
Copyright (c) 2015 Pearson Education Inc.
8+
Created by Pearson Developer Services
9+
10+
Licensed under the Apache License, Version 2.0 (the "License");
11+
you may not use this file except in compliance with the License.
12+
You may obtain a copy of the License at
13+
14+
http://www.apache.org/licenses/LICENSE-2.0
15+
16+
Unless required by applicable law or agreed to in writing, software
17+
distributed under the License is distributed on an "AS IS" BASIS,
18+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
See the License for the specific language governing permissions and
20+
limitations under the License.
21+
22+
Portions of this work are reproduced from work created and
23+
shared by Google and used according to the terms described in
24+
the License. Google is not otherwise affiliated with the
25+
development of this work.

README.md

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Chain-of-Learning
2+
3+
## App Overview
4+
5+
This sample application demonstrates [LearningStudio's Eventing capabilities](http://developer.pearson.com/learningstudio/about) by enabling LearningStudio users to self monitor their course activity on their Google calendar. Users opt-in by registering the Google email address associated with their LearningStudio account. A user's activity in each course will create an all-day event that can be extended to the next day through continued course activity. Consecutive daily activity forms a chain that continues to grow until participation stops. Students gain accountability and motivation from this visual reminder of their persistence in course participation. Teachers gain a reminder of their involvement in each class they manage.
6+
7+
This application's intent is to highlight the potential of combining [LearningStudio's Eventing capabilities](http://developer.pearson.com/learningstudio/about) with third party APIs. The LearningStudio APIs could be used to further enrich such an application. Best practices for subscription management and callback processing for Eventing can be found in the source code.
8+
9+
### Scope of Functionality
10+
11+
This sample app is intended for demonstration purposes, so we made it easy for you to test drive it. It doesn't require you to setup a database or have an email server. In fact, it uses an in-memory store for persistence and never actually sends an email. You would not be able to deploy this in a production setting without making modifications. The good news is you can experience this application's potential quickly. Continue reading to learn how!
12+
13+
## Prerequisites
14+
15+
### Build Environment
16+
17+
* Apache Maven should be installed and configured.
18+
* Java 6 or greater is required.
19+
20+
### Server Environment
21+
22+
* This application assumes you're running an application server (i.e. Tomcat).
23+
* This application requires Java 6 or greater.
24+
25+
## Installation
26+
27+
### Application Configuration
28+
29+
#### LearningStudio Eventing Setup
30+
31+
1. [Get credentials](http://developer.pearson.com/learningstudio/set-1) for Eventing
32+
33+
#### Google App Setup
34+
35+
1. Create an application in the Google Developer Console
36+
2. Enable the Calendar and Google+ API
37+
3. Create a Client ID for this web application
38+
4. Set the redirect url to https://yourserver.com/chain-of-learning/oauth2callback
39+
40+
#### Application Setup
41+
42+
**src/main/resources/com/pearson/pdn/demos/chainoflearning/CalendarUtility.properties**
43+
44+
~~~~~~~~~~~~~~
45+
app.name={Name of the Google App}
46+
app.client.id={Google Client ID}
47+
app.client.secret={Google Client Secret}
48+
~~~~~~~~~~~~~~
49+
50+
**src/main/resources/com/pearson/pdn/demos/chainoflearning/EventingUtility.properties**
51+
52+
~~~~~~~~~~~~~~
53+
eventing.principal.id={LearningStudio Eventing ID}
54+
eventing.principal.key= {LearningStudio Eventing Secret}
55+
eventing.server.url={LearningStudio Eventing Server}
56+
eventing.subscribe.message.callback.url={Application Callback URL}
57+
eventing.subscribe.tag#.key={Name for Subscription Filter}
58+
eventing.subscribe.tag#.value= {Value for Subscription Filter}
59+
~~~~~~~~~~~~~~
60+
61+
*Callback URL:* https://yourserver.com/chain-of-learning/eventing
62+
63+
*Common Tag Names:* MessageType, CourseId
64+
65+
66+
### Server Deployment
67+
68+
#### Build
69+
70+
Run `mvn clean package` to compile the application and assemble a war file.
71+
72+
#### Server
73+
74+
Simply copy the `target/chain-of-learning.war` file to your server. You should be able to access this application from an address like:
75+
76+
http://yourserver.com/chain-of-learning
77+
78+
## License
79+
80+
Copyright (c) 2015 Pearson Education Inc.
81+
Created by Pearson Developer Services
82+
83+
Licensed under the Apache License, Version 2.0 (the "License");
84+
you may not use this file except in compliance with the License.
85+
You may obtain a copy of the License at
86+
87+
http://www.apache.org/licenses/LICENSE-2.0
88+
89+
Unless required by applicable law or agreed to in writing, software
90+
distributed under the License is distributed on an "AS IS" BASIS,
91+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
92+
See the License for the specific language governing permissions and
93+
limitations under the License.
94+
95+
Portions of this work are reproduced from work created and
96+
shared by Google and used according to the terms described in
97+
the License. Google is not otherwise affiliated with the
98+
development of this work.

pom.xml

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.pearson.pdn.demos</groupId>
5+
<artifactId>chain-of-learning</artifactId>
6+
<packaging>war</packaging>
7+
<version>1.0.0</version>
8+
<name>chain-of-learning</name>
9+
<dependencies>
10+
<dependency>
11+
<groupId>log4j</groupId>
12+
<artifactId>log4j</artifactId>
13+
<version>1.2.17</version>
14+
</dependency>
15+
<dependency>
16+
<groupId>com.google.api-client</groupId>
17+
<artifactId>google-api-client</artifactId>
18+
<version>1.18.0-rc</version>
19+
</dependency>
20+
<dependency>
21+
<groupId>com.google.apis</groupId>
22+
<artifactId>google-api-services-plus</artifactId>
23+
<version>v1-rev129-1.18.0-rc</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>com.google.apis</groupId>
27+
<artifactId>google-api-services-calendar</artifactId>
28+
<version>v3-rev84-1.18.0-rc</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.google.oauth-client</groupId>
32+
<artifactId>google-oauth-client</artifactId>
33+
<version>1.18.0-rc</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>com.google.oauth-client</groupId>
37+
<artifactId>google-oauth-client-servlet</artifactId>
38+
<version>1.18.0-rc</version>
39+
</dependency>
40+
<dependency>
41+
<groupId>com.google.http-client</groupId>
42+
<artifactId>google-http-client</artifactId>
43+
<version>1.18.0-rc</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>com.google.http-client</groupId>
47+
<artifactId>google-http-client-jackson2</artifactId>
48+
<version>1.18.0-rc</version>
49+
</dependency>
50+
<dependency>
51+
<groupId>com.google.code.gson</groupId>
52+
<artifactId>gson</artifactId>
53+
<version>2.2.4</version>
54+
</dependency>
55+
56+
<dependency>
57+
<groupId>org.apache.httpcomponents</groupId>
58+
<artifactId>httpclient</artifactId>
59+
<version>4.3.3</version>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.bouncycastle</groupId>
63+
<artifactId>bcprov-jdk15on</artifactId>
64+
<version>1.50</version>
65+
</dependency>
66+
<dependency>
67+
<groupId>javax.servlet</groupId>
68+
<artifactId>servlet-api</artifactId>
69+
<version>2.3</version>
70+
<scope>provided</scope>
71+
</dependency>
72+
</dependencies>
73+
<build>
74+
<finalName>chain-of-learning</finalName>
75+
</build>
76+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* LearningStudio Eventing Sample Application - Chain-of-Learning
3+
*
4+
* Need Help or Have Questions?
5+
* Please use the PDN Developer Community at https://community.pdn.pearson.com
6+
*
7+
* @category LearningStudio Eventing Sample Application - Chain-of-Learning
8+
* @author Wes Williams <[email protected]>
9+
* @author Pearson Developer Services Team <[email protected]>
10+
* @copyright 2015 Pearson Education Inc.
11+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache 2.0
12+
* @version 1.0
13+
*
14+
* Licensed under the Apache License, Version 2.0 (the "License");
15+
* you may not use this file except in compliance with the License.
16+
* You may obtain a copy of the License at
17+
*
18+
* http://www.apache.org/licenses/LICENSE-2.0
19+
*
20+
* Unless required by applicable law or agreed to in writing, software
21+
* distributed under the License is distributed on an "AS IS" BASIS,
22+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23+
* See the License for the specific language governing permissions and
24+
* limitations under the License.
25+
*
26+
* Portions of this work are reproduced from work created and
27+
* shared by Google and used according to the terms described in
28+
* the License. Google is not otherwise affiliated with the
29+
* development of this work.
30+
*/
31+
32+
package com.pearson.pdn.demos.chainoflearning;
33+
34+
import java.io.IOException;
35+
36+
37+
import javax.servlet.ServletException;
38+
import javax.servlet.http.HttpServletRequest;
39+
import javax.servlet.http.HttpServletResponse;
40+
import javax.servlet.http.HttpSession;
41+
42+
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
43+
import com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl;
44+
import com.google.api.client.auth.oauth2.Credential;
45+
import com.google.api.client.extensions.servlet.auth.oauth2.AbstractAuthorizationCodeCallbackServlet;
46+
import com.google.api.client.http.GenericUrl;
47+
import com.google.api.services.calendar.model.Calendar;
48+
49+
/*
50+
These links were useful while putting this together:
51+
52+
https://developers.google.com/google-apps/calendar/instantiate
53+
https://code.google.com/p/google-api-java-client/source/browse/calendar-cmdline-sample/src/main/java/com/google/api/services/samples/calendar/cmdline/CalendarSample.java?repo=samples
54+
https://code.google.com/p/google-api-java-client/
55+
https://developers.google.com/api-client-library/java/apis/calendar/v3
56+
https://code.google.com/p/google-oauth-java-client/wiki/OAuth2
57+
http://javadoc.google-oauth-java-client.googlecode.com/hg/1.11.0-beta/index.html?com/google/api/client/extensions/servlet/auth/oauth2/AbstractAuthorizationCodeServlet.html
58+
https://developers.google.com/+/api/oauth#email
59+
*/
60+
61+
/**
62+
* Handles auth with google using a callback servlet they provide as a quickstart
63+
*
64+
* NOTE: Reference Google's docs for details about their libraries.
65+
*/
66+
public class CalendarCallbackServlet extends AbstractAuthorizationCodeCallbackServlet {
67+
68+
@Override
69+
protected void onSuccess(HttpServletRequest req, HttpServletResponse res, Credential credential)
70+
throws ServletException, IOException {
71+
72+
Calendar calendar = null;
73+
String emailAddress = getUserId(req);
74+
75+
if(CalendarUtility.verifyEmailAddress(credential, emailAddress)) {
76+
com.google.api.services.calendar.Calendar client = CalendarUtility.createCalendarClient(credential);
77+
calendar = CalendarUtility.getCalendar(client);
78+
79+
if(calendar==null) {
80+
calendar = CalendarUtility.createCalendar(client);
81+
}
82+
}
83+
else {
84+
CalendarUtility.forgetUserCredential(emailAddress, credential);
85+
}
86+
87+
if(calendar==null) {
88+
res.sendRedirect(req.getContextPath()+"/failure.jsp");
89+
}
90+
else {
91+
req.getSession().setAttribute("cal", calendar.getId());
92+
res.sendRedirect(req.getContextPath()+"/success.jsp");
93+
}
94+
}
95+
96+
@Override
97+
protected void onError(
98+
HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
99+
throws ServletException, IOException {
100+
// handle error
101+
resp.sendRedirect(req.getContextPath()+"/failure.jsp");
102+
}
103+
104+
@Override
105+
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
106+
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
107+
url.setRawPath(req.getContextPath()+"/oauth2callback");
108+
return url.build();
109+
}
110+
111+
@Override
112+
protected AuthorizationCodeFlow initializeFlow() throws IOException {
113+
return CalendarUtility.initializeFlow();
114+
}
115+
116+
@Override
117+
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
118+
// return user ID
119+
String email = null;
120+
HttpSession session = req.getSession();
121+
if(session!=null) {
122+
email = (String) session.getAttribute("email");
123+
}
124+
125+
return email;
126+
}
127+
}

0 commit comments

Comments
 (0)