<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Chris Weldon]]></title>
  <link href="http://www.chrisweldon.net/atom.xml" rel="self"/>
  <link href="http://www.chrisweldon.net/"/>
  <updated>2014-08-25T03:02:40+00:00</updated>
  <id>http://www.chrisweldon.net/</id>
  <author>
    <name><![CDATA[Chris Weldon]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[On Helpers and the Use of Static]]></title>
    <link href="http://www.chrisweldon.net/blog/2014/03/03/on-helpers-and-the-use-of-static/"/>
    <updated>2014-03-03T05:08:21+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2014/03/03/on-helpers-and-the-use-of-static</id>
    <content type="html"><![CDATA[<p>One of my most recent interactions with several of my colleagues has been over best practices within software development. More specifically, the idea of static classes, static methods, and helper classes. It was a healthy debate with different view points. Some believe that static methods are perfectly fine for development. Others feel that helper classes provide unity to certain practices such as database access. Generally, however, I believe static and helper classes are an anti-pattern and lead to less maintainable code. This post is an expression of why I believe this to be the case. None of the code samples are actual snippets on real projects. They are paraphrased instances of practices I&rsquo;ve seen on a myriad of past projects.</p>

<!--more-->


<h2>So, why are statics bad? </h2>

<p>I&rsquo;m a huge fan of automated testing. I started with unit tests, but have recently moved into the realm of behavior tests. Yet, for any automated testing, you have to have good architecture in your code to ensure that you <em>can</em> test in any environment.</p>

<p>Let me give the most basic example: the use of a logging facility. Take for example the following loggger that I see all too often:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">LoggingHelper</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">LogMessage</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">area</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">logPath</span> <span class="p">=</span> <span class="n">Constants</span><span class="p">.</span><span class="n">LogPath</span><span class="p">;</span>
</span><span class='line'>        <span class="k">using</span> <span class="p">(</span><span class="n">StreamWriter</span> <span class="n">writer</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">File</span><span class="p">.</span><span class="n">AppendText</span><span class="p">(</span><span class="n">logPath</span><span class="p">))</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">writer</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;INFO\t[&quot;</span> <span class="p">+</span> <span class="n">area</span> <span class="p">+</span> <span class="s">&quot;]&quot;</span> <span class="p">+</span> <span class="n">message</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">LogError</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">area</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">logPath</span> <span class="p">=</span> <span class="n">Constants</span><span class="p">.</span><span class="n">LogPath</span><span class="p">;</span>
</span><span class='line'>        <span class="k">using</span> <span class="p">(</span><span class="n">StreamWriter</span> <span class="n">writer</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">File</span><span class="p">.</span><span class="n">AppendText</span><span class="p">(</span><span class="n">logPath</span><span class="p">))</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">writer</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;ERROR\t[&quot;</span> <span class="p">+</span> <span class="n">area</span> <span class="p">+</span> <span class="s">&quot;]&quot;</span> <span class="p">+</span> <span class="n">message</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">LogException</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">area</span><span class="p">,</span> <span class="n">Exception</span> <span class="n">exception</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">logPath</span> <span class="p">=</span> <span class="n">Constants</span><span class="p">.</span><span class="n">LogPath</span><span class="p">;</span>
</span><span class='line'>        <span class="k">using</span> <span class="p">(</span><span class="n">StreamWriter</span> <span class="n">writer</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">File</span><span class="p">.</span><span class="n">AppendText</span><span class="p">(</span><span class="n">logPath</span><span class="p">))</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">writer</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;EXCEPTION\t[&quot;</span> <span class="p">+</span> <span class="n">area</span> <span class="p">+</span> <span class="s">&quot;]&quot;</span> <span class="p">+</span> <span class="n">message</span> <span class="p">+</span> <span class="s">&quot; - &quot;</span> <span class="p">+</span> <span class="n">exception</span><span class="p">.</span><span class="n">Message</span><span class="p">);</span>
</span><span class='line'>            <span class="n">writer</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;Stack Trace&quot;</span> <span class="p">+</span> <span class="n">exception</span><span class="p">.</span><span class="n">StackTrace</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here are a few areas the above code block can improve:</p>

<ul>
<li>There&rsquo;s no exception handling. At all.</li>
<li>There&rsquo;s no mutexes/resource locking. Thus, it&rsquo;s possible for multiple threads to attempt to open the file at the same time. The first one in will succeed. All others will throw exceptions.</li>
<li>It&rsquo;s insanely duplicative. In fact, I was able to copy every line of <code>LogMessage</code> to <code>LogError</code> and only have to change 2 lines of code. The same goes for <code>LogException</code>, where I also added an additional line.</li>
<li>What happens when I have another type of message I need to log? That means I must add another method - 6 of those lines likely the same as <code>LogMessage</code>.</li>
<li>What happens when I need to change the location of the log file?</li>
<li>What happens when I need to change the underlying facility for logging? Say, from files to databases?</li>
</ul>


<p>The last two are key here. For the first, I can change from <code>Constants.LogPath</code> to something like <code>ConfigurationManager.AppSettings["LogPath"]</code>, But what happens when the file is a network file system? Not accessible via standard UNC paths? You&rsquo;re up a creek and this <em>entire class</em> needs to change. That&rsquo;s pretty much the case of the second question.</p>

<p>You should assume that your underlying logging destination can <strong>and will</strong> change at any time. If you think that the simple solution to this is to simply change the <code>LoggingHelper</code> class, think again. Let&rsquo;s take this further. You should assume that your destination will be different for <strong>multiple scenarios</strong>. In enterprise development, this is frequently the case. In a pre-integration environment, you may only want to log to the filesystem because it may be a single server. However, in integration and production you might choose to log to a database since you&rsquo;re deploying to a farm of servers and writing to the filesystem makes diagnosing problems a true headache.</p>

<p>Back to the problem of automated testing, you don&rsquo;t really want any logging. Why? What happens when your test runner doesn&rsquo;t have access to the logging path? What happens when your test environment doesn&rsquo;t have the path at all? What happens when you forget you have your test environment dumping massive amounts of logs to the filesystem only to go on a goose chase figuring out why your builds randomly started to fail due to the disk being full? In the case of unit testing, <code>/dev/null</code> should be your destination.</p>

<p>Let&rsquo;s consider one last secenario: what happens if you want to log to multiple facilities at once?</p>

<p>In any of those cases, using a static class with static methods does not afford you <strong>any</strong> flexibility. If you want to expand to multiple logging facilities, you would be forced to create another static class. That class is now called in addition to this one. Yuck.</p>

<p>Here&rsquo;s where I come back to the <a href="3">SOLID principles</a>. Let&rsquo;s look at how Static classes (and static methods) violate these principles.</p>

<ul>
<li>Open/Closed Principle - Classes should be open for extension, but closed for modification.

<ul>
<li>With statics, you <strong>cannot</strong> extend and override the behavior. You throw out the idea of polymorphism. This makes it <del>very difficult</del> impossible for me to inject different behaviors for whatever need I may have.</li>
</ul>
</li>
<li>Dependency Inversion Principle - Depend upon Abstractions. Do not depend upon concretions.

<ul>
<li>With statics, every class that leverages its facilities are now dependent upon a concretion. There is no way to pass around an abstraction of a static class or regular class with static methods. Your only way of doing this is with reflection and that&rsquo;s a definite code smell.</li>
</ul>
</li>
</ul>


<p>In summary, because I cannot leverage the power of inheritance, polymorphism, or really any aspect of object oriented analysis and design with <code>statics</code>, it feels a lot like procedural programming. I suggest leaving this practice behind.</p>

<h2>So, why are helpers bad?</h2>

<p>My discussion with my colleagues yielded an interesting observation: everyone&rsquo;s opinion of a helper was slightly different. One thought of it as a single data access layer. Another thought of it as a way of providing consistent authentication for data access. But others think of helpers as the giant &ldquo;I don&rsquo;t know where to stick this method&rdquo; bucket. So, you end up with something like this (methods only, since that should convey what I&rsquo;m getting at):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">Utils</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="kt">string</span> <span class="nf">CleanInput</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">FlushCacheIndex</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="kt">bool</span> <span class="nf">CheckIfSystemIsHealthy</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="kt">int</span> <span class="nf">GetCountOfActiveUsers</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="n">MyModel</span> <span class="nf">CreateModelFromInput</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">,</span> <span class="kt">string</span> <span class="n">email</span><span class="p">,</span> <span class="kt">int</span> <span class="n">age</span><span class="p">,</span> <span class="n">DateTime</span> <span class="n">birthday</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>These types of helpers are a maintainability nightmare. For starters, if you haven&rsquo;t read my section above on why statics are bad, step back and read it. Both SOLID principles are still violated. Yet, there are also a couple of others that are violated.</p>

<ul>
<li>Single Responsibility Principle - A class should have only one reason to change.

<ul>
<li>It&rsquo;s clear in the case above that there are multiple reasons this class exists. However, there are other helper classes (such as <code>StringUtils</code> which are not as clear. However, I&rsquo;m still a firm believer that the Open/Closed Principle dictates whether to add yet another method to an existing class, or create a separate class. I&rsquo;m a huge fan of small classes as their much easier to test and maintain.</li>
</ul>
</li>
<li>Interface Segregation Principle - Many client-specific interfaces are better than one general-purpose interface.

<ul>
<li>Okay, so this isn&rsquo;t an interface. ISP is definitely meant for solving another problem. However, the basics behind this principle apply here. This is a general-purpose class. Why should I have my code <strong>strongly-coupled</strong> to this class if all I need is one method within it?</li>
</ul>
</li>
</ul>


<p>Now, to tackle some of the other arguments in favor of helper classes, let&rsquo;s look at another example I&rsquo;ve seen in the past:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">DatabaseHelper</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="k">static</span> <span class="n">DataAccessObject</span> <span class="n">daoInstance</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="n">DataAccessObject</span> <span class="nf">CreateDataAccessObject</span><span class="p">(</span><span class="n">User</span> <span class="n">invokingUser</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">daoInstance</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="kt">var</span> <span class="n">dao</span> <span class="p">=</span> <span class="k">new</span> <span class="n">DataAccessObject</span><span class="p">();</span>
</span><span class='line'>            <span class="n">dao</span><span class="p">.</span><span class="n">AuthenticationMode</span> <span class="p">=</span> <span class="n">AuthenticationModes</span><span class="p">.</span><span class="n">Shared</span><span class="p">;</span>
</span><span class='line'>            <span class="n">dao</span><span class="p">.</span><span class="n">Credentials</span> <span class="p">=</span> <span class="k">new</span> <span class="n">DataAccessCredentials</span><span class="p">(</span><span class="n">invokingUser</span><span class="p">.</span><span class="n">Kerberos</span><span class="p">,</span> <span class="n">invokingUser</span><span class="p">.</span><span class="n">Token</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">dao</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">daoInstance</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Ah, rather than a helper, you meant a factory. Okay, I can dig that&hellip;sorta. We&rsquo;re still using <code>static</code> here, which makes it impossible for me to factorize the creation of my DAO without strongly coupling my business logic to this <em>specific</em> class. Now, a factory is meant to abstract away the details of creating an object of a specific type. There&rsquo;s some generally common expected inputs, and you get a generic implementation at the output. But, how should you go about doing that?</p>

<p>If you&rsquo;re using a proper dependency injection/Inversion of Control container, you&rsquo;ll be able to configure your application instance to inject a provider which implements the following interface:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">DataAccessFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">DataAccessObject</span> <span class="nf">CreateDataAccessObject</span><span class="p">(</span><span class="n">User</span> <span class="n">invokingUser</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Furthermore, if you&rsquo;re in a spot where you need a singleton instance of the <code>DataAccessObject</code>, then you can make sure that you implement the appropriate logic in your Factory instance <strong>and</strong> setup your IoC container to maintain a singleton instance of the object.</p>

<p>When discussing the use of &ldquo;helper&rdquo; classes, it&rsquo;s more difficult to outright say they aren&rsquo;t useful, because each person&rsquo;s definition of helper classes are different. Nevertheless, if you venture down the path of bucket &ldquo;utility&rdquo; classes, stop. There are better approaches you can take.</p>

<h2>Well, I still don&rsquo;t agree with you&hellip;</h2>

<p>That&rsquo;s fine. You&rsquo;re entitled to your opinion. Just don&rsquo;t expect for me to pass your code reviews.</p>

<p>Are there circumstances where the use of a static method might be worth it? Quite possibly. But I rarely encounter those cases. If one of those reasons is &ldquo;it&rsquo;s faster to do it with a static than via good architecture&rdquo; then you&rsquo;re just being lazy. Yes, software development is about delivering value. However, what debt you introduce to the system must later be addressed save you be unable to deliver any value once you&rsquo;ve built a castle with no doors <strong>around you</strong>.</p>

<p>I&rsquo;m not alone in this. Check out just a few other blogs which carry several really good arguments against the use of statics or helpers:</p>

<ul>
<li><a href="http://lostechies.com/chrismissal/2009/06/01/anti-patterns-and-worst-practices-utils-class/">Anti-patterns and Worst Practices - Utils Classes</a></li>
<li><a href="http://oo-programming.blogspot.com/2009/06/util-classes-must-die.html">Util Classes Must Die</a></li>
<li><a href="http://blogs.msdn.com/b/nickmalik/archive/2005/09/06/461404.aspx">Are Helper Classes Evil?</a></li>
<li><a href="http://blogs.msdn.com/b/elee/archive/2009/05/05/helper-classes-are-evil.aspx">Helper Classes are Evil</a></li>
</ul>


<h2>Where did you shape your thoughts on best practices? </h2>

<p>In my previous role at <a href="2">Improving Enterprises</a>, there were a number of really talented technologists, passionate about best practices. They were staunch supporters of user groups and community as well. Thus, my opinions on best practices have been shaped not only through previous co-workers and colleagues, but also by community.</p>

<p>Community has a lot of benefits, and has a lot of diversity of thought. The software community provides an atmosphere for technologists to actively try many of the best practices they preach through katas, discussions, pull requests, and many other channels. These best practices are most commonly focused around the use of patterns. Why reinvent the wheel when patterns exist to help solve the same or similar problems? However, these patterns often have justifiable use: they leverage the facets of object oriented languages in the manner they were <em>expected</em> to be used.</p>

<p>This is where I started to learn about best practices. My source of community was extremely diverse. It included my colleagues at work, my close developer friends, and those technologists in the community who were extremely passionate about their work. Some of these technologists I engaged only through user groups, some through their blogs, and some through discussion boards. I am a high achiever, and in order for me to achieve, I must learn - so I am always on a continuous search for new information - even if it contradicts previous thoughts or practices I held imporant to me.</p>

<p>Finally, the only other way to really learn and solidify the importance of a best practice is to, well, <strong>practice</strong> it. With enough practice, you&rsquo;ll invariably run into other practices which box you into a corner or make your life <em>very</em> difficult. The more times you encounter these situations, the greater a believer in best practices which leverage the power of object oriented design and development.</p>

<p>Diversity of thought is a great practice and should be encouraged. It leads to more out-of-the-box thinking, approaches to problems, and ensures that all risks are vocalized. However, one of the most important things I&rsquo;ve had to learn is that no matter what, diversity of thought should always be supported with sound reason and justification. Simply citing a preference to a mode of practice, idea, or solution without good justification to a practice is hard to accept in a professional setting.</p>

<p>  [2] <a href="http://www.improvingenterprises.com/">http://www.improvingenterprises.com/</a>
  [3] <a href="http://en.wikipedia.org/wiki/SOLID_">http://en.wikipedia.org/wiki/SOLID_</a>(object-oriented_design)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Communication Brevity]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/11/26/brevity/"/>
    <updated>2013-11-26T18:50:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/11/26/brevity</id>
    <content type="html"><![CDATA[<p>Let&rsquo;s talk about something I really don&rsquo;t like: e-mail. Let me clarify this by saying I <em>loathe</em> e-mails on <strong>team</strong> projects. Why? Persistence. Conversations via e-mail have this perception they will be &ldquo;found&rdquo; at a later time, but the proposed value is rarely so useful. Furthermore, new team members or collaborators <em>rarely</em> ever get that context, because it&rsquo;s buried in <strong>another</strong> person&rsquo;s e-mail. This is my approach to how teams should communicate to ensure longevity of this critically important information.</p>

<!--more-->


<p>I&rsquo;m a huge fan of the <a href="http://blogs.atlassian.com/2009/01/2009_email_brev/">e-mail brevity challenge</a>. The idea is simple: keep your e-mails short. 140 characters short. What this limits you to do is <strong>huge</strong>. Do you think you can have technical design discussions with 140 characters? What about researching technical support problems? How about product feature ideas? Clarifying how your team came to the conclusion to disable a feature due to security constraints? You might be able to do this in a bunch of 140 character e-mails, but that&rsquo;s hardly a good use of time.</p>

<h1>The Problem</h1>

<p>For those examples I listed above, how important is it to your team to find that information now or three years from now? Let&rsquo;s face it - most teams undergo turnover at some point and with some degree of variability. Those whom are left find themselves struggling to find the context - the <em>why</em> - beind a particular decision. This becomes more evident the longer time passes since a decision was made.</p>

<p>We have this problem now. I am considering simplifying a system we have currently. Yet, I can&rsquo;t find any context to understand why the system is currently so complex. Everyone agrees there <strong>should</strong> be a reason, but nobody knows <em>why</em> that reason is. The <strong>how</strong> of the system was perfectly documented, but the <em>why</em> was not. If current (and former) history are any sign, it&rsquo;s likely the conversation of <em>why</em> has been lost somewhere along the way.</p>

<h1>The Solution</h1>

<p>As previously indicated, expressing yourself via e-mail in 140 characters or less is hard. You want to know what isn&rsquo;t hard to express under that constraint? A URL.</p>

<p>The solution to this problem is easy. If you shift your conversation online, its longevity or persistance is no longer tied to the life of someone&rsquo;s inbox. We have what we call a &ldquo;posting&rdquo; culture at the firm - a process to keep as many people who are directly involved or <em>may</em> be involved informed about the progress of our work. However, doing so via e-mail is laborious, especially if you leave out a stakeholder. However, if the conversation is non-private, having that conversation on an online social platform enables those stakeholders to opt-in to your updates. They can sit on the sidelines watching the activity, or if they see something that requires their intervention, they can take charge and engage in the conversation.</p>

<p>But what about private conversations? Most social platforms have the capability for engaging in private conversation. Whether this be through closed collaboration/team rooms or direct messages between you and another user. However, once decisions have been made, it becomes easy to promote the relevant pieces of those conversations from private to public - it&rsquo;s already online.</p>

<h1>Additional Benefits</h1>

<p>The problems of traditional e-mail go beyond simply lack of context. Many corporate e-mail platforms <strong>still</strong> don&rsquo;t provide metadata tagging. Searching for e-mail means you search conversations only <em>you</em> were directly involved. Being able to keep track of the conversation thread is dismal with our tools - only a few e-mail clients (and only very recently) are able to present conversations in threaded views. Most people <strong>still</strong> don&rsquo;t know those features exist! Finally, collboration on documents still happens by shipping them via e-mail. Which is the authoritative <em>final</em> version? Finally, what <strong>was</strong> the final decision of that chain of e-mails about how to proceed on our design?</p>

<p>Moving the conversation online to social platforms opens up many other benefits. Tagging (primarily #tags, pronounced as hashtags) are in most platforms. For those not familiar, tagging content with certain keywords enables easier discoverability. When you search for relevant conversations using those keywords, the search engine considers tagged posts more relevant than posts having those words somewhere in the document. A human made the decision that keyword pertains to this conversation, rather than that word being used in a conversation about something completely different. Search is also enhanced as you&rsquo;re now searching all <em>open</em> and <strong>public</strong> conversations, broadening your search potential.</p>

<p>Being able to follow conversations is much easier. Threaded views enable clear visibility and understanding of the flow of conversations. Furthermore, most social platforms (especially in the Q&amp;A space) have options for marking something as a &ldquo;correct&rdquo; or &ldquo;most helpful&rdquo; answer. Leveraging these same features, even for team discussions accomplishes two things:</p>

<ul>
<li>You know exactly which decision was made, even when the content indicating that a decision had been made was unclear.</li>
<li>You have all of the conversation surrounding why that decision was made.</li>
</ul>


<p>Finally, when it comes to sharing and collaborating on content, like Word/Excel/PowerPoint documents, moving that online and providing a <em>single</em> authoritative source for the document reduces confusion on which is the final version and the final copy.</p>

<h1>Give it a Try</h1>

<p>Don&rsquo;t wait. Force yourself into this model. It will be hard - you&rsquo;ll want to revert back to your old ways of typing lengthy e-mails and using distribution lists. When you find yourself writing even just <strong>two</strong> sentences in an e-mail: stop. Immediately move to your online space and continue. Don&rsquo;t be tempted to reply in e-mail to someone sending you the link to the topic thread they started online - keep the conversation where it originated! But move it online if it started in e-mail!</p>

<p>While your team starts adopting this pattern of communication, you&rsquo;ll see some short-term gains (like discoverability, transparency, clarity of decisions, inclusion, etc.). However, this is all about the long-term gains your team will have. The more content you push online, the better it will be for your team when it comes to retaining critical information. It <em>will</em> be worth it!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SharePoint 2013 My Site Timer Jobs Missing]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/08/02/sharepoint-2013-my-site-timer-jobs-missing/"/>
    <updated>2013-08-02T15:07:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/08/02/sharepoint-2013-my-site-timer-jobs-missing</id>
    <content type="html"><![CDATA[<p>The way My Sites are created in SharePoint 2013 is vastly different from SharePoint 2010, but for good reason. I won&rsquo;t go into the details of how it&rsquo;s changed, as Wictor Wilen has done an <em>excellent</em> job of this already in his blog post <a href="http://www.wictorwilen.se/sharepoint-2013-personal-site-instantiation-queues-and-bad-throughput">SharePoint 2013: Personal Site Instantiation Queues and Bad Throughput</a>. I encountered problems with a new development workstation not setting up My Sites for users appropriately - blocking us from testing our solution, which was dependent upon a user having a My Site. In looking online (and in Wictor&rsquo;s blog post), everything was pointing to checking the following three timer jobs:</p>

<ul>
<li>My Site Instantiation Interactive Request Queue</li>
<li>My Site Instantiation Non-Interactive Request Queue</li>
<li>My Site Second Instantiation Interactive Request Queue</li>
</ul>


<p>The problem is, those timer jobs were missing from my server!</p>

<!--more-->


<p>I checked for the timer jobs first through Central Administration, and then subsequently thru PowerShell. The following are the results I found:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Get-SPTimerJob | sort Name | ft Name</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/01-missing-timerjobs.png" title="Timer Jobs Missing" ></p>

<p>I decided to check for the My Site timer jobs on a know working SharePoint 2013 farm. Sure enough, they were there:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/02-present-timerjobs.png" title="Timer Jobs Present on Farm" ></p>

<p>I wanted to look for a way to re-register timer jobs. There should be no reason for me to do something drastic like uninstall/reinstall the User Profile Service just to get the timer job re-registered. This timer job, as expected, was in the <code>Microsoft.Office.Server.UserProfiles</code> assembly:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/03-timerjob-definition.png" title="Timer Jobs Definition" ></p>

<p>So, I cracked open dotPeek and decided to hunt for that timer job definition and find who was using it. It turns out, there&rsquo;s a web application-level feature (<code>MySiteInstantiationQueuesFeatureReceiver</code>) which registers these timer jobs:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/04-featurereceiver.png" title="Timer Job Feature" ></p>

<p>There is a public static method inside that feature receiver used for registering the timer jobs.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/05-methodtoregistertimerjobs.png" title="Method to Register Timer Jobs" ></p>

<p>So, I had one of two options: invoke the static method directly, or simply toggle the feature. I opted to toggle the feature:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$feat = Get-SPFeature 65B53AAF-4754-46D7-BB5B-7ED4CF5564E1
</span><span class='line'>Disable-SPFeature $feat -Url http://webapp
</span><span class='line'>Enable-SPFeature $feat -Url http://webapp</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/06-toggle-feature.png" title="Toggle Feature" ></p>

<p>Finally, I double checked and verified the timer jobs were now present!</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/07-timerjobspresent.png" title="Timer Jobs Present" ></p>

<p>I then went to the My Site host URL and got into the queue for provisioning. Within 5 minutes, my personal my site was provisioned!</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-08-02-sharepoint-2013-my-site-timer-jobs-missing/08-mysite-provisioned.png" title="My Site Provisioned" ></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting the Confusing SharePoint 2013 SocialDataStoreException]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/05/06/getting-the-confusing-sharepoint-2013-socialdatastoreexception/"/>
    <updated>2013-05-06T11:34:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/05/06/getting-the-confusing-sharepoint-2013-socialdatastoreexception</id>
    <content type="html"><![CDATA[<p>As I was writing an app using the new SharePoint 2013 app model the other day, I ran into an issue when I was trying to follow a site automatically through JavaScript:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>The target of the operation was not found. Internal type name: Microsoft.Office.Server.UserProfiles.SocialDataStoreException. Internal error code: 0.</span></code></pre></td></tr></table></div></figure>




<!--more-->


<p>The problem seemed fairly straight-forward. The targeted site I wanted to follow couldn&rsquo;t be found. However, it didn&rsquo;t make sense. The instance URL I was targeting (<a href="https://chrisweldon.sharepoint.com">https://chrisweldon.sharepoint.com</a>) did in fact exist. Furthermore, I was not already following that site. So, why was this failing?</p>

<p>Let&rsquo;s take a look at some code:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">SP</span><span class="p">.</span><span class="nx">SOD</span><span class="p">.</span><span class="nx">executeOrDelayUntilScriptLoaded</span><span class="p">(</span><span class="nx">userProfilesLoaded</span><span class="p">,</span> <span class="s1">&#39;SP.UserProfiles.js&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">userProfilesLoaded</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">SP</span><span class="p">.</span><span class="nx">SOD</span><span class="p">.</span><span class="nx">executeFunc</span><span class="p">(</span><span class="s1">&#39;userprofile&#39;</span><span class="p">,</span> <span class="s1">&#39;SP.Social.SocialFollowingManager&#39;</span><span class="p">,</span> <span class="nx">followSites</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">followSites</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">context</span> <span class="o">=</span> <span class="nx">SP</span><span class="p">.</span><span class="nx">ClientContext</span><span class="p">.</span><span class="nx">get_current</span><span class="p">();</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">socialManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SP</span><span class="p">.</span><span class="nx">Social</span><span class="p">.</span><span class="nx">SocialFollowingManager</span><span class="p">(</span><span class="nx">context</span><span class="p">);</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">socialSite</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SP</span><span class="p">.</span><span class="nx">Social</span><span class="p">.</span><span class="nx">SocialActorInfo</span><span class="p">();</span>
</span><span class='line'>    <span class="nx">socialSite</span><span class="p">.</span><span class="nx">set_contentUri</span><span class="p">(</span><span class="s2">&quot;https://chrisweldon.sharepoint.com&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">socialSite</span><span class="p">.</span><span class="nx">set_actorType</span><span class="p">(</span><span class="nx">SP</span><span class="p">.</span><span class="nx">Social</span><span class="p">.</span><span class="nx">SocialActorType</span><span class="p">.</span><span class="nx">site</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">socialManager</span><span class="p">.</span><span class="nx">follow</span><span class="p">(</span><span class="nx">socialSite</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">context</span><span class="p">.</span><span class="nx">executeQueryAsync</span><span class="p">(</span>
</span><span class='line'>        <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;Sites followed!&#39;</span><span class="p">);</span> <span class="p">},</span>
</span><span class='line'>        <span class="kd">function</span><span class="p">(</span><span class="nx">sender</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="p">{</span> <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;Error: &#39;</span> <span class="o">+</span> <span class="nx">args</span><span class="p">.</span><span class="nx">get_message</span><span class="p">());</span> <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is fairly straight-forward. I simply setup a social actor to follow and call out to the <code>SocialFollowingManager</code> to attempt to follow that site. This is when I thought, perhaps this is a permissions problem? I&rsquo;m trying to have the JavaScript object model <em>write</em> a request to the Social datastore. Perhaps it wasn&rsquo;t authorized.</p>

<p>I changed the permissions in my <code>AppManifest.xml</code> from <strong>Read</strong> to <strong>Write</strong>:</p>

<table>
<thead>
<tr>
<th> Scope                  </th>
<th> Permission </th>
</tr>
</thead>
<tbody>
<tr>
<td> User Profiles (Social) </td>
<td> Write</td>
</tr>
</tbody>
</table>


<p>Sadly, I received the same error message. However, if you read the <a href="http://msdn.microsoft.com/en-us/library/jj163864.aspx">MSDN Documentation on Developing Social Features in SharePoint 2013</a>, there is a section in there talking about user profiles:</p>

<blockquote><p>User Profiles (http://sharepoint/social/tenant) The permission request scope used to access all user profiles. Only the profile picture can be changed; all other user profile properties are read-only for apps for SharePoint. Apps that request rights for the User Profiles scope must be installed by a tenant administrator.</p></blockquote>


<p>In a nutshell, I have to grant <strong>Tenant</strong> permissions to my app to be able to have my user follow a new site. Therefore, my new permissions look like the following:</p>

<table>
<thead>
<tr>
<th> Scope                  </th>
<th> Permission </th>
</tr>
</thead>
<tbody>
<tr>
<td> User Profiles (Social) </td>
<td> Read</td>
</tr>
<tr>
<td> Tenant                 </td>
<td> Write</td>
</tr>
</tbody>
</table>


<p>As indicated by the paragraph above, the app now needs to be installed by a tenant administrator. However, in doing so, the app now follows sites (and other content) with ease. Why the obscure error message? That I don&rsquo;t know, and I hope the SharePoint team might look to address this with a more <em>correct</em> error message in the near future.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[MigrateUsersToClaims - Operation Is Not Valid Due to the Current State of the Object]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/04/30/migrateuserstoclaims-operation-is-not-valid-due-to-the-current-state-of-the-object/"/>
    <updated>2013-04-30T11:50:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/04/30/migrateuserstoclaims-operation-is-not-valid-due-to-the-current-state-of-the-object</id>
    <content type="html"><![CDATA[<p>I&rsquo;m in the process of migrating my customer from SharePoint 2010 to SharePoint 2013. In their SharePoint 2010 environment, they were still using classic-mode authentication, but are switching to claims-based authentication in SharePoint 2013.</p>

<p>The recommended path to upgrade from 2010 to 2013 is a content and service-application database migration. This works great for us since we <strong>have</strong> to do this piecemeal. However, many of the general approaches for converting to claims-based authentication is to do so at the web-application level, rather than the content-database level (source: <a href="http://technet.microsoft.com/en-us/library/gg251985.aspx">TechNet</a>).</p>

<p>In SharePoint 2013, there&rsquo;s actually an <code>SPWebApplication</code> method dubbed <a href="http://msdn.microsoft.com/en-us/library/jj172686.aspx"><code>MigrateUsersToClaims</code></a> that takes 3 arguments:</p>

<ul>
<li>NTAccount</li>
<li>removePermissionsAfter</li>
<li>SPWebApplication.SPMigrateUserParameters</li>
</ul>


<p>There was no guidance on the NTAccount, other than the user &ldquo;performing&rdquo; the operation. I opted to use the farm account to ensure it had the appropriate level of permissions. The true power of the content database migration comes in with the third parameter. We can add individual content databases to migrate with this parameter rather than worrying about the <em>entire</em> web application.</p>

<p>Props go to <a href="http://blogs.technet.com/b/speschka/archive/2012/07/23/converting-a-classic-auth-content-database-to-claims-auth-in-sharepoint-2013.aspx">Steve Peschka</a> who originally pointed this out. However, in his post, the PowerShell to do this upgrade was the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>-- SNIP -- 
</span><span class='line'>$wa.MigrateUsersToClaims($acc, $true, $arguments)</span></code></pre></td></tr></table></div></figure>


<p>For me, that throws the error <code>Exception calling "MigrateUsersToClaims" with "3" argument(s): "Operation is not valid due to the current state of the object."</code> This was strange, and I couldn&rsquo;t figure it out. So, I cracked open the <code>Microsoft.SharePoint.Administration</code> dll and took a look at the <code>MigrateUsersToClaims</code> method:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="kt">bool</span> <span class="nf">MigrateUsersToClaims</span><span class="p">(</span><span class="n">NTAccount</span> <span class="n">account</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">removePermissionsAfter</span><span class="p">,</span> <span class="n">SPWebApplication</span><span class="p">.</span><span class="n">SPMigrateUserParameters</span> <span class="n">parameters</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">((</span><span class="n">NTAccount</span><span class="p">)</span> <span class="k">null</span> <span class="p">==</span> <span class="n">account</span><span class="p">)</span>
</span><span class='line'>        <span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentNullException</span><span class="p">(</span><span class="s">&quot;account&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">removePermissionsAfter</span> <span class="p">&amp;&amp;</span> <span class="n">parameters</span> <span class="p">!=</span> <span class="k">null</span> <span class="p">&amp;&amp;</span> <span class="p">(</span><span class="n">parameters</span><span class="p">.</span><span class="n">HasDatabaseToMigrate</span> <span class="p">||</span> <span class="n">parameters</span><span class="p">.</span><span class="n">OnlyMigratePolicyUsers</span><span class="p">))</span>
</span><span class='line'>        <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidOperationException</span><span class="p">();</span>
</span><span class='line'>    <span class="c1">// The rest</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>That second one was the one that I questioned. I know the conditions matched for the first two checks. The question was how my parameters looked. Sure enough:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>PS > $arguments
</span><span class='line'>
</span><span class='line'>DatabasesToMigrate      HasDatabaseToMigrate        OnlyMigratePolicyUsers
</span><span class='line'>------------------      --------------------        ----------------------
</span><span class='line'>{WSS_MigrationTest_...}                 True                         False</span></code></pre></td></tr></table></div></figure>


<p>With that, if I changed the middle parameter from <code>$true</code> to <code>$false</code>, the migration finally ran (and completed) succesfully.</p>

<p>Why did this happen? This was because my <code>$acc</code> user is my <strong>farm account</strong>. I&rsquo;m also running my PowerShell session as my <strong>farm account</strong>. This is to ensure that I have full, unfettered access to the SharePoint Object Model and the Content Database. The middle parameter states (from <a href="http://msdn.microsoft.com/en-us/library/jj172686.aspx">MSDN</a>):</p>

<blockquote><p>The **account** will be given the correct permissions to perform the operation. Should this permission be removed when the operation is complete.</p></blockquote>


<p>We definitely don&rsquo;t want this for the farm account. So, my updated code, for reference:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$wa = Get-SPWebApplication http://my-app-url
</span><span class='line'>$acc = "domain\farm-account"
</span><span class='line'>$arguments = New-Object Microsoft.SharePoint.Administration.SPWebApplication+SPMigrateUserParameters
</span><span class='line'>
</span><span class='line'>$contentDb = $wa.ContentDatabase["Content Database Name"]
</span><span class='line'>$arguments.AddDatabaseToMigrate($contentDb)
</span><span class='line'>$wa.MigrateUsersToClaims($acc, $false, $arguments)</span></code></pre></td></tr></table></div></figure>


<p>Cheers. Once again, thanks go to <a href="http://blogs.technet.com/b/speschka/archive/2012/07/23/converting-a-classic-auth-content-database-to-claims-auth-in-sharepoint-2013.aspx">Steve Peschka</a> for figuring this out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Sorry, Only Tenant Administrators Can Add or Give Access to This App]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/04/30/sorry-only-tenant-administrators-can-add-this-app/"/>
    <updated>2013-04-30T10:41:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/04/30/sorry-only-tenant-administrators-can-add-this-app</id>
    <content type="html"><![CDATA[<p>I have just completed building my first SharePoint 2013 application. I came across the error message <code>Sorry, only tenant administrators can add or give access to this app.</code> when trying to deploy the application to my site. This happened regardless if I was deploying using a SharePoint development site or after installing the solution in the app catalog.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-04-30-sorry-only-tenant-administrators-can-add-this-app/error.png" title="Error Message" ></p>

<p>The application required Tenant Read permissions as I&rsquo;m accessing the User Profile through the JavaScript object model. The purpose of using the User Profile JSOM is to get the suggestions of sites and people to follow that SharePoint presents.</p>

<p>Now, the concept of a &ldquo;Tenant&rdquo; makes sense for Office 365 or SharePoint Online. As a hosting provider, there are multiple tenants you want to support in a single environment. However, for an on-premise deployment, this error message didn&rsquo;t make much sense. I started poking around and came across <a href="http://www.social-point.com/tenant-administration-sites">spinning up a tenant administration site</a>, being able to set multiple app tenants through the <a href="http://technet.microsoft.com/en-us/library/jj219772.aspx">App Management Service cmdlets</a>, but none of those really seemed like the right solution for my on-premise deployment. I found an <a href="http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/4e844f6c-2b73-46ff-9cda-05105332b8f8">MDSN Forum Question</a> which seemed closer to the solution. That post recommends splitting the service accounts used to host the App Management and Site Settings services from the farm account. This was critical as the Farm Account is <strong>not allowed</strong> to add apps under its identity whatsoever. You will get an error message when trying to provision, and the ULS logs will indicate that an assertion failed checking that the current account was not the system account.</p>

<p><img class="right" src="http://www.chrisweldon.net/images/posts/2013-04-30-sorry-only-tenant-administrators-can-add-this-app/success.png" title="Provision" ></p>

<p>What did it turn out to be? I just needed to make sure my user account was <strong>directly</strong> added as a member of the <strong>Farm Administrators</strong> group. We have traditionally deployed farm administrators via an Active Directory and local (Administrators) group. However, it appears that the App Management service dislikes this approach and wants users <em>explicitly</em> permissioned to the <strong>Farm Administrators</strong> group. Additionally, after granting your user direct permissions, you need to issue an <code>iisreset</code> so those changes take effect. Then, you can provision your app successfully.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git Interactive Rebase for Svn Without Remotes]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/04/26/git-interactive-rebase-for-svn-without-remotes/"/>
    <updated>2013-04-26T12:30:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/04/26/git-interactive-rebase-for-svn-without-remotes</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve recently switched from using Subversion directly to using <a href="https://www.kernel.org/pub/software/scm/git/docs/git-svn.html">git svn</a> to allow me to use a git workflow, but interact with a subversion repository. It works <em>great</em>, except when I needed to interactive rebase&hellip;</p>

<!--more-->


<p>When moving this workflow into my customer&rsquo;s environment, they require I specify a JIRA ticket on each commit to the repo. I had forgot to do that for the first few commits, which looked like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ git log --oneline
</span><span class='line'>
</span><span class='line'>6fa0719 Fixing the handlebars template to render the target as parent.
</span><span class='line'>21ad0cf Initial commit of the SiteSuggestions app
</span><span class='line'>6430b3b Adding the .gitignore files
</span><span class='line'>095d92e SP-34: Creating branch to track the new suggestions app part.</span></code></pre></td></tr></table></div></figure>


<p>So, when I tried to commit, I got an error indicating that the commit failed. In looking at the error, I saw the pre-commit hook error requiring that I associate the commit with a JIRA ticket. So, my first comment was easy to fix:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ git commit --amend -m "SP-34: Fixing the handlebars template to render the target as parent."
</span><span class='line'>[2013-sitesuggestions-svn 6b4bc64] SP-34: Fixing the handlebars template to render the target as parent."
</span><span class='line'> 1 file changed, 1 insertion(+), 1 deletion(-)</span></code></pre></td></tr></table></div></figure>


<p>Now I just had to figure out how to modify commits <code>21ad0cf</code> and <code>6430b3b</code>. I tried to use git interactive rebase as per the <a href="http://trac.parrot.org/parrot/wiki/git-svn-tutorial">git svn tutorial</a> and per the <a href="http://git-scm.com/book/en/Git-Tools-Rewriting-History">git-scm book</a>. However, in both cases, I got the following error message:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ git rebase -i HEAD-3
</span><span class='line'>fatal: Needed a single revision
</span><span class='line'>invalid branch HEAD-3</span></code></pre></td></tr></table></div></figure>


<p>The solution was to specify the SHA for the commit:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ git rebase -i 6430b3b^</span></code></pre></td></tr></table></div></figure>


<p>This started the rebase process and allowed me to amend the commits for every faulted commit. Now, everything looks correct:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ git log --oneline
</span><span class='line'>
</span><span class='line'>6fa0719 SP-34: Fixing the handlebars template to render the target as parent.
</span><span class='line'>21ad0cf SP-34: Initial commit of the SiteSuggestions app
</span><span class='line'>6430b3b SP-34: Adding the .gitignore files
</span><span class='line'>095d92e SP-34: Creating branch to track the new suggestions app part.</span></code></pre></td></tr></table></div></figure>


<p>When I finally committed using <code>git svn dcommit</code>, everything went perfectly!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Editing the SharePoint 2013 My Sites Web Part Pages]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/04/25/editing-the-sharepoint-my-sites-web-part-pages/"/>
    <updated>2013-04-25T08:24:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/04/25/editing-the-sharepoint-my-sites-web-part-pages</id>
    <content type="html"><![CDATA[<p>The last two weeks have been interesting. I&rsquo;ve been trying to deploy an app part built as part of a SharePoint 2013 app I developed recently. The app part re-creates the &ldquo;Suggestions&rdquo; functionality that you see when visiting the &ldquo;Followed Sites&rdquo; and &ldquo;Followed People&rdquo; pages in your My Site. Those web parts were <strong>not</strong> easily reused in other parts of My Sites. The purpose of creating this app part was to be able to add suggestions directly to the Newsfeed page to make it a more useful information radiator. Unfortunately, editing the Newsfeed page (or any page) in the &ldquo;My Site Host&rdquo; was not nearly as intuitive as I had hoped.</p>

<p><img class="right" src="http://www.chrisweldon.net/images/posts/2013-04-25-editing-the-sharepoint-my-sites-web-part-pages/site-edit-page.png" title="Edit Page in Ribbon" ></p>

<p>I&rsquo;m used to having the ribbon to edit pages in SharePoint, regardless if they are standard publishing pages or web part pages. However, in the &ldquo;My Site Host&rdquo;, there is no ribbon for the standard pages, even when you are a farm administrator. I jumped to the conclusion that I could add the App Part via SharePoint Designer. Sadly, this wasn&rsquo;t the case. SharePoint Designer does not list <strong>any</strong> app parts.</p>

<p>I tried to go through the rigarmarole of adding the app to a separate site through the web editor, then copying the code from within SharePoint Designer and pasting it into the Newsfeed page, only for that to fail. The identifiers for the apps are completely different.</p>

<p><img class="left" src="http://www.chrisweldon.net/images/posts/2013-04-25-editing-the-sharepoint-my-sites-web-part-pages/gear-edit-page.png" title="Edit Page in Settings Menu" ></p>

<p>This is when I stepped back and though that the solution should be simpler than this. It turns out, it was. Click the gear icon (settings menu) in the upper-right corner of SharePoint and you&rsquo;ll find the <strong>Edit Page</strong> link. I felt liberated and frustrated at myself for not checking there earlier. From there, you have complete control to edit the Newsfeed web part page (or any page in the &ldquo;My Site Host&rdquo;).</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2013-04-25-editing-the-sharepoint-my-sites-web-part-pages/newsfeed-web-part.png" title="Newsfeed Web Part Page" ></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using the Quicktate RESTful API]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/01/28/using-the-quicktate-restful-api/"/>
    <updated>2013-01-28T00:17:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/01/28/using-the-quicktate-restful-api</id>
    <content type="html"><![CDATA[<p><a href="http://www.quicktate.com/">Quicktate</a> is a service for which I&rsquo;ve been consulting for since 2009. We have recently released a new <a href="https://api.quicktate.com">RESTful API</a> to help make integrating with the service a <em>breeze</em>. That said, while our new <a href="https://api.quicktate.com/v1/api/index.html">RESTful API documentation</a> uses <a href="http://developers.helloreverb.com/swagger/">Swagger</a> to generate our service documentation, many of the common RESTful semantics we rely on are completely missing from that documentation. Until we figure out an easier way to convey that information via Swagger, here&rsquo;s some basic information on how to get around the API.</p>

<!--more-->


<h2>Authentication</h2>

<p>All requests currently are performed using HTTP Basic authentication. While we are still developing our OAuth provider and intend to use that as our primary mechanism for authenticating users, we currently are accepting your username and password via a standard HTTP Basic Authorization request. As a raw HTTP header, you are looking at the following for authenticating as <code>demo@quicktate.com</code> with password <code>Test1234%</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Authorization: Basic ZGVtb0BxdWlja3RhdGUuY29tOlRlc3QxMjM0JQ==</span></code></pre></td></tr></table></div></figure>


<p>As a cUrl request, you&rsquo;ll be looking at using the <code>-u demo@quicktate.com:Test1234%</code> argument to the command.</p>

<h2>Transcription Requests</h2>

<p>The basis of Quicktate is transcriptions. However, while there is a <code>/transcription</code> resource for our API, you don&rsquo;t actually create transcriptions - that&rsquo;s the job of our typists. Instead, you submit a <code>/transcriptionrequest</code> to Quicktate and operate on that request until a typist has completed transcribing and turns it into a <code>/transcription</code>.</p>

<p>So, we expect very little in the HTTP headers for this type of request. Because you&rsquo;re creating a new Transcription request, the method will be <code>POST</code>. What&rsquo;s most important is the body of the request. Most developers are used to submitting the request as a form request, to where in a PHP application, the variables will come across in <code>$_POST</code>. In this case, however, we expect the body of the message to be either XML or JSON (as indicated in the <code>Content-Type</code> header).</p>

<p>What should be in the body of the message? The transcription request. When creating a transcription request for the first time, you&rsquo;ll need to supply us with the following information:</p>

<table cellspacing="0" cellpadding="1" border="1">
<tr><td>Field Name</td><td>Required?</td><td>Description</td></tr>
<tr><td>callbackDestination</td><td>No</td><td>The URL or e-mail address where a callback should occur upon completion of the transcription.</td></tr>
<tr><td>&#8220;callbackMethod&#8220;</td><td>No *</td><td>The way the callbackDestination should be invoked. This is mandatory if callbackDestination is specified. Valid values include: &#8220;HTTPPOST&#8220;, &#8220;RESTPOST&#8220;, &#8220;XMLRPC&#8220;, &#8220;EMAIL&#8220;.
<tr><td>&#8220;metadata&#8220;</td><td>No</td><td>Your custom metadata for this transcription request. This is sent back to you in the callback so that you have data you can trace back to some internal identifier or record.</td></tr>
<tr><td>&#8220;language&#8220;</td><td>Yes</td><td>Pretty self-explainatory. Valid values are: 1 = English, 2 = Spanish. Others on the way!</td></tr>
<tr><td>&#8220;audiourl&#8220;</td><td>Yes</td><td>The URL of the audio file you wish to be downloaded and transcribed. Must be accessible from the internet. This is required if no &#8220;audiodata&#8220; is present.</td></tr>
<tr><td>&#8220;audiodata&#8220;</td><td>Yes</td><td>A Base 64 encoded block of the audio file to be transcribed. This is required if no &#8220;audiourl&#8220; is present.</td></tr>
</table>


<p>So, a sample HTTP request might look like the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>POST /v1/api/transcriptionrequest HTTP/1.1
</span><span class='line'>Authorization: Basic ZGVtb0BxdWlja3RhdGUuY29tOlRlc3QxMjM0JQ==
</span><span class='line'>User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
</span><span class='line'>Host: api.quicktate.com
</span><span class='line'>Accept: application/json
</span><span class='line'>Content-Type: application/json
</span><span class='line'>Content-Length: 208
</span><span class='line'>
</span><span class='line'>{ 
</span><span class='line'>  "callbackDestination": "https://private.host.callback.com/callback-url.php",
</span><span class='line'>  "callbackMethod": "HTTPPOST",
</span><span class='line'>  "metadata": "My custom metadata",
</span><span class='line'>  "language": 1,
</span><span class='line'>  "audiourl": "http://www.quicktate.com/audio.wav"
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>or from cUrl it would look like the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>curl -u demo@quicktate.com:Test1234% -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d '{ "callbackDestination": "https://private.host.callback.com/callback-url.php", "callbackMethod": "HTTPPOST", "metadata": "My custom metadata", "language": 1, "audiourl": "http://www.quicktate.com/audio.wav" }' -v https://api.quicktate.com/v1/api/transcriptionrequest</span></code></pre></td></tr></table></div></figure>


<p>The response I&rsquo;m likely to receive back will look like the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>HTTP/1.1 201 Created
</span><span class='line'>Server: nginx
</span><span class='line'>Date: Mon, 28 Jan 2013 06:14:43 GMT
</span><span class='line'>Content-Type: application/json
</span><span class='line'>Transfer-Encoding: chunked
</span><span class='line'>Connection: keep-alive
</span><span class='line'>X-Powered-By: PHP/5.3.17-1~dotdeb.0
</span><span class='line'>Vary: Accept
</span><span class='line'>Access-Control-Max-Age: 86400
</span><span class='line'>Access-Control-Allow-Origin: *
</span><span class='line'>Access-Control-Allow-Credentials: true
</span><span class='line'>Access-Control-Allow-Headers: Authorization, X-Authorization, Origin, Accept, Content-Type, X-Requested-With, X-HTTP-Method-Override
</span><span class='line'>Access-Control-Allow-Methods: GET, POST, PUT, DELETE, HEAD, OPTIONS
</span><span class='line'>Location: /v1/api/transcriptionrequest/14967237</span></code></pre></td></tr></table></div></figure>


<p>What&rsquo;s important to realize is that you will only have a successful request submitted when the status code returned is a 201. If you get a 400-level error message, check which one. If it&rsquo;s a 401 or a 403, then you are not sending the proper credentials. If it&rsquo;s just a 400 error, then you need to look at how you&rsquo;re sending your data to the API, because the API doesn&rsquo;t recognize the payload.</p>

<p>Once you&rsquo;ve gotten past that, you may be wondering, how do I access the transcription request now? There is <strong>no</strong> body to this whatsoever. This is one of those REST semantics at play. If you look in the return headers, there is a <code>Location</code> header which specifies exactly where you can access your <code>transcriptionRequest</code>. Simply submit a <code>GET</code> request to that URL and you&rsquo;ll find the status of your transcriptionRequest. The response will look something similar to the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>HTTP/1.1 200 Success
</span><span class='line'>Server: nginx
</span><span class='line'>Date: Mon, 28 Jan 2013 06:14:43 GMT
</span><span class='line'>Content-Type: application/json
</span><span class='line'>Transfer-Encoding: chunked
</span><span class='line'>Connection: keep-alive
</span><span class='line'>X-Powered-By: PHP/5.3.17-1~dotdeb.0
</span><span class='line'>Vary: Accept
</span><span class='line'>Access-Control-Max-Age: 86400
</span><span class='line'>Access-Control-Allow-Origin: *
</span><span class='line'>Access-Control-Allow-Credentials: true
</span><span class='line'>Access-Control-Allow-Headers: Authorization, X-Authorization, Origin, Accept, Content-Type, X-Requested-With, X-HTTP-Method-Override
</span><span class='line'>Access-Control-Allow-Methods: GET, POST, PUT, DELETE, HEAD, OPTIONS
</span><span class='line'>
</span><span class='line'>{
</span><span class='line'>  "id": 14967237,
</span><span class='line'>  "callbackDestination": "https://private.host.callback.com/callback-url.php",
</span><span class='line'>  "callbackMethod": "",
</span><span class='line'>  "status": 0,
</span><span class='line'>  "metadata": "Represents an unprocessed audio file. ",
</span><span class='line'>  "datePosted": "2012-12-01T01:23:45-0600",
</span><span class='line'>  "language": 99,
</span><span class='line'>  "audiodata": null,
</span><span class='line'>  "audiourl": null
</span><span class='line'>},</span></code></pre></td></tr></table></div></figure>


<h2>Completed Transcriptions</h2>

<p>That is, until your transcription is complete. Once your transcription is complete, the resource URL will permanently move. As a result, you&rsquo;ll see the status code for the previous URL change from 200 to 302, indicating that it&rsquo;s been permanently moved. Fortunately, we point you in the direction of where you need to go again, through the <code>Location</code> header:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>HTTP/1.1 302 Moved
</span><span class='line'>Server: nginx
</span><span class='line'>Date: Mon, 28 Jan 2013 06:14:43 GMT
</span><span class='line'>Content-Type: application/json
</span><span class='line'>Transfer-Encoding: chunked
</span><span class='line'>Connection: keep-alive
</span><span class='line'>X-Powered-By: PHP/5.3.17-1~dotdeb.0
</span><span class='line'>Vary: Accept
</span><span class='line'>Access-Control-Max-Age: 86400
</span><span class='line'>Access-Control-Allow-Origin: *
</span><span class='line'>Access-Control-Allow-Credentials: true
</span><span class='line'>Access-Control-Allow-Headers: Authorization, X-Authorization, Origin, Accept, Content-Type, X-Requested-With, X-HTTP-Method-Override
</span><span class='line'>Access-Control-Allow-Methods: GET, POST, PUT, DELETE, HEAD, OPTIONS
</span><span class='line'>Location: /v1/api/transcription/14967237</span></code></pre></td></tr></table></div></figure>


<p>When you submit a <code>GET</code> request to the <code>Location</code> URL listed above, your payload will look like the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>HTTP/1.1 200 Success
</span><span class='line'>Server: nginx
</span><span class='line'>Date: Mon, 28 Jan 2013 06:14:43 GMT
</span><span class='line'>Content-Type: application/json
</span><span class='line'>Transfer-Encoding: chunked
</span><span class='line'>Connection: keep-alive
</span><span class='line'>X-Powered-By: PHP/5.3.17-1~dotdeb.0
</span><span class='line'>Vary: Accept
</span><span class='line'>Access-Control-Max-Age: 86400
</span><span class='line'>Access-Control-Allow-Origin: *
</span><span class='line'>Access-Control-Allow-Credentials: true
</span><span class='line'>Access-Control-Allow-Headers: Authorization, X-Authorization, Origin, Accept, Content-Type, X-Requested-With, X-HTTP-Method-Override
</span><span class='line'>Access-Control-Allow-Methods: GET, POST, PUT, DELETE, HEAD, OPTIONS
</span><span class='line'>
</span><span class='line'>{
</span><span class='line'>  "id": 14967243,
</span><span class='line'>  "metadata": "Represents a processed audio file. ",
</span><span class='line'>  "datePosted": "2012-12-01T01:23:45-0600",
</span><span class='line'>  "dateCompleted": "2012-12-01T01:25:30-0600",
</span><span class='line'>  "wordcount": null,
</span><span class='line'>  "language": 99,
</span><span class='line'>  "transcription": "This is a completed transcription request."
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<h2>More to Come</h2>

<p>Hopefully by next week, I&rsquo;ll have another writeup on how to interact with your transcription requests before we begin processing them.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SqlFileStream Access Is Denied]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/01/08/sqlfilestream-access-is-denied/"/>
    <updated>2013-01-08T13:16:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/01/08/sqlfilestream-access-is-denied</id>
    <content type="html"><![CDATA[<p>I started playing around with SQL filestreams yesterday. We have a need to store large binary objects both quickly and efficiently from SharePoint in our SQL database for regulatory purposes. I found a great <a href="http://www.codeproject.com/Articles/32216/How-to-store-and-fetch-binary-data-into-a-file-str">article on Code Project</a> on how to actually store binary data in a filestream column. However, as I ran the code, I encountered a <code>Win32Exception</code> with the message &ldquo;Access is denied.&rdquo;.</p>

<p>I double (and triple) checked that the permissions for the account executing the code were correct. Since we&rsquo;re using SharePoint, we are using only Windows authentication. Furthermore, I made sure that our connection string was using Integrated Security:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Server=sqlserver01;Database=Journaling;Integrated Security=true;</span></code></pre></td></tr></table></div></figure>


<p>Ultimately, it came down to the fact that the SQL Server was not setup to allow remote server connections to filestream. I managed to fix this by following the <a href="http://msdn.microsoft.com/en-us/library/cc645923.aspx">Enable and Configure FILESTREAM</a> article on MSDN. The <em>Allow remote clients to have streaming access to FILESTREAM data.</em> box was not checked, thus causing my problems.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PHP Preg_match Maximum Length]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/01/06/php-preg-match-maximum-length/"/>
    <updated>2013-01-06T16:09:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/01/06/php-preg-match-maximum-length</id>
    <content type="html"><![CDATA[<p>Last weekend and this weekend I spent a good deal of time trying to track down a PHP error I was having in my customer&rsquo;s production environment. This wasn&rsquo;t an exception being thrown by PHP, but rather, I couldn&rsquo;t readily identify if it was a PHP error or not, because different parts of our infrastructure were throwing different errors during the request.</p>

<!--more-->


<p>The problem was first noticed by an early adopter of the new RESTful API we released a month ago. He kept receiving an HTTP error code 400 with the following message:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>    "message": "Invalid Payload Format"
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>When I dug into this, I found this error was coming from the <a href="https://github.com/codeinchaos/restful-zend-framework">RESTful Zend Framework component</a> I was using to develop our RESTful web service. However, when I looked at the customer&rsquo;s request payload, it looked fine (the <code>audiodata</code> parameter was about 60k in size, properly Base64 encoded):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "callbackDestination": "chris@chrisweldon",
</span><span class='line'>  "callbackMethod": "EMAIL",
</span><span class='line'>  "language": 1,
</span><span class='line'>  "audiodata": "gEUS9gckvq37RG4J7LYg12YdZAwVJCB053EiDJp9iNLDr6vGyOWvFDzyPwqVoS6UVO+ ... etc"
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>However, when I started digging in and debugging this issue, I saw that about half the web requests being sent to my php-fpm backend were malformed. The payload looked like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "callbackDestination": "chris@chrisweldon",
</span><span class='line'>  "callbackMethod": "EMAIL",
</span><span class='line'>  "language": 1,
</span><span class='line'>  "audiodata": "gEUS9gckvq37RG4J7LYg12YdZAwVJCB053EiDJp9iNLDr6vGyOWvFDzyPwqVoS6UVO+ STOPPED SHORT"
</span><span class='line'>{
</span><span class='line'>  "callbackDestination": "chris@chrisweldon",
</span><span class='line'>  "callbackMethod": "EMAIL",
</span><span class='line'>  "language": 1,
</span><span class='line'>  "audiodata": "gEUS9gckvq37RG4J7LYg12YdZAwVJCB053EiDJp9iNLDr6vGyOWvFDzyPwqVoS6UVO+ EVEN SHORTER</span></code></pre></td></tr></table></div></figure>


<p>This was a very strange pecularity. The body of the message was being duplicated, but the <code>audiodata</code> parameter was being cut short in two different places in the request. I presumed this was a problem with nginx, but I couldn&rsquo;t find any information to guarantee this. Furthermore, the behavior seemed rather erratic. Some requests would include the full payload, others would have this behavior from above.</p>

<p>That&rsquo;s when I took a look at my syslog. I started to see the following errors in <code>/var/log/syslog</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Jan  6 16:24:53 app01 kernel: [4435039.857398] php5-fpm[19547]: segfault at 7fff7b2a8fe0 ip 000000000048f7dc sp 00007fff7b2a8fd0 error 6 in php5-fpm[400000+824000]</span></code></pre></td></tr></table></div></figure>


<p>I checked the <code>/var/log/php-fpm.log</code> and saw a similar output there as well:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[06-Jan-2013 16:24:53] WARNING: [pool www] child 19547 exited on signal 11 (SIGSEGV) after 450.542383 seconds from start</span></code></pre></td></tr></table></div></figure>


<p>Segmentation faults? This seemed rather extreme just for handling 60k of payload.</p>

<p>I continued digging further and figured out what was going on. I managed to find that the first request passed to the application servers contained the <strong>complete</strong> payload, properly Base64 encoded. However, this request was what triggered the segmentation fault. Once that segmentation fault was triggered, the signal abruptly terminated and nginx re-dispatched the request to a separate application node. This application node was receiving the malformed body, not causing a segmentation fault, and was instead returning the <code>Invalid Payload Format</code> message.</p>

<p>So, to get to the bottom of what was going on, I started throwing logging statements into my application to see where I got to. Eventually, I ended up at a validation block of code, to validate that exact parameter that was having the truncation problems (<code>audiodata</code>):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="k">if</span> <span class="p">(</span><span class="nb">trim</span><span class="p">(</span><span class="nv">$value</span><span class="o">-&gt;</span><span class="na">audiodata</span><span class="p">)</span> <span class="o">!=</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Verify the data is base64 encoded.</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s2">&quot;/^(?:[a-z0-9+\/]{4})*(?:[a-z0-9+\/]{2}==|[a-z0-9+\/]{3}=)?$/i&quot;</span><span class="p">,</span> <span class="nv">$value</span><span class="o">-&gt;</span><span class="na">audiodata</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setMessage</span><span class="p">(</span><span class="s1">&#39;The audio data supplied was either not Base64 encoded or was incomplete.&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>It turns out, <code>preg_match</code> has a <em>configurable</em> maximum upper limit on the number of characters (<a href="http://stackoverflow.com/questions/6173223/preg-match-has-string-size-limit">source</a>). This really makes sense, as regular expression matching should be on small bodies of text (generally, &lt; 10k characters is my good recommendation). Therefore, this was not a suitable solution. We would be better off attempting to base64 decode the text, and if it fails, assume it&rsquo;s invalid. This can easily be done with the following:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="k">if</span> <span class="p">(</span><span class="nb">trim</span><span class="p">(</span><span class="nv">$value</span><span class="o">-&gt;</span><span class="na">audiodata</span><span class="p">)</span> <span class="o">!=</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Verify the data is base64 encoded.</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nb">base64_decode</span><span class="p">(</span><span class="nb">chunk_split</span><span class="p">(</span><span class="nv">$value</span><span class="o">-&gt;</span><span class="na">audiodata</span><span class="p">))</span> <span class="o">==</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setMessage</span><span class="p">(</span><span class="s1">&#39;The audio data supplied was either not Base64 encoded or was incomplete.&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>After deploying this code change, all is well. No more segmentation faults.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Chris Weldon - Microsoft MVP]]></title>
    <link href="http://www.chrisweldon.net/blog/2013/01/05/chris-weldon-microsoft-mvp/"/>
    <updated>2013-01-05T10:08:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2013/01/05/chris-weldon-microsoft-mvp</id>
    <content type="html"><![CDATA[<p><img class="left" src="http://www.chrisweldon.net/images/posts/2013-01-05-chris-weldon-microsoft-mvp/mvplogo.gif" title="Microsoft MVP Logo" >
2012 was a stressful, but rewarding year. Those who know me know I <strong>love</strong> to speak at conferences and user groups. Just how much do I love to speak? Check out my <a href="http://spkr8.com/neraath">SpeakerRate profile</a>. Last year I had 20 talks logged at SpeakerRate, 28 talks in total. Most of those talks were local user groups and local techfests, but I finally managed to hit the national spotlight with one talk at Agile 2012. I know this pales in comparison to some technical speakers, but it&rsquo;s not about the quantity - it&rsquo;s about the quality. I put a lot of time preparing my presentations, as I want my audience to not just be encouraged, but to be <em>motivated</em> to take what they&rsquo;ve learned in my sessions and implement them tomorrow.</p>

<p>The last quarter I eased back on my speaking engagements, largely because I needed to spend more time with my family and because conferences are fairly light in the third quarter. Nevertheless, I woke up on January 1, 2013 to a rather pleasant e-mail - I had been awarded a <a href="http://www.microsoft.com/mvp">Microsoft MVP</a> in ASP.Net/IIS. To say this came as a surprise would be a lie, but I had been skeptical if I was going to get the award, given how competitive the awards are. There tens of thousands of professionals all over the world vying for one of these awards, and in some categories (C# and SharePoint, in particular), you have to go through multiple vetting cycles before you end up receiving the award.</p>

<p><span class='pullquote-left' data-pullquote='an MVP Award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others.'>
For those unfamiliar, an MVP Award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others.. No doubt, that&rsquo;s how I see myself (though a little more modest). I realize that there are some people who only care to get awards such as these as yet another way to pad the resume. Those individuals most definitely do what they do for the wrong reasons.
</span></p>

<p>I do what I do for a number of reasons. First, I love to hear myself talk. Just kidding. Those who know me know I can be (somewhat) shy in the company of others, and never as boisterous as some of those in a clique (I&rsquo;m looking at you Devlin and Bud :-P). That said, I do love meeting new people. I&rsquo;ve forged some really great relationships with people in the community that I would <em>love</em> to work with (and some of them now do!). Even if I never have that opportunity, being able to meet for beers after work with these people is a whole lot of fun.</p>

<p>But, while meeting new people is fun, I consider speaking as a selfless act. I don&rsquo;t speak for myself - I speak for you, the community. If nobody wanted to hear what I had to say, then my conference rooms would be empty and I&rsquo;d likely stay behind my computer or doing other things to help out. However, the fact that I&rsquo;ve concentrated on putting together such high-quality, passionate talks on a variety of different technical and professional areas has proven to be useful to many people in my audience. What matters most is having an impact on at least one person&rsquo;s perception of a topic, whether that&rsquo;s opening their eyes to a new technology, providing a different perspective on how to write software, or simply inspiring them to try again at something they previously failed at - that&rsquo;s what I really love.</p>

<h2>How I View the Award</h2>

<p><span class='pullquote-right' data-pullquote='I thought I was a hot shot coming into Improving Enterprises; working with such a talented, professional, and wonderful group of technologists and mentors has really helped me remain consistently modest about my technical abilities.'>
Some people see the award as an affirmation that they are the most elite, technically proficient individiuals in the world. I won&rsquo;t lie - that&rsquo;s how I&rsquo;ve always percieved Microsoft MVPs. Some of them are stellar individuals who really are at the top of their game. However, to assume that I&rsquo;ve reached the pinnacle of my technical abilities is far from the truth. I thought I was a hot shot coming into Improving Enterprises; working with such a talented, professional, and wonderful group of technologists and mentors has really helped me remain consistently modest about my technical abilities.
</span></p>

<p>In our field, there are experts, people who cannot achieve a level higher than they are already at. However, those individuals are experts on such a niche topic, that field itself is already evolved to its maximum potential, allowing for experts to finally attain their place. However, I see myself as extremely proficient in a lot of the areas I work - SharePoint, PHP, ASP.Net, and systems administration, in particular. That said, because each of those areas are so broad and have so many different uses, it&rsquo;s impossible for me to become an &ldquo;expert&rdquo; in these fields. It&rsquo;s hard for <strong>anyone</strong> to become an expert in these fields. If you come across anyone who claims to be an expert, I guarantee you&rsquo;ll find gaps in their knowledge somewhere. That&rsquo;s how I view experts - people who know everything there is to know.</p>

<p>With that said, I am humbled to know that Microsoft does see me as not only a skilled technologist, but that my contributions to the community are useful. That&rsquo;s ultimately how I view this MVP Award - it&rsquo;s affirmation that I should continue to do what I&rsquo;m doing. It&rsquo;s Microsoft willing to expend resources and provide me with information that will continue to help me educate my audience.</p>

<p>I don&rsquo;t (and won&rsquo;t) hold my MVP award above anyone else - that&rsquo;s just not the type of person I am. Instead, I proudly wear this badge of honor as a beacon for others to reach out to ask questions. I&rsquo;m always interested in helping people out - that&rsquo;s why I work for Improving Enterprises. Their motto directly aligns with my goals - <em>Improving - It&rsquo;s what we do.</em></p>

<h2>Thanks</h2>

<p>I would not be receiving this award if it weren&rsquo;t for the help of <a href="http://www.improvingenterprises.com">Improving Enterprises</a>. The company actively encourages community participation, and goes above and beyond to help each other out with mentoring, guidance, and access to some of the best people in our area. There are two people from Improving who have been great motivators and put their necks on the line to vouch for me - Devlin Liles and Tim Rayburn. You guys rock and I love working with you both! Allen Hurst, my mentor for the last two and a half years, has truly been an inspiration, and has become one of my best friends. Without him, I likely wouldn&rsquo;t have been such an avid speaker. Zain Naboulsi and Chris Koenig, both from Microsoft, were also a great help towards getting me vetted through the MVP process and deserve major kudos.</p>

<p>Of course, I would not be nearly as successful at the things I do without my family. I thank my father, David Weldon, for showing me the way early in being a speaker. For as long as I can remember, my father not only attended medical conferences, but was frequently a speaker at them, and often times went out of his way to make sure that I could attend to watch him speak. While I rarely ever understood the material, his charisma and style of presenting have rubbed off - in a very positive way. Thank you, dad.</p>

<p>Finally, to my wife, Melissa, and son, Tristan, you both deserve the sun and the moon. You both motivate me to continually be a better person, encourage me when I am under stress, and are understanding when I am not around. I am often times not around or am too busy to spend the quality time you two deserve, and for that I&rsquo;m sorry. I shout from my proverbial mountain top how much I love you both, and how much you both mean to me, and thank you both so incredibly much for being such a wonderful and patient family.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SharePoint 2013 Community Tagging Architecture and Bug]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/12/20/sharepoint-2013-community-tagging-architecture-and-bug/"/>
    <updated>2012-12-20T13:29:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/12/20/sharepoint-2013-community-tagging-architecture-and-bug</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve spent yesterday evening and today really sinking my teeth into the internals of SharePoint 2013&rsquo;s social features, trying to identify how items are cataloged and surfaced. This led to some very interesting revelations as to where I can find information relating to each of SharePoint&rsquo;s moving parts. As I continued to dig, I managed to identify a significant problem with surfacing hashtags, aka <strong>#tags</strong>, in community sites. This post serves as a place for hopefully the search engines to surface this problem for other users, and I will catalog my findings and hopefully eventual resolution with Microsoft.</p>

<!--more-->


<p><strong>Update (25/Apr/2013)</strong>: <a href="#update">Microsoft has implemented a bugfix for this. See below for more information.</a></p>

<h2>Background</h2>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-1-community-discussion.png"></p>

<p>This blogpost (and the ordeal mentioned above) all started with the community discussion thread seen in the screenshot above. In order for all social features to work correctly, you have to have the following services configured correctly in your SharePoint 2013 environment:</p>

<ul>
<li>Managed Metadata Service</li>
<li>Search Service</li>
<li>User Profile Service</li>
</ul>


<p>Each of these are used in a variety of different ways to knit the social story together. Let&rsquo;s start with the lowest common denominator in the tagging story: tags. If you read my <a href="http://www.chrisweldon.net/blog/2012/12/18/sharepoint-2013-tagging-social-tags/">previous blog post</a>, you&rsquo;ll get a better understanding of what <strong>Tags &amp; Notes</strong> are used for in SharePoint. Through that interface, you can tag a list item, file, or even a list with any managed metadata that&rsquo;s marked &ldquo;taggable&rdquo;. The purpose is to help surface relevant content within an enterprise without going through the hassle of creating custom metadata columns on document libraries.</p>

<p>In SharePoint 2013, there is a new managed metadata term set, dubbed <strong>Hashtags</strong>. This is a system-level term set, and cannot be deleted or created. However, all terms created within are fully manageable. This term store contains the terms created when a user creates a tag beginning with a hash (#). This occurs no matter where the user tags something: a file, comment, microblog post, or a community discussion. Suppose for a moment that a user adds a community discussion post with four <em>new</em> hashtags: <code>#reply</code>, <code>#outlook</code>, <code>#metadata</code>, and <code>#termstore</code>. Upon submitting that post, those terms will immediately be added to the <code>ECMTermLabel</code> database table in the Managed Metadata Service database.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SELECT</span> <span class="n">TOP</span> <span class="mi">1000</span> <span class="p">[</span><span class="n">PartitionId</span><span class="p">],</span> <span class="p">[</span><span class="n">TermId</span><span class="p">],</span> <span class="p">[</span><span class="n">LCID</span><span class="p">],</span> <span class="p">[</span><span class="n">Label</span><span class="p">],</span> <span class="p">[</span><span class="n">IsDefault</span><span class="p">]</span>
</span><span class='line'><span class="k">FROM</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">ECMTermLabel</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-2-termstore.png"></p>

<p>However, all across SharePoint and <em>especially</em> the search service, the terms are not refered to by their integer identifiers. Instead, they&rsquo;re referred by their <code>UniqueId</code> guid. This is found by looking at the <code>ECMTerm</code> table, alongside the <code>ECMTermLabel</code> table:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SELECT</span> <span class="n">TOP</span> <span class="mi">1000</span> <span class="p">[</span><span class="n">Id</span><span class="p">],</span> <span class="p">[</span><span class="n">UniqueId</span><span class="p">]</span>
</span><span class='line'><span class="k">FROM</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">ECMTerm</span><span class="p">]</span>
</span><span class='line'><span class="k">WHERE</span> <span class="n">Id</span> <span class="k">IN</span> <span class="p">(</span><span class="mi">1088</span><span class="p">,</span> <span class="mi">1089</span><span class="p">,</span> <span class="mi">1090</span><span class="p">,</span> <span class="mi">1091</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-3-term-uniqueid.png"></p>

<p>At this point, it&rsquo;s important to rehash that hashtags are not social by default. When it comes to using the <strong>Tags &amp; Notes</strong> board, it is possible to enable any tags used there (including hashtags) to be &ldquo;socialized&rdquo;. However, the &ldquo;new&rdquo; social features (community discussions, microblog posts and comments) do not make those tags social. You can check by querying the User Profile Service SocialDB&rsquo;s <code>SocialTags</code> table.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-4-socialtags.png"></p>

<h3>Deeper Dive - Where are my Hashtags?</h3>

<p>So, I wanted to find out where my hashtags really were being used. So, this took me on a deep dive through the SharePoint content database. As this was all read only, this didn&rsquo;t really matter if I was poking around trying to find data. Because there are several tables with hundreds of columns, I wanted to hone in precisely the list I was looking for my hashtags: the <strong>Discussions List</strong>. I cracked open the <code>AllLists</code> table and queried based on title:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SELECT</span> <span class="n">TOP</span> <span class="mi">1000</span> <span class="p">[</span><span class="n">tp_SiteId</span><span class="p">],</span> <span class="p">[</span><span class="n">tp_WebId</span><span class="p">],</span> <span class="p">[</span><span class="n">tp_ID</span><span class="p">],</span> <span class="p">[</span><span class="n">tp_Title</span><span class="p">]</span>
</span><span class='line'><span class="k">FROM</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">AllLists</span><span class="p">]</span>
</span><span class='line'><span class="k">WHERE</span> <span class="p">[</span><span class="n">tp_Title</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;Discussions List&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-5-contentdb-listid.png"></p>

<p>The <code>tp_ID</code> is what I what I needed, as it is the list&rsquo;s unique identifier for me to pull content out of the <code>AllUserData</code> table. This table contains all user-provided data in all SharePoint sites stored within this content database. Therefore, it&rsquo;s massive, even for an environment with only a single site collection like a community site. Performing the following query allowed me to find the discussion comment that I added in the topmost screenshot.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SELECT</span> <span class="n">TOP</span> <span class="mi">1000</span> <span class="p">[</span><span class="n">tp_ColumnSet</span><span class="p">]</span>
</span><span class='line'><span class="k">FROM</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">AllUserData</span><span class="p">]</span>
</span><span class='line'><span class="k">WHERE</span> <span class="n">tp_ListId</span> <span class="o">=</span> <span class="s1">&#39;75D9F5D7-8B83-4252-BB52-48D5E5F91B01&#39;</span> <span class="k">ORDER</span> <span class="k">BY</span> <span class="n">tp_Modified</span> <span class="k">DESC</span>
</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-6-contentdb-discussioncomment.png"></p>

<p>This yields a field which is viewable in an XML editor. The resulting XML for the screenshot of the comment made by me in the post above looks like the following. As you can see in the <code>ntext9</code> XML field, we have the hashtags that SharePoint has identified within the body of the comment, as well as their unique identifiers from the managed metadata service. Further proof that community sites are being tagged appropriately.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;int1&gt;</span>42<span class="nt">&lt;/int1&gt;</span>
</span><span class='line'><span class="nt">&lt;int2&gt;</span>1<span class="nt">&lt;/int2&gt;</span>
</span><span class='line'><span class="nt">&lt;int3&gt;</span>42<span class="nt">&lt;/int3&gt;</span>
</span><span class='line'><span class="nt">&lt;int7&gt;</span>1<span class="nt">&lt;/int7&gt;</span>
</span><span class='line'><span class="nt">&lt;ntext2&gt;</span><span class="ni">&amp;lt;</span>div class=&quot;ExternalClass27572E39547C412CA62D7D22B7FC380F&quot;<span class="ni">&amp;gt;&amp;lt;</span>p<span class="ni">&amp;gt;</span>Let&#39;s test. <span class="ni">&amp;lt;</span>span class=&quot;ms-rtestate-read ms-socialentity&quot; data-hashtag=&quot;00000000-0000-0000-0000-000000000000&quot; data-hashname=&quot;#reply&quot;<span class="ni">&amp;gt;&amp;lt;</span>a class=&quot;ms-hashTag&quot; href=&quot;/_layouts/15/FeedRedirector.aspx?type=tag<span class="ni">&amp;amp;</span>amp;value=%23reply&quot; rel=&quot;#reply&quot;<span class="ni">&amp;gt;</span>#reply<span class="ni">&amp;lt;</span>/a<span class="ni">&amp;gt;&amp;lt;</span>/span<span class="ni">&amp;gt;</span> <span class="ni">&amp;lt;</span>span class=&quot;ms-rtestate-read ms-socialentity&quot; data-hashtag=&quot;00000000-0000-0000-0000-000000000000&quot; data-hashname=&quot;#outlook&quot;<span class="ni">&amp;gt;&amp;lt;</span>a class=&quot;ms-hashTag&quot; href=&quot;/_layouts/15/FeedRedirector.aspx?type=tag<span class="ni">&amp;amp;</span>amp;value=%23outlook&quot; rel=&quot;#outlook&quot;<span class="ni">&amp;gt;</span>#outlook<span class="ni">&amp;lt;</span>/a<span class="ni">&amp;gt;&amp;lt;</span>/span<span class="ni">&amp;gt;</span> <span class="ni">&amp;lt;</span>span class=&quot;ms-rtestate-read ms-socialentity&quot; data-hashtag=&quot;00000000-0000-0000-0000-000000000000&quot; data-hashname=&quot;#metadata&quot;<span class="ni">&amp;gt;&amp;lt;</span>a class=&quot;ms-hashTag&quot; href=&quot;/_layouts/15/FeedRedirector.aspx?type=tag<span class="ni">&amp;amp;</span>amp;value=%23metadata&quot; rel=&quot;#metadata&quot;<span class="ni">&amp;gt;</span>#metadata<span class="ni">&amp;lt;</span>/a<span class="ni">&amp;gt;&amp;lt;</span>/span<span class="ni">&amp;gt;</span> <span class="ni">&amp;lt;</span>span class=&quot;ms-rtestate-read ms-socialentity&quot; data-hashtag=&quot;00000000-0000-0000-0000-000000000000&quot; data-hashname=&quot;#termstore&quot;<span class="ni">&amp;gt;&amp;lt;</span>a class=&quot;ms-hashTag&quot; href=&quot;/_layouts/15/FeedRedirector.aspx?type=tag<span class="ni">&amp;amp;</span>amp;value=%23termstore&quot; rel=&quot;#termstore&quot;<span class="ni">&amp;gt;</span>#termstore<span class="ni">&amp;lt;</span>/a<span class="ni">&amp;gt;&amp;lt;</span>/span<span class="ni">&amp;gt;</span> <span class="ni">&amp;lt;</span>/p<span class="ni">&amp;gt;&amp;lt;</span>/div<span class="ni">&amp;gt;</span><span class="nt">&lt;/ntext2&gt;</span>
</span><span class='line'><span class="nt">&lt;ntext9&gt;</span>#metadata|9434622a-60e1-47c6-9b58-17b955c31410;#outlook|497ba856-65ff-45d7-89f6-6302e041e4b8;#reply|5c68c7c8-38cc-4964-850f-8c1e02076c04;#termstore|b2969adf-a746-4c0e-b38f-db7a77de7788<span class="nt">&lt;/ntext9&gt;</span>
</span><span class='line'><span class="nt">&lt;nvarchar3&gt;</span><span class="ni">&amp;lt;</span>8b0edc16e721456986d9d04eac185d5d@SharePoint<span class="ni">&amp;gt;</span><span class="nt">&lt;/nvarchar3&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>The Bug</h2>

<p>The root cause of me digging down this rabbit hole was no matter what I did, I couldn&rsquo;t find content tagged with certain hashtags that I <em>know</em> existed. I had a tendency to use the <code>#sharepoint</code> hashtag a <em>lot</em> in both my microblog feed as well as in my community discussion. Yet, when I attempted to search for that hashtag through the search center user interface, only the microblog posts would show - none of the community discussion threads.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-7-search.png"></p>

<p>Furthermore, when I would check the hashtag profile for <code>#sharepoint</code>, it would show the same - only microblog posts, no community discussions. This is a <strong>significant</strong> usability issue.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-8-hashtagprofile.png"></p>

<p>I verified when creating a reply to a community discussion, complete with a <em>new</em> hashtag, the hashtag does get added to the managed metadata term set, as seen in the query from the Managed Metadata Service database above. In the <code>ECMTermLabel</code> database table, we can clearly identify the hashtag terms <code>#reply</code>, <code>#outlook</code>, <code>#metadata</code>, and <code>#termstore</code> added as part of the comment. As seen in the XML block from <code>AllUserData</code> above, we see that SharePoint is correctly associating the hashtags in the post with their identity in the managed metadata service. Just to make sure that the latest hashtags are exhibiting this problem, I performed a search and found nothing.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-9-outlook.png"></p>

<p><img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-10-contenttypes.png">
The biggest thing that I wanted to find out was whether Discussion Lists were properly surfacing hashtags as the appropriate metadata for the search service to identify them. When I looked at the list settings for the Discussions List, I found that it was affiliated with two content types: <code>Discussion</code> and <code>Message</code>. For the discussion list, we can clearly see that it is not directly using hashtags via the columns composition:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-11-columns.png"></p>

<p>Furthermore, if you look at the Discussion and Message content types, <strong>neither</strong> reference Hashtags as a column:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-12-discussion-columns.png">
<img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-13-message-columns.png"></p>

<p>Just to double check, I decided to look at the Microfeed for my personal site to see if the hashtags were being elevated as their own column. You can access your microfeed list by going to <code>/personal/USERNAME/Lists/PublishedFeed</code>. Indeed, when I looked at the columns for this list, <strong>Hashtags</strong> from the Managed Metadata Columns collection <strong>were</strong> being surfaced:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-20-sharepoint-2013-community-tagging-architecture-and-bug/bug-14-publishedfeed-columns.png"></p>

<h2>Summary</h2>

<p><del>If this is indeed a bug, I can hope that Microsoft will fix this problem ASAP, as it&rsquo;s a significant hinderance to groups adopting SharePoint 2013 for it&rsquo;s social aspects. Despite all the marketing statements indicating that 2013 makes things much easier to find, this seems to be a limitation of SharePoint Social Search. I plan on creating a bug with Microsoft&rsquo;s bugreporting system and will keep this post updated with information as it evolves.</del></p>

<p><strong>Update (25/Apr/2013)</strong>: I have received word from Jennifer Bester (<a href="http://twitter.com/jbester" name="update" target="_blank">@jbester</a>), a Microsoft Field Engineer, that Microsoft <strong>has</strong> acknowledged this as a bug and has implemented a fix. It is due to be released in the June 2013 CU for SharePoint. As soon as that CU is published I&rsquo;ll be applying it to our on-premise environment. SharePoint Online customers <strong>should</strong> be seeing this bug fixed ahead of the CU.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SharePoint 2013 Tagging - Social Tags, Hashtags, and Keywords]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/12/18/sharepoint-2013-tagging-social-tags/"/>
    <updated>2012-12-18T09:07:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/12/18/sharepoint-2013-tagging-social-tags</id>
    <content type="html"><![CDATA[<p>SharePoint 2013 is now publicly available and enterprises are taking an earnest look at many of its features, specifically the social features. I won&rsquo;t lie, I&rsquo;m a fairly decent microblogger, and at <a href="http://www.improvingenterprises.com/">Improving Enterprises</a> we actively use <a href="http://www.yammer.com/">Yammer</a> to communicate company-wide. That feature is increasingly useful to have meaningful conversations when it comes to promoting achievements, asking questions that require a larger audience to answer, and to share transient things like pictures and videos. However, when it comes to sharing documents and collaborating on a project, SharePoint wins over <a href="http://www.yammer.com/">Yammer</a> every time. That&rsquo;s why we have <a href="http://office365.microsoft.com/">Office 365</a> within our company. So, to hear that many of Yammer&rsquo;s features are now native to SharePoint, I became very interested in digging in - as did my customer.</p>

<p><a href="http://www.improvingenterprises.com/">Improving</a> is not nearly as large a company as the customer I work for. They are a financial institution with 40k+ employees worldwide. As a result, they have a distinct need to be social. But, they are also encumbered with some regulatory restrictions affecting their social deployment. As a result, introducing social across their firm is quite a challenge, especially when there are many stakeholders who are considering multiple competing products, including <a href="http://www.jivesoftware.com/">Jive</a>, <a href="http://www.osqa.net/">The Open Source Q&amp;A System (OSQA)</a>, and <a href="http://www.yammer.com/">Yammer</a>.</p>

<p>A <strong>large</strong> part of social in the listed products and many other social networks is the concept of tagging. SharePoint 2010 started venturing down the path of tags by creating the <em>Tags and Notes</em> board, giving users the ability to tag files and lists publicly (or privately), making it easier to categorize items in SharePoint. You could also enhance your user profile by indicating what topics (Keywords) you should be asked about, giving users a sense that you&rsquo;re the expert in those key fields. All in all, a good step in the social direction, but still behind the curve.</p>

<p>SharePoint 2013 continued to build on tagging with the introduction of <strong>#tags</strong> (prononunced hashtags). This is more beneficial to the social story for many reasons. First: hashtags become a first-class citizen in the sense that users no longer have to go out of their way to add a tag to something (like a conversation, comment, or microblog entry). Second: hashtags are always public, meaning that users have the collection of hashtags at their fingertips, giving them helpful hints on how to categorize their entry. Third: hashtags seem to be used anywhere you can tag - whether it&rsquo;s in conversations, comments, or when tagging documents or libraries.</p>

<p>However, as I continued to dig into the social and tagging story, there seems to be some discrepancies in several of the features. The purpose of this post is to highlight that while <strong>#tags</strong> seem to be the direction that Microsoft would rather push users to use in their tagging strategy, integrating their existing social tagging strategy seemed to be left behind in SharePoint 2013.</p>

<!--more-->


<h2>Show Me More Tags</h2>

<h3>Tags &amp; Notes</h3>

<p>As mentioned above, there are several different ways to tag content in SharePoint 2013. The first is the original tagging strategy through the <em>Tags &amp; Notes</em> board.</p>

<p><img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/tags-and-notes-ribbon.png">
<img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/tags-and-notes.png"></p>

<p>In this board, when you start typing text, you&rsquo;ll get helpful hints of the various <strong>Keywords</strong> already available by means of other user contributions and pre-populated keywords from administrators of the Managed Metadata. What&rsquo;s even more impressive is you can not only leverage Keywords from traditional tags, but also <strong>#tags</strong>:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/tags-and-notes-hints.png"></p>

<h3>Newsfeed</h3>

<p>As everyone has been talking about, the Newsfeed is probably the singular most important feature to the social story. It&rsquo;s the user&rsquo;s &ldquo;dashboard&rdquo; into what&rsquo;s relevant to them, what&rsquo;s happening for everyone, and how to get to most other contextually-relevant content in the farm. If you read most of the marketing talk on the SharePoint 2013 social features, one of the biggest considerations was how to surface content that&rsquo;s not just useful, but contextually relevant. Finding a sales report from the previous quarter may be useful in my position, but when I&rsquo;m trying to search for content on the proposed social media marketing strategy, it isn&rsquo;t useful.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/newsfeed.png">
<img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/newsfeed-following.png"></p>

<p>From the newsfeed, I can quickly share status updates with everyone, my team, or other audiences of the sites I&rsquo;m following. I can mention other users by using an @ symbol in front of their name and also have multiple <strong>#tags</strong> in a single post. At a glance, I also see information about the sites, documents, people, and tags that I&rsquo;m following, making it easy to get around to find items that are most relevant to me. Searching for content is ubiquitous - you can pretty much search for content from anywhere in your SharePoint farm using the out-of-the-box templates.</p>

<h3>Communities</h3>

<p>Communities are the next biggest value-add to social adoption in SharePoint 2013. Communities are reminicent to forums and Q&amp;A boards (like <a href="http://www.stackoverflow.com/">StackOverflow</a>). Users can start threads in different categories of conversation and have rich discussion. <strong>#tags</strong> are ubiquitous, and can be added to questions and replies. I won&rsquo;t go into the number of different features of communities, but suffice to say that I can easily add <strong>#tags</strong> to any of my interactions and they surface within searches and the newsfeed just like hashtags used in my microblogs.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/community-question.png"></p>

<p>However, one thing that appears to be less straight-forward is using managed metadata/keywords to tag individual responses. I can access the <strong>Tags &amp; Notes</strong> button from the <strong>Page</strong> tab, but what&rsquo;s less clear is what a &ldquo;Page&rdquo; is in the context of tagging content. Does it relate to the entire thread, or just the question? There are some unanswered questions around general social tagging for community discussions.</p>

<p><strong>Off-topic:</strong> The biggest thing communities are meant to replace: distribution lists. Microsoft threatened to remove distribution lists from Exchange 2007 in favor of SharePoint, but backed off when they nearly had an enterprise revolt. They stayed away from the topic in Exchange 2010 and SharePoint 2010 (as far as I could tell), but 2013 seems to be a renewed effort. The message: communicating heavily through e-mail using Distribution Lists is a terrible approach. I&rsquo;m in agreement. When I was a heavy Atlassian Confluence user, I found little point in communicating lengthy conversations in e-mail. Once I left, those e-mails would no longer be useful to future teams, and valuable business justification and decisions will be lost. Instead, I preferred to document and carry out these conversations in a Wiki (largly due to the <a href="http://blogs.atlassian.com/2009/01/2009_email_brev/">E-mail Brevity Challenge of 2009</a>).</p>

<h4>Social Tags</h4>

<p>What&rsquo;s important to note, however, is the use of tags via the <strong>Tags &amp; Notes</strong> board are <strong>not</strong> social tags by default. This is nothing new from SharePoint 2010, if you&rsquo;ve already taken a look at this. What&rsquo;s even more surprising is tags in communities or on your newsfeed are also, not social tags. To fix <strong>Tags &amp; Notes</strong>, you have to go into the document library settings (specifically, the <em>Enterprise Metadata and Keywords Settings</em> section in order to enable the ability to save the metadata on this list as social tags. I have yet to figure out how to do this for communities or newsfeeds.</p>

<p><img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/enable-social-tags.png"></p>

<p>Personally, I feel that this is a missed opportunity. If Microsoft wants to solidify the social story more, then trying to surface the tagging of documents only helps that cause. Additionally, doesn&rsquo;t it make sense that all <strong>#tags</strong> are social tags? If we&rsquo;re using it in a social context, then it should be surfaced by the social controls. I digress, however, as the use cases for tagging vary widely and this may have been a strategic decision.</p>

<p>Why does marking a tag a social tag important? In SharePoint 2010 (and 2013), the only way you can surface a tag in your newsfeed is to follow it. To be able to follow it, the tag has to be a social tag. Not just any enterprise metadata can be followed in your newsfeed. For a large majority of metadata, however, this is totally fine: we likely don&rsquo;t care to surface metadata from a term set dubbed <em>SOX Compliance Restriction Codes</em> showing ST123X-F.</p>

<p><img class="left" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/tag-cloud.png"></p>

<p>Another reason social tags are important: the Tag Cloud. The tag cloud is a cool (but not innovative) feature to help surface the most popular tags in your subsite (or across the entire farm). The size of the text changes based on the number of uses of a particular tag. Nevertheless, other items like the tag cloud rely solely on social tags, not managed metadata tags. Therefore, when you drop one of those controls into a site, what&rsquo;s rendered is based <strong>only</strong> on social tags. Crack open the code to check for yourself. I did.</p>

<h3>Hashtags</h3>

<p>This is the newest addition to the social tagging strategy in SharePoint 2013. <strong>#tags</strong>, like enterprise keywords and social tags, are a broadly defined concept meant to be leveraged in a wide capacity. Much like in social networking sites like Twitter and Facebook, the use of tags are to categorize a post, making it easier for individuals to search and identify related contents. All one has to do is add a hash in front of any word and SharePoint will convert that to a hashtag. When viewing the comment with a hashtag, SharePoint automatically renders it as a bold hyperlink to help make navigating and finding related content easier.</p>

<p><img class="left" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/hashtags-newsfeed.png"></p>

<p>I regularly go to conferences that define a hashtag for people to use when posting to Twitter. This makes it easy for me as a conference organizer <strong>and</strong> an attendee to perform a search strictly on that hashtag. SharePoint is no different: they&rsquo;ve realized that searching for hashtags and surfacing those results is strategically important to help further the social adoption in 2013. We see this through the hashtag profile pages (accessible by simply clicking the hashtag link) and through featured content controls in the search center.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/hashtags-profilepage.png">
<img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/hashtags-trending.png">
<img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/hashtags-search-featured-content.png"></p>

<p>Other controls exist (particularly in the newsfeed) that surface trending hashtags, which is useful to help bring visibility to important conversations or activities within the company.</p>

<h4>Hashtags and Social Tags in the Managed Metadata Service</h4>

<p>However, where I find the disconnect with the social strategy is that not all hashtags are social tags. Furthermore, not all Managed Metadata / Enterprise Keywords are social tags. Yet, most of this content all ends up in the Managed Metadata Service, but in two distinctly different System Term Sets: Hashtags and Keywords.</p>

<p><img class="left" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/managed-metadata-service-overview.png"></p>

<p>Even in our simple test environment with 7 enterprise users testing the social features, it became quite easy to cross-polute our term sets. While all of our terms in the Hashtag set are definitely hashtags, many of the terms in the Keywords set can be clasified as hashtags.</p>

<p><img class="left" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/managed-metadata-service-hashtags-set.png">
<img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/managed-metadata-service-keywords-set.png"></p>

<p>What&rsquo;s really disappointing about this is the fact that none of those tags in either are guaranteed to make it to the social tags. Those are stored completely separately from the Managed Metadata Service. Social tags are an aspect of the user profile service and are stored in those databases. This is where things start to get very confusing. If you crack open the <em>User Profile Service Social Database</em>, there&rsquo;s a <code>SocialTags</code> table that contains all tags used for Social elements. As you can see in the below results, these include regular keyword metadata tags as well as hashtags.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/user-profile-service-social-tags-table.png"></p>

<p>There are a couple of ways this is relevant. I can choose to follow a hashtag in SharePoint quite easily. In fact, SharePoint does an <strong>excellent</strong> job surfacing how to follow hashtags on your newsfeeds. While I can also follow social (not hash) tags, there is a distinct disconnect. If I tag a document with the <strong>SharePoint</strong> tag, if I&rsquo;m following the <strong>#SharePoint</strong> hashtag, I won&rsquo;t see that document in my newsfeed. I have to be following <strong>both</strong> the <strong>SharePoint</strong> tag and the hashtag.</p>

<p><img class="right" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/hashtags-follow.png"></p>

<p>This also affects search. As seen above, I can search for a hashtag and see all content tagged as a featured search result. However, searching for standard social tags can only be done through the tag profile page, or by using a specialized search string that&rsquo;s really only formable by clicking links only from the tag profile. The result is an inconsistent search experience for users when it comes to tags.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-12-18-sharepoint-social-tags/social-tags-search.png"></p>

<h2>Conclusion</h2>

<p>I&rsquo;m overwhelmingly optimistic about the social story in SharePoint 2013. It&rsquo;s been missing for too long and has hindered adoption of SharePoint as a fundamental enterprise collaboration platform. For enterprises which have internet filters restricting access to Facebook, Twitter, and many other social networking sites, this will come as a welcome relief to employees who enjoy that form of social interaction. The communities and the newsfeed bridge two types of social communities: the forum community with the more mainstream social media community.</p>

<p>That said, Microsoft has introduced a major uphill battle for the enterprise to strategize on how to roll out social. I firmly believe that leaving it strictly to the community to self-describe their social story will result in the same cluttered mess that SharePoint is in most enterprises. Adoption will languish and the story gets that much more difficult for the organization to trust the social story in v.Next.</p>

<p>My gut recommendation for tagging in SharePoint 2013 is the following. This is likely to evolve as I come to understand the original intent behind how <strong>#tags</strong> were supposed to play with social tags.</p>

<ul>
<li>If you&rsquo;re rolling this new, recommend users always define tags in terms of <strong>#tags</strong>.</li>
<li>If you&rsquo;re upgrading:

<ul>
<li>See which keywords make sense to resurface as <strong>#tags</strong>.</li>
<li>Delist the original keywords you converted to <strong>#tags</strong> as taggable.</li>
</ul>
</li>
<li>Drop the Tag Cloud Web Part into community sites to surface popular tags.</li>
<li>Appoint someone in the organization as being responsible for the Keywords and Hashtags term stores.

<ul>
<li>This person should be responsible for pre-populating these term stores with common terminology throughout the organization.</li>
<li>This person should seek out other more specific terminology used within specialized departments.</li>
<li>This person should prune irrelevant, inappropriate, or duplicate terms in each of the stores to keep the sets fairly sane and easy for users.</li>
</ul>
</li>
<li>Give employees time to play with and <em>learn to use</em> the social features in SharePoint 2013.

<ul>
<li>Users who have used Facebook and Twitter understand the value and will quickly feel at-home.</li>
<li>Users who have used forums will also feel right at-home with communities and will quickly want to create their own.

<ul>
<li>Dissuade them from creating a new community unless they have a significant enough interest and make them realize they need to be a curator to keep it alive.</li>
</ul>
</li>
<li>Users who are anti-social or have not adopted Facebook or Twitter (like my parents) need this time to understand the value of that feature.</li>
<li>All users need time to figure out what they have to do to follow <strong>#tags</strong>, users, documents, and lists.</li>
<li>Come up with a compelling story of how your department uses social.

<ul>
<li>After all, if you&rsquo;re not eating your own dog food, how do you expect your users to use it?</li>
</ul>
</li>
</ul>
</li>
</ul>


<p>Either way, the social features will really help to drive adoption of SharePoint 2013 and you&rsquo;ll enjoy them when you start playing with them. If you have any questions, don&rsquo;t heistate to drop a comment below or shoot me an e-mail at chris (at) chrisweldon (dot) net.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[It's Time to Learn Windows Azure]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/10/10/its-time-to-learn-windows-azure/"/>
    <updated>2012-10-10T17:02:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/10/10/its-time-to-learn-windows-azure</id>
    <content type="html"><![CDATA[<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-10-10-its-time-to-learn-windows-azure/windows_azure_logo2.jpeg" title="Windows Azure" ></p>

<p>On October 22nd, I&rsquo;ll be presenting with several of our best Azure consultants at the <a href="http://www.improvingenterprises.com/events/event/windows-azure-developer-camp/">Windows Azure Developer Camp</a> at Microsoft&rsquo;s Houston Offices. <a href="http://www.improvingenterprises.com">Improving Enterprises</a> has been working on our Azure competencies for the last couple of years and have had <em>great</em> success at several customer engagements where we deployed solutions to Azure. These engagements combined with the <a href="http://www.improvingenterprises.com/about/people">amazing talent</a> we have here at Improving has allowed us to maintain our Microsoft Certified Partnership and become an Azure Circle Partner. In short, this should be an <em>awesome</em> <strong>free</strong> event.</p>

<p>At this event, we&rsquo;ll be having not only presentations, but <em>hands-on workshops</em> on the following topics:</p>

<ul>
<li>Windows Azure Cloud Services</li>
<li>Windows Azure SQL Database</li>
<li>Windows Azure Virtual Machines</li>
<li>Windows Azure Access Control Service</li>
<li>Windows Azure Mobile Services</li>
</ul>


<p>If you&rsquo;ve always been interested in learning about how to make the move to the cloud, there&rsquo;s never been a better time. This event is <strong>free</strong>, and everything (food, drinks, the software bits) are provided. It is BYOC (bring your own computer), so make sure to install the <a href="http://www.devcamps.ms/windowsazure/downloads">Azure Camps Kit</a> ahead of the event! I look forward to seeing you there!</p>

<h3 style="text-align: center;"><a href="http://www.improvingenterprises.com/events/event/windows-azure-developer-camp/">More Info and Registration</a></h3>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SqlCacheDependency in HTTP Module Supporting SharePoint]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/10/08/sqlcachedependency-in-http-module-supporting-sharepoint/"/>
    <updated>2012-10-08T16:40:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/10/08/sqlcachedependency-in-http-module-supporting-sharepoint</id>
    <content type="html"><![CDATA[<p>A customer of mine had some code that caches all of the rows from a SQL table in order to ensure the highest possible thruput with low overhead. Unfortunately, the code was caching the data on the <strong>first</strong> request, and not letting go of the cached data. Therefore, the only way to clear the cache or load new records was to perform an <code>iisreset</code>, taking the website offline. For this production SharePoint instance which serves over 40k employees, this is not an acceptable solution during the day. So, we decided to look into an alternative solution: <code>SqlCacheDependency</code>.</p>

<!--more-->


<p>Disclaimer: Ultimately, I plan on coming back around and <em>completely</em> refactoring what you see below. It&rsquo;s ugly as sin and can be <em>much</em> improved. I&rsquo;ll write a separate blog post once I do. However, I felt it important to at least get this off my chest, as I&rsquo;m notoriously bad about making sure to blog about solutions I find.</p>

<p>As a little more background, the customer had written a custom <code>IHttpModule</code> that sits in the IIS Pipeline for their SharePoint sites. The purpose of this module was to check if the user should be redirected to a different page based on the current requesting page. However, since this sits in front of a SharePoint site <em>and</em> serves 40k employees, it needed to be <strong>fast</strong>. Therefore, they used the following caching strategy:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">OnBeginRequest</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Cache</span><span class="p">.</span><span class="n">Count</span> <span class="p">==</span> <span class="m">0</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">DataTable</span> <span class="n">dataTable</span> <span class="p">=</span> <span class="n">DataAccessLayer</span><span class="p">.</span><span class="n">GetUrlMap</span><span class="p">();</span>
</span><span class='line'>        <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">row</span> <span class="k">in</span> <span class="n">dataTable</span><span class="p">.</span><span class="n">Rows</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Cache</span><span class="p">.</span><span class="n">Insert</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s">&quot;SourceUrl&quot;</span><span class="p">],</span> <span class="n">row</span><span class="p">[</span><span class="s">&quot;DestinationUrl&quot;</span><span class="p">]);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">string</span> <span class="n">destinationUrl</span> <span class="p">=</span> <span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Cache</span><span class="p">[</span><span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Request</span><span class="p">.</span><span class="n">Url</span><span class="p">.</span><span class="n">ToString</span><span class="p">()]</span> <span class="k">as</span> <span class="kt">string</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">destinationUrl</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Redirect to destination Url.</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The following is a simple sample of the method being called in the <code>DataAccessLayer</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">static</span> <span class="n">DataTable</span> <span class="nf">GetUrlMap</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">string</span> <span class="n">connectionString</span> <span class="p">=</span> <span class="n">ConfigHelper</span><span class="p">.</span><span class="n">GetConnectionString</span><span class="p">(</span><span class="s">&quot;URLMap&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">using</span> <span class="p">(</span><span class="n">SqlConnection</span> <span class="n">connection</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlConnection</span><span class="p">(</span><span class="n">connectionString</span><span class="p">))</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">SqlCommand</span> <span class="n">command</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCommand</span><span class="p">(</span><span class="s">&quot;usp_GetUrlMap&quot;</span><span class="p">,</span> <span class="n">connection</span><span class="p">);</span>
</span><span class='line'>        <span class="n">command</span><span class="p">.</span><span class="n">CommandType</span> <span class="p">=</span> <span class="n">CommandType</span><span class="p">.</span><span class="n">StoredProcedure</span><span class="p">;</span>
</span><span class='line'>        <span class="n">connection</span><span class="p">.</span><span class="n">Open</span><span class="p">();</span>
</span><span class='line'>        <span class="n">DataTable</span> <span class="n">table</span> <span class="p">=</span> <span class="k">new</span> <span class="n">DataTable</span><span class="p">();</span>
</span><span class='line'>        <span class="n">SqlDataAdapter</span> <span class="n">adapter</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlDataAdapter</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
</span><span class='line'>        <span class="n">adapter</span><span class="p">.</span><span class="n">Fill</span><span class="p">(</span><span class="n">table</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">table</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>(<strong>Disclaimer:</strong> this isn&rsquo;t the real code. It&rsquo;s a shortening of what&rsquo;s actually happening.)</p>

<h2>The Problem</h2>


<p>Well, for the astute coder, you&rsquo;ll quickly realize that there is no expiration set on the items inserted into the cache. Furthermore, there&rsquo;s nothing else that actually invalidates the cache. Therefore, the only way that we can get new data into the cache is to perform an <code>iisreset</code>, something that is not allowed during normal business hours. Therefore, it was time to come up with a different solution for invalidating the cache.</p>

<p>We talked about options such as sending a specific query string parameter and using that as the &ldquo;trigger&rdquo; to empty the cache. However, that becomes problemmatic as we have a farm-based SharePoint scenario supported by a NetScalar load balancer, meaning we&rsquo;d have to touch each web front end directly to ensure this works. That&rsquo;s tedious and subject to yet another concern: the possibility that the data in the cache will differ between servers.</p>

<h2>The Solution</h2>


<p>This is when we started looking at automated mechanisms to &ldquo;notify&rdquo; the caching subsystem that data has been updated, and to invalidate the cache. This is where the <a href="http://msdn.microsoft.com/en-us/library/system.web.caching.sqlcachedependency(v=vs.100).aspx" target="_blank">SqlCacheDependency</a> class comes into play. This class allows me to add a dependency to a specific database table for cache invalidation <em>or</em> a <code>SqlCommand</code>.</p>

<p>For applications written against Microsoft SQL Server 7.0 and SQL Server 2000, the <code>SqlCacheDependency</code> required configuration changes and some <code>aspnet_regsql</code> commands to be executed in order to prepare the enviornment to use the CacheDependency approprately. Even there, the <code>SqlCacheDependency</code> relied on polling the database - a rather expensive operation.</p>

<p>However, when using SQL Server 2005 and newer, Microsoft introduced a new asynchronous notifications system making it much simpler to know when changes to database records occur without having to constantly poll the table. This makes it much less expensive for tracking and something we were willing to consider. Even more importantly, it required <strong>no</strong> configuration changes to the Web Front Ends.</p>

<p>So, I started making the modifications to our caching engine to help support this. Because this is fairly tightly coupled to data access, though, my initial proof-of-concept includes some mandatory modifications to the data access layer (something I was not particularly comfortable with):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="n">DataTable</span> <span class="nf">GetUrlMap</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">string</span> <span class="n">connectionString</span> <span class="p">=</span> <span class="n">ConfigHelper</span><span class="p">.</span><span class="n">GetConnectionString</span><span class="p">(</span><span class="s">&quot;URLMap&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">using</span> <span class="p">(</span><span class="n">SqlConnection</span> <span class="n">connection</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlConnection</span><span class="p">(</span><span class="n">connectionString</span><span class="p">))</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">SqlCommand</span> <span class="n">command</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCommand</span><span class="p">(</span><span class="s">&quot;usp_GetUrlMap&quot;</span><span class="p">,</span> <span class="n">connection</span><span class="p">);</span>
</span><span class='line'>        <span class="n">command</span><span class="p">.</span><span class="n">CommandType</span> <span class="p">=</span> <span class="n">CommandType</span><span class="p">.</span><span class="n">StoredProcedure</span><span class="p">;</span>
</span><span class='line'>        <span class="n">connection</span><span class="p">.</span><span class="n">Open</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">SqlCacheDependency</span> <span class="n">cacheDependency</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="k">try</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">cacheDependency</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlCacheDependency</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">catch</span> <span class="p">(</span><span class="n">DatabaseNotEnabledForNotificationException</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">try</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">SqlCacheDependencyAdmin</span><span class="p">.</span><span class="n">EnableNotifications</span><span class="p">(</span><span class="n">connectionString</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">catch</span> <span class="p">(</span><span class="n">TableNotEnabledForNotificationException</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="k">try</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>                <span class="n">SqlCacheDependencyAdmin</span><span class="p">.</span><span class="n">EnableTableForNotifications</span><span class="p">(</span><span class="n">connectionString</span><span class="p">,</span> <span class="s">&quot;URLMap&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span><span class="p">)</span>
</span><span class='line'>            <span class="p">{</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">finally</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">DataTable</span> <span class="n">table</span> <span class="p">=</span> <span class="k">new</span> <span class="n">DataTable</span><span class="p">();</span>
</span><span class='line'>            <span class="n">SqlDataAdapter</span> <span class="n">adapter</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SqlDataAdapter</span><span class="p">(</span><span class="n">command</span><span class="p">);</span>
</span><span class='line'>            <span class="n">adapter</span><span class="p">.</span><span class="n">Fill</span><span class="p">(</span><span class="n">table</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>            <span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Cache</span><span class="p">.</span><span class="n">Insert</span><span class="p">(</span><span class="s">&quot;URLMap&quot;</span><span class="p">,</span> <span class="n">table</span><span class="p">,</span> <span class="n">cacheDependency</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">table</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The above code is fairly straight-forward. The database and the table must have notifications setup at the SQL-level in order to have the caching dependency work in the prescribed manner. This is done through the <code>SqlCacheDependencyAdmin</code> class calls above. According to the <a href="http://msdn.microsoft.com/en-us/library/system.web.caching.sqlcachedependency(v=vs.100).aspx" target="_blank">MSDN documentation</a>, the only time exceptions would occur when calling those methods would be when the user executing the commands does not have the required permissions.</p>

<p>Other than setting up the <code>SqlCacheDependency</code>, everything else is the same. Oh, except for the fact that you have to supply the dependency <em>with</em> the object you are storing in the cache. Therefore, now the data access layer is now <strong>strongly</strong> coupled to the caching mechanism. I feel <em>really</em> dirty doing this.</p>

<p>If you look at the original code, you&rsquo;ll notice that I was caching each of the URLs as separate items in the cache. Unfortunately, if you attempt to do that here, you will get an exception with the message:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>An attempt was made to reference a CacheDependency object from more than one cache entry.</span></code></pre></td></tr></table></div></figure>


<p>Therefore, the &ldquo;fix&rdquo; for this is to store the entire <code>DataTable</code> in a single cache entry. This isn&rsquo;t bad, but means we have to move our lookup for the matching redirection record from &ldquo;hiding&rdquo; it within the caching logic to being a little more explicit. I actually plan to refactor this and use something like a <code>Dictionary</code> to make lookups still be more performant than right now - O(n).</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">OnBeginRequest</span><span class="p">(</span><span class="kt">object</span> <span class="n">sender</span><span class="p">,</span> <span class="n">EventArgs</span> <span class="n">e</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">DataTable</span> <span class="n">dataTable</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">string</span> <span class="n">destinationUrl</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Cache</span><span class="p">.</span><span class="n">Count</span> <span class="p">==</span> <span class="m">0</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Returning from the DataAccessLayer is redundant now.</span>
</span><span class='line'>        <span class="n">dataTable</span> <span class="p">=</span> <span class="n">DataAccessLayer</span><span class="p">.</span><span class="n">GetUrlMap</span><span class="p">();</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">dataTable</span> <span class="p">=</span> <span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Cache</span><span class="p">[</span><span class="s">&quot;URLMap&quot;</span><span class="p">]</span> <span class="k">as</span> <span class="n">DataTable</span><span class="p">;</span>
</span><span class='line'>    <span class="k">foreach</span> <span class="p">(</span><span class="n">DataRow</span> <span class="n">row</span> <span class="k">in</span> <span class="n">dataTable</span><span class="p">.</span><span class="n">Rows</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s">&quot;SourceUrl&quot;</span><span class="p">].</span><span class="n">Equals</span><span class="p">(</span><span class="n">HttpContext</span><span class="p">.</span><span class="n">Current</span><span class="p">.</span><span class="n">Request</span><span class="p">.</span><span class="n">Url</span><span class="p">.</span><span class="n">ToString</span><span class="p">(),</span> <span class="n">StringComparison</span><span class="p">.</span><span class="n">InvariantCultureIgnoreCase</span><span class="p">))</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="n">destinationUrl</span> <span class="p">=</span> <span class="n">row</span><span class="p">[</span><span class="s">&quot;DestinationUrl&quot;</span><span class="p">];</span>
</span><span class='line'>            <span class="k">break</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(!</span><span class="kt">string</span><span class="p">.</span><span class="n">IsNullOrEmpty</span><span class="p">(</span><span class="n">destinationUrl</span><span class="p">))</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Redirect to destination Url.</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<h2>SQL Stored Procedure Gotcha</h2>


<p>After all of the changes that I made, when I stepped thru the debugger, I was noticing very strange behavior. After I loaded items into the cache, the first request to the cache immediately afterwards (literally the following line after <code>GetUrlMap()</code>) was returning <code>null</code> - it couldn&rsquo;t find the <code>DataTable</code> it <em>just</em> cached. Very pecular indeed.</p>

<p>I suspected it had something to do with the stored procedure. First, I read a couple of articles which indicated that you must make sure that the SQL command executed in the stored procedure reference all schemas and tables - explicitly. Furthermore, you could <strong>not</strong> select all columns using the wildcard (*). Instead, you had to be explict with the columns you select. So, the following two SQL commands would not work using the <code>SqlCacheDependency</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">URLMap</span><span class="p">;</span>
</span><span class='line'><span class="k">SELECT</span> <span class="n">SourceUrl</span><span class="p">,</span> <span class="n">DestinationUrl</span> <span class="k">FROM</span> <span class="n">URLMap</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Instead, you had to change to be the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SELECT</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">URLMap</span><span class="p">].</span><span class="n">SourceUrl</span><span class="p">,</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">URLMap</span><span class="p">].</span><span class="n">DestinationUrl</span> <span class="k">FROM</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">URLMap</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>Unfortunately, after making these changes, it didn&rsquo;t solve the problem. I continued to hunt down the issue and managed to come across an <a href="http://forums.asp.net/t/1010106.aspx" target="_blank">ASP.Net forum post</a> which suggested to look for the following in my stored procedure:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">SET</span> <span class="n">NOCOUNT</span> <span class="k">ON</span>
</span></code></pre></td></tr></table></div></figure>


<p>Sure enough, this was in my Stored Procedure (as it seems to be for most). After removing, the cache resumed working correctly and didn&rsquo;t immediately purge after inserting. Essentially, the <a href="http://msdn.microsoft.com/en-us/library/ms181122(v=sql.90).aspx" target="_blank">MSDN Page for Creating a Query for Notification</a> indicates that using <code>SET NOCOUNT ON</code> is not allowed for stored procedures.</p>

<h2>Specifics with SharePoint</h2>


<p>I came across two specific issues that you have to keep in mind with loading this in SharePoint. First is how you declare the <code>SqlCacheDependency</code>. The <a href="http://msdn.microsoft.com/en-us/library/system.web.caching.sqlcachedependency(v=vs.100).aspx" target="_blank">reference documentation</a> indicates to use just the name of the database and the name of the table. This is fine <em>if</em> you have the connectionstring stored in your <code>Web.config</code> file. If you don&rsquo;t (as is the case in our environment), then you <strong>cannot</strong> use this manner of watching for database table changes - you <em>must</em> use a stored procedure or regular SQL Command.</p>

<p>Second, you have to be mindful of the fact that you cannot simply drop the <code>SqlDependency.Start(connectionString)</code> in <code>Application_Start</code> - SharePoint is in strict control of <code>Application_Start</code> However, putting it in your <code>IHttpModule</code>&rsquo;s <code>Init()</code> method is totally fine:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">void</span> <span class="nf">Init</span><span class="p">(</span><span class="n">HttpApplication</span> <span class="n">application</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">string</span> <span class="n">connectionString</span> <span class="p">=</span> <span class="n">ConfigHelper</span><span class="p">.</span><span class="n">GetConnectionString</span><span class="p">(</span><span class="s">&quot;URLMap&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="n">SqlDependency</span><span class="p">.</span><span class="n">Start</span><span class="p">(</span><span class="n">connectionString</span><span class="p">);</span>
</span><span class='line'>    <span class="n">application</span><span class="p">.</span><span class="n">BeginRequest</span> <span class="p">+=</span> <span class="n">OnBeginRequest</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Happy coding!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[FAST Search Thruput Optimization Troubleshooting]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/09/26/fast-search-thruput-optimization-troubleshooting/"/>
    <updated>2012-09-26T15:32:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/09/26/fast-search-thruput-optimization-troubleshooting</id>
    <content type="html"><![CDATA[<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/logo-fs4sp.png" title="Fast Search Server 2010 for SharePoint" ></p>

<p>The last couple of weeks in September I was tasked with identifying and fixing a problem with our production <a href="http://sharepoint.microsoft.com/en-us/product/capabilities/search/Pages/Fast-Search.aspx" target="_blank">FAST Search for SharePoint</a> environment: slow crawl rates. Our incremental crawls were taking anywhere between 45 minutes and several hours to run for each cycle, and a full crawl was taking in excess of 65 hours to crawl just under 1 million documents. Atrocious. I had little previous experience administering FAST search environments, and by the end of this process, I feel like a solid power administrator (but still by no means an &ldquo;expert&rdquo;). This post is meant to share my thought process, findings, resources, and other information available to me to help identify the bottlenecks and implement a fix to this problem.</p>

<!--more-->


<h2>About FAST Search for SharePoint (FS4SP)</h2>


<p>FAST Search was originally developed by a company called FAST Search and Transfer and was acquired by Microsoft in 2008. The acquisition was a strategic move on Microsoft&rsquo;s part to enter the enterprise search market. Although Microsoft had their own search products (Microsoft Search Server and Search Server 2010), the scalability and feature sets provided with FAST Search far outweigh that of Microsoft&rsquo;s search products. Unfortunately, these extra features come at a premium, but are truly necessary if you really want a rich search experience for users.</p>

<p><span class='pullquote-right' data-pullquote='Architecturally, FAST search components are very easy to configure and scale out to increase not only query thruput, but also crawling and indexing thruput and capacity.'>
Architecturally, FAST search components are very easy to configure and scale out to increase not only query thruput, but also crawling and indexing thruput and capacity. This is done by using a matrix configuration where servers are arranged into rows and columns. When you read the technical documentation, by adding rows, you increase redundancy of services, but also query capacity. However, when you add columns, you increase indexing capacity and thruput. Discussing the nuances of search rows and columns is another blog post in itself, so I&rsquo;ll leave that for a future post.
</span></p>

<p>Beyond simply adding servers to rows and columns, deciding which servers host which services involved in the content pipeline is extremely easy. All it takes is a configuration file change and issuing a single command across all servers in the FAST farm. You can also have multiple instances of the services to provide load balancing and high availability. How this works is also worthy of another blog post.</p>

<p>The following is how our environment is architected:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/topology.png" title="Our FAST Farm Topology" ></p>

<p>This is a fairly typical environment, where we are taking advantage of two rows of indexers for high availability, with two index columns for expanded capacity. Document processing is spread out over <em>all servers</em> to have more than enough pipeline bandwidth to constantly work on the large volume of content that our crawlers will be sending to our environment. Finally, these servers have 12 cores, 32G of RAM, and two GigE nics in a teaming configuration: more than beefy enough servers to quickly chew through the massive amount of content expected to be thrown its way.</p>

<h2>The Problem</h2>


<p>Our crawl rate was atrocious. The last full crawl took 63:47:23 to crawl 870K+ items - an effective crawl rate of 3.78 documents per second. Incremental crawls were taking in excess of 20 minutes each. This didn&rsquo;t make much sense given the horsepower that we had in our FAST and SharePoint environment. So, I was tasked with trying to get this crawl rate improved. But first, I had to learn how to administer a FAST environment.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/crawl-history-pre-network-updates.png" title="Crawl History - Pre-Updates" ></p>

<h2>Brain Food - The Books I Used</h2>


<p>One of the first books that I picked up was <a href="http://amzn.com/0470584661" target="_blank"><em>Professional Microsoft Search: FAST Search, SharePoint Search, and Search Server</em></a> (ISBN 978-0-470-58466-8). I read the majority of the book, but eventually stopped. This book is <em>not</em> very technically-oriented. It gives a great overview of the differences between the OOB SharePoint Search, Microsoft Search Server, and FAST Search. It provides screenshots and basic information on how to install FAST. It also provides the theory behind capacity planning and architecture, and considerations when building search-based applications. Ultimately, however, tips and information on how to administer the environment and identify bottlenecks was woefully inadequate.</p>

<p>The next book I started to read was <a href="http://amzn.com/0735662223" target="_blank"><em>Working with Microsoft FAST Search Server 2010 for SharePoint</em></a>. After cracking open this book, I was much more pleased and found more information on the various powershell commands and executables provided by FAST. In fact, one of the most important resources was a series of links I was able to find throughout the book that point to different pages on TechNet. These pages include the tools and other detailed information necessary to administer the FAST environment:</p>

<ul>
<li><a href="http://technet.microsoft.com/en-us/library/ff393782.aspx" target="_blank">FAST Search PowerShell Commandlets</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ee943520.aspx" target="_blank">FAST Search for SharePoint Command-Line Tools</a></li>
<li><a href="http://technet.microsoft.com/en-us/library/ff383289.aspx" target="_blank">Performance Counters</a></li>
<li><a href="http://technet.microsoft.com/en-us/library/gg604768.aspx" target="_blank">Performance and Capacity Monitoring</a></li>
</ul>


<p><span class='pullquote-left' data-pullquote='a good crawl rate should be between 45 and 60 documents per second.'>
One of the best resources I found was on <a href="http://www.youtube.com/watch?v=zoebkKWE_zs" target="_blank">YouTube</a>, titled <a href="http://www.youtube.com/watch?v=zoebkKWE_zs" target="_blank">Troubleshooting FAST Search and the SharePoint Crawler - An Operational Viewpoint</a> by <a href="http://blogs.msdn.com/b/kristopherloranger/" target="_blank">Kristopher Loranger</a> from Microsoft. One of the best tidbits in the video was this: a good crawl rate should be between 45 and 60 documents per second. So, I had a goal to shoot for. But, most importantly, he gave a simple trick to help identify where the bottleneck is: temporarily suspend indexing. By suspending indexing and performing another full crawl, you can identify whether the problem is on the SharePoint infrastructure, or on the FAST infrastructure side. If there is speedup after suspending indexing, the problem is FAST. Otherwise, the problem is SharePoint. A pretty simple technique to keep in your back pocket.
</span></p>

<p>The best article I found on the TechNet site was that on <a href="http://technet.microsoft.com/en-us/library/gg604768.aspx" target="_blank">Performance and Capacity Monitoring</a>. This told me specifically which performance counters to monitor, and how to use that information to identify bottlenecks. I kept referring back to this article when setting up Performance Monitor on each of the various servers.</p>

<h2>Interesting FAST Search Log Entries</h2>


<p>While looking through and gathering information that could be used to identify any bottlenecks in our environment, I decided to look at the FAST admin server logs in <code>&lt;FASTInstall&gt;\var\log\all.log</code>. In there, I noticed a <em>significant</em> number of the following entries:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemmsg: Subsystem operation call timeout (session 3, ops 558-&gt;558), sleeping 84 seconds before resubmitting operation set
</span><span class='line'>systemmsg: Subsystem operation call timeout (session 3, ops 551-&gt;551), sleeping 47 seconds before resubmitting operation set
</span><span class='line'>systemmsg: Subsystem operation call timeout occured 3 times, sending callback
</span><span class='line'>systemmsg: Subsystem operation call timeout occured 3 times, sending callback
</span><span class='line'>systemmsg: Subsystem operation call timeout occured 3 times, sending callback
</span><span class='line'>systemmsg: Subsystem operation call timeout occured 3 times, sending callback</span></code></pre></td></tr></table></div></figure>


<p>This was a significant problem during the full crawl. In fact, 15MB of those log entries kind of a problem. It was happening roughly once a second. Ultimately, what confused me about those log entries was the fact they were logged at an <code>INFO</code> log level - not warning or error. Call timeouts that occur that frequently should indicate some significant problem - but where? Was it a network problem, a processing problem, or some configuration problem? My gut reaction was to consider this a network problem, but I needed more statistics to be able to more acutely identify the elements influencing this problem.</p>

<h2>Performance Monitor - Knowledge is Power</h2>


<p>As mentioned above, I kept referring back to the <a href="http://technet.microsoft.com/en-us/library/gg604768.aspx" target="_blank">Performance and Capacity Monitoring</a> document on Microsoft TechNet and proceeded to setup monitors in Performance Monitor. The following explains what I setup on each of the servers in the environment.</p>

<ul>
  <li>
    <strong>Content SSA / Crawler</strong>
    <ul>
      <li>Batches Ready (OSS Search FAST Content Plugin)</li>
      <li>Batches Submitted (OSS Search FAST Content Plugin)</li>
      <li>Processor % (Processor)</li>
      <li>Bytes Total/sec (Network Interface)</li>
    </ul>
  </li>
  <li>
    <strong>Content Distributors</strong>
    <ul>
      <li>Document Processors (FAST Search Content Distributor)</li>
      <li>Document Processors Busy (FAST Search Content Distributor)</li>
      <li>Average Dispatch Time (ms) (FAST Search Content Distributor)</li>
      <li>Bytes Total/sec (Network Interface)</li>
    </ul>
  </li>
  <li>
    <strong>Indexers</strong>
    <ul>
      <li>Current Queue Size (FAST Search Indexer Status)</li>
      <li>FiXML Fill Rate (FAST Search Indexer)</li>
      <li>Active documents (FAST Search Indexer Partition)</li>
      <li>Bytes Total/sec (Network Interface)</li>
    </ul>
  </li>
</ul>




<h3>Understand the Data Flow before Understanding the Statistics</h3>


<p><span class='pullquote-right' data-pullquote='A problem earlier in the content pipeline can manifest bad / inappropriate metrics further down the line.'>
Before we began to look at the statistics, it&rsquo;s important to understand how the content flows from end-to-end. A problem earlier in the content pipeline can manifest bad / inappropriate metrics further down the line. So, identifying the bottleneck where it really is (as early as possible) is truly important. The steps of content processing is best represented by this image found on <a href="http://technet.microsoft.com/en-us/library/gg604768.aspx" target="_blank">TechNet</a>:
</span></p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/fast-content-flow.png" title="FAST Content Flow" ></p>

<p>Let&rsquo;s take a look at a few of the metrics I managed to gleam from these performance metrics.</p>

<h4>Content Search Service Application / Crawler</h4>


<p>Per our architecture, we have only a single crawler component. So, getting a sense of how much content the Content SSA is pushing to the Content Distributors is the first step in the process. Again, if you refer back to the diagram of the content processing pipeline, sending data from the crawler to the document processor is the first step. So, let&rsquo;s look at the network diagrams for this server:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/contentssa-network-before.png" title="Content SSA Network Before Fix" ></p>

<p>We are looking at two network interfaces as there is not a consolidated performance counter for the &ldquo;virtual&rdquo; paired interface that Broadcom creates for us. Therefore, I have to look at each of the network interfaces. Nevertheless, you can see that the peak network traffic for this server was roughly 57 MBps, averaging at only 443 KBps. This isn&rsquo;t really high thruput considering the dual paired GigE network interfaces on this server.</p>

<p>If we look at the network traffic on the admin server, it echos that of the Content SSA - low network thruput (peak traffic 127 MBps, averaging around 477 KBps):</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/admin-network-before.png" title="FAST Admin Network Before Fix" ></p>

<p>So, while this is looking like a network bottleneck, it&rsquo;s still important for us to look at the other statistics. Unfortunately, I don&rsquo;t have screenshots of the next important statistic: <strong>Batches Ready</strong>. I found that when looking at that statistic, it rose sharply and remained high throughout the crawl - in excess of 15K items, regularly refilling after dropping to about 7-8K. What this meant was the crawler was able to chew through data faster than the FAST search environment was able to process it. If <strong>Batches Ready</strong> was close to or at 0, then that would mean the crawler could not keep up with the FAST search processing. So, this news made me question whether I was on the proper path hunting down a network issue.</p>

<p>However, this did not rule out the possibility of a network problem. I was able to look at the <strong>Batches Submitted</strong> statistic and find that it was <em>very</em> low. This is indicative of some bottleneck (either network or disk), as the content server should have been able to push all of the batches as soon as they were ready. But, the amount being submitted during each cycle was dismal - less than 100 batches per cycle.</p>

<p>So, let&rsquo;s switch over to the Document Dispatcher to figure out what may be going on there. Again, continuing with my hunch, I wanted to look at the <strong>Average dispatch time</strong>. This is solidly a network bottleneck monitor, and the results below further my suspicions. Average dispatch times were in excess of 12,900 ms. According to Microsoft, dispatch times over 10 ms indicate network congestion.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/admin-processinganddispatch-before.png" title="FAST Admin Processing and Dipatch Times - Before Fix" ></p>

<p>Of course, an obligatory look at the document processors in-use is necessary. Disappointingly, we were not using even half of our document processors on average. But, this is likely because we can&rsquo;t feed enough content fast enough to the servers, leaving the document processor threads idle, waiting for work. An easy way of double checking the values below is to run the following command from command line:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>psctrl status</span></code></pre></td></tr></table></div></figure>


<p>This will show the status of <strong>all</strong> document processors in the farm. Based on the graph below, most times when I was checking that, most DPs were idle. However, just because we had a little under half working at seemingly all times, they weren&rsquo;t doing much. This metric is literally either an indicator that a DP is working or it&rsquo;s not. If you dig into the workload by using the command above, you&rsquo;d have found that most servers were only processing between 4 and 5 documents at a time. Looking at the CPU utilization of each of the document processing servers, I was barely exceeding 30% usage because of this lack of processing.</p>

<p>As I continued to look at the other metrics (like processor, network, disk), it became increasingly apparent that those metrics were deficient due to the lack of sufficient content reaching the servers. I continued to search the internet for recommendations, and finally managed to come across&hellip;</p>

<h2>The Solution</h2>


<p>The solution actually came in the form of two Microsoft articles: one on <a href="http://technet.microsoft.com/en-us/library/hh851996.aspx" target="_blank">TechNet<a/>, the other on the <a href="http://support.microsoft.com/kb/2570111" target="_blank">Microsoft KnowledgeBase site</a>. I finally managed to walk down the hierarchy of articles on the <a href="http://technet.microsoft.com/en-us/library/ee781286.aspx" target="_blank">FAST Search Server 2010 for SharePoint documentation</a> to the Troubleshooting section. Inside, there was an article titled <a href="http://technet.microsoft.com/en-us/library/hh851996.aspx" target="_blank">Crawling: Slow crawling and slow copying between the indexer and the search nodes</a>. This indeed identified the problems that I surmised: the network was the bottleneck.</p>

<p>In reading about the solution, it recommended that I turn off <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/gg463469.aspx" target="_blank">Network Task Offloading</a>. This was down at a hardware level that I had never really learned, despite my systems administration experience. In essence, Network Task Offloading helps ensure the responsibilities of initiating and validating network traffic between systems is delegated to the network controller hardware rather than the CPU. It makes sense: I want specialized controllers (network controllers, audio controllers, video controllers) to be responsible for processing the data they were specifically created to process. However, as the TechNet article mentions, Task Offloading causing slow crawl problems is typically seen in virtualized environments, and for good reason. In a virtual environment, the VM does not have direct access to the network controller. Instead, it&rsquo;s provided with a virtual adapter. If the virtualization kernel doesn&rsquo;t know to translate requests to that virtual adapter to the physical network controller, then inevitably the CPU gets the responsibility of processing those requests - at a significant premium over just telling the CPU to do it in the first place.</p>

<p>However, that was only part of the solution. When I continued to search, I came across a Microsoft KnowledgeBase article titled <a href="http://support.microsoft.com/kb/2570111" target="_blank">You cannot crawl or index SharePoint sites in FAST Search Server 2010</a>. This article referenced not only Network Task Offloading, but also <a href="http://support.microsoft.com/kb/951037" target="_blank">TCP Chimney Offload</a>. Ultimately, I <em>loved</em> that the KnowledgeBase article explained <strong>why</strong> these two things were bad for the FAST Search environment: IPSEC. IPSEC is implemented at Layer 3 (Networking Layer) of the OSI model. As a result, having TCP connections offloaded to hardware, unfamiliar with the security policies in place, will result in improper network activity.</p>

<p>Though the solution was straight-forward, it took me about 10 minutes per box to impelment. Do the following steps to <strong>all</strong> of your FAST servers as well as your Content SSA servers (crawlers):</p>

<h3>Disable TCP Chimney Offload and Task Offload</h3>


<p>Open a command prompt on your server as an administrator (make sure to use <strong>Run as Administrator</strong> if UAC is in effect). Then, run the following commands:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>netsh int tcp set global chimney=disabled
</span><span class='line'>netsh int ip set global taskoffload=disabled</span></code></pre></td></tr></table></div></figure>


<p>You can then verify those are disabled with the following commands:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>netsh int tcp show global
</span><span class='line'>netsh int ipv4 show global</span></code></pre></td></tr></table></div></figure>


<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/network-command.png" title="Disabling TCP Chimney and Task Offload" ></p>

<h3>Disable Checksum and Large Send Offload at Hardware Level (for Physical Servers)</h3>


<p>If you are not using Virtual Machines, you need to check the hardware-level configuration of each of your network adapters. In my case, we were using a Dell Server complete with Broadcom GigE network adapters which had to be configured through it&rsquo;s proprietary Broadcom Advanced Control Suite 3. I went through each of the network adapters in that interface and found the following settings:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/network-chimney.png" title="Disable Large Send Offload" ></p>

<p>Then, I had to check the server-level configuration for Checksum Offload and ensure it was set to disabled:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/network-checksum.png" title="Disable Checksum Offload" ></p>

<p>Finally, our systems administrators setup teaming across our network adapters for high availability and load balancing. I double checked the teaming configuration that <strong>IPv4 Checksum Offload</strong> and <strong>IPv4 Large Send Offload</strong> were not enabled. Thankfully, once I disabled those features on each of the network cards, the software was intelligent to disable that at the teaming level. However, it would be a good idea that you double check to make sure that your network card does the same:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/network-team.png" title="Team Configuration" ></p>

<h3>Reboot the Server</h3>


<p>This one is patently obvious. Once you muck with these network settings, you need to reboot to make sure they take effect.</p>

<h2>Results</h2>


<p>After making all of these changes, I started another full crawl to see if that made any bit of difference. At the completion of the full crawl, a total of 936872 results in 3:28:47 for an effective rate of 74.788 documents per second. This is an increase of nearly 20 fold, an <strong>amazing</strong> improvement, and well exceeding the desired crawl rate. To look at the results, let&rsquo;s start from the beginning and look at the networking charts on the crawl server:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/contentssa-network-after.png" title="Content SSA After Networking Updates" ></p>

<p>In looking at the Content SSA updates, the maximum thruput was 210 MBps, and the average was 8 MBps! A <strong>great</strong> speedup. That&rsquo;s a sufficient level of network traffic, so let&rsquo;s check out the admin network traffic.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/admin-network-after.png" title="Admin After Networking Updates" ></p>

<p>While the graph is less than menacing, the numbers don&rsquo;t lie: maximum thruput of 194 MBps and an average thruput of 10.9 MBps. Also significant speedup. Knowing that the content over the network seems to be flowing well, let&rsquo;s see how the crawl server&rsquo;s queue looked:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/contentssa-batches-after.png" title="Content SSA Batches Ready" ></p>

<p>The peak was still higher than I would like, but still much improved compared to previous: 9300. Considering the average was 922 batches ready for dispatch, I&rsquo;m more than happy with that level of improvement. Let&rsquo;s check out our document processor utilization:</p>

<p><img src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/admin-documentprocessors-after.png" title="Admin Document Processors after Networking Updates" ></p>

<p>You&rsquo;ll notice we have the same number of document processors available as previously: 37. However, what you&rsquo;ll also notice is at several points we had <strong>all</strong> document processors busy - none were idling. This typically occured as the processing load increased, and died off as the document processors completed processing. To verify that we were feeding content quickly enough to do the document processors, let&rsquo;s take a look at our dispatch rate:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/admin-processinganddispatch-after.png" title="Admin Average Dispatch Time" ></p>

<p>The average dispatch times were <strong>much</strong> lower. The peak was still unacceptable (at 8190ms), but you can see that was a rather odd fluke in our measurements. There may have been some other blocking process or anomaly in the network to cause this dispatch time, as the overall average is significantly lower than the max: 213ms. This is still outside of the recommended range Microsoft states (10ms), but is still significantly lower than our previous result.</p>

<p>Ultimately, the last thing to check was how the index servers responded to these updates. If we look at the processor metrics alone, you can see that the processor was finally being more fully utilized. Although these performance graphs barely show 100% utilization, the live graphs were almost peaking at 100% <em>constantly</em>:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/indexer-row0-processor-after.png" title="Indexer Row 0 Processor After Network Updates" ></p>

<p>But although the processor is a good metric of how utilized the server is, what&rsquo;s more important to determine that the indexers have sufficient amount of data to work against, is the FiXML rate. When we look at that, we see the rate is largely above 75%, the threshhold Microsoft recommends is necessary for a &ldquo;healthy&rdquo; FAST indexing envrionment:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/indexer-row0-fixml-after.png" title="Indexer Row 0 Processor After Network Updates" ></p>

<p>Looking at our crawl times now, I&rsquo;m <em>much</em> happier to see incremental crawls taking less than 10 minutes a piece, even when indexing 40K+ items:</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/crawl-history-post-network-updates.png" title="Crawl History after Network Updates" ></p>

<h2>Admin Reports and Conclusion</h2>


<p><span class='pullquote-right' data-pullquote='However, by paying close attention to the details and studying how your system is behaving, you&#8217;ll eventually find what you&#8217;re looking for.'>
In short, troubleshooting this issue was no walk in the park. FAST is not an easy system to understand. Throwing SharePoint into the mix (which is just as large and difficult) only makes matters worse. However, by paying close attention to the details and studying how your system is behaving, you&rsquo;ll eventually find what you&rsquo;re looking for.
</span></p>

<p>&lt;rant&gt;
Finding the information on what to look for, though, can be just as challenging. I found that things really started to take off for me only <em>after</em> I started reading the Microsoft FAST book. TechNet had the required documentation that I needed to understand how to diagnose the problem. Yet, I found that finding information on TechNet was <em>extremely</em> challenging. For a product that can cost in the tens of thousands of dollars for just a small environment, I&rsquo;d really like to see Microsoft invest some time in really understanding how end users look through their documentation, and really improve it. The &ldquo;auto-hiding&rdquo; links in the navigation heiarchy on the left of the page suck. What sucks even more? Not having an automatically expandable hierarchy so I can browse the hierarchy of contents. The fact that it would take me 15-20 clicks to get to the bottom of the FAST documentation is absurd - I should be able to have a full ToC - not a ToC at every major section all the way to the bottom of the stack.
&lt;/rant&gt;</p>

<p>I leave you with these wonderful Administrative Report graphs, just because I think they&rsquo;re actually really useful bits of information, though I don&rsquo;t feel like diving in to explain all of these.</p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/report-admin-crawl-protocol.png" title="Admin Reports Crawl Rate for Protocol" ></p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/report-admin-crawl-type.png" title="Admin Reports Crawl Rate for Type" ></p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/report-admin-crawlrate-ssa.png" title="Admin Reports Crawl Rate for SSA" ></p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/report-admin-crawlrate-type.png" title="Admin Reports Crawl Rate by Type" ></p>

<p><img class="center" src="http://www.chrisweldon.net/images/posts/2012-09-26-fast-search-thruput-optimization-troubleshooting/report-admin-queue.png" title="Admin Reports Content Queue" ></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SharePoint 2010 FAST Search Errors]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/08/23/sharepoint-2010-fast-search-errors/"/>
    <updated>2012-08-23T14:46:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/08/23/sharepoint-2010-fast-search-errors</id>
    <content type="html"><![CDATA[<p>Today I ran into a slew of interesting errors while working on my customer&rsquo;s SharePoint 2010 instance. They reported they were receiving errors while trying to search for content on their sites. As is typical, searching <em>had</em> worked before, but was no longer working. For reference, the error when they used the little search box below the ribbon was none other than the obligatory useless standard SharePoint error message:</p>

<p><img src="http://www.chrisweldon.net/images/posts/2012-08-23-sharepoint-2010-fast-search-errors/useless-sharepoint-error.png" alt="Useless SharePoint Error" /></p>

<p>If you get this, it&rsquo;s time to crack open the Event Viewer and the SharePoint Logs. If you&rsquo;re not on a single server environment (aka: a Farm), trying to find the Correllation ID is going to be truly fun. However, once you&rsquo;ve found the Correllation ID, look for the next Unexpected or Critical error. Initially, I came across the following <strong>Unexpected</strong> error:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>CoreResultsWebPart::OnInit: Exception initializing: System.NullReferenceException: Object reference not set to an instance of an object.
</span><span class='line'>at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.SetPropertiesOnQueryReader()
</span><span class='line'>at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnInit(EventArgs e)</span></code></pre></td></tr></table></div></figure>


<p>with the detailed exception being:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Internal server error exception: System.NullReferenceException: Object reference not set to an instance of an object.
</span><span class='line'>at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.SetPropertiesOnQueryReader()
</span><span class='line'>at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnInit(EventArgs e) System.NullReferenceException: Object reference not set to an instance of an object.
</span><span class='line'>at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.SetPropertiesOnQueryReader()
</span><span class='line'>at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnInit(EventArgs e)</span></code></pre></td></tr></table></div></figure>


<p>However, when I went digging a little further, I found the following error. If you find it as well, you&rsquo;re on the same track that I am:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Failed to connect to FASTSEARCHSERVER:PORT Failed to initialize session with document engine: Unable to resolve Contentdistributor</span></code></pre></td></tr></table></div></figure>


<p><strong>FASTSEARCHSERVER:PORT</strong> is the server and port of the FAST Search Service you should have already installed. If you find this, your query service application may not be able to talk to the FAST Search Server. I suggest you check for one (or all) of the following.</p>

<h2>Ensure the FAST Search Services are Running</h2>


<p>First, log in to all to all servers where you have installed the FAST Search Services. You&rsquo;ll need to open the Services Management console by doing the following:</p>

<ol>
<li>Go to <strong>Start</strong> &gt; <strong>Run</strong></li>
<li>Type <strong>services.msc</strong> and press enter</li>
<li>If you have UAC, you&#8217;ll be prompted for your Admin username and password</li>
</ol>


<p>In the list of services, search for the following and make sure <strong>all</strong> are started:</p>

<ul>
<li>FAST Search for SharePoint</li>
<li>FAST Search for SharePoint Monitoring</li>
<li>FAST Search for SharePoint Sam Admin</li>
<li>FAST Search for SharePoint Sam Worker</li>
</ul>


<p>If any of them are not started, I suggest shutting them all down. From there, only start the <strong>FAST Search for SharePoint</strong> service. This <em>should</em> start the other three services as well. Once they are all started, perform an <strong>iisreset</strong> on the web front ends (especially the one running the <strong>SharePoint Search Query and Site Settings Service</strong>) and try the search again.</p>

<h2>SSL Certificate Problem</h2>


<p>If the search is still failing after doing the above check, you need to check to see if the SSL Certificate used for FAST Search communication has expired. I found a <em>great</em> <a href="http://social.technet.microsoft.com/Forums/en-US/fastsharepoint/thread/890b9d38-f226-4afe-963b-59eba2450c80" target="_blank">TechNet article</a> (which points to an even better <a href="http://sharepointmalarkey.wordpress.com/2012/02/29/failed-to-initialize-session-with-document-engine-unable-to-resolve-contentdistributor/" target="_blank">Blog Post by SharePoint Malarkey</a> regarding this problem. Review the instructions in the <a href="http://sharepointmalarkey.wordpress.com/2012/02/29/failed-to-initialize-session-with-document-engine-unable-to-resolve-contentdistributor/" target="_blank">blog post</a> to verify whether you indeed have this problem.</p>

<h2>Is Anyone the Query Server?</h2>


<p>If you <em>continue</em> to receive errors after performing the above steps, check your SharePoint logs again for the Correllation ID. Somewhere around there you may find the following <strong>Unexpected</strong> error that looks similar to that at the top of this blog post:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>CoreResultsWebPart::OnInit: Exception initializing: Microsoft.SharePoint.SPEndpointAddressNotFoundException: There are no addresses available for this application.</span></code></pre></td></tr></table></div></figure>


<p>If you look above this error, you may find another <strong>Critical</strong> error:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>There are no instances of the Microsoft.Office.Server.Search.Administration.SearchQueryAndSiteSettingsServices started on any server in this farm.</span></code></pre></td></tr></table></div></figure>


<p>If you indeed see these exceptions, then you need to check this out. Do the following:</p>

<ol>
<li>Go to Central Administration</li>
<li>Go to Application Management &gt; Manage Services on Server</li>
<li>Go through each of the <strong>Servers</strong> and see if any of them have the <strong>Search Query and Site Settings Service</strong> started.</li>
<li>If <strong>none</strong> have this service started, start this service on the same server that&#8217;s running <strong>SharePoint Server Search</strong> according to the <strong>Servers in Farm</strong> page.</li>
<li>Run <strong>iisreset</strong> on the server where you found the Correllation ID.</li>
</ol>


<p>By this point, things should start looking up and you should actually get a search page with results.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Factory - Sans Conditionals]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/07/04/a-factory-sans-conditionals/"/>
    <updated>2012-07-04T08:53:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/07/04/a-factory-sans-conditionals</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://www.chrisweldon.net/images/posts/2012-07-04-a-factory-sans-conditionals/factory.jpg"></p>

<p>I attended <a href="http://austincodecamp2012.com/" target="_blank">Austin Code Camp</a> a few weekends ago and had a blast! There were plenty of enthusiastic, passionate individuals gathered and ready to learn - the makings for a great one day conference. While there, I attended the session <em>Must-Know Design Patterns</em> by <a href="http://www.robvettor.com/" target="_blank">Rob Vettor</a>. In that session, he discussed several very useful patterns, including the <a href="http://en.wikipedia.org/wiki/Decorator_pattern" target="_blank">Decorator Pattern</a>, the <a href="http://www.oodesign.com/factory-pattern.html" target="_blank">Factory Pattern</a>, and numerous other useful patterns. In seeing his code samples for the factory pattern, I was a bit disappointed to see his entire block of <code>if/else if/else</code> statements simply moved from his business logic to the factory. While this is still technically the better approach than leaving it in business logic, I find there&rsquo;s a better way to do this. In fact, there&rsquo;s a <em>zero</em> case statement way of doing this in C#. If you&rsquo;re curious to find out how to create a factory without a single <code>if</code> or <code>switch</code> statement, read on.</p>

<!--more-->


<p><span class='pullquote-right' data-pullquote='The goal is simple: get rid of most (if not all) case statements in your code.'></p>

<p>If you&rsquo;ve never heard of it, check out the <a href="http://www.antiifcampaign.com/" target="_blank">Anti If Campaign</a>. I wasn&rsquo;t aware of this until about a year ago, but prior to that I was already a practitioner of their preachings. The goal is simple: get rid of most (if not all) case statements in your code. Why? An increase in the number of case statements increases the branch (cyclomatic) complexity of your logic. You have to add more unit tests to ensure you hit everyone of those branches. It&rsquo;s far too often the case that your code isn&rsquo;t just a set of conditional statements - it has other logic surrounding it. It&rsquo;s messy, and it&rsquo;s poor design.</p>

<p></span></p>

<p>If you are truly paying attention to object-oriented design patterns, you&rsquo;d realize there are ways for you to structure your code in a manner that minimizes or eliminates the need for conditional statements. Most people revolt when I make this assertion. Some of the arguments I&rsquo;ve heard include:</p>

<ol>
<li>Won&#8217;t you create too many classes to maintain? I have a hard enough time navigating my codebase as-is. </li>
<li>Aren&#8217;t classes &#8220;heavy&#8221;? Won&#8217;t that bloat the application?</li>
<li>How do I know what my application is doing without if/else if/else statements?</li>
</ol>


<p>My responses are usually:</p>

<ol>
<li>You&#8217;ll often create many more classes. But, if you have a) sound organizational plans and b) a somewhat-modern IDE you can find any of the classes you use. Learn to use your IDE so you can help you navigate your codebase.</li>
<li>It depends on the class. Often, I create many <em>extremely</em> lightweight classes and only allow them to live while I need them to help keep memory consumption to a minimum.</li>
<li>Are you flinging code at your screen like a monkey flings poo at others? How else do you expect to build your application? Understanding these (and other) design principles will allow you to make sense of what your app is doing, rather than treating it like some voodoo blackbox.</li>
</ol>




<h3>The Problem</h3>


<p>Let&rsquo;s take a look at a sample problem that I&rsquo;d like to make much simpler. The code sample below should be fairly easy to follow. We are a custom factory responsible for building different makes and models of vehicles. As you can see, the majority of our business logic is tied up trying to figure out how to create the vehicle and assign it the options.</p>

<figure class='code'><figcaption><span> (VehicleController.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/VehicleController.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">VehicleController</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">ActionResult</span> <span class="nf">buildVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">,</span> <span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">Vehicle</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Honda&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Civic&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// Ooh! My favorite!</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Civic</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Accord&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Accord</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;CR-V&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CRV</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Honda&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Chevrolet&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Suburban&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Suburban</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Silverado&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Silverado</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Chevrolet&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;BMW&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Pompus luxury vehicle.</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Ferrari&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Not likely in my lifetime.</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Lamborghini&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// I wish.</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Save.</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">vehicleContext</span><span class="p">.</span><span class="n">Attach</span><span class="p">(</span><span class="n">vehicle</span><span class="p">);</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">vehicleContext</span><span class="p">.</span><span class="n">SaveAll</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Display our newly created vehicle.</span>
</span><span class='line'>        <span class="k">return</span> <span class="nf">View</span><span class="p">(</span><span class="s">&quot;BuildVehicle&quot;</span><span class="p">,</span> <span class="n">vehicle</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The cyclomatic complexity of this action alone is ridiculous. Controller actions should be simple and straight-forward: collect data and validate, pass to business logic, return response. Any controller action over 20 LoC is doing too much and some refactoring should be considered. So, what should we do?</p>

<h3>The Pattern</h3>


<p>Let&rsquo;s take the first step and refactor that gigantic if block into a separate factory:</p>

<figure class='code'><figcaption><span> (VehicleFactory.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/VehicleFactory.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">VehicleFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">buildVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">,</span> <span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">Vehicle</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Honda&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Civic&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// Ooh! My favorite!</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Civic</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Accord&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Accord</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;CR-V&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CRV</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Honda&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Chevrolet&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Suburban&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Suburban</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Silverado&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Silverado</span><span class="p">();</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>                <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Chevrolet&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;BMW&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Pompus luxury vehicle.</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Ferrari&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Not likely in my lifetime.</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Lamborghini&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// I wish.</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This <em>greatly</em> simplifies our <code>VehicleController</code> (see below), but does little to solve our cyclomatic complexity problem. Furthermore, one of the biggest problems I have with this as a factory is it will have to be modified <strong>every time</strong> a business use case related to the factory changes. We need a better solution to help make this easier to maintain and unit test.</p>

<figure class='code'><figcaption><span> (VehicleController-v01.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/VehicleController-v01.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">VehicleController</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">ActionResult</span> <span class="nf">buildVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">,</span> <span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">VehicleFactory</span> <span class="n">factory</span> <span class="p">=</span> <span class="k">new</span> <span class="n">VehicleFactory</span><span class="p">();</span>
</span><span class='line'>        <span class="n">Vehicle</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="n">factory</span><span class="p">.</span><span class="n">buildVehicle</span><span class="p">(</span><span class="n">make</span><span class="p">,</span> <span class="n">model</span><span class="p">,</span> <span class="n">color</span><span class="p">,</span> <span class="n">numDoors</span><span class="p">,</span> <span class="n">options</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Save.</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">vehicleContext</span><span class="p">.</span><span class="n">Attach</span><span class="p">(</span><span class="n">vehicle</span><span class="p">);</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">vehicleContext</span><span class="p">.</span><span class="n">SaveAll</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Display our newly created vehicle.</span>
</span><span class='line'>        <span class="k">return</span> <span class="nf">View</span><span class="p">(</span><span class="s">&quot;BuildVehicle&quot;</span><span class="p">,</span> <span class="n">vehicle</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, the first option I&rsquo;d push for is moving the actual creation of each make into a separate factory. So, we&rsquo;ll have a <code>HondaFactory</code>, a <code>ChevroletFactory</code>, and other factories for each of our other types. So, looking at the refactor for the <code>HondaFactory</code>, we have something similar to the following:</p>

<figure class='code'><figcaption><span> (HondaFactory.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/HondaFactory.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">HondaFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">Vehicle</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Civic&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Ooh! My favorite!</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Civic</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Accord&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Accord</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;CR-V&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CRV</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Honda&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>And here&rsquo;s our <code>ChevroletFactory</code>:</p>

<figure class='code'><figcaption><span> (ChevroletFactory.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/ChevroletFactory.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ChevroletFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">Vehicle</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Suburban&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Suburban</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Silverado&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Silverado</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Chevrolet&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we need to figure out how to get our main <code>VehicleFactory</code> to route requests to each of these different factories <strong>without</strong> conditionals. But, before we do this, let&rsquo;s think about what we just did. We need to realize that each of the factories we created are doing <em>the same thing</em>. When you start having several classes doing the same thing, it&rsquo;s time to introduce an interface. With this, we also introduce what will be termed as the <strong>evaluator</strong>:</p>

<figure class='code'><figcaption><span> (IVehicleFactory.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/IVehicleFactory.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IVehicleFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">Vehicle</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">]);</span>
</span><span class='line'>    <span class="kt">bool</span> <span class="nf">CanCreateMake</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>CanCreateMake</code> evaluates the make and returns whether this factory can handle it. We then are able to change our <code>HondaFactory</code> to look like:</p>

<figure class='code'><figcaption><span> (HondaFactory-v01.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/HondaFactory-v01.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">HondaFactory</span> <span class="p">:</span> <span class="n">IVehicleFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">Vehicle</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Civic&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Ooh! My favorite!</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Civic</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Accord&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Accord</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;CR-V&quot;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Only comes in 4 doors. So, ignore numDoors.</span>
</span><span class='line'>            <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CRV</span><span class="p">();</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>            <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">throw</span> <span class="k">new</span> <span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot make requested model for Honda&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">return</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="kt">bool</span> <span class="nf">CanCreateMake</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Honda&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, let&rsquo;s store all of our vehicle factories into a collection in our primary <code>VehicleFactory</code> and pull out the one we want to use:</p>

<figure class='code'><figcaption><span> (VehicleFactory-v01.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/VehicleFactory-v01.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">VehicleFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="n">IList</span><span class="p">&lt;</span><span class="n">IVehicleFactory</span><span class="p">&gt;</span> <span class="n">factories</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">IVehicleFactory</span><span class="p">&gt;();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="nf">VehicleFactory</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="k">new</span> <span class="n">HondaFactory</span><span class="p">());</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="k">new</span> <span class="n">ChevroletFactory</span><span class="p">());</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">buildVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">,</span> <span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">IVehicleFactory</span> <span class="n">usableFactory</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">SingleOrDefault</span><span class="p">(</span><span class="n">fac</span> <span class="p">=&gt;</span> <span class="n">fac</span><span class="p">.</span><span class="n">CanCreateMake</span><span class="p">(</span><span class="n">make</span><span class="p">));</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">usableFactory</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="n">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot create vehicle of the requested make.&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">usableFactory</span><span class="p">.</span><span class="n">CreateVehicle</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">color</span><span class="p">,</span> <span class="n">numDoors</span><span class="p">,</span> <span class="n">options</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We&rsquo;re definitely getting there, but there&rsquo;s one glaring problem. As mentioned previously, I hate the way factories are usually implemented, as they require modification if we need to add a new conditional. We&rsquo;re still in the same boat here. If we begin to manufacture a new make, we have to create that specific make&rsquo;s factory <strong>and</strong> modify this central factory to register it. This breaks the <a href="http://en.wikipedia.org/wiki/Open/closed_principle" target="_blank">Open/Closed Principle</a>, and we need to fix it. Thankfully, our interfaces help.</p>

<p>At Lone Star PHP an individual approached me after my SOLID talk to mention that he&rsquo;s not sold on the use of interfaces. He said that interfaces seem to be there only for the developers - as a means to help them add new classes that perform the same types of activities. But, he still didn&rsquo;t see a computer-use for them. That&rsquo;s when I busted out the use of Reflection. Reflection helps me walk my codebase and find objects of specific types without ever being aware of what is out there. Reflection will help us solve this problem.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="nf">VehicleFactory</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">var</span> <span class="n">discoveredFactories</span> <span class="p">=</span> <span class="n">Assembly</span><span class="p">.</span><span class="n">GetExecutingAssembly</span><span class="p">().</span><span class="n">GetTypes</span><span class="p">()</span>
</span><span class='line'>        <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">type</span> <span class="p">=&gt;</span> <span class="n">type</span><span class="p">.</span><span class="n">GetInterfaces</span><span class="p">().</span><span class="n">Any</span><span class="p">(</span><span class="n">intrfce</span> <span class="p">=&gt;</span> <span class="n">intrfce</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">IVehicleFactory</span><span class="p">))));</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">AddRange</span><span class="p">(</span><span class="n">discoveredFactories</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is now <em>completely</em> implementation agnostic and accomplishes our second goal: create a factory that&rsquo;s safe against modifications - this factory is not likely to ever change. The added benefit that I&rsquo;ve introduced is the ability to drop in any new make factory that implements <code>IVehicleFactory</code>, recompile, and deploy - and it will automatically be picked up by my assembly. That&rsquo;s sexy.</p>

<p>Our final factory that all of our core business logic will use looks like:</p>

<figure class='code'><figcaption><span> (VehicleFactory-v02.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/VehicleFactory-v02.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">VehicleFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="n">IList</span><span class="p">&lt;</span><span class="n">IVehicleFactory</span><span class="p">&gt;</span> <span class="n">factories</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">IVehicleFactory</span><span class="p">&gt;();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="nf">VehicleFactory</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">discoveredFactories</span> <span class="p">=</span> <span class="n">Assembly</span><span class="p">.</span><span class="n">GetExecutingAssembly</span><span class="p">().</span><span class="n">GetTypes</span><span class="p">()</span>
</span><span class='line'>            <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">type</span> <span class="p">=&gt;</span> <span class="n">type</span><span class="p">.</span><span class="n">GetInterfaces</span><span class="p">().</span><span class="n">Any</span><span class="p">(</span><span class="n">intrfce</span> <span class="p">=&gt;</span> <span class="n">intrfce</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">IVehicleFactory</span><span class="p">))));</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">AddRange</span><span class="p">(</span><span class="n">discoveredFactories</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">buildVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">,</span> <span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">IVehicleFactory</span> <span class="n">usableFactory</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">SingleOrDefault</span><span class="p">(</span><span class="n">fac</span> <span class="p">=&gt;</span> <span class="n">fac</span><span class="p">.</span><span class="n">CanCreateMake</span><span class="p">(</span><span class="n">make</span><span class="p">));</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">usableFactory</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="n">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot create vehicle of the requested make.&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">usableFactory</span><span class="p">.</span><span class="n">CreateVehicle</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">color</span><span class="p">,</span> <span class="n">numDoors</span><span class="p">,</span> <span class="n">options</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<h3>Rinse and Repeat</h3>


<p>Now that the basics have made themselves apparent, you should be able to figure out how to get rid of the remainder of the if/else blocks of this code. If you need further guidance, keep reading. Otherwise, I suggest you jump to the <a href="#Summary">summary</a>.</p>

<p>To get rid of the remainder of the if/else statements we have in our individual make factories, we apply the same principles that we did the first time around. We need yet another factory responsible for each model of the car. We then need a way to determine if that factory can handle the creation of the requested model. It&rsquo;s time for yet another interface:</p>

<figure class='code'><figcaption><span> (IMakeVehicles.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/IMakeVehicles.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IMakeVehicles</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">Vehicle</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">]);</span>
</span><span class='line'>    <span class="kt">bool</span> <span class="nf">CanCreateModel</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, let&rsquo;s create our first vehicle, a Civic:</p>

<figure class='code'><figcaption><span> (CivicFactory.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/CivicFactory.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">CivicFactory</span> <span class="p">:</span> <span class="n">IMakeVehicles</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">Civic</span> <span class="n">vehicle</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Civic</span><span class="p">();</span>
</span><span class='line'>        <span class="n">vehicle</span><span class="p">.</span><span class="n">Doors</span> <span class="p">=</span> <span class="n">numDoors</span><span class="p">;</span>
</span><span class='line'>        <span class="n">vehicle</span><span class="p">.</span><span class="n">Color</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
</span><span class='line'>        <span class="n">vehicle</span><span class="p">.</span><span class="n">Options</span> <span class="p">=</span> <span class="n">options</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">vehicle</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="kt">bool</span> <span class="nf">CanCreateModel</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">model</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Civic&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We do the same thing for all of our other models. The conditional evaluator is moved from the if block into the <code>CanCreateModel</code> method, and the body of the if statement is moved into <code>CreateVehicle</code>. All that&rsquo;s left is to apply the same trick that we did in the <code>VehicleFactory</code> to auto-discover our model factories. But - how do we make sure the Honda Factory only discovers factories relating to it, rather than <strong>all</strong> makes? The simplest approach here is to refactor IMakeVehicles to be a generic interface:</p>

<figure class='code'><figcaption><span> (IMakeVehicles-v01.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/IMakeVehicles-v01.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IMakeVehicles</span><span class="p">&lt;</span><span class="n">TModelType</span><span class="p">&gt;</span> <span class="k">where</span> <span class="n">TModelType</span> <span class="p">:</span> <span class="n">Vehicle</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">TModelType</span> <span class="nf">CreateVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">]);</span>
</span><span class='line'>    <span class="kt">bool</span> <span class="nf">CanCreateModel</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We then update our <code>CivicFactory</code> to use the following definition:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">CivicFactory</span> <span class="p">:</span> <span class="n">IMakeVehicles</span><span class="p">&lt;</span><span class="n">Honda</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="n">Honda</span> <span class="nf">CreateVehicle</span><span class="p">(...);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This allows us to use the same Assembly trick from earlier on a strongly-typed interface. The assumption here is that <code>Civic : Honda</code> and <code>Honda : Vehicle</code>. Without that relationship, this trick will not work.</p>

<p>We finish up by changing our <code>HondaFactory</code> to look like the following:</p>

<figure class='code'><figcaption><span> (HondaFactory-v02.cs)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-07-04-a-factory-sans-conditionals/HondaFactory-v02.cs'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">HondaFactory</span> <span class="p">:</span> <span class="n">IVehicleFactory</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">private</span> <span class="n">IList</span><span class="p">&lt;</span><span class="n">IMakeVehicles</span><span class="p">&lt;</span><span class="n">Honda</span><span class="p">&gt;&gt;</span> <span class="n">factories</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">IMakeVehicles</span><span class="p">&lt;</span><span class="n">Honda</span><span class="p">&gt;&gt;();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="nf">VehicleFactory</span><span class="p">()</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">discoveredFactories</span> <span class="p">=</span> <span class="n">Assembly</span><span class="p">.</span><span class="n">GetExecutingAssembly</span><span class="p">().</span><span class="n">GetTypes</span><span class="p">()</span>
</span><span class='line'>            <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">type</span> <span class="p">=&gt;</span> <span class="n">type</span><span class="p">.</span><span class="n">GetInterfaces</span><span class="p">().</span><span class="n">Any</span><span class="p">(</span><span class="n">intrfce</span> <span class="p">=&gt;</span> <span class="n">intrfce</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">IVehicleFactory</span><span class="p">&lt;</span><span class="n">Honda</span><span class="p">&gt;))));</span>
</span><span class='line'>        <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">AddRange</span><span class="p">(</span><span class="n">discoveredFactories</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="n">Vehicle</span> <span class="nf">buildVehicle</span><span class="p">(</span><span class="kt">string</span> <span class="n">model</span><span class="p">,</span> <span class="kt">string</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">numDoors</span><span class="p">,</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">options</span> <span class="p">=</span> <span class="kt">string</span><span class="p">[</span><span class="m">0</span><span class="p">])</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">IVehicleFactory</span> <span class="n">usableFactory</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">factories</span><span class="p">.</span><span class="n">SingleOrDefault</span><span class="p">(</span><span class="n">fac</span> <span class="p">=&gt;</span> <span class="n">fac</span><span class="p">.</span><span class="n">CanCreateModel</span><span class="p">(</span><span class="n">model</span><span class="p">));</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">usableFactory</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="n">InvalidArgumentException</span><span class="p">(</span><span class="s">&quot;Cannot create vehicle of the requested model.&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">usableFactory</span><span class="p">.</span><span class="n">CreateVehicle</span><span class="p">(</span><span class="n">color</span><span class="p">,</span> <span class="n">numDoors</span><span class="p">,</span> <span class="n">options</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="kt">bool</span> <span class="nf">CanCreateMake</span><span class="p">(</span><span class="kt">string</span> <span class="n">make</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">make</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="s">&quot;Honda&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><a href="#" name="Summary"></a></p>

<h3>Summary</h3>


<p>As we have seen, you can easily refactor your logic in such a way that&rsquo;s a lot more straight-forward to maintain. You&rsquo;ve created a factory that can be reused in multiple places across your application. Instead of having to maintain a gargantuan and growing class, you being to worry about micro-factories that are focused on your specific needs. Your micro-factories are able to be reused across components. You have encapsulated all logic associated with the creation of a particular vehicle in a single class, rather than splitting the determination of when to create the class and how to create it in separate classes. Your unit test classes for each of these components are so small, you stop worrying about how to create your 18-level chain mock to test a single conditional statement. In short: you achieve OO bliss.</p>

<p>What I&rsquo;ve introduced is not new. In fact, this is a variation of the <a href="http://en.wikipedia.org/wiki/Command_pattern" target="_blank">Command Pattern</a>. I also <strong>heavily</strong> rely on this pattern when I&rsquo;m implementing <a href="http://en.wikipedia.org/wiki/Strategy_pattern" target="_blank">strategies</a> within my code. Strategies change often, so when I need to introduce a new strategy, I create the class, implement the interface, rebuild, and go! Removing a strategy is as simple as pressing the delete key. One class and everything else is taken care of for me.</p>

<p>If you have questions or comments about this pattern, please feel free to reach out to me via <a href="mailto:chris@chrisweldon.net">e-mail</a> or through the comment page below. I would love to hear other&rsquo;s ideas on this implementation.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RESTful Web Services Authentication in Zend Framework]]></title>
    <link href="http://www.chrisweldon.net/blog/2012/06/25/restful-web-services-authentication-in-zend-framework/"/>
    <updated>2012-06-25T08:10:00+00:00</updated>
    <id>http://www.chrisweldon.net/blog/2012/06/25/restful-web-services-authentication-in-zend-framework</id>
    <content type="html"><![CDATA[<p><img class="left" src="http://www.chrisweldon.net/images/posts/2012-06-25-restful-web-services-authentication-with-zend-framework/zendframework-logo.png" title="Zend Framework" ></p>

<p>Over this past weekend, I spent time working on a new set of web services for an existing customer. Previously, their web services were XMLRPC based, and performed authentication by sending the username and an API key rather than a password over the wire. These web services were secured via HTTPS, but use of HTTPS was <strong>not mandatory</strong>. Since the API exposed methods that allowed you to create, read, and delete records associated with a customer, the use of this API without using SSL could be disastrous for its customers.</p>

<p>We had multiple outstanding requests to convert our web services to be REST-based and have also had the request to implement OAuth. These are definitely the direction we are heading for the project, but due to resource contraints (i.e. myself being the only developer), I have to be mindful about when I can deliver value. While implementing the new RESTful services this weekend, I finally came upon the authentication requirement which caused me to question: what is the most appropriate mechanism for authenticating my identities? Read on for the justification of what authentication mechanism I decided upon and how I implemented it in Zend Framework.</p>

<!--more-->


<h2>Possible Authentication Solutions</h2>


<p>The business model our customer uses involves many API customer integrations. While the majority are single customer API integrations (i.e. volume customers who bill against a single account), we are starting to have more interest from third parties who want their customers to integrate their personal accounts with our service. Sound familiar? Of course it does - many great web services on the internet do that already. Facebook, LinkedIn, Flickr, and many more online services have integrations with countless numbers of third party providers. However, customers don&rsquo;t wish to share their Facebook password with all of these third party sites. How do they let the third party site consume their data on their behalf (term: impersonate)?</p>

<h3>OAuth</h3>


<p><span class='pullquote-right' data-pullquote='OAuth is a clever way of performing a handshake and passing signed messages between servers to obtain an access token to perform activities on behalf of the requestor.'></p>

<p>They use an open protocol called <a href="http://oauth.net/" target="_blank">OAuth</a>. OAuth is a clever way of performing a handshake and passing signed messages between servers to obtain an access token to perform activities on behalf of the requestor. Your password is entered only at the site where the password is stored, yet the site requesting access will still be able to access your data in a secure way as if it were you accessing the data.</p>

<p></span></p>

<p>OAuth is the perfect solution to my authentication problem. There&rsquo;s just one issue: it takes time to setup and implement correctly. In no particular order, the steps include:</p>

<ul>
<li>Setting up database tables to store:
<ul>
<li>Registered OAuth Consumers</li>
<li>Consumer Requests</li>
<li>Consumer Access Tokens</li>
</ul></li>
<li>Writing a web site to handle user requests</li>
<li>Writing the backend supporting logic to handle requests and access tokens</li>
<li>Implementing a workflow for registering OAuth consumers</li>
</ul>


<p>That&rsquo;s a tremendous number of tasks. While I would love to fully implement an OAuth provider, I just do not have the time. It would easily take me a couple of weeks at the pace I currently work (about 15 hours per week). So, I have to consider alternative options.</p>

<h3>HTTP Basic vs. Sessions</h3>


<p>The simplest solution is to send the username and password with each request using <a href="http://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank">HTTP Basic</a>. It&rsquo;s quick to implement, it doesn&rsquo;t require any complex behaviors on the client or the server (unlike OAuth), and it&rsquo;s widely supported by every browser and HTTP client. Here&rsquo;s what a raw request would look like using Basic authentication:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>GET /api/request/12345 HTTP/1.1
</span><span class='line'>Host: api.example.com
</span><span class='line'>Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==</span></code></pre></td></tr></table></div></figure>


<p>It&rsquo;s very simple and light. Now, to the naked eye, you can&rsquo;t see that the username is <strong>Aladdin</strong> and the password is <strong>open sesame</strong>. However, that encoded string is simply Base64 encoded version of <strong>Aladdin:open sesame</strong>. Essentially, it&rsquo;s plain text, meaning anyone along the way to the destination can sniff the header and get my username and password. This is a significant concern, but is lessend when you <strong>enforce</strong> SSL connectivity. However, the risk is still there. Traditional security practices dictate that as the frequency of the transmission of credentials increases, so does the risk of them being compromised, especially if those credentials are in plain text. Thus, from a security perspective, HTTP Basic Authentication is not the best solution. The general security recommendation is if you can minimize the number of times your credential goes across the wire, the risk decreases.</p>

<p>Many posts online give consideration to having a single RESTful resource perform authentication and create a session for the user. Thus, the username and password would be sent down <em>once</em> at the beginning of the session. A cookie is then sent back each subsequent time to identify the user&rsquo;s session. This is something I absolutely don&rsquo;t like: RESTful web services are supposed to be state-less. Therefore, having a session active for any period of time violates this principle. Another argument in favor of using this method of authenticating clients is it reduces the request body. Again, in order for a session to be stateful over HTTP, you have to submit a cookie with <strong>each</strong> request. Cookies are fairly small in size, but when you compare that to a username/password combination in HTTTP Basic sent on every request - it&rsquo;s about the same size.</p>

<h3>HMAC</h3>


<p><img class="right" src="http://www.chrisweldon.net/images/posts/2012-06-25-restful-web-services-authentication-with-zend-framework/amazon-web-services-logo.png" title="Amazon Web Services" ></p>

<p><a href="http://aws.amazon.com/" target="_blank">Amazon&rsquo;s AWS</a> took a very interesting approach to dealing with security, called <a href="http://en.wikipedia.org/wiki/Hash-based_message_authentication_code" target="_blank">Hash-based Message Authentication Code (HMAC)</a>. The idea is very similar to how RSA encryption works (e.g. your standard SSL encryption when working with web sites). <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html" target="_blank">Amazon&rsquo;s specific implementation</a> relies on a prior exchange of public and private keys that only the client and the server should know. The idea is the request body plus some additional parameters (such as date, user id, etc.) are hashed using the private key. This payload is sent to the server, where the server generates the same hash from the request body (including those parameters) and checks to see if the hash matches. If it does, it executes the request. Riyad Kalla wrote an <em>excellent</em> <a href="http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication" target="_blank">blog post</a> explaining this in much greater detail that I suggest you check out.</p>

<p>From a security perspective, this definitely solves the problem with not sending credentials over the wire. It&rsquo;s simpler than implementing OAuth, as I don&rsquo;t need additional database tables to support requests and access tokens. Yet, the work necessary on <em>both</em> the client and server-side is much more significant than HTTP Basic authentication. I can implement this solution in a reasonable amount of time. However, I&rsquo;m significantly concerned about user adoption of the new services. For them to have to learn and implement HMAC to ensure absolutely secure web services will certainly drive-down the number of users who are willing to consume my web services. It&rsquo;s possible they still will consume my services. Plus, the security-conscious will love this as a solution.</p>

<h2>Considerations</h2>


<p>All in all, I had several options to weigh. One of the first that had to be considered was how secure my customer&rsquo;s credentials really needed to be. What types of services am I securing with their credentials? In reality, the type of content being secured is <em>not</em> highly classified materials or supremely private, personally-identifyable information. They are basic requests to start, or check on, a workflow. Future service offerings through this API will allow interactions such as managing your account, getting lists of completed workflows (and associated data), but will still be low-risk information.</p>

<p>In short, I opted to use HTTP Basic authentication. I plan on <strong>enforcing</strong> SSL connections to the web service. While this is still subject to main-in-the-middle attacks and can result in exposure of a user&rsquo;s credentials, the risk and gains of doing that are low enough to warrant this as an acceptable solution. Some customers may totally dislike this as an option, and that&rsquo;s fine. They can continue using the just-as-insecure XMLRPC services until I have a chance to spin up OAuth.</p>

<h2>Implementing in Zend Framework</h2>


<p>Thankfully, Zend Framework makes adding a provider VERY easy. By creating a class that extends <code>Zend_Controller_Plugin_Abstract</code>, we can hook into the <code>preDispatch</code> pipeline and validate the <code>Authorization</code> header at that point. The code sample shown at the end of this post is fairly self-explainatory. However, I&rsquo;ll break it down here.</p>

<h3>Checking for Authorization Header</h3>


<p>We first need to check to make sure the header even exists <strong>and</strong> is in the proper format. The proper format is Base64 encoded, with the username and password being separated by a colon. That&rsquo;s what the following bit of code does. <strong>Note:</strong> the <code><em>redirectNoAuth</code> and <code></em>redirectInvalidRequest</code> are helper methods to forward to the appropriate error controller actions.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="nv">$authorizationHeader</span> <span class="o">=</span> <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getHeader</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">AUTHORIZATION_HEADER</span><span class="p">);</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="nv">$authorizationHeader</span> <span class="o">==</span> <span class="k">null</span> <span class="o">||</span> <span class="nv">$authorizationHeader</span> <span class="o">==</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectNoAuth</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nv">$authorizationHeader</span> <span class="o">=</span> <span class="nb">base64_decode</span><span class="p">(</span><span class="nv">$authorizationHeader</span><span class="p">);</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">&#39;/[^\:]*\:.*/i&#39;</span><span class="p">,</span> <span class="nv">$authorizationHeader</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectInvalidRequest</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>From there, we extract the username and password from the authorization header and attempt to authenticate. The <code>\My\Auth\Adapter</code> is a <code>\Zend_Auth_Adapter_Abstract</code>, so the logic of authenticating our users is encapsulated there.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="nv">$authorizationParts</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="nv">$authorizationHeader</span><span class="p">);</span>
</span><span class='line'><span class="nv">$username</span> <span class="o">=</span> <span class="nv">$authorizationParts</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span><span class='line'><span class="nv">$password</span> <span class="o">=</span> <span class="nv">$authorizationParts</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="k">try</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$authAdapter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\My\Auth\Adapter</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_customreRepository</span><span class="p">,</span> <span class="nv">$username</span><span class="p">,</span> <span class="nv">$password</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$authAdapter</span><span class="o">-&gt;</span><span class="na">authenticate</span><span class="p">()</span> <span class="o">!=</span> <span class="nx">\Zend_Auth_Result</span><span class="o">::</span><span class="na">SUCCESS</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectNoAuth</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>        <span class="k">return</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_customerRepository</span><span class="o">-&gt;</span><span class="na">findOneByUsername</span><span class="p">(</span><span class="nv">$username</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">\Zend_Registry</span><span class="o">::</span><span class="na">set</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">IDENTITY_KEY</span><span class="p">,</span> <span class="nv">$user</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">\Exception</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectNoAuth</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>    <span class="k">return</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>At the end of that try block, you&rsquo;ll notice that I use the customer repository to fetch the user by his username and store that in the <code>\Zend_Registry</code>. This is for use later in the APIs when I need to know which user has authenticated with the service, so I can apply authorization constraints against that user. That&rsquo;s ultimately the only reason you&rsquo;ll notice the <code>\Doctrine\ORM\EntityManager</code> and the <code>\My\Entity\Repository\CustomerRepository</code> being used in this class. It&rsquo;s consumed by our authentication adapter and used to find the entity when we&rsquo;ve authenticated them.</p>

<p>That&rsquo;s pretty much it. The full class compliment can be found below. I welcome any feedback or suggestsions to this article!</p>

<figure class='code'><figcaption><span>Basic Authentication Plugin  (BasicAuthPlugin.php)</span> <a href='http://www.chrisweldon.net/downloads/code/2012-06-25-restful-web-services-authentication-in-zend-framework/BasicAuthPlugin.php'>download</a></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="o">&lt;?</span><span class="nx">php</span>
</span><span class='line'><span class="k">namespace</span> <span class="nx">My\Controller\Plugin</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">use</span> <span class="nx">\Doctrine\ORM\EntityManager</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">\My\Entity\Repository\CustomerRepository</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">\My\Auth\Adapter</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="sd">/**</span>
</span><span class='line'><span class="sd"> * HTTP Basic Authentication Plugin for My API</span>
</span><span class='line'><span class="sd"> */</span>
</span><span class='line'><span class="k">class</span> <span class="nc">BasicAuthPlugin</span> <span class="k">extends</span> <span class="nx">\Zend_Controller_Plugin_Abstract</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">const</span> <span class="no">AUTHORIZATION_HEADER</span> <span class="o">=</span> <span class="s1">&#39;Authorization&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">const</span> <span class="no">IDENTITY_KEY</span> <span class="o">=</span> <span class="s1">&#39;Identity&#39;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/** @var \Doctrine\ORM\EntityManager */</span>
</span><span class='line'>    <span class="k">private</span> <span class="nv">$_entityManager</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/** @var \My\Entity\Repository\CustomerRepository */</span>
</span><span class='line'>    <span class="k">private</span> <span class="nv">$_customerRepository</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">(</span><span class="nx">EntityManager</span> <span class="nv">$entityManager</span><span class="p">,</span> <span class="nx">CustomerRepository</span> <span class="nv">$customerRepository</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_entityManager</span> <span class="o">=</span> <span class="nv">$entityManager</span><span class="p">;</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_customerRepository</span> <span class="o">=</span> <span class="nv">$customerRepository</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">preDispatch</span><span class="p">(</span><span class="nx">\Zend_Controller_Request_Abstract</span> <span class="nv">$request</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="nv">$authorizationHeader</span> <span class="o">=</span> <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getHeader</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">AUTHORIZATION_HEADER</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nv">$authorizationHeader</span> <span class="o">==</span> <span class="k">null</span> <span class="o">||</span> <span class="nv">$authorizationHeader</span> <span class="o">==</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectNoAuth</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// The header needs to be base64 decoded, then match the regex in order to proceed.</span>
</span><span class='line'>        <span class="nv">$authorizationHeader</span> <span class="o">=</span> <span class="nb">base64_decode</span><span class="p">(</span><span class="nv">$authorizationHeader</span><span class="p">);</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">&#39;/[^\:]*\:.*/i&#39;</span><span class="p">,</span> <span class="nv">$authorizationHeader</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectInvalidRequest</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$authorizationParts</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="nv">$authorizationHeader</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$username</span> <span class="o">=</span> <span class="nv">$authorizationParts</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span><span class='line'>        <span class="nv">$password</span> <span class="o">=</span> <span class="nv">$authorizationParts</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Authenticate.</span>
</span><span class='line'>        <span class="k">try</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$authAdapter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\My\Auth\Adapter</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_customerRepository</span><span class="p">,</span> <span class="nv">$username</span><span class="p">,</span> <span class="nv">$password</span><span class="p">);</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nv">$authAdapter</span><span class="o">-&gt;</span><span class="na">authenticate</span><span class="p">()</span> <span class="o">!=</span> <span class="nx">\Zend_Auth_Result</span><span class="o">::</span><span class="na">SUCCESS</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectNoAuth</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>                <span class="k">return</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>            <span class="c1">// Get the user and set their identity in the registry.</span>
</span><span class='line'>            <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_customerRepository</span><span class="o">-&gt;</span><span class="na">findOneByUsername</span><span class="p">(</span><span class="nv">$username</span><span class="p">);</span>
</span><span class='line'>            <span class="nx">\Zend_Registry</span><span class="o">::</span><span class="na">set</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">IDENTITY_KEY</span><span class="p">,</span> <span class="nv">$user</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">\Exception</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_redirectNoAuth</span><span class="p">(</span><span class="nv">$request</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Redirects users to our no authentication error page.</span>
</span><span class='line'><span class="sd">     *</span>
</span><span class='line'><span class="sd">     * @param \Zend_Controller_Request_Abstract $request</span>
</span><span class='line'><span class="sd">     * @return mixed</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">protected</span> <span class="k">function</span> <span class="nf">_redirectNoAuth</span><span class="p">(</span><span class="nx">\Zend_Controller_Request_Abstract</span> <span class="nv">$request</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getModuleName</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;api&#39;</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>            <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getControllerName</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;error&#39;</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>            <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getActionName</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;noauth&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Forward the request to the noauth error page.</span>
</span><span class='line'>        <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">setModuleName</span><span class="p">(</span><span class="s1">&#39;api&#39;</span><span class="p">)</span>
</span><span class='line'>                <span class="o">-&gt;</span><span class="na">setControllerName</span><span class="p">(</span><span class="s1">&#39;error&#39;</span><span class="p">)</span>
</span><span class='line'>                <span class="o">-&gt;</span><span class="na">setActionName</span><span class="p">(</span><span class="s1">&#39;noauth&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Redirects users to our invalid request error page.</span>
</span><span class='line'><span class="sd">     *</span>
</span><span class='line'><span class="sd">     * @param \Zend_Controller_Request_Abstract $request</span>
</span><span class='line'><span class="sd">     * @return mixed</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">protected</span> <span class="k">function</span> <span class="nf">_redirectInvalidRequest</span><span class="p">(</span><span class="nx">\Zend_Controller_Request_Abstract</span> <span class="nv">$request</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getModuleName</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;api&#39;</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>            <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getControllerName</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;error&#39;</span> <span class="o">&amp;&amp;</span>
</span><span class='line'>            <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">getActionName</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;invalid&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Forward the request to the noauth error page.</span>
</span><span class='line'>        <span class="nv">$request</span><span class="o">-&gt;</span><span class="na">setModuleName</span><span class="p">(</span><span class="s1">&#39;api&#39;</span><span class="p">)</span>
</span><span class='line'>                <span class="o">-&gt;</span><span class="na">setControllerName</span><span class="p">(</span><span class="s1">&#39;error&#39;</span><span class="p">)</span>
</span><span class='line'>                <span class="o">-&gt;</span><span class="na">setActionName</span><span class="p">(</span><span class="s1">&#39;invalid&#39;</span><span class="p">)</span>
</span><span class='line'>                <span class="o">-&gt;</span><span class="na">setParam</span><span class="p">(</span><span class="s1">&#39;message&#39;</span><span class="p">,</span> <span class="s1">&#39;Invalid authentication header.&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
</feed>
