Recreate Office Web Apps // Proxy

Long time, no blog. Lots to do, and worth blogging about, but I just cannot find the time. Hopefully after March I will.

Recently at a customer I had to recreate the office web apps farm. As I have never done that before I tried naively:
Install the certificate, set the correct URLs on the server and recreate the SPWopiBindings.

Well there was a Proxy in my way, and the URL I wanted to use (spofficewebapps.customer.tld) was not in the list of exceptions.

So it didn’t work (adding the spwopibinding).


Office Web Apps Server:

$dns = "spofficewebapps.customer.tld"
set-location Cert:\LocalMachine\My
$cert = gci | ? { $_.DnsNameList.Unicode -eq $dns } | select -First 1;
$cert.FriendlyName = $dns
Set-OfficeWebAppsFarm -InternalURL "https://$dns" -ExternalUrl "https://$dns" -CertificateName "$dns"

SharePoint Server:

Remove-SPWopiBinding -All:$true -Confirm:$false
New-SPWopiBinding -ServerName "spofficewebapps.customer.tld"

What I got is that the Server was not available. Like this:
But my certificate was there, I could reach the https://spofficewebapps.customer.tld/hosting/discovery/ just fine and so none of the results from Google fit my bill.

What now? Well here is the list of remedies:
– Add the new URL to the list of Proxy exceptions
– Do not use Set-OfficeWebAppsFarm, but rather destroy and create (see below)
– Restart all servers involved

Then another thing: My servers aren’t getting the Proxy exceptions pushed. So I had to add them to Internet Explorer manually.

Good Code on Office Web Apps:

Remove-OfficeWebAppsMachine
$dns = "spofficewebapps.customer.tld"
New-OfficeWebAppsFarm -InternalUrl "https://$dns" -CertificateName "$dns" -EditingEnabled -LogLocation "D:\OWA-LOGS" -RenderingLocalCacheLocation "D:\OWA-CACHE"

So after all that I was finally able to add the office web apps back. By the way a host file entry on the SharePoint Server to the Office web apps Server DID NOT HELP.

Creating a UPA Proxy via PowerShell – technet article typo

http://technet.microsoft.com/en-us/library/ff607737.aspx

In the example it says:

$app = Get-SPServiceApplication -Name PartitionedUserProfileApplication. New-SPProfileServiceApplicationProxy -Name PartitionedUserProfileApplication_Proxy -ProfileServiceApplication $app -PartitionMode

But the Member is -ServiceApplication rather than -ProfileServiceApplication.

Tried it, worked. Keep in mind.

If they had a chance to add a comment, I would have done it there.

Kerberos

Scott Hillier says: All-in-all, Kerberos is a superior authentication mechanism and should be your first choice when deploying SharePoint 2007

Spencer Harbar says: […] how ridiculous it is to attempt to distil Kerberos for SharePoint into 3,000 words.

So Kerberos is non-trivial, but you should have a sound understanding of the matter if you want to have a sensible configuration of your farm running.

Definitely need to shape up on that…

Iteration versus Catching Expected Exceptions

Most SharePoint objects (Microsoft.SharePoint.dll) contain typed collections to store the references to other objects (example: SPList.Items is an SPListItemCollection). The problem is, that these collections implement methods for retrieving objects from these collections that throw ArgumentExceptions if the key-value (unique value: i.e. title, GUID, id, index) does not retrieve a valid element.

If you have a typical update method that has to check if the underlying object exists you will do it using one of the following two possibilities:

public static SPList GetElementTry(SPWeb web, string listName)
{
    SPList list = null;
    try 
    {
       list = web.Lists[listName];
    } 
    catch(Exception) {}
    return list;
}

public static SPList GetElementIterate(SPWeb web, string listName)
{
    SPList list = null;
    string listName = listName.ToLower();
    SPListCollection lists = web.Lists;
    foreach(SPList list in lists)
    {
        if(string.Equals(list.Title.ToLower(), listName))
        {
            return list; 
        }
    }    
    return list;
}

The problem now is: which one is better from a performance and design point of view?

I read somewhere that in Java (I used to develop in Java) if you want a basic metric (and this is a strong abstraction from reality, if it is even applicable) you can say the creation and throwing of an exception costs about 400 times more than a basic comparison (and again, please correct me if I’m wrong in this assumption).

The SharePoint magic number of storage / items / lists / objects: 2GB // 2000.

When you compare this to 400, then you will probably end up saying: I can optimize iteration a little bit so I’ll use this, because it seems more elegant, but I would rather have an internal method that does this for me and instead of throwing an exception it returns null.

Well we’re not in happy-land so you have to make a decision.

Something I would not do though is implement a method ElementExists that does the same thing as the Get-method and instead of returning null / the element it just returns true/false. You can check for null in your code instead, if you encapsulate with a boolean value you need to call your method twice. This is only sensible if you do not need to use the object further.

On how to iterate, check this blog.

The Trouble of using Constant Values

The trouble in SharePoint is that you need a lot of constant values for names of lists, fields, receivers, assemblies, groups, views and content types. Usually you define these in xml documents.

When specifying the components (lists, content types, fields, etc.) using xml you have no possibility to use variables. This is a problem as you have a lot of rework to do once you need to change something and you have a lot of references (references beeing mentions of other components at definition time. This is especially true for applications with high component coupling.

Another thing is that the possibilities for specification are limited. You cannot define lookup fields correctly as you do not know the GUID before the list and the field that are looked up exist (The GUIDs you can insert are not applicable as you would use the equivalent of a class GUID instead of the instance GUID and the instance is not yet created at definition time).

What you will do is either create a feature receiver to tidy up you definition (create remaining lookup fields programmatically using the SharePoint API) or doing the whole routine using the API inside the feature receiver. I favor this option as it reduces the redundancy, it is debuggable and easier to use (less error prone, as Visual Studio assists you). Drawback is of course that the list is not updateable using the intended Microsoft mechanism via stsadm -o upgradesolution.

As there are still some issues with this anyway (specification and deployment), SharePoint change management can be done only using the API from my point of view. So you would create a new one-shot solution containing a feature that on activation changes your application accordingly. There are certainly some issues to get into when doing this, but for SharePoint 2007 you should seriously consider this.

So at this point you are using feature receivers one way or the other for your lookup fields. So it makes sense to declare your constant values at one central point. For the start it does not matter how you do this using one giant class for each type (list, group, content type, view, etc.) or creating a class for each actual object of the sharepoint application but you should always remind yourself that it makes sense to declare variables as constants for performance issues. You should also think about how many objects you want to specify, as you will typically use these in a static context. So you use either lightweight objects, singletons, static class definitions but you definitely separate definition of these constants from your code logic.

For custom components using workflows, eventreceivers and definition of a lot of lists it especially makes sense to use this approach as you will reference your objects using the names as key-value when iterating over the collections or direct access.

The main objective is to be enable management of code that is subject to change a lot. Using redundant string values each and every time makes changing names strenuous and error-prone.