Wednesday, December 4, 2013

Alfresco share custom evaluator to check node associations

In Share, we have evaluator based on that templates, action, indicator can be displayed.
We also can have our own custom evaluator . 

I see - many has requirement to show/hide action based on content/folder associations and which is NOT available OOB.
So, In this example I will show you how you can implement it.

We will implement custom evaluator which checks if content has "cm:references" association then show OOB action - "Delete Document". You can have your custom action or any other action.

First we will start with Share side changes.

Step1:  Define custom evaluator

Create file - custom-documentlibrary-context.xml and put it to \tomcat\shared\classes\alfresco\web-extension

Add below code

Step 2: Create custom evaluator class.

This class calls alfresco repository webscript which accepts content noderef and association name and
checks if content has given association or not and accordingly return true or false.

Step 3:  Add new custom evaluator for delete document action in share-config-custom.xml
So now we are done with Share side changes.
We need to create alfresco repository webscript which checks if node has given association or not. This would be simple javascript webscript

Step1: Create desc file . node-association.get.desc.xml.
Put in to extension folder: \tomcat\shared\classes\alfresco\extension\templates\webscripts\custom\example\node\association
Step 2: Create node-association.get.js

Step 3: Create node-association.get.json.ftl

Deploy your custom code and restart server. Verify Delete action for content with and without cm:reference association.
I have not considered multiple association, you can change it same way.

Hope its helpful!
 

Friday, September 20, 2013

Manage Alfresco through JMX - Revert persistence property from database


We can monitor and manage alfresco through JMX. How to connect alfresco through JMX , Please refer - http://wiki.alfresco.com/wiki/JMX

JMX allows us to change several Alfresco Subsystems configuration without restart of server.
But we must need to know that - this settings are being persisted in database [Not all configurations] and this changes get applied to all nodes in cluster which is NOT always good.

For example you have 2 nodes in cluster and both node has different location for its lucene index .

node1: dir.indexes=/opt/alfresco/lucene/lucene-indexes
node2: dir.indexes=/opt/alfresco/luceneNew/lucene-indexes

Now, if you change node 1 location from JMX then it will also affect node2. and on next restart you can not override changes from your alfresco-global.properties file.
Property value saved in database takes precedence over property file.

How to revert changes

To Revert back this changes, Need to go to Operation tab as shown in below image and click on revert - which will store your default/original value.



Which configuration are persistent

You can know which MBean  properties are persistent from your JMX client [I am using VisualVM].
Go to Metadata tab as shown in below image. MBean with Description as "Persistent Managed Bean" stores property value in Database.





Hope this information will help!

Alfresco 4.2 New Features


Alfresco 4.2 have lot many new and enhanced features. I tried this new version in my local env and I have listed this features.
Alfresco theme has been changed which is very light and sleek.

Alfresco Share NEW UI

New Header
  • Header theme has been changed to for better visualization 


My Files
  • New link is added - My Files for users personal documents
  • In BackEnd - Alfresco explorer - It saves contents to User's Home Folder .


Shared Files
  • New link Shared Files has been added.
  • In Share Repository view, new folder has been added - Shared under Company Home
  • This is default folder for all users to add/share contents which can help to hide system Folders like Sites, Data Dictionary etc...
  • Repository link is as it is which shows all folders under Company Home

Site Interface
  • Site UI has been changed, again new look and for better visualization.
  • Site Page header has been removed. Site customization header and Page headers are combined in single toolbar
  • You can navigate to recently accessed sites from Sites menu

  • In Document Library many new views has been introduced like Filmstrip, Table view etc..


Admin Console
  • Admin console has been divided in two part 
  • Share Admin Tool
    • This includes
      • Tools - Application, Category Manager, Node Browser etc..
      • File Management -Trashcan
      • Content Publishing - Channel Manager
      • Repository - Replication Jobs
      • Users and Groups - Groups, Users


  • Repository Administration Console
    • It runs independently of alfresco app so there is no direct link is available from Share or Explorer UI
    • Need to use this URL to launch this Repository admin console - http://<host-name>:<port>/alfresco/service/enterprise/admin/admin-directorymanagement 
    • This includes 
      • System Summary 
      • Email Services 
      • General- License, Repository Information etc.. 
      • Repository Services -Activities Feed, Repository Server Clustering, Process Engines, Replication Service, Search Service etc.. In this new enhanced Repository Server Clustering is added. 
      • Support Tools -Download JMX Dump 
      • Directories - Directory Management 
      • Virtual File Systems - File Servers, IMAP Service


User Trashcan
  • User trashcan is added in User profile page
  • User can recover/purge deleted items from own trash

Site level activity feed
  • User can control activity feed at individual site level

Download as Zip
  • New action is added to download multiple files together as zip
  • You can select multiple files then from menu select - Download s zip action which will create a zip file
  • You can also download entire folders as a Zip bundle
Google Docs Integration
  • Google docs integration is really improved.
  • You can create doc, xls or PPT file in just one click; you can edit/update your content and can save back to Alfresco
  • Here is Jeff Potts blog for detailed features video - http://ecmarchitect.com/archives/2012/10/10/1715
New Search Dashlets

Site Search
  • It allows you to search contents from your sites if you have added in your personal dashboard OR specific to site if its added on Site dashboard

Saved Search
  • It allows you to save your search term.
  • You need to configure your search term from dashlet configurations
  • So this dashlet will list all contents related to your search term

You may try new version. It has really good user experience!

Reference Link: http://docs.alfresco.com/4.2/index.jsp

Friday, September 6, 2013

Failed to purge nodes - DeletedNodeCleanupWorker


We recently faced issue with alfresco OOB scheduler - DeletedNodeCleanupWorker.
We were getting below error:

"21:00:40,348 WARN [node.db.DeletedNodeCleanupWorker] Failed to purge nodes. If the purgable set is too large for the available DB resources then the nodes can be purged manually as well.
...................
### Error updating database.  Cause: java.sql.SQLException: The DELETE statement conflicted with the REFERENCE constraint "fk_alf_cass_pnode". The conflict occurred in database "alfrescoDB", table "dbo.alf_child_assoc", column 'parent_node_id"

Reason of this error is - Alfresco is referencing to deleted node such that purge is failing because of the constraint on db
This error may affect lucene indexing. Indexes can be out-of-sync and search might not return all results.

To solve this error, We followed below steps.Basically we need to delete corrupted nodes manually from Database.

1)First we need to find out problematic node, For that Run full indexing. You may enable below logger for detail info.


log4j.logger.org.alfresco.repo.node.index.AbstractReindexComponent=debug
log4j.logger.org.alfresco.repo.node.index.IndexTransactionTracker=debug
log4j.logger.org.alfresco.repo.node.index.FullIndexRecoveryComponent=debug
log4j.logger.org.alfresco.repo.node.index.AVMFullIndexRecoveryComponent=debug

2)Check Full indexing logs.Nodes with below error are corrupted nodes which is causing issue.

"Caused by: org.springframework.dao.ConcurrencyFailureException: Attempt to follow reference workspace://SpacesStore/fc4450e4-c316-4531-b90a-b94a0e73a4a5 to deleted node 1260437"

3) We would consider this node 1260437 and we need to delete this node manually from DB. Before we delete this node, we need to make sure it doesn't affect any other contents and it doesn't have any child.

4)Need to execute below queries. For example, I got 2 corrupted nodes - 1260437,467222. I have also provided query result so you can know which nodes we needs to consider again from result and how we can go bottom of the tree.

From below query, Mainly we need to consider :SELECT * FROM alf_child_assoc WHERE parent_node_id IN(1260437,467222)

SELECT * FROM alf_node_assoc WHERE source_node_id IN (1260437,467222); - No Records
SELECT * FROM alf_node_assoc WHERE target_node_id IN (1260437,467222); - No Records
SELECT * FROM alf_usage_delta WHERE node_id IN (1260437,467222); - No Records
SELECT * FROM alf_node_aspects WHERE node_id IN (1260437,467222); - No Records
SELECT * FROM alf_node_properties WHERE node_id IN (1260437,467222); - No Records
SELECT * FROM alf_child_assoc WHERE child_node_id IN (1260437,467222); - No Records

SELECT * FROM alf_child_assoc WHERE parent_node_id IN (1260437,467222);
id version parent_node_id type_qname_id child_node_name_crc child_node_name child_node_id qname_ns_id qname_localname qname_crc is_primary assoc_index
1164570 1 1260437 193 -3852862330 68a0807e-99d1-4208-a28c-8153c45805ea 1260445 6 webpreview 1387062285 1 -1

SELECT * FROM alf_node WHERE alf_node.id IN (1260437,467222);
id version store_id uuid transaction_id node_deleted type_qname_id acl_id audit_creator audit_created audit_modifier audit_modified audit_accessed locale_id
467222 6 6 7295c299-f750-4b5f-84d5-381059f117a5 1581812 1 32 (null) HFRHH300 2012-07-09T19:11:03.430-04:00 HFRHH300 2013-05-19T16:16:42.048-04:00 (null) 1
1260437 4 6 65b506c4-e24d-4347-9961-331ee7df36dd 1473392 1 32 (null) HFINN500 2013-04-23T16:49:00.372-04:00 HFINN500 2013-04-23T16:49:01.658-04:00 (null) 1

Above query result, we can identify that node 1260437 has child with id: 1260445.
So again we need to execute query for node: 1260445 to make sure it doesn't have any child.

SELECT * FROM alf_child_assoc WHERE parent_node_id IN (1260445); - No Result

From query result we can confirm node 1260445 doesn't have any child. So we are good to delete three nodes - 1260437, 467222, 1260445

5) Need to execute below DELETE query.

DELETE * FROM alf_node_assoc WHERE source_node_id IN (1260437,467222,1260445); 
DELETE * FROM alf_node_assoc WHERE target_node_id IN (1260437,467222,1260445);
DELETE * FROM alf_usage_delta WHERE node_id IN (1260437,467222,1260445);
DELETE * FROM alf_node_aspects WHERE node_id IN (1260437,467222,1260445);
DELETE * FROM alf_node_properties WHERE node_id IN (1260437,467222,1260445);
DELETE * FROM alf_child_assoc WHERE child_node_id IN (1260437,467222,1260445);
DELETE * FROM alf_child_assoc WHERE parent_node_id IN (1260437,467222,1260445);
DELETE * FROM alf_node WHERE alf_node.id IN (1260437,467222,1260445);

NOTE: Must need to take care of below things, before you delete nodes from DB.

1) Need to execute delete in given order
2) Must need to take DB backup. Once this nodes are deleted and if any issue then there is no way we can recover it.
3) Also take lucene backup if in case any issue.

Final Steps

1) Shutdown alfresco
2) Take database backup
3) Take lucene backup
4) Execute delete queries
5) Start alfresco with FULL index ON. [Optional]
6) Monitor scheduler for few days.Issue should be resolved.

We successfully executed in our env - alfresco 4.0.1EE and  DB: SQL server 2008.

Hope this helps! 

Friday, March 25, 2011

How to customize Alfresco Share 3.4 Advanced Search Form

This post will guide you - how you can define your custom content type and custom properties in Share 3.4 advanced search form.

I am assuming, you know how to deploy custom content model and you have deployed CustomContentModel. Which contains doc:testContractType content type and some custom properties like doc:conName, doc:conNumber, doc:conStatus and doc:conType

Modify → \tomcat\shared\classes\alfresco\web-extension\share-config-custom.xml

Add following configuration to include your custom content type in Advances Search option

<config evaluator="string-compare" condition="AdvancedSearch">
   <advanced-search>
       <forms>
           <form labelId="search.form.label.doc_testContractType"         descriptionId="search.form.desc.doc_testContractType">doc:testContractType</form>
      </forms>
  </advanced-search>
</config>

Add relavent i18 string in property file under test.properties
To add that property file, Go to tomcat\shared\classes\alfresco\web-extension
Modify – custom-slingshot-application-context.xml and add following code.


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- Add Knowledge Base messages -->
    <bean id="webscripts.test.resources" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
          <property name="resourceBundles">
           <list>
               <value>alfresco.messages.test</value>
           </list>
        </property>
</bean>
</beans>

Create property file named test.properties under \tomcat\shared\classes\alfresco\messages
Add following i18 string

search.form.label.doc_testContractType=Test Custom Type
search.form.desc.doc_testContractType=Searches for all types of TestCustomType

To include custom fields for search, add following configuration in share-config-custom.xml under \tomcat\shared\classes\alfresco\web-extension\

<config evaluator="model-type" condition="doc:testContractType">
    <forms>
       <!-- Following fields will be visible during advanced search form -->
            <form id="search">
                 <field-visibility>
                        <show id="cm:title"/>
                        <show id="doc:conName" />
                        <show id="doc:conNumber" />
                        <show id="doc:conStatus" />
                       <show id="doc:conType" />
                 </field-visibility>
        </form>
</forms>
</config>



How to exclude workflow from list in Alfresco Share 3.4

This post will guide you how you can exclude particular workflow from alfresco share Start Worklfow List

By default, all workflow those are registered in DM are available in Share.
If you want to exclude any particular workflow then add following configuration in
\tomcat\shared\classes\alfresco\web-extension\share-config-custom.xml

Under tag, define the list of the workflow that you want to exclude from list.

If you want to hide all the task of particular model then define its prefix in tag.
Suppose, you want to start your custom workflow from coding rather than manually. You may need users to perfrom that task then hide only the workflow not the task.


<config evaluator="string-compare" condition="Workflow">
   <hidden-workflows>
         <workflow name="jbpm$doc:testAppRej"/>
</hidden-workflows>

  <hidden-tasks>
        <task type="doc:*"/>
  </hidden-tasks>
 </config>

Getting started with Alfresco WCMQS

Alfresco WCM Quick Start

Web Quick Start is a sample application built on top of the Alfresco Share for Alfresco WCM platform. This application is built on Spring MVC, Spring Surf and OpenCMIS.

Advantages of Alfresco WCMQS
1.Easy-to-install package
2.To provide developers with a strong starting point for their Alfresco implementations
3.In context web editing: Edit the content from browser
4.Office-to-Web: Users can draft content using MS Office, collaborate in real time through Google Docs, and then use automated rules to publish to the web
5.Shared Network Drive: Map the web library to network drive. Drag-and-drop new web content from their desktop to the web.

Refer http://wiki.alfresco.com/wiki/Web_Quick_Start_Installation_and_Configuration to install and import WCM Quick start site data

Structure of the WCMQS

The Quick Start demo site has main two folders
1.Quick Start Editorial - Editorial version of site
2.Quick Start Live. - Live version of site

Folder hierarchy will be

Alfresco Quick Start cm:folder→ Quick Start Editorial - ws:website → root – ws:webroot →Section folder ws:section → collections- ws:webassetCollectionFolder / ws:article/ws:indexPage/ws:image → latest.articles - ws:webassetCollection

Within these folder hierarchy, every folders are type of ws:section - these folders are responsible for navigation link for the site header.
Each this section folder contains index.html(landing page) and collections sub folder. Where collections folder is responsible to manage assets collections. When user creates any section folder then index.html and collections folder will be created automatically.
Asset collections is collection of web assets.
In Collections folder three default asset collection - folder will be created. Featured.article, latest.articles and section.articles
In section folder user can have web content, image, landing page as asset.

Metadata for each type

Quick Start Editorial – ws:website
Host Name:localhost
Host Port :8080
Web App Context :wcmqs
Site Configuration:isEditorial=true/false – You want to allow editing of the content from the browser or not
Publish Target:Quick Start Live

Section folder ws:section
Template Mapping: ws:indexPage=sectionpage2
Templates are share page
Template mapping indicates the layout of your page/web content – how this page should be displayed, how the data should be rendered
Template mapping can be done at section level as well as asset level.
ws:indexPage=sectionpage2 - This indicates that all asset/web content of type ws:article should be rendered as per template articlepage1 for that particular section folder
If a template mapping is not found for the requested section, the parent is then checked. This process repeats up to the root section. The root section holds the site-wide template configuration settings.

Rendition Config:
The Alfresco Rendition Service is used to view content dynamically according to mapping. It is used for resizing images, producing flash previews of pdf documents
Content type or mime type can be mapped to rendition definition.
ws:image=ws:imagePreview,application/pdf=ws:swfPreview - Any asset of type "ws:image" will have two renditions generated ("ws:smallThumbnail" and "ws:imagePreview"), and any asset with the "application/pdf" MIME type will have a Flash preview rendition generated (the "ws:swfPreview" rendition).
Order Index:
To configure the order in which navigation links display
Lowest value of order index appears to the right of the Home link and the remaining links are added in ascending numerical order
Exclude from navigation :
It allows you to show or hide that section in the site header

ws:article
Template Name
User can define rendition template for this particular asset

latest.articles – ws:webassetCollection
Asset can be displayed two ways
1.Static asset collection – You may select assets manually to display in that particular section
2.Dynamic asset collection – You may provide query to include asset dynamically on a scheduled basis.
Query Language:
It allows you to render content dynamically by specifying either cmis-alfresco query string or by lucene.
Query:
Specify query - which asset should be included or excluded dynamically
Maximum Size :
Maximum number of assets to display
Minutes To Query Refresh:
Query will be fired within given time interval
Web Assets:
User can select web asset manually to display for that section

Create a web content
Select the section folder where you want to create an article. Create a content with mime type HTML.
You can add image from its Edit metadata page

Visitor feedback comment
Comment in quick start is stored in Data List page
You can check Visitor Feedback list which contains different column like comment, rating, asset on which it has been commented etc.
Different actions are available - Edit, Delete and Duplicate

How to Publish the web content
Content can be published using workflows. If content gets approved then content is copied from Quick Start Editorial folder to the Quick Start Live folder.

There are two workflows available in Share
1.Review and Publish Section Structure - Enables you to review and publish the structure of a section of the website
2.Review and Publish - Enables you to review and publish web content

To publish particular section, initialize workflow on that section's index.html. It will publish that section folder, collection folder as well its subsection folders.
To publish the content you must initialize the Review and Publish workflow