I'm building a collection of sites that share content. Part of the requirements were that there would only be one central location where data was to be stored, so one of the implementations we are investigating is having Courier on the data store, and having the sites set up as repos for the data to be transferred to.
The normal Courier dialogues only allow for data to be transferred to one repo at a time (picked from the dropdown), so I am making several assumptions here:
I can call the API to loop through all the repos registered in the source Umbraco installation, and call the transfer method for each of them, and that would be best practice.
Courier will overwrite property values on the destination environments with the ones from the source environment
I have several questions:
I would much rather override the normal Courier deploy dialogue, and have a checkbox list instead of the dropdown that is presented by default. However, I don't know what methods are being called in that particular dialogue - am I right in thinking I should be doing this by creating my own dialogue, replacing the right clcik menu action on the Courier item and loading my dialogue in at that point?
If so, what are the correct methods to call in order to compare, package and deploy an item? The Developers document dates from 2011 and only has a list of all the events I can subscribe to, but not of the methods I can call. Is there an updated API document somewhere, that I am missing?
Is there a flag I can set in order to tell Courier to override information when transferring? For example, if I'm transferring over Page 1 from source to destination 1, and destination 1 already has a Page 1, the values of the source one will override the ones on the destination.
Finally, by default courier will overwrite property values, so you should not need to do this, however, if you do, I would recommend you used a data resolver
Finally, you might want to trigger events at certain points in the extraction, like when things have completed, the db connection is closed, or all files have been transfered, then you need even event provider:
Hi Per, and thanks for the extra info - it's very helpful. I'd just need some more information, to confirm I'm going the right way here.
I've created a new right click context menu item in Umbraco, that posts to an .aspx page I created. On the page itself, I'm presenting all the available repos and allowing the user to check where they should go.
In code, I'm creating a new RepositoryStorage variable for each repo alias, and a RevisionPackaging where I pass in the destination and a revision name as parameters.
var rs = new RepositoryStorage();
var destination = rs.GetByAlias(repoAlias);
var engine = new RevisionPackaging(destination, revisionName);
engine.EnableInstantCompare(destination);
var itemIdentifier = new ItemIdentifier("DocumentGuid", ProviderIDCollection.documentItemProviderGuid);
engine.AddToQueue(itemIdentifier, true, 3);
however, no revision seems to be getting created in App_Data/Courier/Revisions, and debugging seems to indicate only that item gets added to the queue, and none of its dependencies. Do I have to create a new itemIdentifier for every different item I want to package, and if so, how can I check for dependencies using the Courier API(for example, check for a document's template, attached media items, macros used in the template, etc).
Also, calling engine.Package() at the end of that code block throws an error -
System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://courier.umbraco.org/SaveResourceContents. at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest() at System.Web.Services.Protocols.SoapServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
Could you post the configuration of the destination repo? seems like there is no webservice endpoint to receive calls, also, if you should be able to just create a new packaging without a destination, which should then just store your items on the local site
The endpoint is there, as the normal courier transfer works. What I'd like to know is the various methods to call if, for example:
I want to transfer an Umbraco document and its associated properties (including some custom datatypes - I am assuming I need to write a custom provider for those)
I want to transfer an Umbraco document, all its children and their associated properties
I want to compare the current document in my source environment to the same document in a repo.
Going through the examples you've kindly provided so far, the workflow Courier follows seems to be:
assign a unique ItemIdentifier to the Umbraco Item being transferred(media or content)
figure out the correct provider based on the item identifier
figure out dependencies
create the manifest
package items according to the manifest
transfer the archive via the webservice
unpack it on the source
deploy everything in the correct places following the info stored in the manifest.
However, I'm a bit of a loss as to how that takes place, as the ItemIdentifier seems to be allocated by the provider, and the provider requires an ItemIdentifier - which puts me in a bit of a vicious circle. I'm sure I'm missing something :)
var engine = new RevisionPackaging(Revision);
//get a specific provider
var provider = Umbraco.Courier.Core.ProviderModel.ItemProviderCollection.Instance.GetProvider("DocumentItemProvider");
//get root items
provider.AvailableSystemItems();
//get childitems
var rootItem = provider.AvailableSystemItems()[0];
var childrenOfRoot = provider.AvailableSystemItems(rootItem.ItemId);
//get a specific provider id
var guid = Umbraco.Courier.ItemProviders.ProviderIDCollection.documentItemProviderGuid;
//add one document + children and unlimited dependencies
engine.AddToQueue(rootItem.ItemId, true, -1);
engine.Package();
Notice the engine doesnt have a source or destination, in that case it will just default to local site, if you set a destination, it will try to transfer and store the revision files on that site.
If you want to compare against a site, you add the instantcompare option, like you have in your code.
There is a sample project here, which contains tasks for nant, which shows this is a broader picture (note, for some odd reason it contains some DIFF markup)
If I create a RevisionPackaging with only the revision name as a parameter, everything works fine. A Revision gets created on my source repo fine. However, when I add a destination, I get that SOAP error I pasted above. I don't know what causes that.
I looked at the courier.config files and they all have the correct references; the admin credentials are correct as well. Looking at the error though, it's almost like it's expecting the request to come from the http://courier.umbraco.org/ namespace. is there a requestnamespace being set, and might that possibly interfere with the API being called from another namespace?
The courier.umbraco.org namespace is registered in the webservice, seems like the client and service method signature is out of sync, I've logged in as a bug for now, since it is not within the scope of the next release to get this fixed.
I would recommend you perform packaging against the local site and then transfer the result afterwards, instead of packging a site and imediately transfer its parts to an external site.
Courier and multiple repo transfers
I'm building a collection of sites that share content. Part of the requirements were that there would only be one central location where data was to be stored, so one of the implementations we are investigating is having Courier on the data store, and having the sites set up as repos for the data to be transferred to.
The normal Courier dialogues only allow for data to be transferred to one repo at a time (picked from the dropdown), so I am making several assumptions here:
I have several questions:
To do this, you need to script your own packaging and extraction, so 2 steps:
1. Collect all the items you need in a revision, aka. packaging.
https://github.com/umbraco/Courier/blob/master/Documentation/Developer%20Documentation/Packaging%20and%20Extraction/Packaging.md
2. Deploy the items to any number of target sites, aka extraction
https://github.com/umbraco/Courier/blob/master/Documentation/Developer%20Documentation/Packaging%20and%20Extraction/Extracting.md
Finally, by default courier will overwrite property values, so you should not need to do this, however, if you do, I would recommend you used a data resolver
https://github.com/umbraco/Courier/blob/master/Documentation/Developer%20Documentation/Data%20Resolvers.md
Finally, you might want to trigger events at certain points in the extraction, like when things have completed, the db connection is closed, or all files have been transfered, then you need even event provider:
https://github.com/umbraco/Courier/blob/master/Documentation/Developer%20Documentation/Event%20Providers.md
Hi Per, and thanks for the extra info - it's very helpful. I'd just need some more information, to confirm I'm going the right way here.
I've created a new right click context menu item in Umbraco, that posts to an .aspx page I created. On the page itself, I'm presenting all the available repos and allowing the user to check where they should go.
In code, I'm creating a new RepositoryStorage variable for each repo alias, and a RevisionPackaging where I pass in the destination and a revision name as parameters.
however, no revision seems to be getting created in App_Data/Courier/Revisions, and debugging seems to indicate only that item gets added to the queue, and none of its dependencies. Do I have to create a new itemIdentifier for every different item I want to package, and if so, how can I check for dependencies using the Courier API(for example, check for a document's template, attached media items, macros used in the template, etc).
Also, calling engine.Package() at the end of that code block throws an error -
System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: http://courier.umbraco.org/SaveResourceContents.
at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
Any ideas?
Could you post the configuration of the destination repo? seems like there is no webservice endpoint to receive calls, also, if you should be able to just create a new packaging without a destination, which should then just store your items on the local site
Hi Per,
The endpoint is there, as the normal courier transfer works. What I'd like to know is the various methods to call if, for example:
Going through the examples you've kindly provided so far, the workflow Courier follows seems to be:
However, I'm a bit of a loss as to how that takes place, as the ItemIdentifier seems to be allocated by the provider, and the provider requires an ItemIdentifier - which puts me in a bit of a vicious circle. I'm sure I'm missing something :)
I've attached the courier.config as well: http://pastebin.com/WbsxUGf8
Exemple:
Notice the engine doesnt have a source or destination, in that case it will just default to local site, if you set a destination, it will try to transfer and store the revision files on that site.
If you want to compare against a site, you add the instantcompare option, like you have in your code.
There is a sample project here, which contains tasks for nant, which shows this is a broader picture (note, for some odd reason it contains some DIFF markup)
https://github.com/umbraco/Courier/tree/master/Samples/Courier.Tasks
That was really helpful. Thank you!
If I create a RevisionPackaging with only the revision name as a parameter, everything works fine. A Revision gets created on my source repo fine. However, when I add a destination, I get that SOAP error I pasted above. I don't know what causes that.
I looked at the courier.config files and they all have the correct references; the admin credentials are correct as well. Looking at the error though, it's almost like it's expecting the request to come from the http://courier.umbraco.org/ namespace. is there a requestnamespace being set, and might that possibly interfere with the API being called from another namespace?
Hi Andrei
The courier.umbraco.org namespace is registered in the webservice, seems like the client and service method signature is out of sync, I've logged in as a bug for now, since it is not within the scope of the next release to get this fixed.
I would recommend you perform packaging against the local site and then transfer the result afterwards, instead of packging a site and imediately transfer its parts to an external site.
/per
is working on a reply...