97
Java Social JSR, It’s Alive Antoine Sabot-Durand Java EE Expert, Architect Ippon Technologies @antoine_sd Werner Keil Build Manager, DevOps Expert, Agile Coach Maersk Line @wernerkeil mardi 13 novembre 12

Devoxx Java Social and Agorava

Embed Size (px)

DESCRIPTION

Slides of Devox 2012 university "Java Social JSR, it's alive". Talking about JSR 357 and Agorava framework

Citation preview

Page 1: Devoxx Java Social and Agorava

Java Social JSR, It’s Alive

Antoine Sabot-DurandJava EE Expert, Architect

Ippon Technologies@antoine_sd

Werner KeilBuild Manager, DevOps Expert,

Agile CoachMaersk Line@wernerkeil

mardi 13 novembre 12

Page 2: Devoxx Java Social and Agorava

Antoine Sabot-Durand

• Java EE expert at Ippon Technologies

• Architect and Tech consultant

• 16 years in IT

• Java & OSS :

• Agorava technical leader

• Apache Deltaspike Commiter

• Member of l’EG CDI 1.1(JSR 346)

• @antoine_sd

2

mardi 13 novembre 12

Page 3: Devoxx Java Social and Agorava

• Consultant – Coach

• Creative Cosmopolitan

• Open Source Evangelist

• Software Architect

• Java Godfather

• JCP Executive Committee Member

• Eclipse UOMo Project Lead

• DevOps Guy

Werner Keil - Bio

3

mardi 13 novembre 12

Page 4: Devoxx Java Social and Agorava

Agenda

• Episode I : History – JSR 357 Rise and Fall

• The precursors

• From Seam Social to JSR 357

• What went Wrong?

• Episode II : Standards in Social Media

• The standards part

• The non standard part

• So what would be a Java Standard for Social Media ?

4

mardi 13 novembre 12

Page 5: Devoxx Java Social and Agorava

Agenda (2)• Espisode III : The Agorava Project

• Agorava Demo

• From JSR 357 to Agorava

• Agorava architecture

• Extending Agorava

• Related JSR : Security & identity

• Differences from other APIs and Frameworks

• Episode IV: Agorava, the technical parts

• Jackson Mapping Mixin

• CDI in Agorava 0.5

• JsonSchema2Pojo

• JAX-RS 2.0 client Framework in Agorava 1.0

• Episode V : Demo and Q&A 5

mardi 13 novembre 12

Page 6: Devoxx Java Social and Agorava

Episode I JSR 357 Rise and Fall

mardi 13 novembre 12

Page 7: Devoxx Java Social and Agorava

Before JSR 357 (Java Social)

7

mardi 13 novembre 12

Page 8: Devoxx Java Social and Agorava

Twitter4j

8

• Twitter4J is an unofficial Java library for the Twitter API.With Twitter4J, you can easily integrate your Java application with Twitter.

• Its author, Yusuke Yamamoto used to work at Twitter. While he did, he was briefly meant to represent Twitter in the Social JSR EG.

• It’s light and based on Java 1.4 to be integrated in mobile app for instance

mardi 13 novembre 12

Page 9: Devoxx Java Social and Agorava

Scribe Java

• Scribe is java framework that provides basic OAuth function

• It also contains configuration for a lot of Social Media

• Only one dependency on Apache Common Codec

• At the heart of Agorava 0.5

9

mardi 13 novembre 12

Page 10: Devoxx Java Social and Agorava

DaliCore – CMS

• More than a CMS → DaliCore

• Adds functionality common to users, content and permissions on top of Java EE 6.

• Focus on Users and Permissions.

• In about every project that uses DaliCore, users should be able to login with existing credentials (Facebook, Twitter, Google Connect,...)

• Dali modules extend DaliCore

10

mardi 13 novembre 12

Page 11: Devoxx Java Social and Agorava

Spring Social

• Spring social that inspired Seam Social and Agorava and is more mature

• Spring Social module were used to create first agorava modules (thanks to OSS and ASL2)

• But it’s Spring only module....

11

mardi 13 novembre 12

Page 12: Devoxx Java Social and Agorava

And then the JSR 357 was proposed

• In march 2012 on Werner Keil initiative, Java Social was submitted to the JCP to become a JSR

• It proposed to standardized access to Social Media in Java

• It was voted down by 8 votes against 5

12

mardi 13 novembre 12

Page 13: Devoxx Java Social and Agorava

What went Wrong? (Feedback from vote)

13

mardi 13 novembre 12

Page 14: Devoxx Java Social and Agorava

Too Broad ?

14

Maybe...

mardi 13 novembre 12

Page 15: Devoxx Java Social and Agorava

Too Soon?

15Lack of real POC...mardi 13 novembre 12

Page 16: Devoxx Java Social and Agorava

It can’t be standardized?

16

FALSEmardi 13 novembre 12

Page 17: Devoxx Java Social and Agorava

Episode IIStandards in Social Media

mardi 13 novembre 12

Page 18: Devoxx Java Social and Agorava

Standard part in social media

18

• All social medias use REST as transmission protocol

• Most of them transmit data in JSON format and some in XML

• Identification & Authentication are almost always based on OAuth protocol

mardi 13 novembre 12

Page 19: Devoxx Java Social and Agorava

REST

• REpresentational State Transfer : Requests about resource representation (customer, book, order)

• REST is based on low level HTTP concepts

• Each resource has a unique identifier (an URI). 4 HTTP verbs can be applied to a uri : GET, POST, PUT, DELETE

• Java has a standard to deal with REST: JAX-RS. Version 1.0 doesn’t provide client API yet. JAX-RS 2.0 will provide one

19

mardi 13 novembre 12

Page 20: Devoxx Java Social and Agorava

1: { 2: "firstName": "John", 3: "lastName" : "Smith", 4: "age" : 25, 5: "address" : 6: { 7: "streetAddress": "21 2nd Street", 8: "city" : "New York", 9: "state" : "NY",10: "postalCode" : "10021"11: },12: "phoneNumber":13: [14: {15: "type" : "home",16: "number": "212 555-1234"17: },18: {19: "type" : "fax",20: "number": "646 555-4567"21: }22: ]23: }

JSONJavascript Object Notation : This data format comes from Javascript. It became a standard for online services including Social Media.

20

mardi 13 novembre 12

Page 21: Devoxx Java Social and Agorava

OAuth

• OAuth is a protocol to delegate rights for an application to act on the behalf of an user who granted its rights without giving awayher login / password

• Developped by Twitter, Magnolia and Google, it was made standard by IETF in april 2010 under RFC 5849

• Version 2.0, simpler to use but often citicised by its too many implementation s was standardized in October 2012 under RFC 6749 and 6750. It’s already used by many actors (Facebook, Google, Microsoft)

• All social Media are based on OAuth 1.0a or 2.0.

• To use OAuth, one has to create an application on the targeted service to have an entry point for consumer 21

mardi 13 novembre 12

Page 22: Devoxx Java Social and Agorava

OAuth has 3 step

22

• Creating an application in the OAuth Social Media service

• Initialization : the right granting phase also called the OAuth Dance. At the end of the dance we obtain an access token (formed by a public and secret part) use in next step

• Signature : each request is signed with access token and token identifying the OAuth application that was granted the rights

mardi 13 novembre 12

Page 23: Devoxx Java Social and Agorava

OAuth Step 1 : Create an application

23

mardi 13 novembre 12

Page 24: Devoxx Java Social and Agorava

OAuth : application settings

24

mardi 13 novembre 12

Page 25: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25Consuming service server

Social Media Service(where OAuth application is declared)

user

mardi 13 novembre 12

Page 26: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

1

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

user

mardi 13 novembre 12

Page 27: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

12

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service ask a request token tot he Social

Media (using OAuth application keys). It also send

a callback url

user

mardi 13 novembre 12

Page 28: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

12

3

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

token is returned by SM

Consuming service ask a request token tot he Social

Media (using OAuth application keys). It also send

a callback url

user

mardi 13 novembre 12

Page 29: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

12

3

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

pagetoken is returned by SM

4

Consuming service ask a request token tot he Social

Media (using OAuth application keys). It also send

a callback url

user

mardi 13 novembre 12

Page 30: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

12

3

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

pagetoken is returned by SM

45

Consuming service ask a request token tot he Social

Media (using OAuth application keys). It also send

a callback url

Once authenticated, social media redirects user on call back url with a

verification code

user

mardi 13 novembre 12

Page 31: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

12

3

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

pagetoken is returned by SM

45

Consuming service ask a request token tot he Social

Media (using OAuth application keys). It also send

a callback url

Once authenticated, social media redirects user on call back url with a

verification code

6

with the code and request token consuming service request an access

token

user

mardi 13 novembre 12

Page 32: Devoxx Java Social and Agorava

The OAuth 1.0a «Dance»

25

12

3

client asks for a resource on the

consuming service

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

pagetoken is returned by SM

45

Consuming service ask a request token tot he Social

Media (using OAuth application keys). It also send

a callback url

Once authenticated, social media redirects user on call back url with a

verification code

6

with the code and request token consuming service request an access

token

7

Social media returns Access token

user

mardi 13 novembre 12

Page 33: Devoxx Java Social and Agorava

The OAuth 2.0 «Dance» now in SSL

26Consuming service server

Social Media Service(where OAuth application is declared)

user

mardi 13 novembre 12

Page 34: Devoxx Java Social and Agorava

The OAuth 2.0 «Dance» now in SSL

26

1

client asks for a resource on the

consuming serviceSSL is mandatory

Consuming service server

Social Media Service(where OAuth application is declared)

user

mardi 13 novembre 12

Page 35: Devoxx Java Social and Agorava

The OAuth 2.0 «Dance» now in SSL

26

1

client asks for a resource on the

consuming serviceSSL is mandatory

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

page user

2

mardi 13 novembre 12

Page 36: Devoxx Java Social and Agorava

The OAuth 2.0 «Dance» now in SSL

26

1

client asks for a resource on the

consuming serviceSSL is mandatory

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

page

Once authenticated, social media redirects user on call back url with a

verification code

user

2 3

mardi 13 novembre 12

Page 37: Devoxx Java Social and Agorava

The OAuth 2.0 «Dance» now in SSL

26

1

client asks for a resource on the

consuming serviceSSL is mandatory

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

page

Once authenticated, social media redirects user on call back url with a

verification code

with the code and request token consuming service request an access

token

user

2 3

4

mardi 13 novembre 12

Page 38: Devoxx Java Social and Agorava

The OAuth 2.0 «Dance» now in SSL

26

1

client asks for a resource on the

consuming serviceSSL is mandatory

Consuming service server

Social Media Service(where OAuth application is declared)

Consuming service

redirect user on the social media login

page

Once authenticated, social media redirects user on call back url with a

verification code

with the code and request token consuming service request an access

token

Social media returns Access token

user

2 3

4

5

mardi 13 novembre 12

Page 39: Devoxx Java Social and Agorava

OAuth Signature : original request

27

mardi 13 novembre 12

Page 40: Devoxx Java Social and Agorava

OAuth Signature : original request

27

POST /1/statuses/update.json?include_entities=true HTTP/1.1Accept: */*Connection: closeUser-Agent: OAuth gem v0.4.4Content-Type: application/x-www-form-urlencodedContent-Length: 76Host: api.twitter.com

status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21

mardi 13 novembre 12

Page 41: Devoxx Java Social and Agorava

OAuth Signature : request & OAuth params

28

mardi 13 novembre 12

Page 42: Devoxx Java Social and Agorava

OAuth Signature : request & OAuth params

28

status Hello Ladies + Gentlemen, a signed OAuth request!

include_entities true

oauth_consumer_key xvz1evFS4wEEPTGEFPHBog

oauth_nonce kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg

oauth_signature_method HMAC-SHA1

oauth_timestamp 1318622958

oauth_token 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb

oauth_version 1.0

mardi 13 novembre 12

Page 43: Devoxx Java Social and Agorava

OAuth Signature : parameter string

29

mardi 13 novembre 12

Page 44: Devoxx Java Social and Agorava

OAuth Signature : parameter string

29

include_entities=true&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog&oauth_nonce=kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1318622958&oauth_token=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb&oauth_version=1.0&status=Hello%20Ladies%20%2B%20Gentlemen%2C%20a%20signed%20OAuth%20request%21

mardi 13 novembre 12

Page 45: Devoxx Java Social and Agorava

OAuth Signature : Base String

30

mardi 13 novembre 12

Page 46: Devoxx Java Social and Agorava

OAuth Signature : Base String

30

POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521

mardi 13 novembre 12

Page 47: Devoxx Java Social and Agorava

OAuth Signing key

31

mardi 13 novembre 12

Page 48: Devoxx Java Social and Agorava

OAuth Signing key

31

VQ5CZHG4qUoAkUUmckPn4iN4yyjBKcORTW0wnok4r1k&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE

Application consumer key secret part

Access Token secret part

mardi 13 novembre 12

Page 49: Devoxx Java Social and Agorava

OAuth Signature : Signed request

32

mardi 13 novembre 12

Page 50: Devoxx Java Social and Agorava

OAuth Signature : Signed request

32

POST /1/statuses/update.json?include_entities=true HTTP/1.1Accept: */*Connection: closeUser-Agent: OAuth gem v0.4.4Content-Type: application/x-www-form-urlencodedAuthorization: OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog", oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg", oauth_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1318622958", oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb", oauth_version="1.0"Content-Length: 76Host: api.twitter.com

status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21

mardi 13 novembre 12

Page 51: Devoxx Java Social and Agorava

The non Standard parts

33

• Non standard identity management or any other API across Social Media

• More than that. There is no Social Media that Guarantee :

• Its API won’t change for a given period

• backward compatibility when its API change

mardi 13 novembre 12

Page 52: Devoxx Java Social and Agorava

• A basic heart providing basic services :

• OAuth and Rest request

• Multi Social Media connexions

• Polymorphic services to enforce standard on social Media

• Connector definition for Social module

• So this standard would be a kind Java Social Connector definition standard

So what would be a standard for Social ?

34

mardi 13 novembre 12

Page 53: Devoxx Java Social and Agorava

Socializer Demo

mardi 13 novembre 12

Page 54: Devoxx Java Social and Agorava

Episode IIIAgorava Project

mardi 13 novembre 12

Page 55: Devoxx Java Social and Agorava

From JSR 357 to Agorava

37

• Before Agorava there was Seam Social part of Seam 3 JBoss project

• In begining of 2012, Seam was stopped to be merged in Apache DeltaSpike

• Agorava was born mainly from Seam Social after JSR 357 attempt

• One of it’s goals is to be the missing POCfor a new Java Social JSR

mardi 13 novembre 12

Page 56: Devoxx Java Social and Agorava

Linked concept Security and Identity

• Identity, Privacy and Trust

• Identity attributes are properties of a digital subject

• A digital subject is a digital representation of an entity that is an actor or target of a digital operation.

• Privacy is the degree to which the availability of an entity’s identity attributes can be controlled

• Trust is an evaluation of the reliability of a representation of a digital subject

• An identity is a set of identity attributes that distinguish an entity

38

mardi 13 novembre 12

Page 57: Devoxx Java Social and Agorava

Identity for Social Media

• Java Identity API (JSR 351) goals for Social Media

• Attribute Service composed of attribute providers

• specification will define contracts to facilitate repository integrations by third parties.

• Reference Implementation will provide some specific integrations including those provided by contributors to Open Source project; Facebook, Twitter, and LinkedIn will be among the identity repositories considered for integration within the reference integration, as will their associated programming interfaces and protocols, including Facebook Connect, Google-ID and OAuth 2.0.

39

mardi 13 novembre 12

Page 58: Devoxx Java Social and Agorava

Facebook JSR 351 Example – Agent

56

@Named("Facebook")

public class FacebookRepositoryAgent implements RepositoryAgent {

public AttributeRepository getAttributeRepository(String repositoryName) {

TableIdentifier tID = null;

AttributeRepository rvalue = null;

try {

tID = FacebookTableID.valueOf(repositoryName);

rvalue = repositoryTable.get(tID);

} catch (IllegalArgumentException iae) {

}

if (rvalue == null) {

rvalue = new FacebookAttributeRepository(new RepositoryDescriptor(FacebookRepositoryAgent.class,tID.name()));

repositoryTable.put(tID,rvalue);

}

return rvalue;

}

mardi 13 novembre 12

Page 59: Devoxx Java Social and Agorava

Facebook JSR 351 Example – Repository

57

public class FacebookAttributeRepository implements AttributeRepository {

private RepositoryDescriptor _repositoryDescriptor;

private ProviderLookupContext _context; FacebookLookupService _lookupService;

public FacebookAttributeRepository(RepositoryDescriptor descriptor) {

_repositoryDescriptor = descriptor;

_context = new ProviderLookupContext(descriptor);

_lookupService = new FacebookLookupService(this);

}

public RepositoryDescriptor getRepositoryDescriptor() {

return _repositoryDescriptor;

}

[…]

public IDPredicate and(IDPredicate ... predicates) {

return new FacebookPredicate(_context, IDBooleanOperator.and, predicates);

}

mardi 13 novembre 12

Page 60: Devoxx Java Social and Agorava

Facebook JSR 351 Example – Connect

58

JSONObject graphValues = getResponseValues(graphResponse);

user = (String) graphValues.get(userPropertyName);

Iterator<String> it = graphValues.keys();

while (it.hasNext()) {

String key = it.next();

final URI id = new URI(userInfoEndpoint + "/" + key);

final Collection<String> names = new ArrayList<String>();

final Object value = graphValues.get(key);

final IDAttributeValue attributeValue = new IDAttributeValue() {

public Serializable getValue() {

return (Serializable) value;

}

public Collection getValues() {

return Collections.EMPTY_LIST;

}

};

}

mardi 13 novembre 12

Page 61: Devoxx Java Social and Agorava

Agorava Goals

43

• Provides generics services across different Social Media (identification, Post, etc...)

• Dynamic discovery of Social Media modules (core detect what modules are available at startup)

• Managing multiple Social Media connection at the same time

• Provides high level services (and binding) to interact with Social Media

mardi 13 novembre 12

Page 62: Devoxx Java Social and Agorava

Agorava 0.5 Macro architecture

• Agorava core is the «smart part» of the framework

• Modules are mainly REST API and JSON mapping

• Today Agorava has a CDI implementation only

• On the roadmap we plan to provide :

• full Java SE support

• JSR 330 (Guice and/or Spring) support 44

Agorava Core

API

Java SE Impl

CDI impl

@Inject impl

Guice impl Spring impl

TwitterModule

LinkedInModule

FacebookModule

Social Media Xmodule

mardi 13 novembre 12

Page 63: Devoxx Java Social and Agorava

Agorava core API architecture

45

+getMyProfile()+resetConnection()+isConnected()+getVerifierParamName()+getSocialMediaName()

«interface»api.

SocialMediaApiHub

+getToken()+getSecret()

«interface»api.oauth.

OAuthToken

+getApiKey()+getApiSecret()+getCallback()+getScope()+getSocialMediaName()

«interface»api.oauth.

OAuthAppSettings

+getRequestToken()+getAccessToken(OAuthToken, String)+signRequest(OAuthToken, OAuthRequest)+getVersion()+getAuthorizationUrl(OAuthToken)+requestFactory(RestVerb, String)+tokenFactory(String, String)

«interface»api.oauth.

OAuthProvider

+getFullName()+getProfileImageUrl()+equals(Object)

api.UserProfile

+isConnected()+getType()+get(String, Class)+get(String, Class, Object[n])+post(String, Map, Class)+post(String, Object, Object[n])+put(String, Object, Object[n])+delete(String)+setRequestHeader(Map)

«interface»api.rest.

RestService

+getRequestToken()+setRequestToken(OAuthToken)+getAccessToken()+setAccessToken(OAuthToken)+getVerifier()+setVerifier(String)+setUserProfile(UserProfile)+getUserProfile()+getServiceQualifier()+isConnected()+getName()

«interface»api.oauth.

OAuthSession

+getService()+getSession()

«interface»api.oauth.

OAuthServiceAware

+send()+addHeader(String, String)+addBodyParameter(String, String)+addBodyParameters(Map)+addQuerystringParameter(String, String)+addPayload(String)+getQueryStringParams()+getBodyParams()+getUrl()+getSanitizedUrl()+getBodyContents()+getVerb()+getHeaders()+setConnectTimeout(int, TimeUnit)+setReadTimeout(int, TimeUnit)+getCompleteUrl()+addPayload(byte[n])+getCharset()+setCharset(String)+setConnectionKeepAlive(boolean)

«interface»api.rest.

RestRequest

+addOAuthParameter(String, String)+getOauthParameters()

«interface»api.oauth.

OAuthRequest

+buildUri(String, String, String)+buildUri(String, Map)+buildUri(String)+buildUri(String, Object)

cdi.AbstractSocialMediaApi

+getAccessToken()+getAuthorizationUrl()+getVerifier()+initAccessToken()+sendSignedRequest(RestVerb, String)+sendSignedRequest(RestVerb, String, Map)+sendSignedRequest(RestVerb, String, String, Object)+setVerifier(String)+setAccessToken(String, String)+setAccessToken(OAuthToken)+sendSignedXmlRequest(RestVerb, String, String)+getSession()+sendSignedRequest(OAuthRequest)+get(String, Class, boolean)

«interface»api.oauth.

OAuthService

mardi 13 novembre 12

Page 64: Devoxx Java Social and Agorava

Main classes

46

+getMyProfile()+resetConnection()+isConnected()+getVerifierParamName()+getSocialMediaName()

«interface»api.

SocialMediaApiHub

+getApiKey()+getApiSecret()+getCallback()+getScope()+getSocialMediaName()

«interface»api.oauth.

OAuthAppSettings

+getRequestToken()+getAccessToken(OAuthToken, String)+signRequest(OAuthToken, OAuthRequest)+getVersion()+getAuthorizationUrl(OAuthToken)+requestFactory(RestVerb, String)+tokenFactory(String, String)

«interface»api.oauth.

OAuthProvider

+getRequestToken()+setRequestToken(OAuthToken)+getAccessToken()+setAccessToken(OAuthToken)+getVerifier()+setVerifier(String)+setUserProfile(UserProfile)+getUserProfile()+getServiceQualifier()+isConnected()+getName()

«interface»api.oauth.

OAuthSession

+buildUri(String, String, String)+buildUri(String, Map)+buildUri(String)+buildUri(String, Object)

cdi.AbstractSocialMediaApi

+getAccessToken()+getAuthorizationUrl()+getVerifier()+initAccessToken()+sendSignedRequest(RestVerb, String)+sendSignedRequest(RestVerb, String, Map)+sendSignedRequest(RestVerb, String, String, Object)+setVerifier(String)+setAccessToken(String, String)+setAccessToken(OAuthToken)+sendSignedXmlRequest(RestVerb, String, String)+getSession()+sendSignedRequest(OAuthRequest)+get(String, Class, boolean)

«interface»api.oauth.

OAuthService

mardi 13 novembre 12

Page 65: Devoxx Java Social and Agorava

OAuth configuration

47

• OAuthAppSettings contains needed infos to start the OAuth Dance :

• Public and private keys of OAuth application

• Callback URL

• OAuth 2.0 scope

• Name of the Social Media to which these settings are related

public interface OAuthAppSettings {

public String getApiKey();

public String getApiSecret();

public String getCallback();

public String getScope();

public String getSocialMediaName();

}

mardi 13 novembre 12

Page 66: Devoxx Java Social and Agorava

OAuth support

48

• OAuthProvider provides OAuth support. Its implementation uses OAuthAppSettings to get initatilized

• There one can :

• Create a RequestToken

• Get the URL to start connexion

• Get the Acces Token

• Create OAuth signature

public interface OAuthProvider { public OAuthToken getRequestToken();

public OAuthToken getAccessToken(OAuthToken tok, String ver);

public void signRequest(OAuthToken tok, OAuthRequest req);

public String getVersion();

public String getAuthorizationUrl(OAuthToken requestToken);

public OAuthRequest requestFactory(RestVerb v, String uri);

public OAuthToken tokenFactory(String token, String secret);

}

mardi 13 novembre 12

Page 67: Devoxx Java Social and Agorava

Rest calls with OAuthService

49

• OAuthService uses OAuthProvider to create and sign requests. It provides higher level services :

• Integration of user OAuth session

• Management of OAuth life cycle

• Sending simple Rest Request

• Sending signed Rest Request

public interface OAuthService extends RestService {

public OAuthToken getAccessToken();

public String getAuthorizationUrl();

public String getVerifier();

public void initAccessToken();

public RestResponse sendSignedRequest(RestVerb verb, String uri);

public RestResponse sendSignedRequest(RestVerb verb, String uri, Map<String, ?> params);

public RestResponse sendSignedRequest(RestVerb verb, String uri, String key, Object value);

public void setVerifier(String verifierStr);

public void setAccessToken(String token, String secret);

public void setAccessToken(OAuthToken token);

public RestResponse sendSignedXmlRequest(RestVerb verb, String uri, String payload);

public OAuthSession getSession();

public RestResponse sendSignedRequest(OAuthRequest request);

<T> T get(String uri, Class<T> clazz, boolean signed);}

mardi 13 novembre 12

Page 68: Devoxx Java Social and Agorava

High level API root : AbstractSocialMediaApi

50

• AbstractSocialMediaApi is the root for each family of API in a given social media module

• Some services provides more than ten API families (for instance Twitter)

• So we need a concept to gather these families

mardi 13 novembre 12

Page 69: Devoxx Java Social and Agorava

API families Hubs with SocialMediaApiHub

51

• Hubs are here to :

• Provide a gathering class for all API families of a given service

• Be the entry point of generic functionalities across different Social Media

• They also are the entry point of Social Media configuration

public interface SocialMediaApiHub extends OAuthServiceAware, Serializable {

public UserProfile getMyProfile();

public void resetConnection();

public boolean isConnected();

public String getVerifierParamName();

public String getSocialMediaName();

}

mardi 13 novembre 12

Page 70: Devoxx Java Social and Agorava

OAuthSession contains user specific infos

• OAuthSession contains data to handle the user part of an OAuth connexion :

• RequestToken

• Verifier

• And last but not least AccessToken

• OAuthSession keeps alos track of connected user identity

52

public interface OAuthSession extends Serializable {

public OAuthToken getRequestToken();

public void setRequestToken(OAuthToken requestToken);

public OAuthToken getAccessToken();

public void setAccessToken(OAuthToken accessToken);

public String getVerifier();

public void setVerifier(String verifier);

public void setUserProfile(UserProfile userProfile);

public UserProfile getUserProfile();

public Annotation getServiceQualifier();

public boolean isConnected();}

mardi 13 novembre 12

Page 71: Devoxx Java Social and Agorava

Bootstraping Twitter in CDI Impl

53

Thanks to Generic Beans extension this producer create 4 beans with different scopes.By default OAuth app settings are read in agorava.properties file

+getAccessToken()+getAuthorizationUrl()+getVerifier()+initAccessToken()+sendSignedRequest(RestVerb, String)+sendSignedRequest(RestVerb, String, Map)+sendSignedRequest(RestVerb, String, String, Object)+setVerifier(String)+setAccessToken(String, String)+setAccessToken(OAuthToken)+sendSignedXmlRequest(RestVerb, String, String)+getSession()+sendSignedRequest(OAuthRequest)+get(String, Class, boolean)

«interface»api.oauth.

OAuthService

+getRequestToken()+setRequestToken(OAuthToken)+getAccessToken()+setAccessToken(OAuthToken)+getVerifier()+setVerifier(String)+setUserProfile(UserProfile)+getUserProfile()+getServiceQualifier()+isConnected()+getName()

«interface»api.oauth.

OAuthSession

+getRequestToken()+getAccessToken(OAuthToken, String)+signRequest(OAuthToken, OAuthRequest)+getVersion()+getAuthorizationUrl(OAuthToken)+requestFactory(RestVerb, String)+tokenFactory(String, String)

«interface»api.oauth.

OAuthProvider

@Twitter@ApplicationScoped@OAuthApplication@Producespublic SocialMediaApiHub OAuthSettinsProducer(TwitterServicesHub service) { return service;}

+getMyProfile()+resetConnection()+isConnected()+getVerifierParamName()+getSocialMediaName()

«interface»api.

SocialMediaApiHub

@Twitter@ApplicationScoped

@Twitter@ApplicationScoped @Twitter

@SessionScoped@Twitter@ApplicationScoped

mardi 13 novembre 12

Page 72: Devoxx Java Social and Agorava

Create a new Agorava module

54

• To create a new module for Agorava 0.5, you have to :

• Create a Qualifier (annotation) tagued with @ServiceRelated meta annotation

• Create a low level API class containing basic endpoints to the new Social service. The class should use the same name as qualifier

• Extend AbstractSocialMediaApi to create the root class for all API families of the new Social Media

• Extend AbstractSocialMediaApiHub to gather Api families and implements generic services

• At minima create Service class to deal with user profile in the new service

mardi 13 novembre 12

Page 73: Devoxx Java Social and Agorava

Episode IVTechnologies in Agorava

mardi 13 novembre 12

Page 74: Devoxx Java Social and Agorava

Jackson

mardi 13 novembre 12

Page 75: Devoxx Java Social and Agorava

Jackson

• JSON to Pojo binding

• A JAX-B like solution for JSON

• Works with JAX-B anotations

• Provides also Json parsing tools

• Provides an elegant solution : the Mixin to configure mapping outside of the pojo 57

mardi 13 novembre 12

Page 76: Devoxx Java Social and Agorava

Mixin Example

58

public class Trend { private final String name;

private final String query;

public Trend(String name, String query) { this.name = name; this.query = query; }

public String getName() { return name; }

public String getQuery() { return query; }

}

@JsonIgnoreProperties(ignoreUnknown = true)abstract class TrendMixin {

@JsonCreator TrendMixin(@JsonProperty("name") String name, @JsonProperty("query") String query) { }

}

mardi 13 novembre 12

Page 77: Devoxx Java Social and Agorava

Module configuration is needed to use mixin

59

class TwitterModule extends SimpleModule { public TwitterModule() { super("TwitterModule", new Version(1, 0, 0, null)); } @Override public void setupModule(SetupContext context) { context.setMixInAnnotations(TwitterProfile.class, TwitterProfileMixin.class); context.setMixInAnnotations(SavedSearch.class, SavedSearchMixin.class); context.setMixInAnnotations(Trend.class, TrendMixin.class); }}

ObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new TwitterModule);

mardi 13 novembre 12

Page 78: Devoxx Java Social and Agorava

CDI

mardi 13 novembre 12

Page 79: Devoxx Java Social and Agorava

Simple dependency injection

61

@ApplicationScopedpublic class JsonMapperJackson implements JsonMapper {...}

public class OAuthServiceImpl implements OAuthService {

... @Inject protected JsonMapper jsonService;

...}

mardi 13 novembre 12

Page 80: Devoxx Java Social and Agorava

Qualified Injection

62

@Qualifier@ServiceRelated@Target({TYPE, METHOD, PARAMETER, FIELD})@Retention(RUNTIME)@Documentedpublic @interface Twitter {}

public abstract class TwitterBaseService extends AbstractSocialMediaApi {... @Inject @Twitter private OAuthService service;...}

mardi 13 novembre 12

Page 81: Devoxx Java Social and Agorava

Producer

63

@ApplicationScopedpublic class JsonMapperJackson implements JsonMapper {

@Produces private final ObjectMapper objectMapper = new ObjectMapper();...}

public class GraphApiImpl extends FacebookBaseService implements GraphApi {

@Inject private ObjectMapper objectMapper;...}

mardi 13 novembre 12

Page 82: Devoxx Java Social and Agorava

Programatic injection

64

public class OAuthServiceImpl implements OAuthService {

@Inject @Any private Instance<OAuthProvider> providers;... protected Annotation qualifier;... private OAuthProvider getProvider() { return providers.select(getQualifier()).get(); }...}

mardi 13 novembre 12

Page 83: Devoxx Java Social and Agorava

Programmatic injection for Mixin

65

@Inject @Any protected Instance<Module> moduleInstances;... @PostConstruct protected void init() { for (Module module : moduleInstances) { registerModule(module); } }

@Twitterclass TwitterModule extends SimpleModule {...}

@Facebookclass FacebookModule extends SimpleModule {...}

@ServiceXclass ServiceXModule extends SimpleModule {...}

mardi 13 novembre 12

Page 84: Devoxx Java Social and Agorava

Context & context Mixup

66

@SessionScopedpublic class MultiSessionManagerImpl implements MultiSessionManager, Serializable {

@Produces @Named @Current private OAuthSession currentSession;

public String initNewSession(String servType) { Annotation qualifier = getServicesToQualifier().get(servType); setCurrentSession(new OAuthSessionImpl(qualifier)); return getCurrentService().getAuthorizationUrl(); }}

@ApplicationScopedpublic class OAuthServiceImpl implements OAuthService {

@Inject @Any protected Instance<OAuthSession> sessionInstances;...}

mardi 13 novembre 12

Page 85: Devoxx Java Social and Agorava

Decorator

67

@Decoratorpublic abstract class TwitterTLServiceDecorator implements TwitterTimelineService {

@Inject @Delegate @Any private TwitterTimelineService delegate;

@Override public Tweet updateStatus(String status) { System.out.println("*** In Decorator ***"); delegate.updateStatus(status + "decorated" ); }}

mardi 13 novembre 12

Page 86: Devoxx Java Social and Agorava

Events

68

public class OAuthServiceImpl implements OAuthService {... @Inject @Any private Event<OAuthComplete> completeEventProducer;... public synchronized void initAccessToken() { session.setAccessToken(getProvider().getAccessToken(getRequestToken(), session.getVerifier())); Event<OAuthComplete> event = completeEventProducer.select(getQualifier()); event.fire(new OAuthComplete(SocialEvent.Status.SUCCESS, "", session)); }}

public class FacebookServicesHub extends AbstractSocialMediaApiHub {...

@Inject Instance<FacebookBaseService> services;... public void initMyProfile(@Observes @Facebook OAuthComplete oauthComplete) { if (oauthComplete.getStatus() == Status.SUCCESS) oauthComplete.getEventData().setUserProfile(services.select(UserServiceImpl.class).get().getUserProfile()); }...}

mardi 13 novembre 12

Page 87: Devoxx Java Social and Agorava

CDI extensions

mardi 13 novembre 12

Page 88: Devoxx Java Social and Agorava

CDI Extensions why ?

• An extension allows to

• Create beans or injection points

• modify beans or injection points

• Cancel beans creation

• More generally to analyse all beans and change them before the application is launch

70

mardi 13 novembre 12

Page 89: Devoxx Java Social and Agorava

Understanding extensions

71

• Once the application is running, bean manager is immutable (no dynamic bean in CDI)

• Extensions will be launch when the application is launch

• Extensions are also Beans

mardi 13 novembre 12

Page 90: Devoxx Java Social and Agorava

CDI Lifecycle

72

Deploy Application

Before Bean Discovery

Process Producers

Process Anotated Types

ScanArchive

ApplicationRunning

After Deployment Validation

Before Shutdown

Undeploy Application

ProcessBeans

After Bean Discovery

ProcessInjection Taget

Process Observer Methods

mardi 13 novembre 12

Page 91: Devoxx Java Social and Agorava

To create an extension

73

• Create a class which implements Extension

• Add one or more method that Observes CDI lifecycle steps to modify Bean Manager content

• Add this file in classpathMETA-INF/services/javax.enterprise.inject.spi.Extension

in which you add qualified name of the extension class

mardi 13 novembre 12

Page 92: Devoxx Java Social and Agorava

Simple Example : @Veto

74

 <X> void processAnnotatedType(@Observes final ProcessAnnotatedType<X> pat, BeanManager beanManager) {        final AnnotatedType<X> annotatedType = pat.getAnnotatedType();        final Class<X> javaClass = annotatedType.getJavaClass();        final Package pkg = javaClass.getPackage();

        // Support for @Veto        if (annotatedType.isAnnotationPresent(Veto.class) || (pkg != null && pkg.isAnnotationPresent(Veto.class))) {            pat.veto();            log.info("Preventing " + javaClass + " from being installed as bean due to @Veto annotation");            return;        }}

mardi 13 novembre 12

Page 93: Devoxx Java Social and Agorava

New technologies in version 1.0

• JAX-RS 2.0 client framework

• Development has just started

• It will deprecated Java Scribe in Agorava

• OAuth filters has to be written for this client

• Json 2 pojo schema

• An easy way to generate pojo from Json

• Demo

75

mardi 13 novembre 12

Page 94: Devoxx Java Social and Agorava

Major API Evolution in version 1.0

76

public interface HasUpdate {

public boolean sendUpdate(String message);

}

public interface HasTimeline {

public List<String> getTimeLine(); public List<String> getTimeLine(Date from, Date to); public List<String> getTimeLine(String fromId); }

public class FacebookServicesHub extends AbstractSocialMediaApiHub implements HasUpdate, HasTimeline

@Inject @Any Instance<HasUpdate> updatables;... for (HasUpdate updatable : updatables) { updatable.sendUpdate(msg); }

mardi 13 novembre 12

Page 95: Devoxx Java Social and Agorava

Q&A

mardi 13 novembre 12

Page 96: Devoxx Java Social and Agorava

• Agorava Project: http://agorava.org

• Follow us http://twitter.com/agoravaproj

• Fork Agorava http://github.com/agorava

Links

mardi 13 novembre 12

Page 97: Devoxx Java Social and Agorava

• DaliCore: http://java.net/projects/dalicore/

• Oracle SocialLink: http://java.net/projects/sociallink

• JSR 351 Identity API: http://java.net/projects/identity-api-spec

• Nobis JSR 351 RI: http://java.net/projects/nobis/

Links

mardi 13 novembre 12