{"id":28411,"date":"2015-10-16T21:16:52","date_gmt":"2015-10-16T15:46:52","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=28411"},"modified":"2024-01-02T17:48:41","modified_gmt":"2024-01-02T12:18:41","slug":"content-migration-in-aem-using-slingpostservlet","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/content-migration-in-aem-using-slingpostservlet\/","title":{"rendered":"Content Migration in AEM using SlingPostServlet"},"content":{"rendered":"<p>A very basic migration flow looks as follows:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-28413\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/Untitled.png\" alt=\"Migration flow in AEM\" width=\"954\" height=\"295\" \/><\/p>\n<p>In this scenario, you have a CMS(that could be Sitecore, Drupal, WordPress or any other CMS) which has <a title=\"Legacy to AEM Migration Services\" href=\"http:\/\/www.tothenew.com\/wcm\/cq-aem-development-consulting\">source content that needs to be migrated to AEM<\/a>. To achieve this, we typically need to do following things:<\/p>\n<ul>\n<li>Get content from source CMS in any format(XML, CSV, etc)<\/li>\n<li>Process this content and extract content that needs to be exported to AEM. This would include parsing XML\/CSV exported by source CMS and massaging it(if needed).<\/li>\n<li>The processed content is then imported to AEM. There can be various strategies for this, like Talend, Package Manager and SlingPostServlet.<\/li>\n<\/ul>\n<p>I like SlingPostServlet as I feel it is closer to coding than other strategies. This blog is focused on that only. Considering that source CMS gives you XML, I created a <a href=\"https:\/\/github.com\/viveksachdeva\/aem-utils\/blob\/master\/Migration.groovy\" target=\"_blank\" rel=\"noopener\">Groovy script<\/a> for migration. Here are the steps:<\/p>\n<ul>\n<li>Parsing XML using Groovy XML Parser<\/li>\n<\/ul>\n<p>[java]<\/p>\n<p>def records = new XmlParser().parseText(file.text)?.blog<\/p>\n<p>[\/java]<\/p>\n<ul>\n<li>Creating a map out of parsed content<\/li>\n<\/ul>\n<p>[java]<br \/>\nrecords.eachWithIndex { blog, idx -&gt;<br \/>\n    def name = blog.name.text()<br \/>\n    def content = blog.outline.text()<br \/>\n    def status = blog.status.text()<br \/>\n    def parentSubject = blog.subject_parent.text()<br \/>\n    Map contentMap = [<br \/>\n            &quot;.\/jcr:primaryType&quot;: &quot;cq:Page&quot;,<br \/>\n            &quot;.\/jcr:content\/jcr:primaryType&quot;: &quot;cq:PageContent&quot;,<br \/>\n            &quot;.\/jcr:content\/jcr:title&quot;: &quot;${name}&quot;,<br \/>\n            &quot;.\/jcr:content\/blog\/sling:resourceType&quot;: resourceType,<br \/>\n            &quot;.\/jcr:content\/blog\/status&quot;: status,<br \/>\n            &quot;.\/jcr:content\/blog\/parentSubject&quot;: parentSubject,<br \/>\n            &quot;.\/jcr:content\/blog\/text\/sling:resourceType&quot;: &quot;foundation\/components\/text&quot;,<br \/>\n            &quot;.\/jcr:content\/blog\/text\/text&quot;: &quot;${content}&quot;<br \/>\n    ]<br \/>\n    callPost(&quot;${baseContentPath}blog${idx}&quot;, contentMap)<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>Any key in the map corresponds to a property in JCR. If you split the property by &#8220;\/&#8221;, last element would give you the property name and elements from first to second last gives you the hierarchy. Taking example of<\/p>\n<p>[code]&quot;.\/jcr:content\/blog\/status&quot;: &quot;Published&quot;[\/code]<\/p>\n<p>entry in the map, this key would create hierarchy jcr:content -&gt; blog and blog node would have a property status and value Published .<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-28419\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/jcr.png\" alt=\"content structure\" width=\"915\" height=\"155\" \/><\/p>\n<ul>\n<li>Posting content to AEM<\/li>\n<\/ul>\n<p>[java]<br \/>\nvoid callPost(String baseURL, Map contentMap) {<br \/>\n    \/*Setting auth basic in request doesnt work&#8230; Had to set it in headers*\/<br \/>\n\/\/        http.auth.basic(&quot;admin&quot;, &quot;admin&quot;)<br \/>\n    MigrationConfiguration.client.request(Method.POST) {<br \/>\n        uri.path = baseURL<br \/>\n        requestContentType = ContentType.URLENC<br \/>\n        headers.&#8217;Authorization&#8217; = &quot;Basic ${&quot;admin:admin&quot;.bytes.encodeBase64().toString()}&quot;<br \/>\n        body = contentMap<\/p>\n<p>        response.failure = { resp -&gt; println &quot;\\nERROR: ${resp.statusLine} for ${uri.path}&quot; }<br \/>\n    }<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>And that is all you need to do. \ud83d\ude42<\/p>\n<p>You can now check the content hierarchy in CRX. You can modify this Groovy script as per your use case.<\/p>\n<p>In addition, if you would like to know more on Content Migration to AEM, here&#8217;s a simple step-by-step guide on how to do it?<\/p>\n<p><span id=\"hs-cta-wrapper-e0c5b1de-0ad5-42eb-9cde-5355f76912ae\" class=\"hs-cta-wrapper\"><span id=\"hs-cta-e0c5b1de-0ad5-42eb-9cde-5355f76912ae\" class=\"hs-cta-node hs-cta-e0c5b1de-0ad5-42eb-9cde-5355f76912ae\"> <a href=\"http:\/\/insights.tothenew.com\/cq-aem-migrating-content-to-aem\"><img decoding=\"async\" id=\"hs-cta-img-e0c5b1de-0ad5-42eb-9cde-5355f76912ae\" class=\"hs-cta-img\" style=\"border-width: 0px\" src=\"https:\/\/no-cache.hubspot.com\/cta\/default\/481864\/e0c5b1de-0ad5-42eb-9cde-5355f76912ae.png\" alt=\"Fundamental Guide for Migrating Content to AEM | TO THE NEW\" \/><\/a><br \/>\n<\/span><\/span>Please put in your comments in case there are suggestions to improve it or if you face\u00a0any issue with this.<\/p>\n<p>Thanks!!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A very basic migration flow looks as follows: In this scenario, you have a CMS(that could be Sitecore, Drupal, WordPress or any other CMS) which has source content that needs to be migrated to AEM. To achieve this, we typically need to do following things: Get content from source CMS in any format(XML, CSV, etc) [&hellip;]<\/p>\n","protected":false},"author":48,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":116},"categories":[1],"tags":[4847,2624,1580,2007,1207,2623,9,2622,2589],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/28411"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/48"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=28411"}],"version-history":[{"count":1,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/28411\/revisions"}],"predecessor-version":[{"id":59879,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/28411\/revisions\/59879"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=28411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=28411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=28411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}