bp-6 repository customization best practices

Post on 22-May-2015

1.688 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

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-environment-validation/)!

• Currently targets version 3.3 (though mostly still applicable)!

• Maintained by Support!Zero Day Config Guide or ZDC • Enterprise Only!

• Available in the KB section of support site!

Donʼt Query if Donʼt Have to Query!

Know you nodes

JavaScript!

!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 vs High usage!

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 OK Subtraction is Not If you must remove!• Hide it from the users in the client!• Mark Java references deprecated!• NEVER modify the DB directly!

Donʼt Force It!

• Donʼt force your model to fit the UI!• Sometimes the best approach is a simple custom UI!• The repository has capabilities beyond what Explorer and Share!

We Enforce the Law!!

There was a bug the allowed you to work incorrectly across models. We’ve fixed the bug. This may result in broken models when upgrading from earlier versions. Take care to thoroughly test your models before upgrading. You may need to not only fix your model, but massage the data, or fix your custom code.!

Turn It Off!Have you

tried turning it

off…

When Possible Turn off unneeded Services

• File interfaces!•  Indexing (Less important in 4.0)!• Quota Calculations!• Subsystems!

Youʼre Using Web Services!?!

SOAP just makes me feel dirty • Use Web Scripts over SOAP API • If you must use SOAP ‒ CMIS*!

*Though creating your own SOAP Client won’t be as easy as just using Apache Chemistry

BFSIT!?! Bulk File System Import Tool!Available on Google Code, not official supported by Alfresco. Maintained by Alfresco Employees.!

Single purpose import:!Read content (metadata and versions supported) from the Filesystem!

http://code.google.com/p/alfresco-bulk-filesystem-import/!

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

Indexes Database Filesystem

4.0

Indexes * Database 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!

Test. Test. Test.!

Packaging!

AMPs are not the best and lack some features

But….

…They provide process and encapsulation of customizations!

Outline!

A few things learned Permissions JavaScript API AttributeService

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.!

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>

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>

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>

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.

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.!

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!

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>

Security Interceptor Code Snippet!

<bean id="SendableService_security" class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityInterceptor">

<!– 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>

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!

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!

Code Snippet!

public class SendableScriptAPI extends BaseScopableProcessorExtension { // 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); }

}

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>

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).!

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.!

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); }

Richard McKnight Richard.McKnight@alfresco.com @rmknightstar http://www.oldschooltechie.com

Jared Ottley Jared.ottley@alfresco.com @jottley http://jared.ottleys.net

Contact Information!

top related