alfresco-community-repo/source/java/org/alfresco/repo/transfer/TransferServiceToBeRefactoredTest.java
Dave Ward 9c563e35c6 Merged V3.4-BUG-FIX to HEAD
24662: 3.4.1 bug fix branch
   24718: Merged V3.3 to V3.4-BUG-FIX
      24717: Fix ALF-5555: It is impossible to edit review date from record's details page
   24719: Fix for ALF-6106: Error on Check In operation with % symbol (SPP)
   24733: Better fix for ALF-6106: Error on Check In operation with % symbol
   24734: Fix for ALF-6089: Incorrect order of fields at 'Create Series', 'Create Category' and 'Create Folder' forms   
      The name, title and description fields are now placed in their own group on the server, all other non custom rm fields are put in an 'other' group, the client side config then declares a set for each group and orders them appropriately.
   24752: Merged V3.4 to V3.4-BUG-FIX
      24751: Merged V3.3-BUG-FIX to V3.4 (RECORD ONLY)
         Restored V3.3-BUG-FIX mergeinfo, somehow truncated in revision 24274
   24753: Merged V3.3-BUG-FIX to V3.4-BUG-FIX
      23870: Merge Dev to V3.3_BUG_FIX
         ALF-4243: F5 load-balancer sending regular HTTP requests to Alfresco server causing Faces Servlet to throw java.lang.NullPointerException (MyFaces upgrade to from 1.1.5 to 1.1.7)
      23897: Additional fixes and tweaks since introduction of MyFaces 1.1.7 library.
      23919: More JSF component id related fixes.
      23945: More MyFaces1.1.7 JSF page fix ups
      23959: Another MyFaces 1.1.7 dup id issue fixed.
      24008: ALF-4243
         - Upgraded MyFaces from 1.1.7 to 1.1.8 to fix a bug seen in 1.1.7
         - Added handling for the fact that valuebound properties that result in null now cause an exception where-as they were perfectly valid in 1.1.5.
      24419: Merge from V3.3 to V3.3-BUG-FIX
         r.24418 Fix for ALF-6075. Running out of /tmp space on the server is causing uploads to fail.
   24768: Fixes ALF-6295: Allows MySQL to not be installed via unattended installer invocation
   24771: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
      24767: Merged BRANCHES/V3.3 to BRANCHES/V3.4:
           24765: ALF-6547: fix intermittent test failure (AssetServiceImplTest renameFile/renameFolder) - fallout from ALF-1948
   24779: Merge V3.3 to V3.4-BUG-FIX
     24497 : ALF-3092 - deployment service - catch Throwable from Begin.
     24684 : Merge DEV/BELARUS/V3.3-BUG-FIX-2010_10_04 to V3.3
       23498 : ALF-5498 In Windows XP, placing a Folder with a Name that already Exists Removes all Content of the Existing Folder
     24749 :  ALF-6174 - Transfer Service fails with double peer assoc custom content type
     24766 : ALF-5603 - It is impossible to assign workflow from workflow console to non-admin user
   24802: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
      24801: Fix for ALF-3055: "SecurityTestSuite hangs when run in DOD5015 context - failed authentication audit hangs on DB connection"
           - do failed audits in a separate thread (from a thread pool)
   24812: Fix ALF-6316: A new "spoof" multivalue text property (cm:tagScopeSummary) is now made available for TagScope nodes when accessed via the getProperty or getProperties operations on the standard node service. The values of this property take the form "<tagname>=<tagcount>". A new interceptor has been added to the node service to do this (TagScopePropertyMethodInterceptor). WQS has been tweaked to make use of this new property, and the now defunct behaviour has been removed.
   24820: Work in progress refactoring transaction handling of transfer unit tests.
   24822: Merged BRANCHES/V3.4 to BRANCHES/DEV/V3.4-BUG-FIX:
      24821: Fix for ALF-3055: "SecurityTestSuite hangs when run in DOD5015 context - failed authentication audit hangs on DB connection"
          - fix up unit tests
   24834: ALF-6468 - Update the scheduled actions folder bootstrap to use localisable names and descriptions, following the normal pattern
   24836: Added system property 'system.cache.disableImmutableSharedCaches' (false by default)
    - Equivalent to disabling Hibernate L2 cache for *immutable* entities
    - Allows distinction between mutable and immutable cache entries
   24850: Fix ALF-6562: Moved property that is used to label the WQS dashlet on the "configure site dashboard" page out of the Slingshot project and into the WQS Share Module project. Corrected its value to "Web Quick Start" rather than "WCM Quick Start".
   24857: Merged V3.4 to V3.4-BUG-FIX
      24853: Merged V3.3 to V3.4 
         24852: Fixed ALF-6573 "Incorrect name of subgroups on "Groups" page"
   24870: Removed svn:mergeinfo from root
   24873: Merged V3.3 to V3.4-BUG-FIX (RECORD ONLY)
      21789: ALF-4333: Fix
         - Updated RepoPrimaryManifestProcessorImpl so it can handle deletions that are reported by either pre-delete noderef or archived noderef (previously only handled the latter).
         - Updated TransferManifestNodeFactory so that it handles the case where the status of the node to transfer is "deleted".
         - Updated UnitTestTransferManifestNodeFactory so that it handles the change to TransferManifestNodeFactory above.
         - Added new tests for deletion cases.
      23259: Merged HEAD to V3.3
         23256: Fix ALF-4573: Start Workflow action is absent for edited document and working copy in Share
      23346: Brought WebQS module in (including build process but not installer elements yet)
      23371: "Simply" added wcmqs to installer
      23391: ALF-5367: Copy dlls into tomcat/bin as appropriate.
      23485: Merged V3.4 to V3.3 (fix backported for V3.3.x lines)
         23472: Fixed ALF-5408: SQL Server missing ON DELETE CASCADE declarations
      23515: Merged PATCHES/V3.2.0 to V3.3
         23514: ALF-5554: Merged HEAD to V3.2.0
            23153: When updating tag scopes following system shutdown/restore, be smarter about quickly skipping tag scopes that another (new) thread is currently working on
            23283: More debugging level logging for tagging updates, to help identify the problem with periodic multi-threaded test failures on bamboo
      23535: Merged V3.4 to V3.3 (complements 23517: ALF-5552)
         23508: Fixed ALF-5559: Permission interceptors can fail if Lucene returns invalid NodeRefs
      23564: ALF-5600: Merged V3.4 to V3.3
         23424: Fixes: ALF-2989 - Incorrect sideId reference in URL for event in Site Calendar Dashlet
            Adds support for displaying events that start in the past but finish in the future (previously only events that start in the future were shown)
      23586: MERGED V3.4 to V3.3
         22864: Fix for ALF-5005: "Create and edit functions on AWE become "confused""
         23042: Fix ALF-5127: Impossible to create an article/blog (WCMQS) [Must clear panel hideEvent handler if manually hiding a YUI panel]
         23561: Fixes: ALF-4569 - Removes universal override of input width box and switches the editor form panel to adjust it's width based on content rather than window size. 
                  Fixes: ALF-4570 - Adds an override for the CSS 'top' property of the form dialogue to ensure it's always below the ribbon. (Was being set automatically by the YUI widget.panel call)
         23569: Fixes: ALF-5606 - Ribbon wasn't resizing correctly after the form events.
      23630: Backport of installer
      23631: Added 64-bit & deployment installers
      23664: Fixes ALF-5691: TransferService: Multi-byte characters are not encoded correctly
      23681: Fixes ALF-5699: TransferService: Snapshot file from source repo never contains complete MLText properties
      23695: Fixed bug exposed after fixing ALF-5699. Parsing of MLText properties out of the transfer snapshot file was incorrect, and that was causing multi-lingual property values to be duplicated
      23709: ALF-5699: Fix NPE in ManifestIntegrationTest
      23734: Merged V3.4 to V3.3
         23731: Fixes for ALF-3098 and ALF-3097
             - Share - Security check on Personal Dashboard - only the owning user can view a user dashboard page
             - Share - Security issue on Customize Site Dashboard - private and moderated site dashboard pages no longer visible to non-members, customise site and dashboard pages only accessible to SiteManager
      23747: ALF-5696: Merged V3.4 to V3.3
         23585: Fixed ALF-5372 "JavaScript error on Groups management dialog with IE8 : document.getElementById is null"
      23790: Fixed ALF-3823 "Share: RSS feed can't be read: http://cds-srv.sun.com:8700/rss/update/public/sunalert_update.xml - ok with other RSS client."
      23883: Fixes ALF-5759: WQS: Attempt to copy a website section fails
      23907: Merged DEV/BELARUS/V3.3-BUG-FIX-2010_09_20 to V33
         22750: ALF-4846: Update rules are firing on inbound actions 
      23931: Undid rev 23907 (Reverse-merged /alfresco/BRANCHES/DEV/BELARUS/V3.3-BUG-FIX-2010_09_20:r22750)
      23961: Fixed ALF-5686 "Incorrect behaviour of "All" filter in "My Tasks" dashlet"
         - Variables assigned in a <#macro> shall always be assigned using <#local> (using <#assign> makes them globally available which might cause naming collisions)
      24132: Disable intermittent failing unit test
      24148: ALF-6007: Merged HEAD to V3.3
         23049: Fixed ALF-5099: Error when trying to go back in Create Web Content Wizard (only with certain XSDs)
      24263: Merged from V3.3-BUG-FIX to V3.3
      24264: V3.3-BUG-FIX to V3.3
         24262: Stress test code for ALF-5025: Support background processing of archiving
      24287: Added missing import
      24336: Merged V3.4 to V3.3
         23205: Fix for ALF-2111 - Download URLS are different on different pages, authentication fails when URL sent
      24353: Merged V3.4 to V3.3
         24352: Fix SQL fallout from ALF-6078
      24510: Merged V3.4 to V3.3
         21960: First round of date refactoring: Document Library pages now expect XML dates (ISO8601) from Share data webscripts
         21961: Share client-side I18N utility now emulates sever-side handling of doubled-up single quotes.
      24526: Merged V3.4 to V3.3
         24402: Fix for performance degredation related to ALF-3823. 
             RSS feed processing in JavaScript relies on Rhino impl of regex - this is extreemly slow as Rhino regex is by far the slowest component of the library. 
             Switched code to use the Java Regex libraries to improve performance and reduce memory usage.
      24587: Merged V3.4 to V3.3
         24564: Fix for ALF-3727: Custom permissions aren't visible in Explorer UI
      24604: Merged V3.4 to V3.3 
         24602: Build fix for RM permission model loading - collateral damage for R 24564
      24774: Merged BRANCHES/V3.4 to BRANCHES/V3.3:
         23492: Fixed ALF-5550: DB2: Unable to insert values into alf_string_value
      24813: Merged BRANCHES/V3.4 to BRANCHES/V3.3:
         24750: Limit installer builds to 2 threads
   24874: Merged V3.4 to V3.4-BUG-FIX
      24667: Resolve ALF-6202 - MT: fix offline edit (Share)
      24672: Fixes from Gloria for: ALF-6339 and ALF-6337
      24673: Merge V3.3 to V3.4
         24668 : Upgrade of large repository to latest 3.3 fails on excession of mysql table lock size
      24674: Fixes ALF-6294: Remove illegal CLI option
      24675: Fix ALF-6099: CLONE - IE6: Sometimes errors occur on almost actions in Office Add-ins. Removed linebreaks from JSON response template & prevented "undefined" entries in URL.
      24680: ALF-6120 : Version notes are lost for versioned items migrated from 2.2 to 3.4.0
      24681: Merged BRANCHES/DEV/BELARUS/V3.4-2010_12_14 to BRANCHES/V3.4:
         24609: MT - ALF-3563
         24640: MT - ALF-3563
         (merged w/ minor improvement)
      24685: Fixes ALF-6403: Change installer window height on Linux
      24688: Fix ALF-6029 (part II) 
              - MT: cannot "Show Folders" for "Data Dictionary" in Afresco Share
              - part II adds patch and removes workaround
      24689: Fixes: ALF-6219 - Incorrectly formatted variable in translation
      24691: MT: ALF-3263
              - Explorer login now fails with consistent error message ("Unable to login - unknown username/password.") if tenant does not exist or is disabled
      24692: Fixes: ALF-6370 and ALF-6225 among others - sweep of FR and DE resource bundles for quote escaping.
      24694: Fixes ALF-6424.  Erased erroneous equals sign
      24695: Fixes: ALF-6320 - removed the country specific portion of the language pack suffixes for French, German and Spanish. This enables speakers of those languages outside of those countries to benefit from the language packs.
      24696: Fix for ALF-6299: XSS attack on editing blog post with XSS data in IE6&IE7
      24700: Swaps _it_IT for _it to make Italian language pack available to Italian speakers outside of Italy.
      24703: Avoid DB2 query failure if someone passes in a made-up UUID
              - Test RunningActionRestApiTest was making up a long node UUID
              - DB2 fails to set the parameter with SQLSTATE=22001
      24706: Merged V3.4-BUG-FIX to V3.4
         24705: Fix for ALF-6365, ALF-6335
      24708: Fix ALF-6386: View Details and Edit Metadata icons are incorrect for folder
      24709: Missing first/last name handling.
      24711: Merged V3.3 to V3.4
         24710: ALF-5535 - Fix to correctly format json number values (not as numeric human readable strings)
      24713: Fix ALF-5404: It is now possible to configure who receives notifications of "Contact Us" requests by setting a configuration property on the WQS website node, such as "feedbackAssignee.Contact Request=brian"
             Also added missing Spring MVC source to 3rd Party.
      24715: Fix for ALF-6412. OOoDirect always tries to connect to port 8100.
               Formerly the ooo.port property did not exist for the OOoDirect connector. It was added in r.23182 for the soffice process, but not for the connector bean. Now added for the connector too.
      24721: Fix for ALF-6351 - Simple search breaks if override config is used and does not contain new 'repository-search' element
      24728: Fixes: ALF-5685 - Incorrect encoding of Japanese Characters
      24732: Fixes ALF-6381 and others - calendar strings appearing incorrectly. Problem was an unicode encoded comma preventing the property string being broken up into different days of the weeks or months.
      24739: Fix ALF-6545: DB2: SQLCODE=-302, SQLSTATE=22001 (testCreateMultiLingualCategoryRoots)
              - Shortened Japanese name to 14 characters
      24740: Fixes: ALF-6413 (with some translations still pending).
      24742: Update readmes.
      24744: Merged HEAD to BRANCHES/V3.4:
         24137: Fixes: ALF-5642, ALF-3892, ALF-5043 & Brings Add Event dialog in line with other forms in share by disabling the popup validation error box.
      24746: Build/test fix: PostgreSQL -AssetServiceImplTest.renameFolder
      24755: Merged V3.3 to V3.4 (RECORD ONLY)
         21789: ALF-4333: Fix
            - Updated RepoPrimaryManifestProcessorImpl so it can handle deletions that are reported by either pre-delete noderef or archived noderef (previously only handled the latter).
            - Updated TransferManifestNodeFactory so that it handles the case where the status of the node to transfer is "deleted".
            - Updated UnitTestTransferManifestNodeFactory so that it handles the change to TransferManifestNodeFactory above.
            - Added new tests for deletion cases.
         23259: Merged HEAD to V3.3
            23256: Fix ALF-4573: Start Workflow action is absent for edited document and working copy in Share
         23346: Brought WebQS module in (including build process but not installer elements yet)
         23371: "Simply" added wcmqs to installer
         23391: ALF-5367: Copy dlls into tomcat/bin as appropriate.
         23485: Merged V3.4 to V3.3 (fix backported for V3.3.x lines)
            23472: Fixed ALF-5408: SQL Server missing ON DELETE CASCADE declarations
         23515: Merged PATCHES/V3.2.0 to V3.3
            23514: ALF-5554: Merged HEAD to V3.2.0
               23153: When updating tag scopes following system shutdown/restore, be smarter about quickly skipping tag scopes that another (new) thread is currently working on
               23283: More debugging level logging for tagging updates, to help identify the problem with periodic multi-threaded test failures on bamboo
         23535: Merged V3.4 to V3.3 (complements 23517: ALF-5552)
            23508: Fixed ALF-5559: Permission interceptors can fail if Lucene returns invalid NodeRefs
         23564: ALF-5600: Merged V3.4 to V3.3
            23424: Fixes: ALF-2989 - Incorrect sideId reference in URL for event in Site Calendar Dashlet
               Adds support for displaying events that start in the past but finish in the future (previously only events that start in the future were shown)
         23586: MERGED V3.4 to V3.3
            22864: Fix for ALF-5005: "Create and edit functions on AWE become "confused""
            23042: Fix ALF-5127: Impossible to create an article/blog (WCMQS) [Must clear panel hideEvent handler if manually hiding a YUI panel]
            23561: Fixes: ALF-4569 - Removes universal override of input width box and switches the editor form panel to adjust it's width based on content rather than window size. 
                     Fixes: ALF-4570 - Adds an override for the CSS 'top' property of the form dialogue to ensure it's always below the ribbon. (Was being set automatically by the YUI widget.panel call)
            23569: Fixes: ALF-5606 - Ribbon wasn't resizing correctly after the form events.
         23630: Backport of installer
         23631: Added 64-bit & deployment installers
         23664: Fixes ALF-5691: TransferService: Multi-byte characters are not encoded correctly
         23681: Fixes ALF-5699: TransferService: Snapshot file from source repo never contains complete MLText properties
         23695: Fixed bug exposed after fixing ALF-5699. Parsing of MLText properties out of the transfer snapshot file was incorrect, and that was causing multi-lingual property values to be duplicated
         23709: ALF-5699: Fix NPE in ManifestIntegrationTest
         23734: Merged V3.4 to V3.3
            23731: Fixes for ALF-3098 and ALF-3097
                - Share - Security check on Personal Dashboard - only the owning user can view a user dashboard page
                - Share - Security issue on Customize Site Dashboard - private and moderated site dashboard pages no longer visible to non-members, customise site and dashboard pages only accessible to SiteManager
         23747: ALF-5696: Merged V3.4 to V3.3
            23585: Fixed ALF-5372 "JavaScript error on Groups management dialog with IE8 : document.getElementById is null"
         23790: Fixed ALF-3823 "Share: RSS feed can't be read: http://cds-srv.sun.com:8700/rss/update/public/sunalert_update.xml - ok with other RSS client."
         23883: Fixes ALF-5759: WQS: Attempt to copy a website section fails
         23907: Merged DEV/BELARUS/V3.3-BUG-FIX-2010_09_20 to V33
            - 22750: ALF-4846: Update rules are firing on inbound actions 
         23931: Undid rev 23907 (Reverse-merged /alfresco/BRANCHES/DEV/BELARUS/V3.3-BUG-FIX-2010_09_20:r22750)
         23961: Fixed ALF-5686 "Incorrect behaviour of "All" filter in "My Tasks" dashlet"
            - Variables assigned in a <#macro> shall always be assigned using <#local> (using <#assign> makes them globally available which might cause naming collisions)
         24132: Disable intermittent failing unit test
         24148: ALF-6007: Merged HEAD to V3.3
            23049: Fixed ALF-5099: Error when trying to go back in Create Web Content Wizard (only with certain XSDs)
         24263: Merged from V3.3-BUG-FIX to V3.3
         24264: Merged V3.3-BUG-FIX to V3.3
            24262: Stress test code for ALF-5025: Support background processing of archiving
         24287: Added missing import
         24336: Merged V3.4 to V3.3
            23205: Fix for ALF-2111 - Download URLS are different on different pages, authentication fails when URL sent
         24353: Merged V3.4 to V3.3
            24352: Fix SQL fallout from ALF-6078
         24510: Merged V3.4 to V3.3
            21960: First round of date refactoring: Document Library pages now expect XML dates (ISO8601) from Share data webscripts
            21961: Share client-side I18N utility now emulates sever-side handling of doubled-up single quotes.
         24526: Merged V3.4 to V3.3
            24402: Fix for performance degredation related to ALF-3823. 
                RSS feed processing in JavaScript relies on Rhino impl of regex - this is extreemly slow as Rhino regex is by far the slowest component of the library. 
                Switched code to use the Java Regex libraries to improve performance and reduce memory usage.
         24587: Merged V3.4 to V3.3
            24564: Fix for ALF-3727: Custom permissions aren't visible in Explorer UI
         24604: Merged V3.4 to V3.3 
            24602: Build fix for RM permission model loading - collateral damage for R 24564
      24775: Merged BRANCHES/V3.3 to BRANCHES/V3.4: (RECORD-ONLY) - already in V3.4
         24774: (RECORD-ONLY) Merged BRANCHES/V3.4 to BRANCHES/V3.3:
            23492: Fixed ALF-5550: DB2: Unable to insert values into alf_string_value
      24788: Add evaluation use message for OSX installer
      24790: Removed svn:mergeinfo on root
      24791: Fixed ALF-6560: MIME type not detected (set to application/octet-stream) when content written via FileFolderService
             - First access of content on a new file (FileFolderService.getWriter) guesses a mimetype
             - The initial mimetype guess *was* done during create, but that was expensive.
             - Added unit test to cover regression
      24803: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4:
         24773: DE bug fixes received from translators 10th Jan.
         24776: ES files received from translators 10th Jan
         24793: FR files received from translators 10th Jan
         24792: IT files received from translators 10th Jan
      24804: Temporarily removing Japanese language bundle
      24856: Merged BRANCHES/DEV/dwebster/ to BRANCHES/V3.4:
         24848: Latest Language updates from Translators
      24863: ALF-6029 (MT Share - repo' view after upg)
   24880: Merged V3.3 to V3.4-BUG-FIX
      24463: Fixed ALF-4398 "Path to rule set is not displayed" ($html alias was missing from a merge)
      24465: Merge V3.3 to V3.4 (RECORD ONLY)
         24463: Fixed ALF-4398 "Path to rule set is not displayed" ($html alias was missing from a merge)
      24493: Fix for Mac OS X CIFS logon problem, change UID to start at one as zero has special meaning, plus other minor fixes. JLAN-112.
      24569: Fix for ALF-5333: Webdav - Online editing of files in a folder with German umlauts does not report correct characters
      24611: Fix broken build due to merge #fail (r24460 / ALF-4015)
      24668: ALF-4557 - Upgrade of large repository to latest 3.3 fails on excession of mysql table lock size
      24707: Fix for handling of null first/last name in wiki page list
      24710: ALF-5535 - Fix to correctly format json number values (not as numeric human readable strings)
      24794: Fix for ALF-4984 - Outdated custom-slingshot-application-context.xml.sample file for share
      24798: Fix for ALF-5806: Lucene query does not return expected result.
         - Alfresco FTS now supports the prefixes ~ and = for phrase queries
      24814: Build fix after r24798: Fix for ALF-5806: Lucene query does not return expected result.
      24823: Synchronization improvements to RemoteClient and http proxy hosts
      24825: Fixed #3 of ALF-6308 "Share data issues"
         - Share falls back to use "html uploader" (in all browsers except IE) when "JSESSIONID" cookie is unreachable from javascript (like when "HttpOnly cookies" is activated on the server.
      24835: Fixed ALF-5484: Check-in does not update association
         - Copy code when copying over an existing target node was NOT processing associations
         - Fallout from refactor and subsequent fixes related to ALF-958 (Target associations aren't copied)
         - Some commented-out unit tests reintroduced
      24842: Fix for ALF-6308 item #4 - validate the redirect URL to ensure it is a relative url
      24845: Merged DEV/DAVEW/SAP to V3.3
         23874: ALF-5822: Correct Lucene throttling mechanism to prevent build up of excessive committed deltas
            - Also correct BatchProcessor's mechanism for single-threading batches with cross dependencies
            - Single-threaded batches must be sequenced in order
         23876: ALF-5822: Default lucene.indexer.mergerTargetOverlaysBlockingFactor to 2 for better write performance under load
         24022: ALF-5822: Refinement of fix
            - Don't block a thread that has already entered the prepare phase with another indexer (e.g. a cross-store commit). Otherwise it could block indefinitely and never enter the commit phase
            - Also added extra debug diagnostics and handle all Throwables on failure
         24023: ALF-5822: Minor correction to debug log message
         24421: ALF-6134: Do not export org.hibernate.jmx.StatisticsService through JMX to avoid excessive blocking under load
         24422: ALF-6135: Remove lock contention from concurrent Lucene searches
            - Added a RW Lock and Thread local-based solution to org.apache.lucene.store.FSDirectory.FSIndexInput.readInternal() to avoid contention during multiple parallel Lucene searches. This is already recognized as a bottleneck by the Lucene developers, who offer NIOFSDirectory as an alternative, which unfortunately doesn't work on Windows.
            - Added RW lock to org.apache.lucene.index.TermInfosReader.ensureIndexIsRead()
            - Threads no longer hanging in lucene searches during load tests. Woohoo!
         24423: ALF-6136: Don't call through to org.apache.log4j.NDC unless debug is enabled as it's heavily synchronized. Also avoid dynamic method invocation by using a delegate.
         24426: ALF-6138 (SURF - PARTIAL): 'Warm' the java.beans.Introspector cache for key Freemarker accessible bean classes on loading in static initializers
         24428: ALF-6139 (SURF - PARTIAL): First log in to Share is expensive due to 'lazy' dashboard creation and excessive synchronization
            - Added AVMRemoteStore.createDocuments() for creating multiple XML documents at once, all embedded within the same master XML document in the request body 
            - Added corresponding saveDocuments() methods to Store, RemoteStore, Model, ModelObjectManager and ModelObjectPersister on the Surf side 
            - Used this in PresetsManager 
            - Removed excessive synchronization from StoreModelObjectPersister 
         24429: ALF-6140 (SURF - PARTIAL): Surf tweaks to allow concurrent execution of web scripts
            - Use StrongCacheStorage instead of MruCacheStorage in RepositoryTemplateProcessor to avoid use of a synchronized cache
            - Tweak cache sizes in FreeMarkerProcessor
            - Use thread local object wrapper delegates in QNameAwareObjectWrapper and PresentationTemplateProcessor to work around synchronization in DefaultObjectWrapper
            - Swap in the same object wrapper to WrappingTemplateModel
            - Use a concurrent HashMap in ModelObjectCache and ModelHelper and remove excessive synchronization
            - Use RW locks rather than synchronized blocks in AbstractWebScript
         24431: ALF-6141: Improvements to IBatis DAO performance under load
            - Use lazyLoadingEnabled="false", enhancementEnabled="false" to avoid unnecessary blocking and generation of CGI proxies in IBATIS DAOs
            - Use useTransactionAwareDataSource="false" to prevent Spring from agressively unwrapping DBCP connections and bypassing the prepared statement cache
         24432: ALF-6142: Remove dependency between RepositoryAuthenticationDAO and Lucene
            - Reworked RepositoryAuthenticationDAO to use a node service lookup by child association QName
            - This required adding a patch to 'upgrade' the qnames of existing authentication nodes, which previously all had the same QName
         24433: ALF-6143: Remove net.sf.ehcache.use.classic.lru setting from EhCacheManagerFactoryBean and InternalEhCacheManagerFactoryBean to prevent serialization of accesses to shared caches by multiple executing threads
         24434: ALF-6144:  DirtySessionMethodInterceptor was causing contention between multiple threads calling the same DAO.
            - Unfortunately method.getAnnotation() is a synchronized call, and thus causes concurrent calls to the same method to contended with each other. 
            - Added a non-blocking cache so that DAOs can be accessed in multiple threads without contending. 
         24435: ALF-6145: Use RW Locks in Subsystem Framework
            - The operations relied on by the dynamic proxies wrapping subsystems were synchronized and thus caused contention when multiple threads were calling in to the same subsystem
            - Replaced synchronized blocks with use of read write locks, thus allowing multiple concurrent readers
         24436: ALF-6146: Regulate PermissionModel accesses with RW locks, rather than synchronized blocks and an excessive number of concurrent hashmaps.
         24438: ALF-6136: Fix build classpath
         24439: ALF-6142: Fixed seeding of admin user password
         24444: ALF-6142: Fix unit test fallout
            - InviteServiceTest needs a transaction
            - RepositoryAuthenticationDao must listen for Person username changes and update authentication node qname accordingly
            - Correction to MT handling in RepositoryAuthenticationDao
            - Repository Authentication Component must 'normalize' the username before passing it through the DAO
         24445: ALF-6145: Correction to lock handling when propagating destroy() events
         24446: ALF-6142: Add new dependencies to unit test
         24448: ALF-6142: Further fix ups
         24461: ALF-6142: Fix unit test
         24664: ALF-6408: Prevent possible deadlock during reindexing
            - waitForHeadOfQueue() now only called in beforeCommit() phase rather than afterCommit() to prevent deadlocking with Lucene throttler
            - indexes are also flushed beforehand in beforeCommit() so that indexing work can still be parallelized
            - also prevent potential deadlock caused by clearing of IndexInfo.thisThreadPreparing in a nested transaction
         24810: ALF-6653: Use read write lock in Hibernate ReadWriteCache to avoid needless contention on L2 cache reads
         24817: ALF-4725: Avoid excessive lock contention in dbcp by upgrading to 1.4
            - also upgraded commons pool
         24818: ALF-6658: Remove synchronization from LockService - transaction local collections used anyway
         24844: ALF-6681: Don't let the PostLookup job stack up in multiple threads
            - Now only executes in one thread at a time and skips scheduled slots where it is already running
      24864: Fix for ALF-5904: Explorer - Space model rights not duplicated when creating a space based on a template
         - copy service no longer uses hasPermission
         - added tests for permission copy scenarios with assorted rights
         - this fix assumed there is nothing special about templates - ie that they should always carry permissions and is the "default" copy behaviour to copy permissions if possible
      24865: ALF-6145: Fix failing unit test
      24878: ALF-6146: Correction to write lock around requiredPermissionsCache
   24881: Increment version revision


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@26792 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2011-04-11 15:57:26 +00:00

4991 lines
221 KiB
Java

/*
* Copyright (C) 2009-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.transfer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeFactory;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.CopyService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.transfer.TransferCallback;
import org.alfresco.service.cmr.transfer.TransferDefinition;
import org.alfresco.service.cmr.transfer.TransferEvent;
import org.alfresco.service.cmr.transfer.TransferEventReport;
import org.alfresco.service.cmr.transfer.TransferException;
import org.alfresco.service.cmr.transfer.TransferReceiver;
import org.alfresco.service.cmr.transfer.TransferService;
import org.alfresco.service.cmr.transfer.TransferTarget;
import org.alfresco.service.descriptor.Descriptor;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.BaseAlfrescoSpringTest;
import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.alfresco.util.PropertyMap;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.ResourceUtils;
/**
* Unit test for TransferServiceImpl
*
* Contains some integration tests for the transfer service
*
* These tests need their transaction management to be re-factored then they can be re-instated into
* TransferServiceImplTest
*
* @author Mark Rogers
*/
@SuppressWarnings("deprecation")
public class TransferServiceToBeRefactoredTest extends BaseAlfrescoSpringTest
{
private TransferService transferService;
private ContentService contentService;
private TransferServiceImpl2 transferServiceImpl;
private SearchService searchService;
private TransactionService transactionService;
private TransferReceiver receiver;
private TransferManifestNodeFactory transferManifestNodeFactory;
private PermissionService permissionService;
private LockService lockService;
private PersonService personService;
private DescriptorService descriptorService;
private CopyService copyService;
String COMPANY_HOME_XPATH_QUERY = "/{http://www.alfresco.org/model/application/1.0}company_home";
String GUEST_HOME_XPATH_QUERY = "/{http://www.alfresco.org/model/application/1.0}company_home/{http://www.alfresco.org/model/application/1.0}guest_home";
String REPO_ID_A = "RepoIdA";
String REPO_ID_B;
String REPO_ID_C = "RepoIdC";
@Override
public void runBare() throws Throwable
{
preventTransaction();
super.runBare();
}
/**
* Called during the transaction setup
*/
protected void onSetUp() throws Exception
{
// Catch transactions left dangling by inadequate transaction handling during test failures
if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_NONE)
{
fail("Dangling transaction at start of test.");
}
super.onSetUp();
// Get the required services
this.transferService = (TransferService)this.applicationContext.getBean("TransferService");
this.contentService = (ContentService)this.applicationContext.getBean("ContentService");
this.transferServiceImpl = (TransferServiceImpl2)this.applicationContext.getBean("transferService2");
this.searchService = (SearchService)this.applicationContext.getBean("SearchService");
this.transactionService = (TransactionService)this.applicationContext.getBean("TransactionService");
this.nodeService = (NodeService) this.applicationContext.getBean("nodeService");
this.contentService = (ContentService) this.applicationContext.getBean("contentService");
this.authenticationService = (MutableAuthenticationService) this.applicationContext.getBean("authenticationService");
this.actionService = (ActionService)this.applicationContext.getBean("actionService");
this.permissionService = (PermissionService)this.applicationContext.getBean("permissionService");
this.receiver = (TransferReceiver)this.applicationContext.getBean("transferReceiver");
this.transferManifestNodeFactory = (TransferManifestNodeFactory)this.applicationContext.getBean("transferManifestNodeFactory");
this.authenticationComponent = (AuthenticationComponent) this.applicationContext.getBean("authenticationComponent");
this.lockService = (LockService) this.applicationContext.getBean("lockService");
this.personService = (PersonService)this.applicationContext.getBean("PersonService");
this.descriptorService = (DescriptorService)this.applicationContext.getBean("DescriptorService");
this.copyService = (CopyService)this.applicationContext.getBean("CopyService");
REPO_ID_B = descriptorService.getCurrentRepositoryDescriptor().getId();
authenticationComponent.setSystemUserAsCurrentUser();
setTransactionDefinition(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW));
assertNotNull("receiver is null", this.receiver);
}
/**
* Test the transfer report.
*
* This is a unit test so it does some shenanigans to send to the same instance of alfresco.
*/
public void testTransferReport() throws Exception
{
setDefaultRollback(false);
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(this.receiver, this.contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Now go ahead and create our first transfer target
* This needs to be committed before we can call transfer asycnc.
*/
String CONTENT_TITLE = "ContentTitle";
String CONTENT_NAME_A = "Report Node A";
String CONTENT_NAME_B = "Report Node B";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
NodeRef nodeRefA = null;
NodeRef nodeRefB = null;
NodeRef testFolder = null;
String targetName = "testTransferReport";
startNewTransaction();
try
{
{
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
testFolder = child.getChildRef();
nodeService.setProperty(testFolder, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(testFolder, ContentModel.PROP_NAME, name);
}
{
/**
* Create a test node that we will read and write
*/
ChildAssociationRef child = nodeService.createNode(testFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(GUID.generate()), ContentModel.TYPE_CONTENT);
nodeRefA = child.getChildRef();
nodeService.setProperty(nodeRefA, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(nodeRefA, ContentModel.PROP_NAME, CONTENT_NAME_A);
ContentWriter writer = contentService.getWriter(nodeRefA, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
ChildAssociationRef child = nodeService.createNode(testFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(GUID.generate()), ContentModel.TYPE_CONTENT);
nodeRefB = child.getChildRef();
nodeService.setProperty(nodeRefB, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(nodeRefB, ContentModel.PROP_NAME, CONTENT_NAME_B);
ContentWriter writer = contentService.getWriter(nodeRefB, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
/**
* Now go ahead and create our first transfer target
*/
if(!transferService.targetExists(targetName))
{
createTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
NodeRef transferReport = null;
NodeRef transferDestReport = null;
/**
* Step 1.
* Call the transfer method. to get a failed transfer - orphan nodes exist
*/
setDefaultRollback(true);
startNewTransaction();
try
{
TestTransferCallback callback = new TestTransferCallback();
Set<TransferCallback> callbacks = new HashSet<TransferCallback>();
callbacks.add(callback);
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(nodeRefA);
nodes.add(nodeRefB);
// missing the folder node (testFolder)
definition.setNodes(nodes);
// Do the transfer here
try
{
transferService.transfer(targetName, definition, callbacks);
fail("transfer should have failed with an orphan not found exception");
}
catch (TransferException te)
{
logger.debug("deliberatly caught and ignored exception");
}
// Can't dirty read transfer report here
boolean foundSourceReport = false;
boolean foundDestReport = false;
for(TransferEvent event : callback.getEvents())
{
if(event instanceof TransferEventReport)
{
TransferEventReport reportEvent = (TransferEventReport)event;
switch (reportEvent.getReportType())
{
case DESTINATION:
foundDestReport = true;
transferDestReport = reportEvent.getNodeRef();
assertNotNull("dest transfer nodeId null", transferDestReport);
break;
case SOURCE:
foundSourceReport = true;
transferReport = reportEvent.getNodeRef();
break;
}
}
}
assertTrue("source report not found", foundSourceReport);
assertTrue("dest report not found", foundDestReport);
}
finally
{
endTransaction();
}
setDefaultRollback(false);
/**
* Now validate the client side error transfer report against the xsd file
*/
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(transferReport, ContentModel.PROP_CONTENT);
assertNotNull("transfer reader is null", reader);
assertEquals("client report mimetype not set", reader.getMimetype(), MimetypeMap.MIMETYPE_XML);
String name = (String)nodeService.getProperty(transferReport, ContentModel.PROP_NAME);
assertTrue("client report does not end with .xml", name.endsWith(".xml"));
logger.debug("This report should have failed");
if(logger.isDebugEnabled())
{
dumpToSystemOut(transferReport);
}
// Now validate the client side transfer report against the XSD
Source transferReportSource = new StreamSource(reader.getContentInputStream());
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/report/TransferReport2.xsd";
Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
Validator validator = schema.newValidator();
try
{
validator.validate(transferReportSource);
}
catch (Exception e)
{
fail(e.getMessage() );
}
}
finally
{
endTransaction();
}
/**
* Step 2
* Call the transfer method to get a good success transfer report
*/
startNewTransaction();
try
{
{
TestTransferCallback callback = new TestTransferCallback();
Set<TransferCallback> callbacks = new HashSet<TransferCallback>();
callbacks.add(callback);
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(nodeRefA);
nodes.add(nodeRefB);
nodes.add(testFolder);
definition.setNodes(nodes);
transferReport = transferService.transfer(targetName, definition, callbacks);
assertNotNull("transfer report is null", transferReport);
// Can't dirty read transfer report here
boolean foundSourceReport = false;
boolean foundDestReport = false;
for(TransferEvent event : callback.getEvents())
{
if(event instanceof TransferEventReport)
{
TransferEventReport reportEvent = (TransferEventReport)event;
switch (reportEvent.getReportType())
{
case DESTINATION:
foundDestReport = true;
transferDestReport = reportEvent.getNodeRef();
assertNotNull("dest transfer nodeId null", transferDestReport);
assertFalse("dest transfer nodeId not correct", transferReport.equals(transferDestReport));
break;
case SOURCE:
foundSourceReport = true;
assertEquals("source transfer nodeId not correct", transferReport, reportEvent.getNodeRef());
break;
}
}
}
assertTrue("source report not found", foundSourceReport);
assertTrue("dest report not found", foundDestReport);
}
}
finally
{
endTransaction();
}
/**
* Now validate the client side transfer report against the xsd file
*/
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(transferReport, ContentModel.PROP_CONTENT);
assertNotNull("transfer reader is null", reader);
logger.debug("This report should succeed");
if(logger.isDebugEnabled())
{
dumpToSystemOut(transferReport);
}
// Now validate the client side transfer report against the XSD
Source transferReportSource = new StreamSource(reader.getContentInputStream());
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/report/TransferReport2.xsd";
Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
Validator validator = schema.newValidator();
try
{
validator.validate(transferReportSource);
}
catch (Exception e)
{
fail(e.getMessage() );
}
}
finally
{
endTransaction();
}
/**
* Now validate the destination side transfer report against its xsd file
*/
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(transferDestReport, ContentModel.PROP_CONTENT);
assertNotNull("transfer reader is null", reader);
assertEquals("dest report mimetype not set", reader.getMimetype(), MimetypeMap.MIMETYPE_XML);
String name = (String)nodeService.getProperty(transferReport, ContentModel.PROP_NAME);
assertTrue("dest report does not end with .xml", name.endsWith(".xml"));
if(logger.isDebugEnabled())
{
dumpToSystemOut(transferDestReport);
}
// Now validate the destination side transfer report against the XSD
Source transferReportSource = new StreamSource(reader.getContentInputStream());
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/reportd/TransferDestinationReport.xsd";
Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
Validator validator = schema.newValidator();
try
{
validator.validate(transferReportSource);
}
catch (Exception e)
{
fail("Destination Transfer Report " + e.getMessage() );
}
}
finally
{
endTransaction();
}
/**
* Now validate all transfer reports.
*/
startNewTransaction();
try
{
String query = "TYPE:\"trx:transferReportDest\"";
ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, query);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final String TRANSFER_REPORT_SCHEMA_LOCATION = "classpath:org/alfresco/repo/transfer/reportd/TransferDestinationReport.xsd";
Schema schema = sf.newSchema(ResourceUtils.getURL(TRANSFER_REPORT_SCHEMA_LOCATION));
Validator validator = schema.newValidator();
for(ResultSetRow result : results)
{
NodeRef reportNode = result.getNodeRef();
logger.debug("validating reportNode " + reportNode);
// Now validate the destination side transfer report against the XSD
ContentReader reader = contentService.getReader(reportNode, ContentModel.PROP_CONTENT);
assertNotNull("transfer reader is null", reader);
if (reader.getMimetype().equals(MimetypeMap.MIMETYPE_XML))
{
Source transferReportSource = new StreamSource(reader.getContentInputStream());
try
{
validator.validate(transferReportSource);
}
catch (Exception e)
{
fail("Destination Transfer Report reportNode:" + reportNode + " message :" + e.getMessage() );
}
}
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
logger.debug("now delete the target:" + targetName);
transferService.deleteTransferTarget(targetName);
}
finally
{
endTransaction();
}
} // test transfer report
private void dumpToSystemOut(NodeRef nodeRef) throws IOException
{
ContentReader reader2 = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
assertNotNull("transfer reader is null", reader2);
InputStream is = reader2.getContentInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s = br.readLine();
while(s != null)
{
System.out.println(s);
s = br.readLine();
}
}
private UnitTestTransferManifestNodeFactory unitTestKludgeToTransferGuestHomeToCompanyHome()
{
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(this.receiver, this.contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
return testNodeFactory;
}
/**
* Test the transfer method behaviour with respect to sync folders - sending a complete set
* of nodes and implying delete from the absence of an association.
*
* This is a unit test so it does some shenanigans to send to the same instance of alfresco.
*
* Tree of nodes
*
* A1
* | |
* A2 A3 (Content Node)
* |
* A4 A5 (Content Node)
*
* Test steps -
* 1 add A1
* transfer(sync)
* 2 add A2, A3, A4, A5
* transfer(sync)
* 3 remove A2
* transfer(sync) A4 and A5 should cascade delete on source
* 4 remove A3
* transfer(sync)
* 5 add back A3 - new node ref
* transfer(sync)
* 6 add A2, A4, A5
* transfer(sync)
* 7 test delete and restore of a single node
* remove A3 .
* transfer
* restore node A3
* transfer
* 8 test delete and restore of a tree of nodes
* remove A2 (A4 and A5 should cascade delete on source as well)
* transfer
* restore node A2 (and A4 and A5 cascade restore)
* transfer
*/
public void testTransferSyncNodes() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Now go ahead and create our first transfer target
*/
String targetName = "testTransferSyncNodes";
TransferTarget transferMe;
NodeRef A1NodeRef;
NodeRef A2NodeRef;
NodeRef A3NodeRef;
NodeRef A4NodeRef;
NodeRef A5NodeRef;
NodeRef destNodeRef;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Create a test nodes A1 through A5 that we will read and write
*/
{
// Node A1
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A3
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_CONTENT);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A4"), ContentModel.TYPE_CONTENT);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
ContentWriter writer = contentService.getWriter(A4NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_CONTENT);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
ContentWriter writer = contentService.getWriter(A5NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* Step 1. Add Node A1.
*/
startNewTransaction();
try
{
/**
* Transfer Node A with no children
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef));
assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
assertEquals("type is wrong", nodeService.getType(A1NodeRef), nodeService.getType(destNodeRef));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 2. Add Node A2, A3, A4, A5.
*/
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node ref A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node ref A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node ref A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 3 - remove folder node A2
*/
startNewTransaction();
try
{
nodeService.deleteNode(A2NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 4 - remove content node A3
*/
startNewTransaction();
try
{
nodeService.deleteNode(A3NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
//nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertFalse("dest node ref A3 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 5. Add back A3.
*/
startNewTransaction();
try
{
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_CONTENT);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 6. add A2, A4, A5
*/
startNewTransaction();
try
{
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A4"), ContentModel.TYPE_CONTENT);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
ContentWriter writer = contentService.getWriter(A4NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_CONTENT);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
ContentWriter writer = contentService.getWriter(A5NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 7 - test delete and restore of a single node
* remove A3 .
* transfer
* restore node A3
* transfer
*/
startNewTransaction();
try
{
logger.debug("Step 7 - delete node A3");
nodeService.deleteNode(A3NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
//nodes.add(A3NodeRef); A3 has gone.
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node ref A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertFalse("dest node ref A3 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node ref A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node ref A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef archivedNode = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, A3NodeRef.getId());
NodeRef newNodeRef = nodeService.restoreNode(archivedNode, A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"));
assertEquals("restored node ref is different", newNodeRef, A3NodeRef);
logger.debug("Step 7 - restore node A3");
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5.
* (So we are seeing what happens to node 3 on the target
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node ref A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node ref A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node ref A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
}
finally
{
endTransaction();
}
/**
* Step 8 - test delete and restore of a tree
* remove A2 (A4, A5) should cascade delete.
* transfer
* restore node A2
* transfer
*/
startNewTransaction();
try
{
nodeService.deleteNode(A2NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef archivedNode = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, A2NodeRef.getId());
nodeService.restoreNode(archivedNode, A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5.
* (So we are seeing what happens to node 2, 4, 5 on the target
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node ref A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node ref A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node ref A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
}
finally
{
endTransaction();
}
}
/**
* Test the transfer method behaviour with respect to sync with (local) alien nodes.
*
* So we have Repository A transferring content and Repository B is the local repo that we
* add and delete alien nodes.
*
* In general an alien node will prevent deletion of the parent folders
*
* <pre>
* Tree of nodes
*
* A1
* | | |
* A2 A3 (Content Node) B9 (Alien Content Node)
* |
* A4 A5 B10 (Alien Content Node) A6
* | |
* A7 B11 (Alien Content Node) A8 B12 B13 (Alien Content Node)
* |
* B14
* </pre>
* Test steps -
* <ol>
* <li>add A1, A2, A3, A4, A5, A6, A7, A8
* transfer(sync)</li>
* <li>add Alien node B9. A1 becomes Alien.</li>
* <li>remove alien node B9. A1 becomes non Alien.</li>
* <li>add Alien node B10. A1 and A2 become Alien</li>
* <li>remove Alien node B10. A1 and A2 become non Alien</li>
* <li>add B12 and B14 A6, A2, A1 becomes Alien</li>
* <li>remove B14, B12, A6, A2, A1 remain Alien</li>
* <li>add B13 A6, A2, A1 remains Alien</li>
* <li>remove B13 A6, A2, A1 remains Alien</li>
* <li>remove B12 A6, A2, A1 becomes non Alien.</li>
* <li>add B9 and B10 A1 and A2 become Alien</li>
* <li>remove B10 A2 becomes non alien A1 remains alien.</li>
* <li>Add B11, delete A2
* transfer sync</li>
* (A5, A6, A7 and A8 should be deleted A2 and A4 remain since they contain alien content.)</li>
* </ol>
*/
public void testTransferInvadedByLocalAlienNodes() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.JAPAN;
String CONTENT_STRING = "Hello";
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*
* Mock the transfer service to be from Repo A
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
final String localRepositoryId = descriptorService.getCurrentRepositoryDescriptor().getId();
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Now go ahead and create our first transfer target
*/
String targetName = "testSyncWithAlienNodes";
TransferTarget transferMe;
NodeRef A1NodeRef;
NodeRef A2NodeRef;
NodeRef A3NodeRef;
NodeRef A4NodeRef;
NodeRef A5NodeRef;
NodeRef A6NodeRef;
NodeRef A7NodeRef;
NodeRef A8NodeRef;
NodeRef B9NodeRef;
NodeRef B10NodeRef;
NodeRef B11NodeRef;
NodeRef B12NodeRef;
NodeRef B13NodeRef;
NodeRef B14NodeRef;
NodeRef destNodeRef;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Create a test nodes A1 through A8 that we will read and write
*/
{
// Node A1
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A3
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_CONTENT);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A4"), ContentModel.TYPE_FOLDER);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_CONTENT);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
ContentWriter writer = contentService.getWriter(A5NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A6
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A6"), ContentModel.TYPE_FOLDER);
A6NodeRef = child.getChildRef();
nodeService.setProperty(A6NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A6NodeRef, ContentModel.PROP_NAME, "A6");
}
{
// Node A7
ChildAssociationRef child = nodeService.createNode(A4NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A7"), ContentModel.TYPE_CONTENT);
A7NodeRef = child.getChildRef();
nodeService.setProperty(A7NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A7NodeRef, ContentModel.PROP_NAME, "A7");
ContentWriter writer = contentService.getWriter(A7NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A8
ChildAssociationRef child = nodeService.createNode(A6NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A8"), ContentModel.TYPE_CONTENT);
A8NodeRef = child.getChildRef();
nodeService.setProperty(A8NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A8NodeRef, ContentModel.PROP_NAME, "A8");
ContentWriter writer = contentService.getWriter(A8NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
} else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* Step 1. add A1, A2, A3, A4, A5, A6, A7, A8
* transfer(sync)
*/
startNewTransaction();
try
{
/**
* Transfer Nodes A1 through A8
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
nodes.add(A6NodeRef);
nodes.add(A7NodeRef);
nodes.add(A8NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", A1destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertEquals("title is wrong", (String)nodeService.getProperty(A1destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
assertEquals("type is wrong", nodeService.getType(A1NodeRef), nodeService.getType(A1destNodeRef));
assertFalse("A1 is alien", nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 2 add Alien node B9 child of A1(dest). A1(dest) becomes Alien because it contains an alien child.
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B9"), ContentModel.TYPE_CONTENT);
B9NodeRef = child.getChildRef();
nodeService.setProperty(B9NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B9NodeRef, ContentModel.PROP_NAME, "B9");
ContentWriter writer = contentService.getWriter(B9NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
// Check injected transferred aspect.
assertTrue("node A1 is not alien aspect", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
assertTrue("node B9 is not alien", (Boolean)nodeService.hasAspect(B9NodeRef, TransferModel.ASPECT_ALIEN));
// Temp code
List<String> invaders = (List<String>) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
assertTrue("invaders contains local repository Id", invaders.contains(localRepositoryId));
assertFalse("invaders contains REPO_ID_A", invaders.contains(REPO_ID_A));
}
finally
{
endTransaction();
}
/**
* Step 3 remove alien node B9. A1 becomes non Alien.
*/
startNewTransaction();
try
{
logger.debug("delete node B9");
nodeService.deleteNode(B9NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A3destNodeRef = testNodeFactory.getMappedNodeRef(A3NodeRef);
List<String> invaders = (List<String>) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A3 is alien", (Boolean)nodeService.hasAspect(A3destNodeRef, TransferModel.ASPECT_ALIEN));
assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* 4 add Alien node B10 child of A2. A1 and A2 become Alien
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B10"), ContentModel.TYPE_CONTENT);
B10NodeRef = child.getChildRef();
nodeService.setProperty(B10NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B10NodeRef, ContentModel.PROP_NAME, "B10");
ContentWriter writer = contentService.getWriter(B10NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
assertTrue("node A1 is not alien aspect", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien aspect", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* 5 remove Alien node B10. A1 and A2 become non Alien
*/
startNewTransaction();
try
{
logger.debug("delete node B10");
nodeService.deleteNode(B10NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
assertFalse("node A1 is still alien aspect", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A2 is still alien aspect", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 6
* add B12 (child of A6) and B14 A6, A2, A1 becomes Alien
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B12"), ContentModel.TYPE_FOLDER);
B12NodeRef = child.getChildRef();
nodeService.setProperty(B12NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B12NodeRef, ContentModel.PROP_NAME, "B12");
child = nodeService.createNode(B12NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B14"), ContentModel.TYPE_CONTENT);
B14NodeRef = child.getChildRef();
nodeService.setProperty(B14NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B14NodeRef, ContentModel.PROP_NAME, "B14");
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A6 is not alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node B14 is not alien", (Boolean)nodeService.hasAspect(B14NodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node B12 is not alien", (Boolean)nodeService.hasAspect(B12NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 7
* Delete B14. B12 remains alien
*/
startNewTransaction();
try
{
nodeService.deleteNode(B14NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A6 is not alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node B12 is not alien", (Boolean)nodeService.hasAspect(B12NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 8
* add B13 A6, A2, A1 remains Alien
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B13"), ContentModel.TYPE_CONTENT);
B13NodeRef = child.getChildRef();
nodeService.setProperty(B13NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B13NodeRef, ContentModel.PROP_NAME, "B13");
ContentWriter writer = contentService.getWriter(B13NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A6 is not alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 9 remove B13 A6, A2, A1 remains Alien Due to B12
*/
startNewTransaction();
try
{
nodeService.deleteNode(B13NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A6 is not alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 10 remove B12 A6, A2, A1 becomes non Alien.
*/
startNewTransaction();
try
{
nodeService.deleteNode(B12NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A2 is still alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A6 is still alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 11 add B9 and B10 A1 and A2 become Alien
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B9"), ContentModel.TYPE_CONTENT);
B9NodeRef = child.getChildRef();
nodeService.setProperty(B9NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B9NodeRef, ContentModel.PROP_NAME, "B9");
ContentWriter writer = contentService.getWriter(B9NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B10"), ContentModel.TYPE_CONTENT);
B10NodeRef = child.getChildRef();
nodeService.setProperty(B10NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B10NodeRef, ContentModel.PROP_NAME, "B10");
writer = contentService.getWriter(B10NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 12 remove B10 A2 becomes non alien A1 remains alien.
*/
startNewTransaction();
try
{
nodeService.deleteNode(B10NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
// BUGBUG
assertTrue("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A2 is still alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* 13 Add Alien node B11.
*/
logger.debug("Step 12 Add Node B11, Delete A2 and sync");
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A4NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B11"), ContentModel.TYPE_CONTENT);
B11NodeRef = child.getChildRef();
nodeService.setProperty(B11NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B11NodeRef, ContentModel.PROP_NAME, "B11");
ContentWriter writer = contentService.getWriter(B11NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
nodeService.deleteNode(A2NodeRef);
}
finally
{
endTransaction();
}
/**
* Step 14
* delete A2 (will cascade delete A4, A5, A6, A7, A8
* transfer sync
* (A5, A6, A7, A8 and should be deleted A2 and A4 remain since they contain alien content.)
*/
startNewTransaction();
try
{
// Now validate A1, A2 and A4 are alien
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A4destNodeRef = testNodeFactory.getMappedNodeRef(A4NodeRef);
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A4 is not alien", (Boolean)nodeService.hasAspect(A4destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("test error: node A2 not deleted", nodeService.exists(A2NodeRef));
assertFalse("test error: node A4 not deleted", nodeService.exists(A4NodeRef));
assertFalse("test error: node A5 not deleted", nodeService.exists(A5NodeRef));
assertFalse("test error: node A6 not deleted", nodeService.exists(A6NodeRef));
assertFalse("test error: node A7 not deleted", nodeService.exists(A7NodeRef));
assertFalse("test error: node A8 not deleted", nodeService.exists(A8NodeRef));
assertTrue("test error: node does not exist", nodeService.exists(A3NodeRef));
/**
* Transfer Nodes A1 through A8
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A3NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
NodeRef A3destNodeRef = testNodeFactory.getMappedNodeRef(A3NodeRef);
NodeRef A4destNodeRef = testNodeFactory.getMappedNodeRef(A4NodeRef);
NodeRef A5destNodeRef = testNodeFactory.getMappedNodeRef(A5NodeRef);
NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
NodeRef A7destNodeRef = testNodeFactory.getMappedNodeRef(A7NodeRef);
NodeRef A8destNodeRef = testNodeFactory.getMappedNodeRef(A8NodeRef);
assertTrue("node A1 not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A4 not alien", (Boolean)nodeService.hasAspect(A4destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node B11 does not exist", nodeService.exists(B11NodeRef));
assertTrue("node A3 deleted", nodeService.exists(A3destNodeRef));
assertFalse("node A5 not deleted", nodeService.exists(A5destNodeRef));
assertFalse("node A6 not deleted", nodeService.exists(A6destNodeRef));
assertFalse("node A7 not deleted", nodeService.exists(A7destNodeRef));
assertFalse("node A8 not deleted", nodeService.exists(A8destNodeRef));
}
finally
{
endTransaction();
}
}
/**
* Test restore of a local node.
* <pre>
* Tree of nodes
* A1 B1
* |
* B2
* |
* B3
* <pre>
* <ol>
* <li>Add B2. A1 is alien.</li>
* <li>Delete B2. A1 not alien</li>
* <li>Restore B2. A1 is alien</li>
* <li>Add B3. A1 is alien</li>
* <li>Delete B2. A1 not alien</li>
* <li>Restore to B1. B2 and B3 not alien.</li>
* </ol>
* @throws Exception
*/
public void testLocalAlienRestore() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.JAPAN;
String CONTENT_STRING = "Hello";
/**
* Now go ahead and create our first transfer target
*/
String targetName = "testRestoreOfAlienNodes";
TransferTarget transferMe;
NodeRef S0NodeRef;
NodeRef A0NodeRef;
NodeRef A1NodeRef;
NodeRef B1NodeRef;
NodeRef B2NodeRef;
NodeRef B3NodeRef;
NodeRef destNodeRef;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Create a test nodes A1 through A8 that we will read and write
*/
{
// Node S0
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
S0NodeRef = child.getChildRef();
nodeService.setProperty(S0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(S0NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A0"), ContentModel.TYPE_FOLDER);
A0NodeRef = child.getChildRef();
nodeService.setProperty(A0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A0NodeRef, ContentModel.PROP_NAME, "A0");
}
{
// Node A1
ChildAssociationRef child = nodeService.createNode(A0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A1"), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, "A1");
}
{
// Node B1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B1"), ContentModel.TYPE_FOLDER);
B1NodeRef = child.getChildRef();
nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B1");
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*
* Mock the transfer service to be from Repo A
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
pathMap.add(new Pair(nodeService.getPath(A0NodeRef), nodeService.getPath(B1NodeRef)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 1. add A1
* transfer(sync)
*/
startNewTransaction();
try
{
/**
* Transfer Nodes A1
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertFalse("A1 is alien", nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 2 add Alien node B1 child of A1(dest).
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B2"), ContentModel.TYPE_FOLDER);
B2NodeRef = child.getChildRef();
nodeService.setProperty(B2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B2NodeRef, ContentModel.PROP_NAME, "B2");
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
// Check injected transferred aspect.
assertTrue("node A1 is not alien aspect", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
assertTrue("node B2 is not alien", (Boolean)nodeService.hasAspect(B2NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 3 remove alien node B2. A1 becomes non Alien.
*/
startNewTransaction();
try
{
logger.debug("delete node B2");
nodeService.deleteNode(B2NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
List<String> invaders = (List<String>) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 4 restore alien node B2. A1 becomes Alien again
*/
startNewTransaction();
try
{
logger.debug("restore node B2");
NodeRef B2ArchiveNodeRef = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, B2NodeRef.getId());
nodeService.restoreNode(B2ArchiveNodeRef, testNodeFactory.getMappedNodeRef(A1NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("B2"));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 5 - add B3
*/
startNewTransaction();
try
{
ChildAssociationRef child = nodeService.createNode(B2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B3"), ContentModel.TYPE_FOLDER);
B3NodeRef = child.getChildRef();
nodeService.setProperty(B3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B3NodeRef, ContentModel.PROP_NAME, "B3");
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("node B3 is not alien", (Boolean)nodeService.hasAspect(B3NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 5 remove alien node B2. A1 becomes non Alien (again).
*/
startNewTransaction();
try
{
logger.debug("delete node B2");
nodeService.deleteNode(B2NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
List<String> invaders = (List<String>) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step6 restore B2 and B3 to B1.
*/
startNewTransaction();
try
{
logger.debug("restore node B2");
NodeRef B2ArchiveNodeRef = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, B2NodeRef.getId());
nodeService.restoreNode(B2ArchiveNodeRef, B1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B2"));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A1NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("node A2 is still alien", (Boolean)nodeService.hasAspect(B2NodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A3 is still alien", (Boolean)nodeService.hasAspect(B3NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
}
/**
* Test the transfer method with regard to permissions on a node.
* <p>
* Step 1:
* Create a node with a single permission
* Inherit:false
* Read, Admin, Allow
* Transfer
* <p>
* Step 2:
* Update it to have several permissions
* Inherit:false
* Read, Everyone, DENY
* Read, Admin, Allow
* <p>
* Step 3:
* Remove a permission
* Inherit:false
* Read, Admin, Allow
* <p>
* Step 4:
* Revert to inherit all permissions
* Inherit:true
* <p>
* This is a unit test so it does some shenanigans to send to the same instance of alfresco.
*/
public void testTransferWithPermissions() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Now go ahead and create our transfer target
*/
String targetName = "testTransferWithPermissions";
TransferTarget transferMe;
NodeRef contentNodeRef;
NodeRef destNodeRef;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Create a test node that we will read and write
*/
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_CONTENT);
contentNodeRef = child.getChildRef();
nodeService.setProperty(contentNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(contentNodeRef, ContentModel.PROP_NAME, name);
ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
permissionService.setInheritParentPermissions(contentNodeRef, false);
permissionService.setPermission(contentNodeRef, "admin", PermissionService.READ, true);
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* Step 1
*/
logger.debug("First transfer - create new node with inheritParent permission off");
startNewTransaction();
try
{
/**
* Transfer our transfer target node
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists with the correct permissions
destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef));
assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef));
// Check ACL of destination node
boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
Set<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> destPerm = permissionService.getAllSetPermissions(destNodeRef);
assertFalse("inherit parent permissions (src) flag is incorrect", srcInherit);
assertFalse("inherit parent permissions (dest) flag is incorrect", destInherit);
// Check destination has the source's permissions
for (AccessPermission p : srcPerm)
{
logger.debug("checking permission :" + p);
assertTrue("permission is missing", destPerm.contains(p));
}
}
finally
{
endTransaction();
}
/**
* Step 2
* Update it to have several permissions
* Inherit:false
* Read, Everyone, DENY
* Read, Admin, Allow
*/
startNewTransaction();
try
{
permissionService.setPermission(contentNodeRef, "EVERYONE", PermissionService.READ, false);
permissionService.setPermission(contentNodeRef, "admin", PermissionService.FULL_CONTROL, true);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer our transfer target node
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists with the correct permissions
destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
// Check ACL of destination node
boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
Set<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> destPerm = permissionService.getAllSetPermissions(destNodeRef);
assertFalse("inherit parent permissions (src) flag is incorrect", srcInherit);
assertFalse("inherit parent permissions (dest) flag is incorrect", destInherit);
// Check destination has the source's permissions
for (AccessPermission p : srcPerm)
{
logger.debug("checking permission :" + p);
assertTrue("Step2, permission is missing", destPerm.contains(p));
}
}
finally
{
endTransaction();
}
/**
* Step 3 Remove a permission
*/
startNewTransaction();
try
{
permissionService.deletePermission(contentNodeRef, "admin", PermissionService.FULL_CONTROL);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer our transfer target node
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists with the correct permissions
destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
// Check ACL of destination node
boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
Set<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> destPerm = permissionService.getAllSetPermissions(destNodeRef);
assertFalse("inherit parent permissions (src) flag is incorrect", srcInherit);
assertFalse("inherit parent permissions (dest) flag is incorrect", destInherit);
// Check destination has the source's permissions
for (AccessPermission p : srcPerm)
{
logger.debug("checking permission :" + p);
assertTrue("permission is missing", destPerm.contains(p));
}
}
finally
{
endTransaction();
}
/**
* Step 4
* Revert to inherit all permissions
*/
startNewTransaction();
try
{
permissionService.setInheritParentPermissions(contentNodeRef, true);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer our transfer target node
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists with the correct permissions
destNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef));
assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef));
// Check ACL of destination node
boolean srcInherit = permissionService.getInheritParentPermissions(contentNodeRef);
Set<AccessPermission> srcPerm = permissionService.getAllSetPermissions(contentNodeRef);
boolean destInherit = permissionService.getInheritParentPermissions(destNodeRef);
Set<AccessPermission> destPerm = permissionService.getAllSetPermissions(destNodeRef);
assertTrue("inherit parent permissions (src) flag is incorrect", srcInherit);
assertTrue("inherit parent permissions (dest) flag is incorrect", destInherit);
// Check destination has the source's permissions
for (AccessPermission p : srcPerm)
{
if(p.isSetDirectly())
{
logger.debug("checking permission :" + p);
assertTrue("permission is missing:" + p, destPerm.contains(p));
}
}
}
finally
{
endTransaction();
}
}
/**
* Transfer with read only flag
*
* Node tree for this test
* <pre>
* A (Folder)
* | |
* B (Content) C (Folder)
* |
* D (Content)
* </pre>
* Step 1
* transfer Nodes ABCD with read only flag set - content should all be locked on destination
* <p>
* Step 2
* lock B (Content node) as user fred
* transfer (read only) - destination lock should change to Admin
* <p>
* Step 3
* lock C (Folder) as user fred
* transfer (read only) - destination lock should change to Admin
* <p>
* Step 4
* transfer without read only flag - locks should revert from Admin to Fred.
* <p>
* Step 5
* remove locks on A and B - transfer without read only flag - content should all be unlocked.
*/
public void testReadOnlyFlag() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
String CONTENT_NAME = "Demo Node 1";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "The quick brown fox";
Set<NodeRef>nodes = new HashSet<NodeRef>();
String USER_ONE = "TransferServiceImplTest";
String PASSWORD = "Password";
String targetName = "testReadOnlyFlag";
NodeRef nodeA;
NodeRef nodeB;
NodeRef nodeC;
NodeRef nodeD;
ChildAssociationRef child;
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(this.receiver, this.contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
TransferTarget transferMe;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Create a test node that we will read and write
*/
String guid = GUID.generate();
child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(guid), ContentModel.TYPE_FOLDER);
nodeA = child.getChildRef();
nodeService.setProperty(nodeA , ContentModel.PROP_TITLE, guid);
nodeService.setProperty(nodeA , ContentModel.PROP_NAME, guid);
nodes.add(nodeA);
child = nodeService.createNode(nodeA, ContentModel.ASSOC_CONTAINS, QName.createQName("testNodeB"), ContentModel.TYPE_CONTENT);
nodeB = child.getChildRef();
nodeService.setProperty(nodeB , ContentModel.PROP_TITLE, CONTENT_TITLE + "B");
nodeService.setProperty(nodeB , ContentModel.PROP_NAME, "DemoNodeB");
{
ContentWriter writer = contentService.getWriter(nodeB , ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
nodes.add(nodeB);
}
child = nodeService.createNode(nodeA, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,"testNodeC"), ContentModel.TYPE_FOLDER);
nodeC = child.getChildRef();
nodeService.setProperty(nodeC , ContentModel.PROP_TITLE, "TestNodeC");
nodeService.setProperty(nodeC , ContentModel.PROP_NAME, "TestNodeC");
nodes.add(nodeC);
child = nodeService.createNode(nodeC, ContentModel.ASSOC_CONTAINS, QName.createQName("testNodeD"), ContentModel.TYPE_CONTENT);
nodeD = child.getChildRef();
nodeService.setProperty(nodeD , ContentModel.PROP_TITLE, CONTENT_TITLE + "D");
nodeService.setProperty(nodeD , ContentModel.PROP_NAME, "DemoNodeD");
{
ContentWriter writer = contentService.getWriter(nodeD , ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
nodes.add(nodeD);
}
// Create users
createUser(USER_ONE, PASSWORD);
/**
* Now go ahead and create our first transfer target
*/
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* Step 1.
* transfer Nodes ABCD with read only flag set - content should all be locked on destination
*/
logger.debug("transfer read only - step 1");
startNewTransaction();
try
{
/**
* Transfer our transfer target nodes
*/
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setReadOnly(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Check destination nodes are locked.
assertTrue("dest node A does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeA)));
assertTrue("dest node B does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeB)));
assertTrue("dest node C does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeC)));
assertTrue("dest node D does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeD)));
assertTrue("dest node A not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeA), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node B not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node C not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node D not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeD), ContentModel.ASPECT_LOCKABLE));
}
finally
{
endTransaction();
}
/**
* Step 2
* lock B (Content node) as user ONE
* transfer (read only) - destination lock should change user to "Admin"
*/
startNewTransaction();
try
{
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
lockService.lock(nodeB, LockType.READ_ONLY_LOCK);
}
finally
{
assertEquals("test error: dest node B lock ownership", nodeService.getProperty(nodeB, ContentModel.PROP_LOCK_OWNER), USER_ONE);
AuthenticationUtil.popAuthentication();
endTransaction();
}
logger.debug("transfer read only - step 2");
startNewTransaction();
try
{
/**
* Transfer our transfer target nodes
*/
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setReadOnly(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Check destination nodes are locked.
assertTrue("dest node A does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeA)));
assertTrue("dest node B does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeB)));
assertTrue("dest node C does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeC)));
assertTrue("dest node D does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeD)));
assertTrue("dest node A not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeA), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node B not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node C not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node D not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeD), ContentModel.ASPECT_LOCKABLE));
// check that the lock owner is no longer USER_ONE
assertTrue("lock owner not changed", !USER_ONE.equalsIgnoreCase((String)nodeService.getProperty(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.PROP_LOCK_OWNER)));
}
finally
{
endTransaction();
}
/**
* Step 3
* lock C (Folder node) as user ONE
* transfer (read only) - destination lock should change to Admin
*/
startNewTransaction();
try
{
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser(USER_ONE);
lockService.lock(nodeC, LockType.READ_ONLY_LOCK);
}
finally
{
assertEquals("test error: dest node C lock ownership", nodeService.getProperty(nodeC, ContentModel.PROP_LOCK_OWNER), USER_ONE);
AuthenticationUtil.popAuthentication();
endTransaction();
}
logger.debug("transfer read only - step 3");
startNewTransaction();
try
{
/**
* Transfer our transfer target nodes
*/
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setReadOnly(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Check destination nodes are locked.
assertTrue("dest node A does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeA)));
assertTrue("dest node B does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeB)));
assertTrue("dest node C does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeC)));
assertTrue("dest node D does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeD)));
assertTrue("dest node A not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeA), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node B not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node C not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node D not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeD), ContentModel.ASPECT_LOCKABLE));
// check that the lock owner is no longer USER_ONE for content node B and folder node C
assertTrue("lock owner not changed", !USER_ONE.equalsIgnoreCase((String)nodeService.getProperty(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.PROP_LOCK_OWNER)));
assertTrue("lock owner not changed", !USER_ONE.equalsIgnoreCase((String)nodeService.getProperty(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.PROP_LOCK_OWNER)));
}
finally
{
endTransaction();
}
/**
* Step 4
* transfer without read only flag - locks should revert from Admin to USER_ONE.
*/
logger.debug("transfer read only - step 4");
startNewTransaction();
try
{
/**
* Transfer our transfer target nodes
*/
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setReadOnly(false); // turn off read-only
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Check destination nodes are not locked.
assertTrue("dest node A does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeA)));
assertTrue("dest node B does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeB)));
assertTrue("dest node C does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeC)));
assertTrue("dest node D does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeD)));
assertFalse("dest node A not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeA), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node B not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.ASPECT_LOCKABLE));
assertTrue("dest node C not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.ASPECT_LOCKABLE));
assertFalse("dest node D not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeD), ContentModel.ASPECT_LOCKABLE));
assertEquals("dest node B lock ownership", nodeService.getProperty(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.PROP_LOCK_OWNER), USER_ONE);
assertEquals("dest node C lock ownership", nodeService.getProperty(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.PROP_LOCK_OWNER), USER_ONE);
}
finally
{
endTransaction();
}
/**
* Step 5
* remove locks on A and B - transfer without read only flag - content should all be unlocked.
*/
logger.debug("transfer read only - step 5");
startNewTransaction();
try
{
lockService.unlock(nodeB);
lockService.unlock(nodeC);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer our transfer target nodes
*/
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setReadOnly(false); // turn off read-only
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Check destination nodes are not locked.
assertTrue("dest node A does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeA)));
assertTrue("dest node B does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeB)));
assertTrue("dest node C does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeC)));
assertTrue("dest node D does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(nodeD)));
assertFalse("test fail: dest node B is still locked", nodeService.hasAspect(nodeB, ContentModel.ASPECT_LOCKABLE));
assertFalse("test fail: dest node C is still locked", nodeService.hasAspect(nodeC, ContentModel.ASPECT_LOCKABLE));
assertFalse("dest node A not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeA), ContentModel.ASPECT_LOCKABLE));
assertFalse("dest node B not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeB), ContentModel.ASPECT_LOCKABLE));
assertFalse("dest node C not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeC), ContentModel.ASPECT_LOCKABLE));
assertFalse("dest node D not locked", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(nodeD), ContentModel.ASPECT_LOCKABLE));
}
finally
{
endTransaction();
}
} // end test read only flag
/**
* Transfer sync from multiple repos.
*
* This is a unit test so does lots of shenanigans to fake transfer from three repositories on a single repo.
*
* Multi-repo sync depends upon the following pieces of functionality
* a) transferred nodes are tagged with a trx:transferred aspect containing the originating repository
* id and the from repository id
* b) to support hub and spoke - when syncing don't imply delete nodes that are not "from" the transferring system
*
* * Tree of nodes
* A1
* | |
* A2 A3 (Content Node) B6 (Content Node)
* |
* A4 A5 B7
*
* Step 1
* Hub and Spoke Sync
* create Tree A1...A5
* transfer (sync)
* check the transfered aspects on destination
* create node B6. Fake its transfered aspect to be from Repo B.
* transfer (sync)
*
* Step 2
* Chain Sync
* Create Node A7 "from repo B".
* Change Nodes A1 ... A5 source to be received "from repo B"
* transfer
*
*/
public void testTwoRepoSync() throws Exception
{
/**
* Step 1
* create Tree A1...A6
* transfer (sync)
* check the transfered aspect
* create node B6. Fake its transfered aspect to be from Repo B, Non Alien.
* transfer (sync)
*/
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - replace the node factory with one that will map node refs, paths etc.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
String repositoryId = REPO_ID_A;
/**
* Now go ahead and create our first transfer target
*/
String targetName = "testTransferSyncNodes";
TransferTarget transferMe;
NodeRef A1NodeRef;
NodeRef A2NodeRef;
NodeRef A3NodeRef;
NodeRef A4NodeRef;
NodeRef A5NodeRef;
NodeRef B6NodeRef;
NodeRef A7NodeRef;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Create a test nodes A1 through A5 that we will read and write
*/
{
// Node A1
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A3
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_CONTENT);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A4"), ContentModel.TYPE_CONTENT);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
ContentWriter writer = contentService.getWriter(A4NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_CONTENT);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
ContentWriter writer = contentService.getWriter(A5NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
/**
* transfer (sync)
* check the transfered aspect
* create node B6. Fake its transfered aspect to be from Repo B, Non Alien.
* transfer (sync)
*/
startNewTransaction();
try
{
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Node B6 - faked transfer from repository B. Child of Destination node A1
NodeRef a1Dest = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertTrue("dest node A does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertEquals("dest node A1 From RepositoryId", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A1NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A1 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A1NodeRef), TransferModel.PROP_REPOSITORY_ID), repositoryId);
assertEquals("dest node A2 From RepositoryId", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A2 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_REPOSITORY_ID), repositoryId);
assertEquals("dest node A3 From RepositoryId", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A3 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_REPOSITORY_ID), repositoryId);
assertEquals("dest node A4 From RepositoryId", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A4 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.PROP_REPOSITORY_ID), repositoryId);
assertEquals("dest node A5 From RepositoryId", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A5 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.PROP_REPOSITORY_ID), repositoryId);
ChildAssociationRef child = nodeService.createNode(a1Dest, ContentModel.ASSOC_CONTAINS, QName.createQName("B6"), ContentModel.TYPE_CONTENT);
B6NodeRef = child.getChildRef();
nodeService.setProperty(B6NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(B6NodeRef, ContentModel.PROP_NAME, "B6");
/**
* The first tranfer was mocked to repository A - this is repository B.
*/
// This is repository B so there's no need to fake it
// nodeService.setProperty(B6NodeRef, TransferModel.PROP_FROM_REPOSITORY_ID, REPO_ID_B);
// nodeService.setProperty(B6NodeRef, TransferModel.PROP_REPOSITORY_ID, REPO_ID_B);
ContentWriter writer = contentService.getWriter(B6NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Does node B6 still exist ?
assertTrue("dest node B6 does not exist", nodeService.exists(B6NodeRef));
assertTrue("B6 not alien", nodeService.hasAspect(B6NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/** Step 2
* Chain Sync
* Change Nodes A1 ... A5 source to be received "from repo B"
* Create Node A7 - Fake it to be received "from repo B"
* transfer
*/
String NEW_TITLE="Chain sync";
startNewTransaction();
try
{
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, NEW_TITLE);
nodeService.setProperty(A1NodeRef, TransferModel.PROP_FROM_REPOSITORY_ID, REPO_ID_B);
nodeService.setProperty(A1NodeRef, TransferModel.PROP_REPOSITORY_ID, REPO_ID_B);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, NEW_TITLE);
nodeService.setProperty(A2NodeRef, TransferModel.PROP_FROM_REPOSITORY_ID, REPO_ID_B);
nodeService.setProperty(A2NodeRef, TransferModel.PROP_REPOSITORY_ID, REPO_ID_B);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, NEW_TITLE);
nodeService.setProperty(A3NodeRef, TransferModel.PROP_FROM_REPOSITORY_ID, REPO_ID_B);
nodeService.setProperty(A3NodeRef, TransferModel.PROP_REPOSITORY_ID, REPO_ID_B);
/**
* The repository was mocked to repoistory A. This is repository B
*/
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A7"), ContentModel.TYPE_CONTENT);
A7NodeRef = child.getChildRef();
nodeService.setProperty(A7NodeRef, ContentModel.PROP_TITLE, NEW_TITLE);
nodeService.setProperty(A7NodeRef, ContentModel.PROP_NAME, "A7");
nodeService.setProperty(A7NodeRef, ContentModel.PROP_TITLE, NEW_TITLE);
nodeService.setProperty(A7NodeRef, TransferModel.PROP_FROM_REPOSITORY_ID, REPO_ID_B);
nodeService.setProperty(A7NodeRef, TransferModel.PROP_REPOSITORY_ID, REPO_ID_B);
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
nodes.add(A7NodeRef);
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
try
{
assertTrue("dest node A7 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A7NodeRef)));
assertEquals("dest node A1 Title", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A1NodeRef), ContentModel.PROP_TITLE), NEW_TITLE);
assertEquals("dest node A1 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A1NodeRef), TransferModel.PROP_REPOSITORY_ID), REPO_ID_B);
assertEquals("dest node A1 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A1NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A2 Title", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), ContentModel.PROP_TITLE), NEW_TITLE);
assertEquals("dest node A2 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_REPOSITORY_ID), REPO_ID_B);
assertEquals("dest node A2 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
assertEquals("dest node A3 Title", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), ContentModel.PROP_TITLE), NEW_TITLE);
assertEquals("dest node A3 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_REPOSITORY_ID), REPO_ID_B);
assertEquals("dest node A3 Repository Id", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), repositoryId);
}
finally
{
endTransaction();
}
} // test two repo sync
/**
* Transfer sync from multiple repos.
*
* This is a unit test so does lots of shenanigans to fake transfer from three repositories on a single repo.
*
* Trees of nodes
* <pre>
* A1 B1 C1
* | |
* A2/images A2 Dummy/images
* | |
* A3 C3
*
* Destination
* B1
* |
* A2/images
* | |
* C3 A3
* |
* C4
* </pre>
* Step 1. Transfer from A to B.
* Step 2. Transfer from C to B (crossing over on A2Dest)
* Step 3. Invade A3Dest via C4
* Step 4. Delete C4. Sync from C
* Step 5. Delete C3 - A2 dest images folder uninvaded.
*/
public void testMultiRepoTransfer() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
String targetName = "testMultiRepoTransfer";
TransferTarget transferMe;
NodeRef S0NodeRef;
NodeRef A1NodeRef;
NodeRef A2NodeRef;
NodeRef A3NodeRef;
NodeRef B1NodeRef;
NodeRef C1NodeRef;
NodeRef C2NodeRef;
NodeRef C3NodeRef;
NodeRef C4NodeRef;
NodeRef A3Dummy;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
{
/**
* Node Source - located under guest home
*/
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
S0NodeRef = child.getChildRef();
nodeService.setProperty(S0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(S0NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A1"), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, "A1");
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, "A1");
}
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("images"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, "images");
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "images");
}
{
// Node A3
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_FOLDER);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, "A3");
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
}
{
// Node B1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B1"), ContentModel.TYPE_FOLDER);
B1NodeRef = child.getChildRef();
nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, "B1");
nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B1");
}
{
// Node C1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C1"), ContentModel.TYPE_FOLDER);
C1NodeRef = child.getChildRef();
nodeService.setProperty(C1NodeRef, ContentModel.PROP_TITLE, "C1");
nodeService.setProperty(C1NodeRef, ContentModel.PROP_NAME, "C1");
}
{
// Node C2/images
ChildAssociationRef child = nodeService.createNode(C1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("images"), ContentModel.TYPE_FOLDER);
C2NodeRef = child.getChildRef();
nodeService.setProperty(C2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C2NodeRef, ContentModel.PROP_NAME, "images");
}
{
// Node C3
ChildAssociationRef child = nodeService.createNode(C2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C3"), ContentModel.TYPE_FOLDER);
C3NodeRef = child.getChildRef();
nodeService.setProperty(C3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C3NodeRef, ContentModel.PROP_NAME, "C3");
}
{
// Node A3 (Dummy)
ChildAssociationRef child = nodeService.createNode(C2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_FOLDER);
A3Dummy = child.getChildRef();
nodeService.setProperty(A3Dummy, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3Dummy, ContentModel.PROP_NAME, "A3 Dummy");
}
{
// Node C4
ChildAssociationRef child = nodeService.createNode(A3Dummy, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"), ContentModel.TYPE_FOLDER);
C4NodeRef = child.getChildRef();
nodeService.setProperty(C4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C4NodeRef, ContentModel.PROP_NAME, "C4");
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - Map path from A1 to B1 (So transfer will transfer by path)
* - Map path from C1 to B1
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map Project A/images to Project B/images
// Map Project C/images to Project A/images
nodeService.getPath(A2NodeRef);
pathMap.add(new Pair(nodeService.getPath(A1NodeRef), nodeService.getPath(B1NodeRef)));
pathMap.add(new Pair(nodeService.getPath(C1NodeRef), nodeService.getPath(B1NodeRef)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 1
* Now transfer in A's nodes to Repo B
*/
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
// Check that A3 dest is a child of A2Dest which is a child of B1
ChildAssociationRef A3Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A3NodeRef));
assertEquals("A3 dest is connected to the wrong node", A3Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A2NodeRef));
ChildAssociationRef A2Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A2NodeRef));
assertEquals("A2 dest is connected to the wrong node", A2Ref.getParentRef(), B1NodeRef);
assertEquals("A2 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_A);
assertEquals("A3 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_A);
}
finally
{
endTransaction();
}
/**
* Step 2
* Now transfer in C's nodes
* B2 (Owned by A) gets invaded by C
*/
startNewTransaction();
try
{
mockedDescriptorService = getMockDescriptorService(REPO_ID_C);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(C1NodeRef);
nodes.add(C2NodeRef);
nodes.add(C3NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
// Check that A3 dest is a child of A2Dest which is a child of B1
// Check that C3 dest is a child of A2Dest
ChildAssociationRef A3Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A3NodeRef));
assertEquals("A3 dest is connected to the wrong node", A3Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A2NodeRef));
ChildAssociationRef C3Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A3NodeRef));
assertEquals("C3 dest is connected to the wrong node", C3Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A2NodeRef));
ChildAssociationRef A2Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A2NodeRef));
assertEquals("A2 dest is connected to the wrong node", A2Ref.getParentRef(), B1NodeRef);
assertTrue("A2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("A3 dest is invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.ASPECT_ALIEN));
assertEquals("A2 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_A);
assertEquals("A3 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_A);
assertEquals("C3 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_C);
}
finally
{
endTransaction();
}
/**
* Step 3
* Invade A3Dest via transfer of C4 from C
*/
startNewTransaction();
try
{
mockedDescriptorService = getMockDescriptorService(REPO_ID_C);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(C4NodeRef);
definition.setNodes(nodes);
definition.setSync(false);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C4NodeRef)));
assertTrue("C4 is not an invader", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C4NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("A3 is not an invader", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.ASPECT_ALIEN));
assertEquals("A2 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_A);
assertEquals("A3 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_A);
assertEquals("C3 dest owned by wrong repo", nodeService.getProperty(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.PROP_FROM_REPOSITORY_ID), REPO_ID_C);
}
finally
{
endTransaction();
}
/**
* Step 4
* Uninvade A3 from C by deleting C4
* Via Sync of A3Dummy (which has the same destination path as A3).
*/
startNewTransaction();
try
{
nodeService.deleteNode(C4NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
mockedDescriptorService = getMockDescriptorService(REPO_ID_C);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A3Dummy);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertFalse("dest node C4 not deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(C4NodeRef)));
logger.debug("A3 Dest is " + testNodeFactory.getMappedNodeRef(A3NodeRef));
assertFalse("A3 Dest still invaded by C4", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 5 - repeat the above test with transfer(non sync) rather than transfer(sync)
* Uninvade by deleting C3.
*/
startNewTransaction();
try
{
nodeService.deleteNode(C3NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
mockedDescriptorService = getMockDescriptorService(REPO_ID_C);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
NodeRef C3Deleted = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, C3NodeRef.getId());
nodes.add(C3Deleted);
definition.setNodes(nodes);
definition.setSync(false);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node C3 not deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertFalse("dest node C4 not deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(C4NodeRef)));
assertFalse("A3 still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A3NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("A2 still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A2NodeRef), TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
} // test multi repo sync
// Utility methods below.
private TransferTarget createTransferTarget(String name)
{
String title = "title";
String description = "description";
String endpointProtocol = "http";
String endpointHost = "MARKR02";
int endpointPort = 7080;
String endpointPath = "/alfresco/service/api/transfer";
String username = "admin";
char[] password = "admin".toCharArray();
/**
* Now go ahead and create our first transfer target
*/
TransferTarget target = transferService.createAndSaveTransferTarget(name, title, description, endpointProtocol, endpointHost, endpointPort, endpointPath, username, password);
return target;
}
/**
* Test the transfer method behaviour with respect to move and alien nodes.
*
* So we have Repository A transferring content and Repository B is the local repo that we
* move alien nodes in and out.
*
* Tree
* <pre>
* B1
* | | |
* C2(p1) C3(p2) A4
* |
* A5
* |
* B6
* </pre>
*
* Step 1: Tansfer in C's nodes to Repo B
*
* Step 2. Transfer in A's nodes to Repo B
*
* Setup tree above. Validat that A2 is child of C2 dest.
* A4 is a child of B1
*
* Step 3. Move A5 from C2 to C3 via transfer.
* C2Dest should stop being invaded by A5, C3Dest should be invaded by A5.
*
* Step 4. Invade A5 by B6. Move from C3 to C2 via transfer.
* C2Dest should be invaded by A and B.
* C3Dest should not be invaded.
*
* Step 5. Move A5 to A4.
* A4 should be invaded by B due to B6 but not by A.
* C2Dest should not be invaded.
*/
public void testMultiRepoTransferMove() throws Exception
{
setDefaultRollback(false);
final String localRepositoryId = descriptorService.getCurrentRepositoryDescriptor().getId();
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
String targetName = "testMultiRepoTransferMove";
TransferTarget transferMe;
NodeRef S0NodeRef;
NodeRef A1NodeRef;
NodeRef B1NodeRef;
NodeRef C1NodeRef;
NodeRef C2NodeRef;
NodeRef C3NodeRef;
NodeRef A4NodeRef;
NodeRef A5NodeRef;
NodeRef B6NodeRef;
NodeRef C2DummyNodeRef;
NodeRef C3DummyNodeRef;
QName C2Path = QName.createQName("p2");
QName C3Path= QName.createQName("p3");
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
{
/**
* Node Source - located under guest home
*/
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
S0NodeRef = child.getChildRef();
nodeService.setProperty(S0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(S0NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A1"), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, "A1");
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, "A1");
}
{
// Node B1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B1"), ContentModel.TYPE_FOLDER);
B1NodeRef = child.getChildRef();
nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, "B1");
nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B1");
}
{
// Node C1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C1"), ContentModel.TYPE_FOLDER);
C1NodeRef = child.getChildRef();
nodeService.setProperty(C1NodeRef, ContentModel.PROP_TITLE, "C1");
nodeService.setProperty(C1NodeRef, ContentModel.PROP_NAME, "C1");
}
{
// Node C2
ChildAssociationRef child = nodeService.createNode(C1NodeRef, ContentModel.ASSOC_CONTAINS, C2Path, ContentModel.TYPE_FOLDER);
C2NodeRef = child.getChildRef();
nodeService.setProperty(C2NodeRef, ContentModel.PROP_TITLE, "C2");
nodeService.setProperty(C2NodeRef, ContentModel.PROP_NAME, "C2");
}
{
// Node C3
ChildAssociationRef child = nodeService.createNode(C1NodeRef, ContentModel.ASSOC_CONTAINS, C3Path, ContentModel.TYPE_FOLDER);
C3NodeRef = child.getChildRef();
nodeService.setProperty(C3NodeRef, ContentModel.PROP_TITLE, "C3");
nodeService.setProperty(C3NodeRef, ContentModel.PROP_NAME, "C3");
}
{
// Node C2 (Dummy)
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, C2Path, ContentModel.TYPE_FOLDER);
C2DummyNodeRef = child.getChildRef();
nodeService.setProperty(C2DummyNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C2DummyNodeRef, ContentModel.PROP_NAME, "C2 Dummy");
}
{
// Node C3 (Dummy)
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, C3Path, ContentModel.TYPE_FOLDER);
C3DummyNodeRef = child.getChildRef();
nodeService.setProperty(C3DummyNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C3DummyNodeRef, ContentModel.PROP_NAME, "C3 Dummy");
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"), ContentModel.TYPE_FOLDER);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, "A4");
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(C2DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_FOLDER);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, "A5");
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - Map path from A1 to B1 (So transfer will transfer by path)
* - Map path from C1 to B1
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map Project A to Project B
// Map Project C to Project B
pathMap.add(new Pair(nodeService.getPath(A1NodeRef), nodeService.getPath(B1NodeRef)));
pathMap.add(new Pair(nodeService.getPath(C1NodeRef), nodeService.getPath(B1NodeRef)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_C);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 1
* Now transfer in C's nodes to Repo B
*/
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(C1NodeRef);
nodes.add(C2NodeRef);
nodes.add(C3NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
// Check that C3 dest is a child of B1
ChildAssociationRef C3Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(C3NodeRef));
assertEquals("A3 dest is connected to the wrong node", C3Ref.getParentRef(), B1NodeRef);
ChildAssociationRef C2Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(C2NodeRef));
assertEquals("A2 dest is connected to the wrong node", C2Ref.getParentRef(), B1NodeRef);
}
finally
{
endTransaction();
}
mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 2
* Now transfer in A's nodes
* C2 (Dest) gets invaded by A4
*/
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C2NodeRef));
assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
ChildAssociationRef A4Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A4NodeRef));
assertEquals("A4 dest is connected to the wrong node", A4Ref.getParentRef(), B1NodeRef);
}
finally
{
endTransaction();
}
/**
* Step 3
* Now move A5
* C3 (Dest) gets invaded by A5
*/
startNewTransaction();
try
{
nodeService.moveNode(A5NodeRef, C3DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
// Check that A4 dest is a child of C3Dest which is a child of B1
ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C3NodeRef));
assertTrue("A5 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C2 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 4 - multi invasion move via transfer service.
* Invade A5 by B6.
* Transfer from C3 back to C2.
*/
startNewTransaction();
try
{
nodeService.moveNode(A5NodeRef, C2DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B6"));
// Node B6
ChildAssociationRef child = nodeService.createNode(testNodeFactory.getMappedNodeRef(A5NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("B6"), ContentModel.TYPE_FOLDER);
B6NodeRef = child.getChildRef();
nodeService.setProperty(B6NodeRef, ContentModel.PROP_TITLE, "B6");
nodeService.setProperty(B6NodeRef, ContentModel.PROP_NAME, "B6");
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
// Check that A4 dest is a child of C2Dest which is a child of B1
ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
ChildAssociationRef B6Ref = nodeService.getPrimaryParent(B6NodeRef);
assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C2NodeRef));
assertEquals("B6 connected to the wrong node", B6Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A5NodeRef));
assertTrue("A5 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C3 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
List<String>invaders = (List<String>)nodeService.getProperty(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.PROP_INVADED_BY);
assertTrue("invaders is too small", invaders.size() > 1);
assertTrue("invaders does not contain REPO A", invaders.contains(REPO_ID_A));
assertTrue("invaders does not contain REPO B", invaders.contains(localRepositoryId));
}
finally
{
endTransaction();
}
/**
* Step 5
* Move
*/
startNewTransaction();
try
{
nodeService.moveNode(A5NodeRef, A4NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"));
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
// Check that A5dest is a child of A4Dest which is a child of B1
ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A4NodeRef));
assertTrue("A4 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("A5 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("B6 dest is not invaded", nodeService.hasAspect(B6NodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("C2 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C3 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
List<String>invaders = (List<String>)nodeService.getProperty(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.PROP_INVADED_BY);
assertTrue("invaders is too big", invaders.size() < 2);
assertFalse("invaders contains REPO A", invaders.contains(REPO_ID_A));
assertTrue("invaders does not contains REPO B", invaders.contains(REPO_ID_B));
}
finally
{
endTransaction();
}
}
/**
* Test the behaviour with regard to copying transferred nodes.
* <p>
* Transfer node read only
* <p>
* Copy transferred node.
* <p>
* New node should not be locked and should not be transferred.
* <p>
* This is a unit test so it does some shenanigans to send to the same instance of alfresco.
*/
public void testCopyTransferredNode() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
/**
* Now go ahead and create our transfer target
*/
String targetName = "testCopyTransferredNode";
TransferTarget transferMe;
NodeRef S0NodeRef;
NodeRef A1NodeRef;
NodeRef A2NodeRef;
NodeRef A3NodeRef;
NodeRef B1NodeRef;
NodeRef B2NodeRef;
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
/**
* Node Source - located under guest home
*/
{
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
S0NodeRef = child.getChildRef();
nodeService.setProperty(S0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(S0NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A1"), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, "A1");
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, "A1");
}
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, "A2");
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A3
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_FOLDER);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, "A3");
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
}
{
// Node B1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B1"), ContentModel.TYPE_FOLDER);
B1NodeRef = child.getChildRef();
nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, "B1");
nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B1");
}
{
// Node B2
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B2"), ContentModel.TYPE_FOLDER);
B2NodeRef = child.getChildRef();
nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, "B2");
nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B2");
}
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - Map path from A1 to B1 (So transfer will transfer by path)
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map Project A to Project B
pathMap.add(new Pair(nodeService.getPath(A1NodeRef), nodeService.getPath(B1NodeRef)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 1
*/
logger.debug("First transfer - ");
startNewTransaction();
try
{
/**
* Transfer our transfer target node
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
definition.setNodes(nodes);
definition.setReadOnly(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists with the correct permissions
NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
assertTrue("dest node ref does not exist", nodeService.exists(A2destNodeRef));
/**
* Copy the node A2 Dest
*/
NodeRef copiedNode = copyService.copy(A2destNodeRef, B2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2Copy"));
assertTrue("copied node does not exist", nodeService.exists(copiedNode));
System.out.println("copied node is " + copiedNode);
assertFalse("copied node still has transferred aspect", nodeService.hasAspect(copiedNode, TransferModel.ASPECT_TRANSFERRED));
assertNull("copied node still has from repository id", nodeService.getProperty(copiedNode, TransferModel.PROP_FROM_REPOSITORY_ID));
assertNull("copied node still has original repository id", nodeService.getProperty(copiedNode, TransferModel.PROP_REPOSITORY_ID));
Set<QName> aspects = nodeService.getAspects(copiedNode);
/**
* Copy a chain of transferred nodes - well A2dest and A3dest
*/
copiedNode = copyService.copy(A2destNodeRef, B2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2Copy2"), true);
assertTrue("copied node does not exist", nodeService.exists(copiedNode));
System.out.println("copied node is " + copiedNode);
assertFalse("copied node still has transferred aspect", nodeService.hasAspect(copiedNode, TransferModel.ASPECT_TRANSFERRED));
assertNull("copied node still has from repository id", nodeService.getProperty(copiedNode, TransferModel.PROP_FROM_REPOSITORY_ID));
assertNull("copied node still has original repository id", nodeService.getProperty(copiedNode, TransferModel.PROP_REPOSITORY_ID));
List<ChildAssociationRef> children = nodeService.getChildAssocs(copiedNode);
for(ChildAssociationRef child : children)
{
assertFalse("copied node still has transferred aspect", nodeService.hasAspect(child.getChildRef(), TransferModel.ASPECT_TRANSFERRED));
assertNull("copied node still has from repository id", nodeService.getProperty(child.getChildRef(), TransferModel.PROP_FROM_REPOSITORY_ID));
assertNull("copied node still has original repository id", nodeService.getProperty(child.getChildRef(), TransferModel.PROP_REPOSITORY_ID));
}
}
finally
{
endTransaction();
}
}
/**
* Test the behaviour with respect to copy of alien nodes.
*
* So we have Repository A transferring content and Repository B is the local repo that we
* copy alien nodes in and out. Copied nodes are not "transferred" so they change
* from being "from repository A" to "from the local repository".
*
* Tree
* <pre>
* B1
* | | |
* C2(p1) C3(p2) A4
* |
* A5
* |
* B6
* </pre>
*
* Step 1: Tansfer in C's nodes to Repo B
*
* Step 2. Transfer in A's nodes to Repo B
*
* Setup tree above. Validat that A2 is child of C2 dest.
* A4 is a child of B1
*
* Step 3. Copy A5 from C2 to C3.
* C2Dest should still be invaded by A5
* C3Dest should be invaded by A5(copy 1) which is now a "B" invader.
*
* Step 4. Copy A5 from C2 to A4.
* C2Dest should still be invaded by A5
* A4Dest should be invaded by A5(copy 2) which is now a "B" invader.
*
* Step 5. Invade A5 dest with B6.
* Copy A5(Dest) to B1 (A5 Copy 3)
* B1 should not be invaded.
* A5 Copy 3 not invaded.
* B6 Copy not invaded.
*
* Step 6. Invade A5 dest with B6.
* Copy A5(Dest) to B1 (A5 Copy 3) with children
* B1 should not be invaded.
* A5 Copy 4 not invaded.
* B6 Copy not invaded.
*
*/
public void testCopyAlien() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
String targetName = "testCopyAlien";
TransferTarget transferMe;
NodeRef S0NodeRef;
NodeRef A1NodeRef;
NodeRef B1NodeRef;
NodeRef C1NodeRef;
NodeRef C2NodeRef;
NodeRef C3NodeRef;
NodeRef A4NodeRef;
NodeRef A5NodeRef;
NodeRef B6NodeRef;
NodeRef C2DummyNodeRef;
NodeRef C3DummyNodeRef;
QName C2Path = QName.createQName("p2");
QName C3Path= QName.createQName("p3");
final String localRepositoryId = descriptorService.getCurrentRepositoryDescriptor().getId();
startNewTransaction();
try
{
/**
* Get guest home
*/
String guestHomeQuery = "/app:company_home/app:guest_home";
ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
assertEquals("", 1, guestHomeResult.length());
NodeRef guestHome = guestHomeResult.getNodeRef(0);
{
/**
* Node Source - located under guest home
*/
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
S0NodeRef = child.getChildRef();
nodeService.setProperty(S0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(S0NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A1"), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, "A1");
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, "A1");
}
{
// Node B1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B1"), ContentModel.TYPE_FOLDER);
B1NodeRef = child.getChildRef();
nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, "B1");
nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B1");
}
{
// Node C1
ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C1"), ContentModel.TYPE_FOLDER);
C1NodeRef = child.getChildRef();
nodeService.setProperty(C1NodeRef, ContentModel.PROP_TITLE, "C1");
nodeService.setProperty(C1NodeRef, ContentModel.PROP_NAME, "C1");
}
{
// Node C2
ChildAssociationRef child = nodeService.createNode(C1NodeRef, ContentModel.ASSOC_CONTAINS, C2Path, ContentModel.TYPE_FOLDER);
C2NodeRef = child.getChildRef();
nodeService.setProperty(C2NodeRef, ContentModel.PROP_TITLE, "C2");
nodeService.setProperty(C2NodeRef, ContentModel.PROP_NAME, "C2");
}
{
// Node C3
ChildAssociationRef child = nodeService.createNode(C1NodeRef, ContentModel.ASSOC_CONTAINS, C3Path, ContentModel.TYPE_FOLDER);
C3NodeRef = child.getChildRef();
nodeService.setProperty(C3NodeRef, ContentModel.PROP_TITLE, "C3");
nodeService.setProperty(C3NodeRef, ContentModel.PROP_NAME, "C3");
}
{
// Node C2 (Dummy)
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, C2Path, ContentModel.TYPE_FOLDER);
C2DummyNodeRef = child.getChildRef();
nodeService.setProperty(C2DummyNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C2DummyNodeRef, ContentModel.PROP_NAME, "C2 Dummy");
}
{
// Node C3 (Dummy)
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, C3Path, ContentModel.TYPE_FOLDER);
C3DummyNodeRef = child.getChildRef();
nodeService.setProperty(C3DummyNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(C3DummyNodeRef, ContentModel.PROP_NAME, "C3 Dummy");
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"), ContentModel.TYPE_FOLDER);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, "A4");
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(C2DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_FOLDER);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, "A5");
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* For unit test
* - replace the HTTP transport with the in-process transport
* - Map path from A1 to B1 (So transfer will transfer by path)
* - Map path from C1 to B1
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map Project A to Project B
// Map Project C to Project B
pathMap.add(new Pair(nodeService.getPath(A1NodeRef), nodeService.getPath(B1NodeRef)));
pathMap.add(new Pair(nodeService.getPath(C1NodeRef), nodeService.getPath(B1NodeRef)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_C);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 1
* Now transfer in C's nodes to Repo B
*/
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(C1NodeRef);
nodes.add(C2NodeRef);
nodes.add(C3NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
// Check that C3 dest is a child of B1
ChildAssociationRef C3Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(C3NodeRef));
assertEquals("A3 dest is connected to the wrong node", C3Ref.getParentRef(), B1NodeRef);
ChildAssociationRef C2Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(C2NodeRef));
assertEquals("A2 dest is connected to the wrong node", C2Ref.getParentRef(), B1NodeRef);
}
finally
{
endTransaction();
}
mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Step 2
* Now transfer in A's nodes
* C2 (Dest) gets invaded by A4
*/
startNewTransaction();
try
{
TransferDefinition definition = new TransferDefinition();
Collection<NodeRef> nodes = new ArrayList<NodeRef>();
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C2NodeRef));
assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
ChildAssociationRef A4Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A4NodeRef));
assertEquals("A4 dest is connected to the wrong node", A4Ref.getParentRef(), B1NodeRef);
}
finally
{
endTransaction();
}
/**
* Step 3. Copy A5 from C2 to C3.
* C2Dest should still be invaded by A5
* C3Dest should be invaded by A5(copy) which is now a "B/local" invader.
*/
startNewTransaction();
try
{
NodeRef copyRef = copyService.copy(testNodeFactory.getMappedNodeRef(A5NodeRef), testNodeFactory.getMappedNodeRef(C3NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("A5 Copy 1"));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
assertTrue("A5(copy 1) is not invaded", nodeService.hasAspect(copyRef, TransferModel.ASPECT_ALIEN));
assertTrue("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
List<String> C2invaders = (List<String>) nodeService.getProperty(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.PROP_INVADED_BY);
List<String> C3invaders = (List<String>) nodeService.getProperty(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.PROP_INVADED_BY);
assertTrue("C3 invaders contains local repository Id", C3invaders.contains(localRepositoryId));
assertFalse("C3 invaders contains REPO_ID_A", C3invaders.contains(REPO_ID_A));
assertFalse("C2 invaders contains local repository Id", C2invaders.contains(localRepositoryId));
assertTrue("C2 invaders contains REPO_ID_A", C2invaders.contains(REPO_ID_A));
}
finally
{
endTransaction();
}
/**
* Step 4. Copy A5 from C2 to A4.
* C2Dest should still be invaded by A5
* A4Dest should be invaded by A5(copy 2) which is now a "B" invader.
*/
startNewTransaction();
try
{
NodeRef copyRef = copyService.copy(testNodeFactory.getMappedNodeRef(A5NodeRef), testNodeFactory.getMappedNodeRef(A4NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("A5 Copy 2"));
assertTrue("dest node A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
assertTrue("A5(copy 2) is not invaded", nodeService.hasAspect(copyRef, TransferModel.ASPECT_ALIEN));
assertTrue("A4 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
List<String> C2invaders = (List<String>) nodeService.getProperty(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.PROP_INVADED_BY);
List<String> A4invaders = (List<String>) nodeService.getProperty(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.PROP_INVADED_BY);
assertTrue("A4 invaders contains local repository Id", A4invaders.contains(localRepositoryId));
assertFalse("C2 invaders contains local repository Id", C2invaders.contains(localRepositoryId));
assertTrue("C2 invaders contains REPO_ID_A", C2invaders.contains(REPO_ID_A));
}
finally
{
endTransaction();
}
/**
* Step 5. Invade A5 dest with B6.
* Copy A5(Dest) to B1 (A5 Copy 3) no children
* B1 should not be invaded.
* A5 Copy 3 not invaded.
* B6 Copy not invaded.
*/
startNewTransaction();
try
{
ChildAssociationRef child = nodeService.createNode(testNodeFactory.getMappedNodeRef(A5NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("B6"), ContentModel.TYPE_FOLDER);
B6NodeRef = child.getChildRef();
nodeService.setProperty(B6NodeRef, ContentModel.PROP_TITLE, "B6");
nodeService.setProperty(B6NodeRef, ContentModel.PROP_NAME, "B6");
assertTrue("A4 dest is not invaded prior to test - test error", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.ASPECT_ALIEN));
NodeRef copyRef = copyService.copy(testNodeFactory.getMappedNodeRef(A5NodeRef), B1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5 Copy 3"));
assertFalse("B1 is invaded", nodeService.hasAspect(B1NodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("A5 copy 3 is invaded", nodeService.hasAspect(copyRef, TransferModel.ASPECT_ALIEN));
}
finally
{
endTransaction();
}
/**
* Step 6. Invade A5 dest with B6.
* Copy A5(Dest) to B1 (A5 Copy 3) with children
* B1 should not be invaded.
* A5 Copy 4 not invaded.
* B6 Copy not invaded.
*/
startNewTransaction();
try
{
assertFalse("B1 is invaded prior to test - test error", nodeService.hasAspect(B1NodeRef, TransferModel.ASPECT_ALIEN));
NodeRef copyRef = copyService.copy(testNodeFactory.getMappedNodeRef(A5NodeRef), B1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5 Copy 4"), true);
assertFalse("B1 is invaded", nodeService.hasAspect(B1NodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("A5 copy 4 is invaded", nodeService.hasAspect(copyRef, TransferModel.ASPECT_ALIEN));
List <ChildAssociationRef> refs = nodeService.getChildAssocs(copyRef);
assertTrue("can't find child of A5 copy 4", refs.size() == 1);
for(ChildAssociationRef ref : refs)
{
assertFalse("B6 copy is invaded", nodeService.hasAspect(ref.getChildRef(), TransferModel.ASPECT_ALIEN));
}
}
finally
{
endTransaction();
}
} // copy node
private void createUser(String userName, String password)
{
if (this.authenticationService.authenticationExists(userName) == false)
{
this.authenticationService.createAuthentication(userName, password.toCharArray());
PropertyMap ppOne = new PropertyMap(4);
ppOne.put(ContentModel.PROP_USERNAME, userName);
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
this.personService.createPerson(ppOne);
}
}
private DescriptorService getMockDescriptorService(String repositoryId)
{
DescriptorService descriptorService = mock(DescriptorService.class);
Descriptor descriptor = mock(Descriptor.class);
when(descriptor.getId()).thenReturn(repositoryId);
when(descriptorService.getCurrentRepositoryDescriptor()).thenReturn(descriptor);
return descriptorService;
}
}