We are using v7.2.4. We bought full Courier, thinking that its API would let us write code to deploy automatically. For example, we have a scheduled task, to call URLs on our staging server to refresh lists from a database, or external RSS news, and we want to use the API to automatically deploy the updated content to our live server.
Our right-click Courier has worked well, and still works well after updating to v2.50.1forv7 (using the hotfix).
I have looked at the documentation and examples, but not even one line from various examples runs. For example:
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
Layout = null;
}
@using Umbraco.Courier.Core;
@using Umbraco.Courier.Core.Storage;
@using Umbraco.Courier.Core.Packaging;
@using Umbraco.Courier.Core.Collections.Manifests;
@{
// our inetpub/wwwroot/bin has Umbraco.Courier.Core.dll
// var rs = new Umbraco.Courier.Core.RepositoryStorage(); // doesn't work
var rs = new RepositoryStorage(); // doesn't work
// RepositoryStorage rs = new RepositoryStorage(); // doesn't work
}
gives:
Compiler Error Message: CS1729: 'Umbraco.Courier.Core.Storage.RepositoryStorage' does not contain a constructor that takes 0 arguments
Is something missing in our setup? Has anybody any code that works with v7 that would let us call Courier within the code to deploy one node of content (with no dependencies) to the live server. Or any way of calling Courier via a scheduled task to deploy a node? Thanks,
Whoah, that is some old api docs - we really need to get these updated - in the meantime, this is a sample app for running both packaging changes and deploying them:
Per are you sure that one is up to date? It's from 2013. When I was messing with it, I was having a hard time compiling it. Lots of squiggly IntelliSense lines.
As J had found with that 2013 link, we too had a hard time and lots of error lines.
My original question still stands: has anybody any code that works with v7 that would let us call Courier within the code to deploy one node of content (with no dependencies) to the live server. Or any way of calling Courier via a scheduled task to deploy a node? Thanks,
using System;
using Umbraco.Courier.Core;
using Umbraco.Courier.Core.Configuration;
using Umbraco.Courier.Core.Storage;
using Umbraco.Courier.Core.Packaging;
using Umbraco.Courier.RepositoryProviders;
namespace CourierCustom.Controllers
{
public class CourierAPIController : Controller
{
private ExecutionContext _executionContext = null;
private SettingsManager _settingsManager = null;
private string _courierConfigFilePath = "YOUR COURIER CONFIG FILE LOCATION HERE";
#region Constructor
public CourierAPIController()
{
_settingsManager = new Umbraco.Courier.Core.Configuration.SettingsManager(_courierConfigFilePath);
_executionContext = new ExecutionContext(_settingsManager);
}
#endregion
public void SampleCode()
{
var repositoryStorage = new RepositoryStorage(_executionContext);
//....
}
}
}
Now have PC capable of running Visual Studio, and with free Visual Studio Express 2015 for Web installed. I have started with Jayv's code above, and am gradually working towards a solution. I'm still confused by the lack of up-to-date documentation (and plenty of out of date documentation), and the hundreds of different Courier classes/methods visible through Visual Studio. If anyone does have a snippet for transferring a basic content item from the source to destination repositories, as defined in our courier.config file, then I'd be pleased to see it.
I worked out how to create an item identifier by joining the database uniqueID, underscore and provider ID.
var repstorage = new RepositoryStorage(_executionContext);
Repository destination = repstorage.GetByAlias("localhost");
Repository source = repstorage.GetByAlias("visualstudio");
var engine = new RevisionPackaging(_executionContext, source, destination, "myrevisionstring");
ItemIdentifier currentbydate = new ItemIdentifier("214dcebb-c472-4656-bd76-cdf33a125dc0_d8e6ad83-e73a-11df-9492-0800200c9a66"); // uniqueID of currentbydate 4168 214dcebb-c472-4656-bd76-cdf33a125dc0
engine.AddToQueue(currentbydate, false, 1);
engine.Package();
It has created a directory App_data/courier/revisions/myrevisionstring that contains a documents directory with 2 courier files, and a properties directory with 2 courier files, but engine.Package is currently giving 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.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
I downloaded a new Umbraco 7.3.0 with Courier 2.52.2 and default Fanoe starter kit into Visual Studio (source). I set up another in IIS on localhost (destination).
Using Courier through the Umbraco web front end in the usual way, Courier transfers items OK. My test page is a top level page with no child pages.
Using the API, I can create a new revision containing that page item and manifest (either by adding the item directly to the revision packaging, or to a manifest that is added to the revision packaging). However, when trying to extract the revision, it always comes back to the source "visualstudio" rather than across to the other Umbraco at "localhost80".
// want revision names to be unique and just used once
TimeSpan span = DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0));
string revision_name = "allans" + ((int)(span.TotalSeconds)).ToString();
var repositoryStorage = new RepositoryStorage(_executionContext);
Repository destination = repositoryStorage.GetByAlias("localhost80");
Repository source = repositoryStorage.GetByAlias("visualstudio");
var engine = new RevisionPackaging(_executionContext, source, destination, revision_name);
ItemIdentifier allantext = new ItemIdentifier("8f6317cb-fab4-416a-a073-9206e0a31dd0_d8e6ad83-e73a-11df-9492-0800200c9a66"); // uniqueID of allantext 8f6317cb-fab4-416a-a073-9206e0a31dd0
engine.ClearQueue();
engine.AddToQueue(allantext, 2147483647);
try
{
engine.Package();
}
catch
{
}
engine.Dispose();
Umbraco.Courier.Core.Collections.Manifests.Item allantextitem = new Umbraco.Courier.Core.Collections.Manifests.Item(allantext);
RevisionManifest rm = Umbraco.Courier.Core.Collections.Manifests.RevisionManifest.CreateFromRevisionName(revision_name);
rm.Add(allantextitem);
rm.Save();
//ExecutionContext c2 = new ExecutionContext();
//var engine2 = new RevisionExtraction(c2, source, destination, revision_name);
var engine2 = new RevisionExtraction(_executionContext, source, destination, revision_name);
engine2.ItemOverwritemode = Umbraco.Courier.Core.Enums.OverwriteMode.Always;
engine2.ResourceOverwritemode = Umbraco.Courier.Core.Enums.OverwriteMode.Always;
engine2.Extract();
engine2.Dispose();
I tried other ways:
var transfer = new RevisionTransfer(_executionContext, source, destination, revision_name);
transfer.GetRevision();
transfer.Transfer();
didn't do much.
And this
var et = new ExtractionTask(_executionContext, source, destination, revision_name);
et.OverwriteExistingitems = Umbraco.Courier.Core.Enums.OverwriteMode.Always;
et.OverwriteExistingResources = Umbraco.Courier.Core.Enums.OverwriteMode.Always;
et.Run();
et.Dispose();
also seemed to extract the revision back to source not destination.
Again, does anyone have a simple code snippet for the current Courier that transfers an item from a source Umbraco to a destination Umbraco? There are lots of samples and documents here and there for obsolete APIs. There doesn't seem to be any working example for the current Courier API. Help please.
(I also tried destinations on another server in case it was just localhost that didn't work.)
So for packaging, this would be the code I would use, this example here just bypasses the whole courier.config so you can see underlying apis for connecting to local and remote site:
using (var ctx = new ExecutionContext())
{
//save packaged data to local site
var tp = new Umbraco.Courier.RepositoryProviders.Local(ctx);
var target = new Repository(tp);
//package data from source.local
var sp = new Umbraco.Courier.RepositoryProviders.CourierWebserviceRepositoryProvider(ctx, 0, "http://source.local");
var source = new Repository(sp);
var packaging = new Umbraco.Courier.Core.Packaging.RevisionPackaging(ctx, source, target, "myrevision");
//if you want to ongoing compare if an item is needed to package, based on the state of the target
packaging.EnableInstantCompare(target);
//add a content node to the queue
packaging.AddToQueue(new ItemIdentifier("GUID", Umbraco.Courier.Core.ItemProviderIds.documentItemProviderGuid), true, int.MaxValue);
//events for ui feedback
//packaging.PackagedItem
packaging.Package();
};
using (var ctx = new ExecutionContext())
{
//extract packaged data to local site
var tp = new Umbraco.Courier.RepositoryProviders.Local(ctx);
var target = new Repository(tp);
//package data from source.local
var sp = new Umbraco.Courier.RepositoryProviders.CourierWebserviceRepositoryProvider(ctx, 0, "http://source.local");
var source = new Repository(sp);
//use either revision name or path ala c:\data\myrevision
var extraction = new Umbraco.Courier.Core.Extraction.RevisionExtraction(ctx, source, target, "myrevision");
extraction.Extract();
};
Thanks Per. Creating our extraction destination repository like in the middle lines in this example (instead of taking the destination from the config file) has fixed it.
Dlls I have referenced are Umbraco.Courier.Core, Umbraco.Courier.RepostiryProviders, Umbraco.DataLayer and Umbraco.Licensing.
Namespaces:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Umbraco.Courier.Core;
using Umbraco.Courier.Core.Collections.Manifests;
using Umbraco.Courier.Core.Configuration;
using Umbraco.Courier.Core.Extraction;
using Umbraco.Courier.Core.Packaging;
using Umbraco.Courier.Core.Storage;
Code:
private static void PackagingByPerPloug()
{
using (var ctx = new ExecutionContext())
{
//(Local does not contain a constructor that takes 1 arguments)
var tp = new Umbraco.Courier.RepositoryProviders.Local(ctx);
var target = new Repository(tp);
//(CourierWebserviceRepositoryProvider does not contain a constructor that takes 3 arguments)
var sp = new Umbraco.Courier.RepositoryProviders.CourierWebserviceRepositoryProvider(ctx, 0, "http://source.local");
var source = new Repository(sp);
//(RevisionPackaging does not contain a constructor that takes 3 arguments)
var packaging = new Umbraco.Courier.Core.Packaging.RevisionPackaging(ctx, source, target, "myrevision");
packaging.EnableInstantCompare(target);
//(Type or namespace "ItemProviderIds" missing)
packaging.AddToQueue(new ItemIdentifier("GUID", Umbraco.Courier.Core.ItemProviderIds.documentItemProviderGuid), true, int.MaxValue);
packaging.Package();
};
}
The key for packaging and extraction is to set the correct source and destination as in theory courier can run outside of both of these sites (as a console app for instance) or on one of them
So as a console app you could connect to one remote source and and compare the packaged data to another remote source.
Or run it on one site, given the local repository provider, it will package to the local filesystem and can compare to the state of that.
Courier API
We are using v7.2.4. We bought full Courier, thinking that its API would let us write code to deploy automatically. For example, we have a scheduled task, to call URLs on our staging server to refresh lists from a database, or external RSS news, and we want to use the API to automatically deploy the updated content to our live server.
Our right-click Courier has worked well, and still works well after updating to v2.50.1forv7 (using the hotfix).
I have looked at the documentation and examples, but not even one line from various examples runs. For example:
gives: Compiler Error Message: CS1729: 'Umbraco.Courier.Core.Storage.RepositoryStorage' does not contain a constructor that takes 0 arguments
Is something missing in our setup? Has anybody any code that works with v7 that would let us call Courier within the code to deploy one node of content (with no dependencies) to the live server. Or any way of calling Courier via a scheduled task to deploy a node? Thanks,
Hi Allan
Whoah, that is some old api docs - we really need to get these updated - in the meantime, this is a sample app for running both packaging changes and deploying them:
https://github.com/umbraco/Courier/blob/master/Samples/Umbraco.Courier.ExtractionConsole/Program.cs
The classes and namespaces used are the ones we recommend to use (and use ourselves as well)
Thanks Per
We too have had difficulty with the sample you provided, including the read only error that J posted, and lots of other lines.
Per are you sure that one is up to date? It's from 2013. When I was messing with it, I was having a hard time compiling it. Lots of squiggly IntelliSense lines.
Example:
As J had found with that 2013 link, we too had a hard time and lots of error lines.
My original question still stands: has anybody any code that works with v7 that would let us call Courier within the code to deploy one node of content (with no dependencies) to the live server. Or any way of calling Courier via a scheduled task to deploy a node? Thanks,
Sample code
}
Now have PC capable of running Visual Studio, and with free Visual Studio Express 2015 for Web installed. I have started with Jayv's code above, and am gradually working towards a solution. I'm still confused by the lack of up-to-date documentation (and plenty of out of date documentation), and the hundreds of different Courier classes/methods visible through Visual Studio. If anyone does have a snippet for transferring a basic content item from the source to destination repositories, as defined in our courier.config file, then I'd be pleased to see it.
I worked out how to create an item identifier by joining the database uniqueID, underscore and provider ID.
It has created a directory App_data/courier/revisions/myrevisionstring that contains a documents directory with 2 courier files, and a properties directory with 2 courier files, but engine.Package is currently giving an error
- I'll continue on Monday
I downloaded a new Umbraco 7.3.0 with Courier 2.52.2 and default Fanoe starter kit into Visual Studio (source). I set up another in IIS on localhost (destination).
The Courier config contains
Using Courier through the Umbraco web front end in the usual way, Courier transfers items OK. My test page is a top level page with no child pages.
Using the API, I can create a new revision containing that page item and manifest (either by adding the item directly to the revision packaging, or to a manifest that is added to the revision packaging). However, when trying to extract the revision, it always comes back to the source "visualstudio" rather than across to the other Umbraco at "localhost80".
I tried other ways:
didn't do much.
And this
also seemed to extract the revision back to source not destination.
Again, does anyone have a simple code snippet for the current Courier that transfers an item from a source Umbraco to a destination Umbraco? There are lots of samples and documents here and there for obsolete APIs. There doesn't seem to be any working example for the current Courier API. Help please.
(I also tried destinations on another server in case it was just localhost that didn't work.)
Hi Allan
So for packaging, this would be the code I would use, this example here just bypasses the whole courier.config so you can see underlying apis for connecting to local and remote site:
For extraction:
Thanks Per. Creating our extraction destination repository like in the middle lines in this example (instead of taking the destination from the config file) has fixed it.
Which DLLs am I to use? I've tried the 2013 DLLs found here https://github.com/umbraco/Courier/tree/master/Samples/Umbraco.Courier.ExtractionConsole/bin/Debug (the most recent I could find) but they're not compatible with your code.
Dlls I have referenced are Umbraco.Courier.Core, Umbraco.Courier.RepostiryProviders, Umbraco.DataLayer and Umbraco.Licensing.
Namespaces:
Code:
The key for packaging and extraction is to set the correct source and destination as in theory courier can run outside of both of these sites (as a console app for instance) or on one of them
So as a console app you could connect to one remote source and and compare the packaged data to another remote source.
Or run it on one site, given the local repository provider, it will package to the local filesystem and can compare to the state of that.
Same goes for extraction.
Hope that helps
is working on a reply...