Best Practices – Extending the Platform!             Jared and Rich!
Pre - Install!Environment Validation Tool or EVT• Available on Google Code !  • (http://code.google.com/p/alfresco-environ...
Donʼt Query if Donʼt Have to Query!Know you nodesJavaScript! !search.findNode()!Java! !new NodeRef()!
There is a cost! Web Scripts in the Repo? For Shame!  • Extra IO!   • To both the DB and the File System!  • Lightly used ...
Content Models!
Do you really need a type?
Important questions to ask!• Is it likely to change frequently!• Is it a fixed state!
But I really need to change that type!?!Adding is OKSubtraction is NotIf you must remove!• Hide it from the users in the c...
Donʼt Force It!• Donʼt force your model to fit the UI!• Sometimes the best approach is asimple custom UI!• The repository h...
We Enforce the Law!!There was a bug the allowed you to workincorrectly across models. We’ve fixed thebug. This may result ...
Have you                                            triedTurn It Off!                              turning it             ...
Youʼre Using Web Services!?! SOAP just makes me feel dirty  •                                    	  •                     ...
Bulk File System Import Tool!Available on Google Code, not      BFSIT!?!official supported by Alfresco.Maintained by Alfres...
Test!        Production != Test!
Know What You are Doing!Training and Certification!Engage Consulting or a Partner!Forums and Blogs!Wiki!Attend Devcon!
Backup!  Pre 4.0        4.0  Indexes     Indexes *  Database     Database Filesystem   Filesystem
Can We Build It!?!What is possible with Alfresco?!You tell us.!
Can We Fix It!?!Not Always!Engage SI partner or Alfresco consulting early!Weigh the costs: Effort to fix vs. Starting over!...
Packaging!AMPs are not the best and lack some featuresBut….…They provide process and encapsulation of customizations!
Outline!A few things learnedPermissionsJavaScript APIAttributeService
A few things learned!Echo --- having a build process that includes deployment early on, is very useful. – Building an AMP ...
Some Ant examples – Package Amp! <target name="package-amp" depends="mkdirs, package-jar" >        <zip destfile="${amp.fi...
Some Ant examples – Update War!  <target name="update-war" depends="package-amp"    <echo>Installing AMP into WAR</echo>  ...
Some Ant examples – Start/Stop Alfresco!<target name="start-alfresco"          description="Start the Alfresco Repository"...
About The Example!This example implements a simple customization that allows documents to be tagged as sendable.Each docum...
Extending Permissions!Why Extend Permissions  –  Allows Developers to Secure new functionality with ACLs!  –  Allows Devel...
Steps!Create Permissions Model File – The Records Management and Share Permissions files are good  examples! – The DTD is a...
Permission Model Code Snippet!<permissions>   <!-- Namespaces used in type references -->    ….   <permissionSet type="sen...
Security Interceptor Code Snippet!<bean id="SendableService_security" class="org.alfresco.repo.security.permissions.impl.a...
Creating JavaScript APIs!Why Create JavaScript APIs – Exposes key functionality to JavaScript! – Allows for the encapsulat...
Steps!Create the Java Class that will provide the API  – Extend the   org.alfresco.repo.jscript.BaseScopableProcessorExten...
Code Snippet!public class SendableScriptAPI extendsBaseScopableProcessorExtension {// Code Omitted     public ScriptNode g...
Bean Definition! <bean id="SendableScriptAPI"  parent="baseJavaScriptExtension" class="com.oldschooltechie.sendable.jscript...
Attribute Service!What is the Attribute Service  – Allows for the storage of arbitrary key value pairs!  – Each key can ha...
Steps For Using the Attribute Server!Determine how you will plan on using it.  – Think about the Key space – use the fact ...
Example Code Snippet…!public static final String SENDABLE_ATTR_NAME = "..SENDABLE_ID..";public static final String SENDABL...
Contact Information!Richard McKnightRichard.McKnight@alfresco.com@rmknightstarhttp://www.oldschooltechie.comJared OttleyJa...
Upcoming SlideShare
Loading in …5
×

BP-6 Repository Customization Best Practices

2,035 views

Published on

Alfresco’s highly customizable repository can often seem overwhelming. Learn approaches for adding common customizations requests (Extending Javascript API, Content Modeling, Permission Modeling, packaging, etc.) from current and former Alfresco consulting staff. Learn where we often see the most common errors and participate in open Q&A.

Published in: Technology
  • Be the first to comment

BP-6 Repository Customization Best Practices

  1. 1. Best Practices – Extending the Platform! Jared and Rich!
  2. 2. Pre - Install!Environment Validation Tool or EVT• Available on Google Code ! • (http://code.google.com/p/alfresco-environment-validation/)!• Currently targets version 3.3 (though mostly stillapplicable)!• Maintained by Support!Zero Day Config Guide or ZDC• Enterprise Only!• Available in the KB section of support site!
  3. 3. Donʼt Query if Donʼt Have to Query!Know you nodesJavaScript! !search.findNode()!Java! !new NodeRef()!
  4. 4. There is a cost! Web Scripts in the Repo? For Shame! • Extra IO! • To both the DB and the File System! • Lightly used vs High usage!
  5. 5. Content Models!
  6. 6. Do you really need a type?
Important questions to ask!• Is it likely to change frequently!• Is it a fixed state!
  7. 7. But I really need to change that type!?!Adding is OKSubtraction is NotIf you must remove!• Hide it from the users in the client!• Mark Java references deprecated!• NEVER modify the DB directly!
  8. 8. Donʼt Force It!• Donʼt force your model to fit the UI!• Sometimes the best approach is asimple custom UI!• The repository has capabilitiesbeyond what Explorer and Share!
  9. 9. We Enforce the Law!!There was a bug the allowed you to workincorrectly across models. We’ve fixed thebug. This may result in broken modelswhen upgrading from earlier versions.Take care to thoroughly test your modelsbefore upgrading. You may need to notonly fix your model, but massage the data, !or fix your custom code.
  10. 10. Have you triedTurn It Off! turning it off…When Possible Turn off unneeded Services •  File interfaces! •  Indexing (Less important in 4.0)! •  Quota Calculations! •  Subsystems!
  11. 11. Youʼre Using Web Services!?! SOAP just makes me feel dirty •  •  !*Though creating your own SOAP Client won’t be as easy as just using Apache Chemistry
  12. 12. Bulk File System Import Tool!Available on Google Code, not BFSIT!?!official supported by Alfresco.Maintained by AlfrescoEmployees.!Single purpose import:!Read content (metadata andversions supported) from theFilesystem!http://code.google.com/p/alfresco-bulk-filesystem-import/!
  13. 13. Test! Production != Test!
  14. 14. Know What You are Doing!Training and Certification!Engage Consulting or a Partner!Forums and Blogs!Wiki!Attend Devcon!
  15. 15. Backup! Pre 4.0 4.0 Indexes Indexes * Database Database Filesystem Filesystem
  16. 16. Can We Build It!?!What is possible with Alfresco?!You tell us.!
  17. 17. Can We Fix It!?!Not Always!Engage SI partner or Alfresco consulting early!Weigh the costs: Effort to fix vs. Starting over!Test. Test. Test.!
  18. 18. Packaging!AMPs are not the best and lack some featuresBut….…They provide process and encapsulation of customizations!
  19. 19. Outline!A few things learnedPermissionsJavaScript APIAttributeService
  20. 20. A few things learned!Echo --- having a build process that includes deployment early on, is very useful. – Building an AMP file is not as much trouble as it may seem.! – Many folks already have an Ant or Maven build config around that you can use (do not re-invent the wheel)!Naming Conventions are important. – If you plan on having multiple customizations in a single repository, this will help avoid conflicts! – Enterprise customers who have a mix of internal development teams and partners must think about this from Day 1.!
  21. 21. Some Ant examples – Package Amp! <target name="package-amp" depends="mkdirs, package-jar" > <zip destfile="${amp.file}" > <fileset dir="${build.dir}" includes="lib/*.jar" /> <fileset dir="${project.dir}" includes="lib/*.jar" /> <fileset dir="${project.dir}/source" includes="config/**/*.*, jsp/**/*.*, css/**/*.*" /> <fileset dir="${project.dir}/source/config/alfresco/module/${module.id}" includes="*.properties" excludes="log4j.properties" /> </zip> </target>
  22. 22. Some Ant examples – Update War! <target name="update-war" depends="package-amp" <echo>Installing AMP into WAR</echo> <java dir="." fork="true" classname= "org.alfresco.repo.module.tool.ModuleManagementTool"> <classpath refid="class.path" /> <arg line="install ${amp.file} ${war.file} -force -nobackup -verbose"/> </java> <delete dir="${alfresco.dir}/tomcat/webapps/alfresco" /> <delete dir="${alfresco.dir}/tomcat/temp/Alfresco" /> <delete dir="${alfresco.dir}/tomcat/work/Catalina/localhost/alfresco" /></target>
  23. 23. Some Ant examples – Start/Stop Alfresco!<target name="start-alfresco" description="Start the Alfresco Repository"> <exec executable="/bin/sh"> <arg line=-c "${alfresco.dir}/alfresco.sh start"/> </exec> </target> <target name="stop-alfresco“ description="Stop the Alfresco Repository"> <exec executable="/bin/sh"> <arg line=-c "${alfresco.dir}/alfresco.sh stop"/> </exec> </target>
  24. 24. About The Example!This example implements a simple customization that allows documents to be tagged as sendable.Each document has a status and a document ID – The document ID does not have to be the object ID and is guaranteed to be unique in the repository.! – The valid statuses are staged, effective and retired.!Users must have ManageSendable Permission to change the sendable status.
  25. 25. Extending Permissions!Why Extend Permissions –  Allows Developers to Secure new functionality with ACLs! –  Allows Developers to Expose new combinations of low level permissions a new role.!Examples of Extended Permissions –  Share! –  Records Management!Caveats and Gotchas –  If you create new permissions you will have some extra work around security.!
  26. 26. Steps!Create Permissions Model File – The Records Management and Share Permissions files are good examples! – The DTD is another good source of documentation -- http:// wiki.alfresco.com/wiki/PermissionModelDTD!Wire in the bean – Add the permissionModelBootstrap bean! – Wire in any additional permissions using Security Interceptors (if needed)! – Add any needed permissions to the slingshotDocLibCustomResponse bean!
  27. 27. Permission Model Code Snippet!<permissions> <!-- Namespaces used in type references --> …. <permissionSet type="senddoc:content" expose="all"> <permissionGroup name="ManageSendable" expose="true"allowFullControl="false"/> <!-- The low level permission to control setting the owner of a node --> <permission name="_ManageSendable" expose="false" requiresType="false"> <grantedToGroup permissionGroup="ManageSendable" /> <requiredPermission on="node" type="sys:base" name="_ReadProperties" /> </permission> </permissionSet></permissions>
  28. 28. Security Interceptor Code Snippet!<bean id="SendableService_security" class="org.alfresco.repo.security.permissions.impl.acegi.MethodS ecurityInterceptor"> <!– Manager Beans Here  <property name="objectDefinitionSource"> <value> com.oldschooltechie.sendable.SendableService.makeNodeEffective= ACL_NODE.1.senddoc:content.ManageSendable com.oldschooltechie.sendable.SendableService.retireNode= ACL_NODE.1.senddoc:content.ManageSendable com.oldschooltechie.sendable.SendableService.*= ACL_ALLOW </value> </property></bean>
  29. 29. Creating JavaScript APIs!Why Create JavaScript APIs – Exposes key functionality to JavaScript! – Allows for the encapsulation of the “heavy lifting” functionality!Some examples of how Custom Javascript APIs are used – Called from Javascript Based webscripts! – Unit testing underlying Java Functionality from JavaScript Scripts that can be run with the Execute Script Action!
  30. 30. Steps!Create the Java Class that will provide the API – Extend the org.alfresco.repo.jscript.BaseScopableProcessorExtension class! – All public methods that are not setters and getters will be exposed as JavaScript methods.! – Make sure that you convert NodeRefs into ScriptNodes and visa versa.! – Make sure that arguments passed and returned are Scalars, Scriptables, Arrays or Maps.!Wire in the bean – Extend the baseJavaScriptExtension bean! – Set the extensionName property!
  31. 31. Code Snippet!public class SendableScriptAPI extendsBaseScopableProcessorExtension {// Code Omitted public ScriptNode getNodeRefById(String docId) { NodeRef result = sendableService.getNodeRefById(docId); return new ScriptNode(result, this.serviceRegistry, getScope()); } public void makeSendable(ScriptNode nodeRef,String docId) { sendableService.makeSendable(nodeRef.getNodeRef(), docId); }}
  32. 32. Bean Definition! <bean id="SendableScriptAPI" parent="baseJavaScriptExtension" class="com.oldschooltechie.sendable.jscript.SendableScriptAPI"> <property name="extensionName"> <value>sendable</value> </property> <property name="sendableService"> <ref bean="SendableService"/> </property> <property name="serviceRegistry"> <ref bean="ServiceRegistry"/> </property> </bean>
  33. 33. Attribute Service!What is the Attribute Service – Allows for the storage of arbitrary key value pairs! – Each key can have up to 3 segments.! – The key segments and values are all Serializables (i.e. can be anything).!Why Use Atrribute Service – There are a number of use cases…..! – Our use case – properties that must have a unique value across nodes.! •  Allows making associations between values and nodes via the Database! •  Allows for Enforcing Uniqueness of certain Values! – AttributeService also allowed for retrieving nodes (immediately across all nodes in a cluster) by a property value. (This is less of an issue in swift).!
  34. 34. Steps For Using the Attribute Server!Determine how you will plan on using it. – Think about the Key space – use the fact that the key is segmented.! – Think about the core operations! – Wrap it all in a component.!
  35. 35. Example Code Snippet…!public static final String SENDABLE_ATTR_NAME = "..SENDABLE_ID..";public static final String SENDABLE_DOC_ID_ATTR_NAME = "..DOC_ID..";public void storeDocId(String doc_id,NodeRef nodeRef) { if (attributeService.exists(SENDABLE_ATTR_NAME, SENDABLE_DOC_ID_ATTR_NAME,doc_id)) { // Check to see if this node has already been registered if (!attributeService.getAttribute(SENDABLE_ATTR_NAME, SENDABLE_DOC_ID_ATTR_NAME,doc_id).equals(nodeRef)) { throw new SendableRuntimeException("Duplicate entry id:"+doc_id); } } attributeService.setAttribute(nodeRef,SENDABLE_ATTR_NAME, SENDABLE_DOC_ID_ATTR_NAME,doc_id); }
  36. 36. Contact Information!Richard McKnightRichard.McKnight@alfresco.com@rmknightstarhttp://www.oldschooltechie.comJared OttleyJared.ottley@alfresco.com@jottleyhttp://jared.ottleys.net

×