Presentation is loading. Please wait.

Presentation is loading. Please wait.

Packages and your Data in Umbraco Cloud

Similar presentations


Presentation on theme: "Packages and your Data in Umbraco Cloud"— Presentation transcript:

1 Packages and your Data in Umbraco Cloud

2 Umbraco as a Service provides as many as four separate environments
To make them work seamlessly together Data must be moved between them

3 Content Structure So what do we need to move? Content data - nodes
Strucutre data – document types

4 Courier makes all this go
By converting documents to item objects Which in turn are serialized to XML documents From there one of two things happens: Umbraco commits the file to Git – or – Umbraco pushes the object via webservices to the target environment Changes are pushed via Git to the target environment

5 ItemProviders make the world go
Each “thing” which needs to be transferred needs an ItemProvider ItemProvider convert a piece of data like a document into an item

6

7 Packages and your Data on Umbraco Cloud Pratically

8 REQUIRED PIECES TO MAKE IT GO SOLID
We’ll take a look at what’s required to support Umbraco as a Service How packages change What need to be implemented to support Umbraco as a Service

9 First a bit of background, so you know what uCommerce is
And what we need from Umbraco Commerce Package for Umbraco since 2009 Our goal: Seamless installation => Package, NuGet, Umbraco as a Service, Umbraco stand-alone Catalogs, Orders, and Marketing in a separate database

10 Data Migration of Structure Data Data Migration of Content Data
Package Installation Data Migration of Structure Data Data Migration of Content Data Couple of things needs to change Installation, packages can now move between environments Data Migration, data created in one environment must be able to recreate in another environment Structure data, data other data relies on, e.g. Document Types for Umbraco, Definitions and DataType for uCommerce Content data, e.g. nodes in Umbraco, stores, catalogs, products in uCommerce

11 Package InstallatioN

12 Umbraco Local Traditional packages are installed into a single environment With no expectation of being moved from one environment to another

13 Umbraco Cloud Install Install Install On Umbraco as a Service
Your package can be installed in any of these environments This is how you’d do with a traditional package Does not provide a good user experience

14 Umbraco Cloud Pull Install
Users will “move” their sites and thus your package between environments They will expect it to “just work”

15 Umbraco Cloud Push Install
Even better they might install your package in different ways Either as an Umbraco package Or a NuGet package if you offer it Preferred

16 Install on every environment
TRADITIONAL PACKAGES Install on every environment Update on every environment To avoid requiring devs to install/upgrade the package in all the environments To make package work in an environment like that It has to be able to install itself upon start AHA the headless installation

17 Install on any environment
HEADLESS PACKAGES Install on any environment Automagical headless set up when moved to a new one To avoid requiring devs to install/upgrade the package in all the environments To make package work in an environment like that It has to be able to install itself upon start AHA the headless installation

18 A Word on Package Actions
public interface umbraco.interfaces.IPackageAction Package actions will not automatically run as no installation occurs So we have to find a way of dealing with all the custom steps required to get the package running We need A way to trigger an installation Some installation steps

19 UMBRACO 6.1+ APPROACH: ApplicationEventHandler
public class RegisterEvents : ApplicationEventHandler { protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) // Run package init, if needed }

20 ? UMBRACO 8 APPROACH: Package Migrations

21 GENRIC .NET APPROACH: PreInit Attribute + HTTP Module Installation
using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; [assembly: PreApplicationStartMethod(typeof(UCommerce.Umbraco7.Installer.App_Start.PreAppStartCode), "LoadModule")] namespace UCommerce.Umbraco7.Installer.App_Start { public class PreApplicationStartCode public static void LoadModule() DynamicModuleUtility.RegisterModule(typeof (Installer)); } uCommerce standardizes on a PreApplicationStartMethod + an HTTP Module This is to ensure we are compatible with as many versions as possible

22 PreInit Attribute + HTTP Module Installation
public class Installer : IHttpModule { public void Init(HttpApplication context) context.BeginRequest += (new EventHandler(this.PreStart)); } public void PreStart(object sender, EventArgs e) if (!_installationWasRun) lock (_padLock) // Run package init, if needed _installationWasRun = RunInstallation(); PreInit Attribute + HTTP Module Installation

23 Another Word on Package Actions
public class umbraco.cms.businesslogic.packager.Installer You might be able to run package actions using the Umbraco installer This means you can stick with what you already have instead of changing it to something else At the very least you can execute actions yourself

24 Should you decide to ship your package in NuGet form as well
Method works with NuGet as well

25 web.config If you need to make changes to web.config a couple of things to keep in mind

26 OK to change web.config Install
It’s OK to make changes in web.config when the package is installed locally The changes are pushed to the dev environment

27 Changes are not retained Use transformations instead
OK to change web.config Changes are not retained Use transformations instead web.Development.xdt.config web.Live.xdt.config Install But not on UaaS The changes you make to web.config are not committed to Git Your package will break at some point You will have to support both approaches as devs might install packages in Umbraco as a Service or locally Remember multiple packages might require changes to web.config To create a seamless install experience You have to manually execute the development transformation locally

28 Seamless Installation
With all this in place you will have a seamless install experience no matter where you install.

29 Seamless Installation
For uCommerce, we also provide the option of installing via NuGet That works seamlessly with Umbraco as a Service as well

30 Move Data Between Environments
With the package up and running We need to deal with day to day of creating data in one environment and First decide what you need to move Data which is content-like: For uCommerce that’s catalogs and products Data which is structure-like: For uCommerce that’s definitions, something similar to document types

31 Content data for uCommerce is catalogs, categories, products

32 Structure data includes Definitions, which are like Document Types from Umbraco

33 Remember that you need to be able to uniquely identify everything
Guid all the things!

34 Structure Data Let’s start with structure data
The underlying bits that other data relies upon

35 Edit/Save Edit occur on one environment and needs to be pushed to another

36 Let’s assume I have created a new definition in uCommerce on the dev environment
What is needed to push the change to a different environment

37 Development Edit/Save
Whenever data is saved, it goes to the database as usual And it needs to go to the file system and ultimately to the Git repository So it can be pushed to the new environment

38

39 BasicEventManager.SendToCache<T>() Edit/Save
Development BasicEventManager.SendToCache<T>() Edit/Save ItemProvider.HandlePack() DTO (for .NET XML serializer) Here’s the process looks like from an implementers perspective 1) SendToCache notifies Umbraco that something needs to be added to cache using an ItemId and ItemProviderId 2) HandlePack is called on the specified ItemProvider, e.g. DataTypeItemProvider or DefinitionItemProvider in our case, with an item 3) HandlePack maps from the DTO type to be serialized as XML to filesystem File in /data/revision/<name of

40 End result is a folder for each ItemProvider

41 A file for each item

42 <Dependencies> <Dependency>
<ProductDefinitionItem xmlns:xsi=" xmlns:xsd=" <Dependencies> <Dependency> <IsChild>false</IsChild> <ItemId> <Id>15876f1f fe6-309ed0f5fca0</Id> <ProviderId>c22fa68e a84-8cce-b94938bff51d</ProviderId> </ItemId> <Name>uCommerce_DataType: 15876f1f fe6-309ed0f5fca0</Name> <ForceHashCheck>true</ForceHashCheck> </Dependency> </Dependencies> <Id>e4e1548d-b5b9-4b28-9c12-ff847e14c69f</Id> <ProviderId>02c6f074-52ac-4c9e-8e84-3f66dd1d4051</ProviderId> <Name>MyDefinition</Name> <ItemType>Item</ItemType> <Resources /> <DefinitionName>MyDefinition</DefinitionName> <Guid>e4e1548d-b5b9-4b28-9c12-ff847e14c69f</Guid> </ProductDefinitionItem> Format dictated by the DTO Serialized by .NET XML serializer

43 Set Up ItemProvider public class DefinitionsItemProvider : ItemProvider { public DefinitionsItemProvider() Name = "uCommerce definitions"; Description = "Items representing uCommerce definitions"; Id = ItemProviderIds.ItemProviderDefinitionId; ExtractionDirectory = "ucommerce_definitions"; Index = 21; ProviderIcon = "/umbraco/images/umbraco/doc.gif"; } Id used to identify which provider to use for an item Before we can start the process, we need to set up an ItemProvider Specific a provider id Where to put files Note: The prefix for the file location to avoid collisions Put files in /data/revisions/ucommerce_definitions

44 BasicEventManager.SendToCache<T>()
Development BasicEventManager.SendToCache<T>() Edit/Save ItemProvider.HandlePack() DTO (for .NET XML serializer) Let’s take a look at the individual steps to implement this First queue an entity to be sent to the file system

45 Queue Object for File System
<component id="SaveDefinition"> <parameters> <tasks> <array> <value>${Definition.UpdateRevision}</value> <value>${Definition.Save}</value> <value>${Definition.Index}</value> <value>${Definition.AddToCache}</value> </array> </tasks> </parameters> </component> var manager = BasicEventManager.GetBasicEventManager; manager.SendToCache<T>(itemIdentifier, entityName); In uCommerce, UI triggers a pipeline Pipeline pokes Umbraco to kick off the process Using the EventManager to provide the ItemId and the ItemProviderId new ItemIdentifier(entity.Guid.ToString(), Providers.ItemProviderIds.ItemProviderDefinitionId)

46 ItemProvider.HandlePack()
Development BasicEventManager.SendToCache<T>() Edit/Save ItemProvider.HandlePack() DTO (for .NET XML serializer) Second ItemProvider.HandlePack Triggered by Umbraco using the ItemProviderId provided in previous step Convert entity to an Item

47 public class DefinitionItemProvider : ItemProvider
{ public override Item HandlePack(ItemIdentifier id) var definition = Definition.FirstOrDefault(x => x.Guid == id && !x.BuiltIn); var result = new DefinitionItem Guid = definition.Guid, Name = definition.Name, }; var dataTypesUsedByDefinition = definition.DefinitionFields.Select(x => x.DataType) .Distinct().Where(x => !x.BuiltIn); foreach (var dataType in dataTypesUsedByDefinition) result.Dependencies.Add( new Dependency("uCommerce_DataType: " + dataType.Guid, dataType.Guid.ToString(), Providers.ItemProviderIds.ItemProviderDataTypeId)); } return result; Convert Entity to Item An ItemProvider for each type of Item you need to store Converts entity to an item, e.g. DefinitionItem : Item

48 (for .NET XML serializer)
Development BasicEventManager.SendToCache<T>() Edit/Save ItemProvider.HandlePack() DTO (for .NET XML serializer) Finally Umbraco Deploy serializes the item using XML serializer

49 <Dependencies> <Dependency>
<ProductDefinitionItem xmlns:xsi=" xmlns:xsd=" <Dependencies> <Dependency> <IsChild>false</IsChild> <ItemId> <Id>15876f1f fe6-309ed0f5fca0</Id> <ProviderId>c22fa68e a84-8cce-b94938bff51d</ProviderId> </ItemId> <Name>uCommerce_DataType: 15876f1f fe6-309ed0f5fca0</Name> <ForceHashCheck>true</ForceHashCheck> </Dependency> </Dependencies> <Id>e4e1548d-b5b9-4b28-9c12-ff847e14c69f</Id> <ProviderId>02c6f074-52ac-4c9e-8e84-3f66dd1d4051</ProviderId> <Name>MyDefinition</Name> <ItemType>Item</ItemType> <Resources /> <DefinitionName>MyDefinition</DefinitionName> <Guid>e4e1548d-b5b9-4b28-9c12-ff847e14c69f</Guid> </ProductDefinitionItem> Prduces something like this on the file system. This can then be pushed to a different environment Where the reverse process is kicked off

50 Umbraco as a Service has picked up the changes
To kick off the deployment process, hit the blue button in Umbraco as a Service

51 ItemProvider.HandleDeserialize()
Live Development Git Push ItemProvider.HandleDeserialize() DTO 1) HandleDeserialize lets you decide how to deal with the binary file 2) HandleExtract is where all the magic happens ItemProvider.HandleExtract()

52 ItemProvider.HandleDeserialize()
Live Development Git Push ItemProvider.HandleDeserialize() Magic DTO 1) HandleDeserialize lets you decide how to deal with the binary file 2) HandleExtract is where all the magic happens This is where you need to figure whether to insert/update/remove elements of the object ItemProvider.HandleExtract()

53 ItemProvider.HandleDeserialize()
Live Development Git Push ItemProvider.HandleDeserialize() DTO Deserialize is trivial ItemProvider.HandleExtract()

54 Specify Class for Deserialization
public class DefinitionsItemProvider : ItemProvider { public override Item HandleDeserialize(ItemIdentifier id, byte[] item) return Serializer.Deserialize<DefinitionItem>(item); } Specify to .NET deserializer which class to serialize as

55 ItemProvider.HandleExtract()
Live Development Git Push ItemProvider.HandleDeserialize() DTO Deserialize is trivial ItemProvider.HandleExtract()

56 Save Item to Data Store public class DefinitionsItemProvider : ItemProvider { public override Item HandleExtract(Item item) var definitionItem = item as DefinitionItem; var definition = Definition.FirstOrDefault(x => x.Guid == item.Guid) ?? new Definition { Guid = item.Guid }; UpdateDefinitionFromItem(definition, item); definition.Save(); return item; } Magic Here you need to convert the item into a form you can save somewhere For uCommerce we use our own data access layer Umbraco ships with PetaPoco if you need it All the work happens here, this is where you figure out whether to update/create/remove/delete etc Basically merge the object

57 Our definition is now present on the other environment, ready for use
It will

58

59

60 public class ProductItemResolver : PropertyDataResolverProvider
{ public override bool ShouldExecute(Item item, ItemEvent itemEvent) // Resolver executes only when packging or extracting if (!(itemEvent == ItemEvent.Extracting || itemEvent == ItemEvent.Packaging)) return false; if (item.ItemId.ProviderId == ItemProviderIds.propertyDataItemProviderGuid) var contentDataItem = (ContentPropertyData)item; return contentDataItem.Data.Any(x => x.PropertyEditorAlias == "uc.picker"); } return false; public override void Packaging(Item item)

61 public class ProductItemResolver : PropertyDataResolverProvider
{ public override void Packaging(Item item) var contentDataItem = (ContentPropertyData)item; foreach (var property in contentDataItem.Data .Where(x => x.PropertyEditorAlias == "uc.picker")) var productIds = (string)property.Value; var productIdsAsList = productIds.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList(); foreach (int productId in productIdsAsList) var guid = Product.Get(productId).Guid; item.Dependencies.Add( new Dependency( "uCommerce_Product: " + guid, guid.ToString(), Providers.ItemProviderIds.ItemProviderProductId)); }

62 ItemProvider Development ItemProvider.HandlePack() DTO
(for .NET XML serializer) And then wer’re back to ItemProviders. The same flow as before.

63 uCommerce Developer Certification Free ONLine Oct 10
We do free training. 250 developers have taken advantage of it in the last 4 months. You should too if you’re considering doing e-commerce on Sitecore ;) Business cards if you want to attend


Download ppt "Packages and your Data in Umbraco Cloud"

Similar presentations


Ads by Google