• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Alfresco Integrations - Alfresco Devcon 2012
 

Alfresco Integrations - Alfresco Devcon 2012

on

  • 705 views

Overview of Alfresco Integrations Work

Overview of Alfresco Integrations Work

Statistics

Views

Total Views
705
Views on SlideShare
705
Embed Views
0

Actions

Likes
0
Downloads
9
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Alfresco Integrations - Alfresco Devcon 2012 Alfresco Integrations - Alfresco Devcon 2012 Presentation Transcript

    • Alfresco Integrations: What Weve Learned So FarJared OttleyIntegrations Engineer
    • Agenda•State of the Union•Projects•Current Status•Jive Toolkit•Dropbox•Maven•Google Docs•Whats New•oAuth Persistance•Create Content Callback•Evaluators, Custom Response•oAuth•Transaction Rollback Handling•JMX
    • Weve Grown•Started with one Engineer - me!•Added a Project Manager - Peter Monks•Added another Engineer - Will Abson
    • Projects•Google Docs v2 (Cloud, Enterprise, Community)•Hyperic Plugin (Community)•Kofax (Enterprise)•XAM Connector (Enterprise)•S3 Connector (Cloud, Enterprise)•Salesforce (Cloud)•Jive Toolkit (Enterprise, Community)•Dropbox Connector (Community)
    • Projects (Cont.)•Spring Social Dropbox (Fork)•Spring Social Google Docs•Spring Social AlfrescoContributed•oAuth1/2 Persistence Service•PDF Toolkit•Share Extras•Maven AMP Plugin•Java CORS Filter•Welsh Language Pack
    • Projects (Cont.)•Share Import-Export Python scripts•Ubuntu QuickStart scripts•WordPress Alfresco plugins•Alfresco Community to Cloud Migration Utility•And More....
    • What does the future hold?The Future is Fluid
    • Jive ToolkitWhat is it?A set of pre-built components that allows Jive to store documents in Alfresco whilestill offering all of the same social features as “native” Jive documents (commenting,rating, discussions, etc.)Availability?Released Early 2012Current supported release version 1.0.5 for Alfresco 3.4.11Support PortalCurrent community release version 1.1 for Alfresco 4.1http://code.google.com/p/alfresco-jive-toolkit/
    • Jive Toolkit (Cont.)Future?•The community project is looking for help.•SolutionSet is taking ownership of the project.•Looking foro Developerso Testerso Users!o Documentation
    • Alfresco Dropbox ConnectorWhat is it?The Alfresco Dropbox Connector allows a user to sync content/folders to theirDropbox Account. Content can be synced to multiple users accounts. When thecontent is updated in Alfresco it will be synced across all synced Dropbox Accounts.It supports manual updates back to Alfresco from Dropbox.Availability?It is current available from Google Code (http://code.google.com/p/alfresco-dropbox-integration/). It is available as acommunity supported project. It requires at least Alfresco 4.1 (Enterprise) or 4.2(Community)
    • Alfresco Dropbox Connector (Cont.)Status?We are looking for Contributors, Testers, Documentation, Users.What happened?Sync.Automatic sync between multiple sources is a complicated issue. It is even morecomplicated when one of the sources doesnt have a full understanding of contentlifecycle....or managing it.
    • Alfresco Dropbox Connector (Cont.)Issue 1: One to ManyContent in Alfresco is shared across multiple users but maintains a single source oftruth.When synced to Dropbox .... we have many sources.Sharing content is explicit: a user has to initiate it. No API support.
    • Alfresco Dropbox Connector (Cont.)Issue 2: VersioningDropbox has poor version support.•Revision created with each save•Revisions only available for the past 30 days•Revisions number are non sequential alphanumeric sequences•Modification dates cant be trustedOne to Many + Versioning = Nightmare.
    • Alfresco Dropbox Connector (Cont.)Issue 3: File Changes (1)Dropbox provides a delta api."A way of letting you keep up with changes to files and folders in a users Dropbox.You can periodically call /delta to get a list of "delta entries", which are instructions onhow to update your local state to match the servers state."In reality, an entry in the delta list means the files is:...New...Update...Move...Copied...Renamed...an entry with no file metadata means the file has been...Deleted...Moved...Renamed...
    • Alfresco Dropbox Connector (Cont.)Issue 3: File Changes (2)It is polling......which is expensive......which drains already costly resources...
    • Alfresco Dropbox Connector (Cont.)
    • Alfresco Dropbox Connector (Cont.)Are we without options?No.Our proposed approachOut of process pollingCMIS Client to AlfrescoRESTful client of DropboxComplicated ordering of content changes out of process
    • Maven3.0.4 or 3.0.5-SNAPSHOTAdd to pom or settings.xml:<pluginRepositories><pluginRepository><id>alfresco-public</id><name>Alfresco</name><url>https://artifacts.alfresco.com/nexus/content/repositories/releases</url></pluginRepository><pluginRepository><id>alfresco-public-snapshots</id><name>Alfresco</name><url>https://artifacts.alfresco.com/nexus/content/groups/public-snapshots/</url></pluginRepository></pluginRepositories>
    • MavenAlfresco dependencies can be found athttps://artifacts.alfresco.comAdd the amp packaging decleration to your pom.xml<packaging>amp</packaging>
    • MavenRepo/Share Pom<plugin><groupId>org.alfresco.maven.plugin</groupId><artifactId>maven-amp-plugin</artifactId><version>3.0.4</version><extensions>true</extensions><configuration><mAmpJarExcludes>alfresco/module/**,alfresco/extension/**,alfresco/messages/**</mAmpJarExcludes> <!--exclude in share --><archive><addMavenDescriptor>false</addMavenDescriptor></archive></configuration></plugin>
    • MavenShare Pom (YUI Minification)<plugin><groupId>net.alchim31.maven</groupId><artifactId>yuicompressor-maven-plugin</artifactId><version>1.2</version><executions><execution><id>compressyui</id><phase>process-resources</phase><goals><goal>compress</goal></goals></execution></executions><configuration><excludes><exclude>**/*.css</exclude><exclude>**/*.get.js</exclude></excludes></configuration></plugin>
    • Maven├── module.properties├── pom.xml└── src├── main│ ├── java│ │ └── org│ │ └── alfresco│ ├── resources│ │ └── alfresco│ │ ├── extension│ │ ├── messages│ │ └── module│ └── webapp│ └── WEB-INF│ └── web.xml└── test├── java└── resources
    • MavenBuild commandmvn clean package [-DskipTests]Amp locationin target directoryValidate amp content in directory of same name as amp (minus amp extension)
    • Google Docs V2• Complete rewriteoUsabilityoFunctionality• No Shared AccountoCreate and Edit content in their account• Google is used as an editor, not persistance• Add-on not part of core• Cloud, Enterprise, Community[Talk about Drive here :-)]
    • Google Docs V2Demo
    • Google Docs V2
    • Google Docs V2OAuth Credentials StoreProvide Token Persistence for oAuth1 and oAuth2Leverages Remote Credentials ServiceDropbox Integrations and Google Docs V2 this service
    • Google Docs V2How Toprivate static OAuth2CredentialsStoreService oauth2CredentialsStoreService;//Store Credentials. RemoteSystemId should be Uniqueoauth2CredentialsStoreService.storePersonalOAuth2Credentials(RemoteSystemId,AccessToken, RefreshToken, ExpiresAt, IssuedAt);//Retrieve Credentials by RemoteSystemIdOAuth2CredentialsInfo oAuth2CredentialsInfo =oauth2CredentialsStoreService.getPersonalOAuth2Credentials(RemoteSystemId);//Update Credentials the same way you add new ones...make sure the RemoteSystemId is thesameoauth2CredentialsStoreService.storePersonalOAuth2Credentials(RemoteSystemId,UpdatedAccessToken, UpdatedRefreshToken, UpdatedExpiresAt, UpdatedIssuedAt);
    • Google Docs V2//Store Shared Credentials. Recomendation: Unqiue RemoteSystemIdoauth2CredentialsStoreService.storeSharedOAuth2Credentials(RemoteSystemId,AccessToken, RefreshToken, ExpiresAt, IssuedAt);//Retrieve by RemoteSystemId Note: this returns a listList<OAuth2CredentialsInfo> sharedCredentials =oauth2CredentialsStoreService.listSharedOAuth2Credentials(RemoteSystemId);//Update Share Credentials. Note the specifics method for updating sharedcredentialsoauth2CredentialsStoreService.updateSharedOAuth2Credentials(oAuth2CredentialsInfo, RemoteSystemId, UpdatedAccessToken, UpdatedRefreshToken,UpdatedExpiresAt, UpdatedIssuedAt);
    • Google Docs V2//Delete Personal Credentials by RemoteSystemIdoauth2CredentialsStoreService.deletePersonalOAuth2Credentials(RemoteSystemId);//Delete Share Credentials requires RemoteSystemId and the oAuth2CredentialsInfoinstance of the specific credentialsList<OAuth2CredentialsInfo> sharedCredentials =oauth2CredentialsStoreService.listSharedOAuth2Credentials(RemoteSystemId);//find the ones you need in the listoauth2CredentialsStoreService.deleteSharedOAuth2Credentials(RemoteSystemId,oAuth2CredentialsInfo);
    • Google Docs V2Create Content ActionAdd to your share-config-custom.xml<config evaluator="string-compare" condition="DocumentLibrary"><create-content><content id="google-docs" label="create-content.googledocs.document"icon="document" index="50" type="javascript"><param name="function">onGoogledocsActionCreateDocument</param></content></create-content></config>
    • Google Docs V2It supports 3 different actions: link, pagelink or javascript:* "link" - accepts a "href" param that will be passed a nodeRef token forsubstitution, used for external links* "pagelink" - accepts a "page" param that will be passed a nodeRef token forsubstitution, used for Share links* "javascript" - accepts & "function" param of an action that will get the currentfolder item as first argument.Evaluators are not currently supported, but permission checks are.
    • Google Docs V2(function() {YAHOO.Bubbling.fire("registerAction", {actionName : "onGoogledocsActionCreateDocument",fn: function dlA_onGoogledocsActionCreateDocument(record){//Do Work HerecreateGoogleDoc.call(this, record, "document");}})})();
    • Google Docs V2DocLib Actions: Evaluators, Custom ResponsesTwo actions:Edit ContentResume Editing ContentEdit ContentOnly a specific set of content can be edited by Google DocsContent that is currently being edited cant be "edited"User must have write access to the nodeDocument Size LimitsGoogle Docs Service can be turned off
    • Google Docs V2Editing Action<action id="google-docs-edit-action-link" type="javascript"icon="google-edit" label="googledocs.actions.edit"><param name="function">onGoogledocsActionEdit</param></action>JavaScript or PageLink?Debugginghttp://localhost:8080/alfresco/service/slingshot/doclib2/node/workspace/SpacesStore/8759ce08-acaa-4d69-807e-23c98a53fd17
    • Google Docs V2User must have write access to the node<permissions><permission allow="true">Write</permission></permissions>Possible PermissionsCancelCheckOutChangePermissionsCreateChildrenDeleteWrite
    • Google Docs V2Content that is currently being edited cant be "edited"Content being edited has the gd2:editingInGoogle aspect applied<bean id="evaluator.doclib.google.docs.doesnothaveaspect"parent="evaluator.doclib.metadata.doesNotHaveAspect"><property name="aspects"><list><value>gd2:editingInGoogle</value></list></property><property name="negateOutput" value="true" /></bean>
    • Google Docs V2Document Size LimitsGoogle Docs has a complex set of sizes (http://support.google.com/drive/bin/answer.py?hl=en&answer=37603)<bean id="evaluator.doclib.metadata.sizeLimit"class="org.alfresco.integrations.web.evaluator.SizeLimitEvaluator"><property name="maxDocumentSize" value="2097152"/><property name="maxSpreadsheetSize" value="20971520"/><property name="maxPresentationSize" value="52428800"/></bean>
    • Google Docs V2Remember!Numeric values in json are doubles.long size = ((Double)node.get("size")).longValue();String contentType = getContentType(node.get("mimetype").toString());if (contentType == null || size > getMaxFileSize(contentType)){return false;}
    • Google Docs V2Only a specific set of content can be edited by Google Docsapplication/vnd.openxmlformats-officedocument.presentationml.presentationapplication/vnd.ms-powerpointtext/tab-separated-valuesapplication/vnd.sun.xml.writerapplication/vnd.ms-excelapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetapplication/rtfapplication/mswordapplication/vnd.oasis.opendocument.texttext/plaintext/csvapplication/x-vnd.oasis.opendocument.spreadsheetapplication/vnd.oasis.opendocument.spreadsheet <!-- GOOGLEDOCS-71 -->application/vnd.openxmlformats-officedocument.wordprocessingml.document
    • Google Docs V2<property name="importFormats"><map><entry key="application/vnd.openxmlformats-officedocument.presentationml.presentation"><value>presentation</value></entry>....</map></property
    • Google Docs V2<property name="exportFormats"><map><entry key="document"><map><entry key="application/vnd.openxmlformats-officedocument.wordprocessingml.document"><value>docx</value></entry>...</map></entry></map></property>
    • Google Docs V2Bonusapplication/x-msmetafile
    • Google Docs V2<bean id="evaluator.doclib.metadata.isMimetype"class="org.alfresco.integrations.web.evaluator.IsMimetypeEvaluator"/><bean id="evaluator.doclib.google.docs.mimetype"parent="evaluator.doclib.metadata.isMimetype"><property name="mimetypes" value="custom.googledocs.importFormats"/></bean>
    • Google Docs V2Google Docs Service can be turned offgoogledocs.enabled=truepublic Serializable populate(){Map<String, Serializable> map = new LinkedHashMap<String, Serializable>(2);map.put("enabled", (Serializable)googledocsService.isEnabled());map.put("importFormats", (Serializable)googledocsService.getImportFormats());return (Serializable)map;}
    • Google Docs V2<bean id="evaluator.doclib.google.docs.enabled"parent="evaluator.doclib.action.metadataValue"><property name="accessor" value="custom.googledocs.enabled"/><property name="comparator"><bean class="org.alfresco.web.evaluator.StringEqualsComparator"><property name="value" value="true" /></bean></property>
    • Google Docs V2Chaining our EvaluatorsEdit Evaluator<bean id="evaluator.doclib.google.docs.edit" parent="evaluator.doclib.action.chainedMatchAll"><property name="evaluators"><list><ref bean="evaluator.doclib.google.docs.enabled"/><ref bean="evaluator.doclib.google.docs.mimetype" /><ref bean="evaluator.doclib.google.docs.doesnothaveaspect" /><ref bean="evaluator.doclib.google.docs.maxsize" /></list></property></bean>
    • Google Docs V2<bean id="evaluator.doclib.google.docs.resume"parent="evaluator.doclib.action.chainedMatchAll"><property name="evaluators"><list><ref bean="evaluator.doclib.google.docs.aspect"/><ref bean="evaluator.doclib.indicator.lockOwner"/></list></property></bean>Resume Edit Evaluator
    • Google Docs V2OAuth WorkflowAuthentication is a challenge no matter what the authentication type.oAuth is only part of the solution for Google Docs...but we leverage it to solveother issues as wellWe leveraged our own spring-social-google-docs.spring-social-google was not compatiblespring-social-google-docs is a wrapper for gdataNewer google client did not provide a client api for Google Docs
    • Google Docs V2
    • Google Docs V2ComponentsTwo Web Scripts1. Provides the Authentication URL2. Completes the Authentication-Persists the TokensClient Side JSInitiate the FlowCalls to RepoOpens ModalDialog or new WindowSecret Sauce: Callback page, browser redirect the auth token torepo
    • Google Docs V2Rollback CallbackUsed to handle additional clean up work when a transaction is rolled back. Couldbe used to perform work in another system or in Alfresco.Clean upNotificationsSome Unit of Work
    • Google Docs V2catch (SomeException e){AlfrescoTransactionSupport.bindListener(new TransactionListenerAdapter() {public void afterRollback() {transactionService.getRetryingTransactionHelper().doInTransaction(newRetryingTransactionCallback<Object>() {public Object execute() throws Throwable{//do work here}}, false, true);}});//Something maybe needed here likethrow new SomeOtherException(e.getMessage(), e);}
    • Google Docs V2JMXAny properties you add to for your custom beans to pick up are made read-only inJMX. If you want read write, make a subsystem.Define your ChildApplicationContextFactory bean in your AMPsmodule.properties file.Create a directory structure in your resource directoryalfresco.subsystems.<category>[.<instance>]Add your systems <name>-context.xml and <name>.properties files
    • Google Docs V2<bean id="googledocs_v2"class="org.alfresco.repo.management.subsystems.ChildApplicationContextFactory"parent="abstractPropertyBackedBean"><property name="category"><value>googledocs</value></property><property name="typeName"><value>v2</value></property><property name="instancePath"><value>v2</value></property><property name="autoStart"><value>true</value></property></bean>
    • Google Docs V2Best PracticesKeep your model in you subsystem.Web Scripts Cannot be defined in your subsystemTest what happens when you unload your subsystem--Subsystems can be automatically reloaded--If you dont want that to happen,Add programmatic controls to keep its beans from beingcalled