tag:blogger.com,1999:blog-19393340388336127242024-03-07T21:19:56.252-06:00Bryant BrabsonBryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.comBlogger67125tag:blogger.com,1999:blog-1939334038833612724.post-70425725273257178562014-08-25T10:19:00.001-05:002014-08-25T10:20:31.928-05:00Deploy Early & OftenOne of my team maxims is "Deploy Early and Often." As soon as a <a href="http://en.wikipedia.org/wiki/Minimum_viable_product" rel="nofollow" target="_blank">minimum viable product</a> is available I want it off the developer's machine and deployed to a server, device, or wherever the final destination is.<br />
<br />
<i>Somewhat</i> akin to <a href="http://en.wikipedia.org/wiki/Test-driven_development" rel="nofollow" target="_blank">TDD</a>,
I'm actually expecting the first couple of deployments to fail. Maybe
you're missing a critical JavaScript library or don't have the same
level of access in the test environment as you do locally. These initial
failures are valuable in detecting any hidden or forgotten
dependencies. Ensuring that your product's deployment process is solid
as early as possible will reduce or eliminate the number of nasty
surprises as you approach the end of development. The last thing you
want to do is to earn the dubious '<a href="http://blog.codinghorror.com/the-works-on-my-machine-certification-program/" target="_blank">Works On My Machine</a>' certification shortly before the release.<br />
<br />
Whether
your deployment process is manual or based around continuous delivery
get your application out there as soon as possible. Whether you adhere
to Agile or work in Waterfall, don't wait until the last moment to test
your release deployment.
<br />
<br />
<span style="font-size: xx-small;"><a href="https://www.linkedin.com/today/post/article/20140814153442-20076979-deploy-early-often" target="_blank">Originally posted on LinkedIn</a>.</span>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-60507911888263567612014-05-05T04:30:00.000-05:002014-05-06T11:07:21.184-05:00New developer? Start with the deliverables.<div id="article-body">
I have a developer new to the team who has an extensive system
administration background. Due to various factors he has been working on
our <a href="http://msdn.microsoft.com/en-us/library/ms181709.aspx" target="_blank">build processes</a>
rather than writing a lot of code initially. He mentioned that he
enjoyed taking this approach because it was a "good bridge" to writing
code.<br />
<br />
That comment caused me to reflect on whether this might be a
good introduction for all new developers. It seems like it, because the
end product is what is important to our customers, not how elegant or
innovative the underlying code is. Yes, of course, there is great value
in well-written, high-performance code but that won't matter if the
deliverable is defective to such a degree that the customer rejects it.<br />
<br />
So
how can one defend against distasteful defective releases?
Configuration management is a set of practices that attempts to improve
software quality. One of the important principles of configuration
management is the concept of <a href="http://www.sans.edu/research/security-laboratory/article/251" target="_blank">repeatable, reproducible builds</a>. A <a href="http://martinfowler.com/articles/continuousIntegration.html" target="_blank">continuous integration</a>
(CI) system gets you started down that path by eliminating the
disruptive variables associated with the vagaries of what is installed
on a developer's machine.<br />
<br />
Setting up a build server as part of
your CI system isn't a turnkey process however. One frequently needs to
rewrite some code or reconfigure dependencies so that the application
can be built in isolation on the build server, free from any detritus
tied directly to a specific development machine. Once you get to that
point you probably start realizing that you should have made some
choices differently in the application. Essentially you're working from
the outside in, and this viewpoint is really important. Think how much
more efficiently the development team can work if projects are initiated
with the goal of cleanly building on the build server rather than
chasing down build issues specific to one person's development
environment. The exercise of having new developers work within the
configuration process earlier in their tenure rather than later
resonates with me. Understanding the meta pieces that form the
application is critical to deploying it, whether it is developers doing
the deployment or a release engineering team.<br />
<br />
I am more concerned
about getting the release right than anything else. Having new
developers- even seasoned developers, for that matter- understand the
importance of writing code that fits easily into a CI environment is
invaluable. For me, this holistic view of the code pays dividends in
efficiency and quality.<br />
<br />
<br />
<span style="font-size: xx-small;"><a href="https://www.linkedin.com/today/post/article/20140501215944-20076979-new-developer-start-with-the-deliverables" target="_blank">Originally posted on LinkedIn</a>.</span></div>
Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-46361604280853657332013-10-03T11:06:00.001-05:002013-10-03T11:06:45.944-05:00404 template errors when using AngularJS directives for BootstrapThis is on me for not reading the manual, or in this case the <a href="https://github.com/angular-ui/bootstrap/tree/gh-pages" rel="nofollow" target="_blank">GitHub README</a>. But since I installed from <a href="http://www.nuget.org/" rel="nofollow" target="_blank">NuGet</a> I wasn't aware of any special instructions on usage. Regardless, my <a href="http://getbootstrap.com/" rel="nofollow" target="_blank">Bootstrap</a> view which used <a href="http://angular-ui.github.io/bootstrap/" rel="nofollow" target="_blank">AngularJS components</a> wasn't working as expected and Firebug revealed the problem:
<br />
<div style="font-size: smaller; margin: 10px;">
NetworkError: 404 Not Found - http://localhost:51293/template/alert/alert.html</div>
Searching through the solution files quickly revealed that there isn't an alert.html or even a template directory. Luckily <a href="https://github.com/angular-ui/bootstrap/issues/570" rel="" target="_blank">someone else had the same problem</a> recently so I wasn't left flailing about searching for an answer in a sea of curly braces.<br />
<br />
Using 'ui-bootstrap-tpls-[version].min.js' in this case rather than 'ui-bootstrap-[version].min.js' solved The Case of the Missing Template.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-66577333265973956762013-03-24T21:30:00.000-05:002013-03-25T10:29:58.033-05:00Management Nugget 1: Avoid The Holiday Time CrunchProjects with 31st of December deadlines should be started well in advance of the holiday vacation time crunch. To most this is blatantly obvious. Some of our peers, however, act surprised that Christmas comes on December 25th every year and that most people take time off around that time. (Some folks take a LOT of time off!) I was astonished by the number of messages I received on 12/27 regarding projects with deadlines of 12/31.<br />
<br />
There is an ancient fable that illustrates this situation: <a href="http://en.wikipedia.org/wiki/The_Ant_and_the_Grasshopper" target="_blank">The Ant And The Grasshopper</a>.<br />
<br />
Now, don't get me wrong. I am firmly in the camp that believes that ALL of IT is one team, and we all succeed or fail together. And to get even more macro, the entire company stands or falls as one. So, yeah, though it might seem otherwise, I AM a team player.<br />
<br />
But...<br />
<br />
But what does that say about the person who hasn't managed their
projects properly and are now looking for you to bail them out? Does
that make them a good team player? How is the greater team helped by someone who doesn't properly manage projects with cross-team dependencies? Or, at the least, ask for help prior to crunch time? Resources have to be diverted, which then impacts quality and timeliness of on-track projects.<br />
<br />
<b><u>A crisis on your part does not constitute an emergency on my part?</u></b><br />
Now, don't be a jerk about it, but, as a manager you're going to have to decide how much you can assist at this late point in time. The right thing to do, of course, is to help your fellow human being. There are plenty of metaphors equating the corporate world as a brutal jungle, but I hope that your workplace isn't a Darwinian struggle for survival.<br />
<br />
There is a corollary to the section title above: <i>Poor planning on your part does not constitute an emergency on my part</i>. The bottom line is that you shouldn't get into this situation in the first place. Plan for contingencies. Look at a calendar when you are planning a project schedule. If YOU are the one that has run out of time it's always better to admit
that you're not going to complete the task(s) at hand on time.<br />
<br />
<b><u>Conclusion</u></b> <br />
I am not claiming that I'm covering new ground with this post. I'm merely describing a management <a href="http://en.wikipedia.org/wiki/Anti-pattern" target="_blank">anti-pattern</a> that seems to be popular in some organizations.<br />
<br />
<b><u>Background</u></b><br />
This is part of a larger series of planned posts: <a href="http://bryantbrabson.blogspot.com/2013/01/management-nuggets-priceless-wisdom.html" target="_blank">Management Nuggets</a>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-9009504036024616922013-01-25T06:30:00.000-06:002013-01-25T10:39:47.642-06:00Rolling my own .NET 4.5 SDKAll I wanted to do was get my TFS 2012 Build Server going. (Getting the core components running was quite a <a href="http://bryantbrabson.blogspot.com/2013/01/build-server-and-lost-tfs-message-queue.html" target="_blank">struggle</a>.) I expected some initial failed builds so wasn't surprised when I was informed of the following:<br />
<br />
<div style="font-size: smaller; margin: 10px;">
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (983): The reference assemblies for framework ".NETFramework,Version=v4.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.</div>
<br />
Finding the .NET 4.5 SDK didn't sound too hard to do. It wasn't, and I learned that it was part of the <a href="http://msdn.microsoft.com/en-us/windows/hardware/hh852363.aspx" target="_blank">Windows Software Development Kit (SDK) for Windows 8</a>. I downloaded the indicated file, which was named sdksetup.exe. Its size hinted that unfortunately it wasn't a standalone installer but (ugh) a web installer. I gave the sdksetup.exe a go on the server but wasn't surprised that it failed due to lack of internet connectivity through our proxy server. My next idea was to either extract the files that I needed locally or install and then copy the files to the server, <a href="http://bryantbrabson.blogspot.com/2010/05/windows-sdk-70a-and-automated-builds.html" target="_blank">which has worked before</a>.<br />
<br />
I missed it the first time around, but the Windows 8 SDK had an <a href="http://msdn.microsoft.com/en-us/windows/hardware/hh852363.aspx#InstallationInstruction" target="_blank">option to download the required files for installation to a separate computer</a> see ('.NET Framework 4.5 SDK Tools on Windows Vista and Windows Server 2008' after the jump). This is important because- and I missed this initially as well- "The installer for the Windows SDK for Windows 8 is not supported on Windows Vista and Windows 2008 Server." Well, that's pretty cool that I can create my own installer, I thought, and away I went.<br />
<br />
<div style="float: left; margin-right: 10px; width: 225px;">
Nothing too exciting initially.</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://2.bp.blogspot.com/-CHxbBfg4_KM/UQKqvZ2oHiI/AAAAAAAABuM/k4AZ6XbcU-I/s1600/w8sdk0_edit.jpg" imageanchor="1"><img border="0" height="235" src="http://2.bp.blogspot.com/-CHxbBfg4_KM/UQKqvZ2oHiI/AAAAAAAABuM/k4AZ6XbcU-I/s320/w8sdk0_edit.jpg" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
I appreciated being able to deselect all of the stuff I wasn't going to need on a build server.</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://3.bp.blogspot.com/-zPOZSXhfDMw/UQGzPzKIQUI/AAAAAAAABrU/rldWIE0mFMc/s1600/w8sdk1.JPG" imageanchor="1"><img border="0" height="236" src="http://3.bp.blogspot.com/-zPOZSXhfDMw/UQGzPzKIQUI/AAAAAAAABrU/rldWIE0mFMc/s320/w8sdk1.JPG" width="320" /></a></div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
Ugh. More proxy issues, even locally. Shades of <a href="http://search.dilbert.com/comic/Mordac" target="_blank">Mordac</a>! I could easily download the .NET 4 redistributable though, so I was still undaunted.</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://2.bp.blogspot.com/-Ok4nZoLNITo/UQG4e-gPaVI/AAAAAAAABr0/23R44uRdwA8/s1600/w8sdk2_edit.jpg" imageanchor="1"><img border="0" height="213" src="http://2.bp.blogspot.com/-Ok4nZoLNITo/UQG4e-gPaVI/AAAAAAAABr0/23R44uRdwA8/s320/w8sdk2_edit.jpg" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
Now things started to get silly. Where was I supposed to find sdk_tools4.msi? Searched Google, other folks were wondering the same thing.
</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://1.bp.blogspot.com/-fT8uj0sBMfw/UQG8dfFAQiI/AAAAAAAABsI/icaUUhCvx_Y/s1600/w8sdk3_edit.jpg" imageanchor="1"><img border="0" height="277" src="http://1.bp.blogspot.com/-fT8uj0sBMfw/UQG8dfFAQiI/AAAAAAAABsI/icaUUhCvx_Y/s320/w8sdk3_edit.jpg" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
Maybe I already possessed sdk_tools4.msi and didn't know it. <a href="http://www.voidtools.com/" target="_blank">Everything</a> proved that theory valid. Hoorah! Now I could build my SDK installer, get the builds rolling, and move on.</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://3.bp.blogspot.com/-chemqft0dAc/UQKelqzoVkI/AAAAAAAABsc/Nxx2qwYr_oU/s1600/w8sdk4.JPG" imageanchor="1"><img border="0" height="62" src="http://3.bp.blogspot.com/-chemqft0dAc/UQKelqzoVkI/AAAAAAAABsc/Nxx2qwYr_oU/s320/w8sdk4.JPG" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<br />
It wasn't to be. After browsing to my local copy of sdk_tools4.msi and clicking Retry, the SDK builder process gracefully prematurely ended, mentioning something about 'bad payload' or the like. Sdksetup.exe revealed an important secret at this point: a log file! Mine was located at 'C:\Users\[Username]\AppData\Local\Temp\standalonesdk'. The file was thankfully extremely verbose, and I could see all of the failed web requests for various resources.<br />
<br />
<br />
<div style="float: left; margin-right: 10px; width: 225px;">
For example, when I was prompted to specify the location of netfx45_dtp.cab...</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://1.bp.blogspot.com/-vW_Y295MFWU/UQKrfWAvrgI/AAAAAAAABuY/kT7sY9HBYH8/s1600/w8sdk5_edit.jpg" imageanchor="1"><img border="0" height="215" src="http://1.bp.blogspot.com/-vW_Y295MFWU/UQKrfWAvrgI/AAAAAAAABuY/kT7sY9HBYH8/s320/w8sdk5_edit.jpg" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
...I searched the contents of the log file for these entries:<br />
<br />
<div style="font-size: smaller; margin: 10px;">
[1F08:1CA8][2013-01-24T15:05:16]: Error 0x80070005: Failed to send request to URL: http://download.microsoft.com/download/F/1/3/[long alphanumeric string]/standalonesdk/Redistributable/4.5.50710/netfx45_dtp.cab<br />
[1F08:1CA8][2013-01-24T15:05:16]: Error 0x80070005: Failed to connect to URL: http://download.microsoft.com/download/F/1/3/[long alphanumeric string]/standalonesdk/Redistributable/4.5.50710/netfx45_dtp.cab<br />
[1F08:1CA8][2013-01-24T15:05:16]: Error 0x80070005: Failed to get size and time for URL: http://download.microsoft.com/download/F/1/3/[long alphanumeric string]/standalonesdk/Redistributable/4.5.50710/netfx45_dtp.cab</div>
I then plugged the URL into a browser which then prompted me to download the file. After downloading, I then specified the location of the file in sdksetup.exe and clicked Retry. It took about 10 minutes or so to get all of the files. Not the most elegant of solutions but hopefully this wasn't something that I was going to have to do often.
<br />
<br />
<br />
<div style="float: left; margin-right: 10px; width: 225px;">
Finally I was finished. But would it work?</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://3.bp.blogspot.com/-Yc4pZP3JQtI/UQKmiq0oHxI/AAAAAAAABtA/wSqupBwQllo/s1600/w8sdk6_edit.jpg" imageanchor="1"><img border="0" height="234" src="http://3.bp.blogspot.com/-Yc4pZP3JQtI/UQKmiq0oHxI/AAAAAAAABtA/wSqupBwQllo/s320/w8sdk6_edit.jpg" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
I copied my new .NET 4.5 SDK installer- and supporting files- to my Windows Server 2008 R2 build machine.</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://1.bp.blogspot.com/-p1H8XTvwKcU/UQKnrD2IwWI/AAAAAAAABtQ/Az1V7G2SROM/s1600/w8sdk10.JPG" imageanchor="1"><img border="0" height="151" src="http://1.bp.blogspot.com/-p1H8XTvwKcU/UQKnrD2IwWI/AAAAAAAABtQ/Az1V7G2SROM/s320/w8sdk10.JPG" width="314" /></a></div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
So far so good.
</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://3.bp.blogspot.com/-Hww71r1wuz8/UQKoiHxCuKI/AAAAAAAABtg/w_-ZAHVI688/s1600/w8sdk7.JPG" imageanchor="1"><img border="0" height="236" src="http://3.bp.blogspot.com/-Hww71r1wuz8/UQKoiHxCuKI/AAAAAAAABtg/w_-ZAHVI688/s320/w8sdk7.JPG" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
Looking promising.
</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://3.bp.blogspot.com/-zIPT0Oi7veY/UQKoom3c3xI/AAAAAAAABts/5q07-SqehBg/s1600/w8sdk8.JPG" imageanchor="1"><img border="0" height="235" src="http://3.bp.blogspot.com/-zIPT0Oi7veY/UQKoom3c3xI/AAAAAAAABts/5q07-SqehBg/s320/w8sdk8.JPG" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
<div style="float: left; margin-right: 10px; width: 225px;">
Done!
</div>
<div style="float: left; text-align: center; width: 320px;">
<a href="http://3.bp.blogspot.com/-WIKABjii_UA/UQKpaXd1X6I/AAAAAAAABt4/GeEapcVA2TE/s1600/w8sdk9.JPG" imageanchor="1"><img border="0" height="236" src="http://3.bp.blogspot.com/-WIKABjii_UA/UQKpaXd1X6I/AAAAAAAABt4/GeEapcVA2TE/s320/w8sdk9.JPG" width="320" /></a>
</div>
<div style="clear: both; height: 10px;">
</div>
I then queued a build, which subsequently completed successfully.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com2tag:blogger.com,1999:blog-1939334038833612724.post-84448349542054021792013-01-23T06:00:00.000-06:002013-01-25T10:35:05.109-06:00Build server and the lost TFS message queueI couldn't get the TFS 2012 RTM build server running initially. My build controller and associated agents were all stopped. The Event log told me that
<br />
<pre style="margin-left: 25px;">Build machine [Machine Name] lost connectivity to message queue tfsmq://buildservicehost-1/.
Reason: Please contact your administrator. There was an error contacting the server.
Technical information (for administrator):
HTTP code 500: System.ServiceModel.ServiceActivationException</pre>
Research yielded some <a href="http://blogs.microsoft.co.il/blogs/kmoraz/archive/2013/01/03/tfs-2012-build-controller-zombified-by-ssl-binding.aspx" target="_blank">similar scenarios</a>, but the configurations were too different from mine to be considered as viable solutions. Example: my build server wasn't using SSL.<br />
<br />
I remembered reading that an <a href="http://blogs.msdn.com/b/buckh/archive/2012/11/26/tfs-and-vs-2012-update-1-now-available.aspx" target="_blank">update for TFS 2012 was available</a>. Because my TFS 2012 instance is not in production use I thought that I would give the update a shot.<br />
<br />
I apologize for the lack of tension and drama in this post, but the update resolved the issue.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-69633173828581306012013-01-09T06:30:00.000-06:002013-01-09T15:09:42.070-06:00Favorite Queries In Visual Studio 2012 Team ExplorerI really need to spend more time exploring Visual Studio 2012's Team Explorer. I just discovered that after adding a query to 'My Favorites' you'll be presented with a helpful summary of the number of Work Items, their State, and the type of query, such as a Flat List or Tree of Work Items.<br />
<br />
<div style="float: left;">
Here's what it looks like:</div>
<div class="separator" style="float: left; text-align: center;">
<a href="http://3.bp.blogspot.com/-LalhISqbcsk/UO3VoLdIkWI/AAAAAAAABqo/ZXnUqo_5aBM/s1600/VS2012_TeamExplorer_WorkItems_Faves.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://3.bp.blogspot.com/-LalhISqbcsk/UO3VoLdIkWI/AAAAAAAABqo/ZXnUqo_5aBM/s1600/VS2012_TeamExplorer_WorkItems_Faves.JPG" /></a></div>
<div style="clear: both;">
</div>
After I made this discovery I did some research and found <a href="http://www.szalapski.com/2012/08/visual-studio-2012-new-team-explorer.html" target="_blank">this nice post on many other new Team Explorer features</a>.<br />
<br />
<div style="margin-top:50px">
<div style="float:left;font-size:smaller;padding-top:160px;margin-right:5px;">Enjoy this ad with my compliments!</div>
<div style="float:left">
<iframe bordercolor="#000000" class="qvazjgcqdpzochiqkmqk" frameborder="0" height="320" hspace="0" marginheight="0" marginwidth="0" scrolling="no" src="http://ad.doubleclick.net/adi/N7433.148119.BLOGGEREN/B7095141.6058;sz=320x320;ord=[timestamp]?;lid=41000613802463546;pid=5237315841213mk0%257E0;usg=AFHzDLt8b0bqybOvCTGkhaTLJOtKWlmkrw;adurl=http%253A%252F%252Fwww.brylanehome.com%252FProduct.aspx%253FPfId%253D223215%2526ProductTypeId%253D1%2526affiliate_id%253D017%2526mr%253AtrackingCode%253D1A38C566-B7C3-E011-8116-001517B1882A%2526mr%253AreferralID%253DNA;pubid=611762;imgsrc=http%3A%2F%2Fmedia.redcatsecom.com%2Fbrylanehome%2Fmc%2F1584_52373_mc_1213.jpg%3Fwid%3D230%26hei%3D331%26qlt%3D95%26op_sharpen%3D1;width=222;height=320" vspace="0" width="320"></iframe></div></div>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-39823331333495732912013-01-07T21:00:00.000-06:002013-03-25T10:20:53.927-05:00Management Nuggets: Priceless Wisdom Dispensed For FreeFor better or worse I have been in IT management for almost 8 years. I haven't been fired, demoted, sued, or assaulted (yet!) so I must be doing something right. I have designed, developed, and managed projects of varying scope, from trivial departmental utilities to enterprise applications. Maybe some day I'll get around to that book I've been threatening to write for so long, but until then it's time to give back to the larger community for the greater good.<br />
<br />
<ul>
<li><a href="http://bryantbrabson.blogspot.com/2013/03/management-nugget-1-avoid-holiday-time.html" target="_blank">Management Nugget 1: Avoid The Holiday Time Crunch </a> </li>
</ul>
Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-15380024502706332742013-01-06T06:30:00.000-06:002013-01-21T16:20:35.622-06:00GIGO / GINO<u><b>Introduction</b></u><br />
Recently I was reviewing a production issue with one of my developers that involved 'bad' data from a third party application blowing up one of our proprietary processes. We do a lot of ugly 'data proctology' like this and don't have a lot of control on the front end. It is what it is. Our conversation caused me to revisit several old topics.<br />
<br />
<div style="text-align: right;">
<a href="http://gan.doubleclick.net/gan_click?lid=41000613802463471&pid=58000000002577560010000M010.0&adurl=http%3A%2F%2Fwww.dsw.com%2Fshoe%2Fetienne%2Baigner%2Bceltic%2Briding%2Bboot%3FprodId%3D257756&usg=AFHzDLtwqILqzANWFVTlkfHbWDNqfKKLlg&pubid=611762" rel="nofollow" target="_blank">Etienne Aigner Celtic Riding Boot (Google Affiliate Ad)</a></div>
<br />
<a href="http://www.youtube.com/watch?v=KiVzLdhz20Y" target="_blank"><u><b>I'm The Garbageman</b></u></a><br />
"Garbage In, Garbage Out". GIGO. <a href="http://en.wikipedia.org/wiki/Garbage_in,_garbage_out" target="_blank">It's an ancient phrase</a> when you consider the short lifespan of computer technology. Many refute the validity of this concept. The argument is that 'bad' data shouldn't be allowed into a system in the first place, and if it does make it in then it is a failure on the developer's part. I tend to agree, and defensively program to prevent GIGO.<br />
<br />
That being said, for better or worse, I think like a developer and so code safeguards accordingly. That means I am not thinking like an end user, and so am going to be outwitted almost constantly. I simply can't think the way that I need to in order to account for the myriad things that a user might do to a given application. (I actively practice trying to put myself in a user's shoes- remember, users are NOT the enemy.)<br />
<br />
There are many testing techniques- automated and manual- that can also help preventing GIGO. Unfortunately, I've yet to be employed by someone who permits the time to develop comprehensive automated test suites because of the time required. Companies have slowly admitted that Quality Assurance departments offer a positive <a href="http://www.investopedia.com/terms/r/returnoninvestment.asp" target="_blank">ROI</a>, and I hope that they come around regarding automated testing as well.<br />
<br />
I realize that QA testing was a tough sell to corporate America (and I guess the entire world's business entities), because in many cases the argument was quite academic:<br />
<div style="font-size: smaller; margin: 10px;">
If we hire people to test our software then we'll have a higher quality product. If we have a higher quality product then we will spend less time working on defects. If we spend less time working on defects then we will have more time to develop new features and enhance shareholder value in ACME Corporation.</div>
But what if ACME Corp's software didn't have many bugs? How do you prove a negative like that? (That's a rhetorical question and I currently don't have the answer.)<br />
<br />
<div style="text-align: right;">
<a href="http://gan.doubleclick.net/gan_click?lid=41000613802464048&pid=23414903&adurl=http%3A%2F%2Fwww.officemax.com%2Foffice-furniture%2Foffice-decor%2Frugs%2Fproduct-prod4140188%3Fcm_mmc%3DPerformics-_-Office%2520Furniture-_-Office%2520Decor-_-Rugs%26ci_src%3D14110944%26ci_sku%3D23414903&usg=AFHzDLsmJNrmPSsafVskVKkmdwUOvQNS2g&pubid=611762" rel="nofollow">Anji Mountain Cobblestone Bamboo Rug, 7'x10' AMB0085-0710 (Google Affiliate Ad)</a></div>
<br />
<u><b>The Void</b></u><br />
Our production issue had taken us beyond GIGO into the realm of GINO ("Garbage In, Nothing Out"). Our process crashed as data was extracted from the source application. And here is where I think that we could do a better job defensively coding around the input and gracefully failing if absolutely necessary. Since we don't have a user interface- or a user!- we can't just present a validation failure message or the like. (The source application is quite deficient in the area of input validation anyway.) <a href="http://en.wikipedia.org/wiki/Fuzz_testing" target="_blank">Fuzz testing</a> might be one technique that could harden our vulnerable process. While this might seem like overkill, we unfortunately don't have total autonomy over how some of our processes are consumed so would need to test for a wide range of issues.
<br /><br />
<u><b>Update</b></u><br />
I recently encountered a new variation of GIGO that involves requirements. Insufficient or overly broad requirements yield garbage as easily as bad input data.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-2116159080275933892012-10-30T13:06:00.001-05:002013-03-05T10:22:10.930-06:00My list of Visual Studio 2012 tweaksIn no particular order, here's a list of things that I like to do to Visual Studio 2012.
<br />
<ul>
<li><a href="http://www.richard-banks.org/2012/06/how-to-prevent-visual-studio-2012-all.html">Return to the days of mixed-case menus</a> </li>
<li><a href="http://blogs.msdn.com/b/visualstudio/archive/2012/10/29/your-visual-studio-your-colors.aspx">Edit colors and themes</a></li>
<li><a href="http://visualstudiogallery.msdn.microsoft.com/3a96a4dc-ba9c-4589-92c5-640e07332afd">Productivity Power Tools</a></li>
<li><a href="http://blog.paulbouwer.com/2010/01/31/replace-diffmerge-tool-in-visual-studio-team-system-with-winmerge/" target="_blank">Use WinMerge as the Compare tool for TFS</a></li>
<li><a href="http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5" target="_blank">Slow Cheetah XML Transforms</a> </li>
<li><a href="http://visualstudiogallery.msdn.microsoft.com/b1ef7eb2-e084-4cb8-9bc7-06c3bad9148f" target="_blank">Microsoft Visual Studio Team Foundation Server 2012 Power Tools</a> </li>
<li><a href="http://code.google.com/p/gitextensions/" target="_blank">Git Extensions</a> - I find myself increasingly using Git as a <a href="http://odetocode.com/Blogs/scott/archive/2008/11/18/spike-code-and-source-control.aspx" target="_blank">local repository for spike code</a> so that I can avoid the ceremony and overkill of <a href="http://msdn.microsoft.com/en-us/library/ms181368%28v=vs.100%29.aspx" target="_blank">TFS Source Control</a></li>
<li><a href="http://msdn.microsoft.com/en-us/data/tools.aspx" target="_blank">SQL Server Data Tools</a> - really handy to have installed when you want to merely run a query or examine a database</li>
</ul>
Here's one that I still need to review, but certainly looks intriguing: <a href="http://visualstudiogallery.msdn.microsoft.com/ee4fcff9-0c4c-4179-afd9-7a2fb90f5838" target="_blank">EntityFramework Reverse POCO Generator</a><br />
<br />
<a href="http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d" target="_blank">Entity Framework Power Tools</a> are worth evaluating. I haven't spent very much time with them yet, but <a href="http://weblogs.asp.net/shijuvarghese/archive/2013/03/03/generating-entity-data-model-diagram-from-ef-code-first-dbcontext.aspx" target="_blank">generating a diagram from a DbContext is useful</a>.
<br />
<br />
<a href="http://www.linqpad.net/" target="_blank">LINQPad</a> isn't an extension, but is indispensable if you work with <a href="http://msdn.microsoft.com/en-us/library/vstudio/bb397926.aspx" target="_blank">LINQ</a>. I want to also call your attention to this <a href="http://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx" target="_blank">excellent post on calling SQL Server stored procedures from LINQPad</a>. I never thought that I would ever need to manipulate the results of a stored procedure call in LINQPad until today, and fortunately <a href="http://www.global-webnet.net/BlogEngine/page/AboutMe.aspx" target="_blank">BillKrat</a>'s article showed me the way.<br />
<br />
Though not part of Visual Studio, <a href="http://tfsintegration.codeplex.com/" target="_blank">Team Foundation Server Integration Tools</a> is incredibly useful if you need to selectively migrate portions of a project, such as Work Items only. Using the tool requires at least an intermediate level of knowledge of TFS.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-89604165991420703752012-10-23T15:04:00.000-05:002012-10-23T15:09:07.445-05:00Test Driving CouchDB and MongoDB with ExpandoObjects<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script>
<script src="http://bryantbrabson.net/sh/scripts/shBrushCSharp.js" type="text/javascript"></script>
<script src="http://bryantbrabson.net/sh/scripts/shBrushJScript.js" type="text/javascript"></script>
<br />
<b><u>Introduction</u></b><br />
I wanted to explore whether a database such as <a href="http://couchdb.apache.org/">CouchDB</a> or <a href="http://www.mongodb.org/">MongoDB</a> was the solution to a data integration problem. (If you are unfamiliar with these databases then I highly recommend the book "<a href="http://martinfowler.com/nosql.html">NoSQL Distilled</a>" by <a href="http://martinfowler.com/">Martin Fowler</a> and <a href="http://www.sadalage.com/">Pramod Sadalage</a>.)
I wanted to quickly get to the exploration phase, so didn't want to spend a lot of time- if any- developing domain models and the like for a skunkworks project like this one. The overarching goal was to expose the integrated data as easily consumable endpoints in a heterogeneous environment, but any deep discussions about service-oriented architecture were premature at this early analytic phase.<br />
<br />
<b><u>Implementation</u></b><br />
Accessing the initial seed data was easy. The source systems were <a href="http://www.microsoft.com/sqlserver/en/us/default.aspx">Microsoft SQL Server</a> so <a href="http://msdn.microsoft.com/en-us/data/ef.aspx">Entity Framework</a> was used to extract data. <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx">ExpandoObjects</a> came into play at this point. <a href="https://www.google.com/search?q=commonality+variability+analysis">Commonality-variability analysis</a> revealed a core set of fields shared between the data sources. My idea was that elements common across data sources, such as names and birth dates, would be persisted using the same set of identifiers. Elements specific to a particular source, such as maiden name or favorite color, could be picked up if needed based on a value indicating the source of the data. That's the beauty of a <a href="http://blog.mongodb.org/post/119945109/why-schemaless">schemaless database</a>- even though all of the items don't have the same 'shape' they can still all be stored together and queried.<br />
<br />
At this point an example would probably help. Line 14 shows the use of an ExpandoObject to capture and reconcile common data elements. In other words, whether the original data was stored as 'firstname' or 'first_name' or 'fname' it is saved to the integration database using the 'FirstName' property. For the initial test phase I took the approach of testing whether the source data existed before creating a property as seen on lines 17, 19, and 21. It is quite possible that the proper approach is to create the properties regardless of whether they exist so that there is a degree of uniformity to the data.<br />
<br />
<pre class="brush:csharp">public IEnumerable<ExpandoObject> GetPeople()
{
var peopleList = new List<ExpandoObject>();
using (var data = new sourceData.data_Entities())
{
var people = from p in data.clients
select p;
if (people != null)
{
foreach (var person in people)
{
dynamic expando = new ExpandoObject();
expando.FirstName = person.firstname;
expando.LastName = person.lastname;
if (!string.IsNullOrWhiteSpace(person.mi))
expando.MiddleName = person.mi;
if (person.birthdate.HasValue)
expando.DOB = person.birthdate.Value;
if (!string.IsNullOrWhiteSpace(person.gender))
expando.Sex = person.gender;
expando.SourceSystemId = person.clientid;
expando.SourceSystem = "Source1";
peopleList.Add(expando);
}
}
}
return peopleList.AsEnumerable();
}
</pre>
<br />
Once the data was captured, the returned object was sent to the following method for upload to the database. In the example below, MongoDB is the destination. One nice side effect of using a list of ExpandoObjects is that this method can be reused because the input argument isn't strongly typed.<br />
<br />
<pre class="brush:csharp">private static void UploadRecords(IEnumerable<ExpandoObject> records, string collectionName = "people")
{
if (records != null)
{
var stopwatch = GetAndStartStopwatch();
MongoServer server = MongoServer.Create(connectionString);
MongoDatabase db = server.GetDatabase("testdb");
MongoCollection<BsonDocument> people = db.GetCollection<BsonDocument>(collectionName);
List<BsonDocument> uploadDocs = new List<BsonDocument>();
IEnumerable<SafeModeResult> results = null;
foreach (var record in records)
{
BsonDocument doc = new BsonDocument();
doc.Add(record as IDictionary<string, object>);
uploadDocs.Add(doc);
}
if (uploadDocs.Count > 0)
results = people.InsertBatch(uploadDocs);
stopwatch.Stop();
log.InfoFormat("Records: {0}. Elapsed time: {1}", uploadDocs.Count, stopwatch.Elapsed);
}
}
</pre>
<br />
In order to use the efficient <a href="http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial#CSharpDriverTutorial-InsertBatchmethod">InsertBatch</a> method, I needed to build up an IEnumerable<BsonDocument>. A <a href="http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial#CSharpDriverTutorial-BsonDocument">BsonDocument</a> is "a collection of name/value pairs" and ExpandoObjects implement the <span class="input">IDictionary<String, Object> interface, so I could loop through the source data and add each item to a BsonDocument (see lines 13-18 above). The new BsonDocument then was added to a List<BsonDocument>, and this list then was used for the call to InsertBatch.</span><br />
<br />
<span class="input">After inserting all the data, I was ready to start querying the database. Here's an example of a couple different items, or "documents" as they are called in MongoDB. Both of these documents are from the same MongoDB <a href="http://www.mongodb.org/display/DOCS/Schema+Design#SchemaDesign-Collections">collection</a>.</span><br />
<br />
<pre class="brush:js">> db.people.findOne({"SourceSystem":"Source1"})
{
"_id" : ObjectId("40842293c1199d1t7k6f0add"),
"FirstName" : "JANE",
"LastName" : "DOE",
"MiddleName" : "X",
"DOB" : ISODate("9999-01-01T06:00:00Z"),
"Sex" : "FEMALE",
"SourceSystemId" : 123,
"SourceSystem" : "Source1"
}
> db.people.findOne({"SourceSystem":"Source2"})
{
"_id" : ObjectId("309423b4c1299d1x7c6f155f"),
"FirstName" : "John",
"LastName" : "Doe",
"SourceSystemId" : 321,
"SourceSystem" : "Source2",
"Sex" : "U"
}
</pre>
<br />
<b><u>Summary</u></b><br />
So far my testing has been going well. Both CouchDB and MongoDB perform well for what I am doing. It's really easy to make sweeping changes to the database if I want to try something else by starting from scratch. Example: it's easy to delete the database if I need to make changes to my expandos. (TOO easy- <a href="http://wiki.apache.org/couchdb/Getting_started_with_Futon">Futon</a> really needs an (optional) confirmation dialog.) The bottom line is that I saved a lot of time using ExpandoObjects. I haven't spent days crafting tailor made objects just to test some theories. While working with CouchDB I was also surprised (though I guess I shouldn't have beem) at how easily <a href="http://restsharp.org/">RestSharp</a> knew what to do with ExpandoObjects. <br />
<br />
Next steps are to expose the data to a variety of clients and test performance. I have been using <a href="http://www.asp.net/web-api">ASP.NET Web API</a> for some time now and I can quickly get XML and JSON output rolling now that I have a populated database. I also need to focus on the variability side of things by loading the 'uncommon' fields into my test collections.<br />
<br />
Would I recommend using this approach for a production system? That really depends on the intent of the system. By using ExpandoObjects you aren't able to take advantage of IntelliSense in Visual Studio, and while that might not be a deal breaker<script>
$(document).ready(function()
{
$("a").attr("target","_blank");
});
</script>, it might seriously impact code maintainability.
<script language="javascript" type="text/javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-42434822711579808232012-09-06T09:37:00.000-05:002012-09-06T09:37:40.902-05:00Integration Executive OverviewIn the past I was asked to provide a brief executive overview of the state of integration efforts with a vendor's product. I felt that it was an honest, objective analysis so am sharing it here, with some parts redacted. I only had a few hours to put it together so admittedly it is a little unpolished.
<div style="text-align:left;margin-top:25px"><h3>Integration Lessons Learned</h3></div>
<ol style="margin-top:25px">
<li style="margin-bottom:10px">
<span style="font-weight:bold">Overview</span><br>
[Vendor] grudgingly acknowledges that ACME Corporation (ACME) has, over the course of many years, created an expansive codebase that extends the capabilities of the [Application] product. There is an opportunity cost associated with the primitive design of the integration as it stands at this time. That cost is derived from the friction of attempting to integrate with a system that is not meant to be extended.
</li>
<li style="margin-bottom:10px">
<span style="font-weight:bold">What's good?</span><br>
There are a couple of places where [Vendor] gets it right.<br><br>
<ul>
<li>HL7 – there are a few places in [Application] that allow import and export of data in the HL7 data exchange format</li>
<li>Custom reports – [Application] allows a certain degree of customization of reports, though not all features of the toolset are available</li>
<li>Overall, the amount of integration done by [ACME] developers and consultants is impressive when you consider the simple fact that <span style="font-style:italic">[Application] isn’t meant to be extended</span>. Regardless, a key part of our day to day operations are based solely upon the hard work and diligence of those who had to discover how to extract information from [Application].</li>
</ul>
</li>
<li style="margin-bottom:10px">
<span style="font-weight:bold">What's bad?</span><br>There are profound consequences to the integration choices that were made.<br><br>
<ul>
<li>Our code is intimately connected to [Application] database, which in software development is known as ‘tight coupling’. What this means is that the slightest change [on the part of Application] can break our codebase, requiring inefficient emergency patch releases [on ACME's part] to keep everything running. Even more insidious is a change that we can’t detect because of its subtlety- think of the ‘Butterfly Effect’ here. Either way, our company is at a disadvantage because we are scrambling to resolve support issues rather than creating value.</li>
<li>Rather than a single source of truth, multiple parties over the years have hooked into the [Application] database. Each group might use and interpret the data differently. This also creates more opportunity cost because of the multiple points of failure. The Master Data Management project is a step in the right direction to unify enterprise data.</li>
</ul>
</li>
<li style="margin-bottom:10px">
<span style="font-weight:bold">What's the solution?</span><br>
Integration code should have as loose a connection as possible to its target. A metaphor to describe this is the electrical cord for a lamp. When you buy a lamp, do you connect it directly to the home wiring? Of course not- what if you want to move the lamp to a new location? We all know that there is a plug that fits a standard sized outlet. So how do we ‘plug in’ code to another party’s application?
<br><br>
An <a href="http://en.wikipedia.org/wiki/Application_programming_interface" target="_blank">Application Programming Interface</a> (API) is a public access point for integration- the electrical outlet from our earlier lamp metaphor. It’s the way that entities can exchange information without being married to one another. Think of the current titans of the internet: Google, Facebook, Amazon, Netflix, and Twitter to name a few. Surely you have used a website or mobile app that displayed information from one of these companies. This third-party integration doesn’t occur by hooking directly into Facebook’s databases- it happens through their public API’s. (See Examples section below.)
<br><br>
As your set of API’s starts to grow, you start to become concerned with <a href="http://msdn.microsoft.com/en-us/library/bb466232" target="_blank">enterprise architecture</a>, which is the practice of reducing complexity and cost while increasing agility by rationally and efficiently connecting systems. There are a number of ways to approach this design, and all are beyond the scope of this document.
</li>
<li style="margin-bottom:10px">
<span style="font-weight:bold">The Future</span><br>
As new systems are purchased their vendors should be questioned as to the presence of an API. Keep in mind that an API isn’t a right- it’s a privilege. Some vendors probably don’t want customers to have access to their data because they see the opportunity for profit in costly customizations.
As our ability to internally disseminate data in a more modern fashion evolves, unused features of tools that we use every day become valuable. For example, <a href="http://www.microsoft.com/en-us/bi/powerpivot.aspx" target="_blank">Microsoft Power Pivot</a> allows Excel users to consume data from a variety of sources and perform high-level business intelligence operations from their desktop.
</li>
<li style="margin-bottom:10px">
<span style="font-weight:bold">Examples</span><br>
<a href="http://developers.facebook.com/">Facebook API</a><br>
<a href="https://developers.google.com/">Google API</a><br>
<a href="https://dev.twitter.com/docs/api">Twitter API</a><br>
<a href="http://aws.amazon.com/">Amazon API</a>
</li>
<li>
<span style="font-weight:bold">Reference</span><br>
<a href="http://accentuate.me/blog/?p=46">Why You Might Need an API</a><br>
<a href="http://www.amazon.com/dp/1449308929/ref=rdr_ext_tmb">APIs: A Strategy Guide</a><br>
<a href="http://msdn.microsoft.com/en-us/library/bb466232">A Comparison of the Top Four Enterprise-Architecture Methodologies</a>
</li>
</ol>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-81596260853277749412012-08-16T11:08:00.001-05:002012-08-16T11:08:56.451-05:00I Feel Like I'm Taking Crazy Pills: Ninject, SignalR, and Nuget<i>"Could not load file or assembly 'Ninject, Version=2.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference."</i>
<br><br>
After 3 hours of wrestling with this error I have solved the problem but don't understand the solution. Maybe it is so blindingly obvious that I am overlooking it. As you can see from the video link below, however, this one really confused me.
<br><br>
<iframe width="560" height="315" src="http://www.youtube.com/embed/AG7LjVCj50Y" frameborder="0" allowfullscreen></iframe>
<br><br>
Clearly there was an outdated reference in one of the three projects that comprised my prototype ASP.NET MVC 3 solution that was using <a target="_blank" href="http://www.ninject.org/">Ninject</a> and <a target="_blank" href="http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx">SignalR</a>. I checked, double-checked, triple-checked references manually as well as in NuGet and everything seemed in order.<br><br>
I noticed that one of my projects had an 'orphaned' NuGet packages.config file. This file had entries for Ninject and Ninject.Extensions.Conventions, but the project didn't actually have references to these assemblies.
<pre class="brush:xml">
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Ninject" version="3.0.1.10" targetFramework="net40" />
<package id="Ninject.Extensions.Conventions" version="3.0.0.11" targetFramework="net40" />
</packages>
</pre>
I like to keep my projects lean and clean so I decided to tidy up. Rather than manually deleting the orphaned file, I decided to use Nuget, thinking that this might be a more thorough approach. After NuGet was finished I tried running the solution again, though I had zero expectations that the problem was solved.
<br><br>
I almost fell out of my office chair when the app started up successfully.
<br><br>
"What in tarnation changed?" I wondered. (I didn't actually use the word '<a href="http://dictionary.reference.com/browse/tarnation" target="_blank">tarnation</a>', but hopefully you get a sense of my surprise and bewilderment.) So...to the Pending Changes window!
<br><br>
<a href="http://2.bp.blogspot.com/-lwa4_WW_6M4/UCvtPggeNNI/AAAAAAAABp0/Wq5kbv93ttQ/s1600/Capture.JPG" imageanchor="1" style=""><img border="0" height="122" width="320" src="http://2.bp.blogspot.com/-lwa4_WW_6M4/UCvtPggeNNI/AAAAAAAABp0/Wq5kbv93ttQ/s320/Capture.JPG" /></a>
<br><br>
I was surprised to see that something had changed with the web.config file. Running a diff on the file revealed why my application had suddenly started to behave:<a href="http://msdn.microsoft.com/en-us/library/2fc472t2%28v=vs.100%29.aspx" target="_blank">binding redirection</a>.
<br><br>
<a href="http://2.bp.blogspot.com/-7RUPaNRi24c/UCvvAM1w16I/AAAAAAAABqA/KXXm6a5E19c/s1600/Capture.2JPG.JPG" imageanchor="1" style=""><img border="0" height="43" width="320" src="http://2.bp.blogspot.com/-7RUPaNRi24c/UCvvAM1w16I/AAAAAAAABqA/KXXm6a5E19c/s320/Capture.2JPG.JPG" /></a>
<br><br>
So that's it for now. Ninject and SignalR both work in harmony. I normally don't like to let mysteries like this linger unsolved, but I've got more important things to do today. (<a href="http://www.microsoft.com/visualstudio/11/en-us">Visual Studio 2012</a> and Windows 8 are both available today, don't you know?)
<script src="http://bryantbrabson.net/sh/scripts/shBrushXml.js" type="text/javascript">
</script><br />
<script language="javascript" type="text/javascript">
<!--
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
-->
</script>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com1tag:blogger.com,1999:blog-1939334038833612724.post-1190924884942198682012-07-20T14:29:00.000-05:002012-07-20T14:37:30.479-05:00Windows 7 dual monitor wallpaper tiles in the wrong directionThe other day I got sucked in by <a href="http://lifehacker.com/wallpaper-wednesday/" target="_blank">Lifehacker's Wallpaper Wednesday</a>. One thing led to another and I downloaded a <a href="http://thepaperwall.com/wallpaper.php?view=0d914caf0b74774847e20f4e77bb08a919ec82ef&fol=duel_monitor" target="_blank">relaxing lake scene</a> that would stretch across my two 23" monitors.<br />
<br />
<div style="text-align: left;">
<div class="separator" style="display: inline; float: right;">
<a target="_blank" href="http://1.bp.blogspot.com/-v0mfXSOfgag/UAmdqgkLVDI/AAAAAAAABpQ/QZKuGT0PA-o/s1600/before.jpg" imageanchor="1" style="margin-bottom: 1em; margin-left: 1em;"><img alt="Before" border="0" height="240" src="http://1.bp.blogspot.com/-v0mfXSOfgag/UAmdqgkLVDI/AAAAAAAABpQ/QZKuGT0PA-o/s320/before.jpg" title="Before" width="320" /></a></div>
<div style="width: 100%;">
However, once I selected my new desktop image I noticed a problem. See the majestic trees on the left monitor? They're supposed to be on the far right of the right monitor, which is also the main display monitor. This is certainly a problem.</div>
<div style="clear: both;">
</div>
</div>
I futilely tried altering the monitor configuration in 'Control Panel\Appearance and Personalization\Display\Screen Resolution' but that never got the results that I wanted. Updated display drivers in case there was a software solution but that didn't solve the problem either.<br />
<br />
I knew that my monitor-spanning image's 'Picture position' had to be set to tile in 'Control Panel\Appearance and Personalization\Personalization\Desktop Background' so I did some searching using terms such as 'tiling wrong way' and tiling 'right to left' and eventually came across <a href="http://www.savagereactor.co.uk/posts/2008/12/31_windows_dual_monitor_wallpapers.html" target="_blank">a post like this one</a> that revealed the underlying issue: Windows starts drawing the image in the top left of the primary display then wraps to the other displays.
<br />
<br />
With this knowledge I realized that I was going to have to use <a href="http://www.getpaint.net/" target="_blank">Paint.Net</a> to resolve the matter.<br />
<br />
The first step was to break up my 3840 x 1080 image into two equal distinct images. Following these steps from the <a href="http://forums.getpaint.net/index.php?/topic/15946-divide-photo-in-half/" target="_blank">Paint.Net forum</a> I was able to produce two 1920 x 1080 images.
<br />
<ol>
<li>Open original source image</li>
<li>Click on Image > Canvas Size</li>
<li>Uncheck Maintain aspect ratio CheckBox</li>
<li>Set pixel size to 1920 width, leaving height as is</li>
<li>Set Anchor to Top Left</li>
<li>Save this half of the photo, naming 'left', '1', or whatever you choose</li>
<li>Click undo, to undo the canvas size and repeat for the right half or reopening the source image and repeat, using 'Top Right' for step 5</li>
</ol>
Now I had to combine the two images produced above into a new 3840 x 1080 image. Again, the <a href="http://forums.getpaint.net/index.php?/topic/20014-combine-2-images-side-by-side/" target="_blank">Paint.Net forum</a> had the answers.
<br />
<ol>
<li>Open the image that you want to appear on the left monitor first</li>
<li>Image > Canvas Size</li>
<li>Uncheck Maintain aspect ratio CheckBox</li>
<li>Set Anchor to Top Right</li>
<li>Double the width (in my case I changed 1920 to 3840)</li>
<li>Import the image that you want to appear on the right monitor by using Layers > Import From File (by default this image's anchor is top left</li>
<li>Save this new file</li>
</ol>
<div class="separator" style="clear: both; text-align: left;">
<a target="_blank" href="http://3.bp.blogspot.com/-tmuJvGFA8uM/UAmv9QbyZLI/AAAAAAAABpg/M6E5sNPh2BA/s1600/after.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="After" border="0" height="240" src="http://3.bp.blogspot.com/-tmuJvGFA8uM/UAmv9QbyZLI/AAAAAAAABpg/M6E5sNPh2BA/s320/after.jpg" title="After" width="320" /></a></div>
Did it work?<br/><br /><b>Yes</b>.
<br/><br/>
Clearly this solution is not applicable to all monitor configurations, but it should give you an idea of how to solve this problem.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com1tag:blogger.com,1999:blog-1939334038833612724.post-8655131834978742262012-06-01T11:35:00.000-05:002012-06-01T11:35:44.507-05:00Using a Func-y Dictionary Instead of a SwitchRecently I felt that the <a href="http://www.dofactory.com/Patterns/PatternStrategy.aspx" target="_blank">Strategy Pattern</a> was appropriate for solving a problem. I thought that a <a href="http://msdn.microsoft.com/en-us/library/06tc147t%28v=vs.80%29.aspx" target="_blank">switch</a> statement would discriminate between the different strategies but I had reservations. I knew that the length of the switch statement would grow and become an eyesore. I had been using <a href="http://msdn.microsoft.com/en-us/vstudio/hh388569.aspx" target="_blank">F#</a> recently and had been really impressed with the succinctness of the language. These factors inspired me to find a more elegant solution to my problem.<br />
<br /><br />
The selection logic for each Concrete Strategy was simply to match a string value exposed as a property of a <a href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object" target="_blank">POCO</a>. The result for each test was <a href="http://en.wikipedia.org/wiki/Boolean_data_type" target="_blank">boolean</a>, and a value of true indicated that a particular Concrete Strategy was to be used. I needed to somehow correlate this boolean test with an instantiated object. It occurred to me that a <a href="http://msdn.microsoft.com/en-us/library/xfhwa508.aspx" target="_blank">Dictionary<TKey, TValue></a> seemed to fulfill the need for this type of lookup. (Because I didn't want to unnecessarily instantiate objects, I threw <a href="http://msdn.microsoft.com/en-us/library/dd642331.aspx" target="_blank">Lazy<T></a> into the mix.)<br />
<br /><br />
Here is how the Dictionary is loaded:
<br />
<pre class="brush:csharp">Dictionary<Func<ITestedObject, bool>, Lazy<IStrategy>> lookup = new Dictionary<Func<ITestedObject, bool>, Lazy<IStrategy>>();
lookup.Add(o => o.Identifier.Equals("ABC-123", StringComparison.OrdinalIgnoreCase), new Lazy<IStrategy>(() => new ConcreteStrategy0()));
lookup.Add(o => o.Identifier.Equals("ABC-456", StringComparison.OrdinalIgnoreCase), new Lazy<IStrategy>(() => new ConcreteStrategy1()));
lookup.Add(o => o.Identifier.Equals("ABC-789", StringComparison.OrdinalIgnoreCase), new Lazy<IStrategy>(() => new ConcreteStrategy2()));
</pre>
<br />
Here is how I use it. In my case I need to test whether members of an IEnumerable<ITestedObject> all have the same Identifier value. If all of the tested items have the same Identifier, which is determined by the use of the Dictionary's key as the predicate in the '<a href="http://msdn.microsoft.com/en-us/library/bb548541.aspx" target="_blank">All</a>' call, then I get the Value from the appropriate Dictionary entry. (Note that the object returned is Lazy<IStrategy>, and I'll have to get the actual Concrete Strategy through a call to <a href="http://msdn.microsoft.com/en-us/library/dd642177.aspx" target="_blank">Lazy<T>.Value</a>.) Specifically:
<pre class="brush:csharp">
var concreteStrategy = lookup.FirstOrDefault(d => someResult.TestedObjects.All(d.Key)).Value;
</pre>
<br />
There is certainly room for refinement and improvement, but this solution worked well for me.
<script src="http://bryantbrabson.net/sh/scripts/shBrushCSharp.js" type="text/javascript">
</script>
<script language="javascript" type="text/javascript">
<!--
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
-->
</script>
Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-37290937915846935532012-03-16T11:43:00.000-05:002012-03-16T11:44:09.484-05:00Mass assignment vulnerability referencesI am a fan of ASP.NET MVC. I am also a fan of security. The two posts below combine those interests by describing how to mitigate mass assignment vulnerabilities.
<ul><li>
<a target="_blank" href="http://www.diaryofaninja.com/blog/2012/03/11/what-aspnet-mvc-developers-can-learn-from-githubrsquos-security-woes">What ASP.Net MVC Developers Can Learn From GitHub’s Security Woes</a></li>
<li><a target="_blank" href="http://odetocode.com/Blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx">6 Ways To Avoid Mass Assignment in ASP.NET MVC</a></li>
</ul>
I am posting these so that my team can refer to them in future if needed.
<br /><br />
Here's a bonus link. I can never remember this syntax: <a target="_blank" href="http://geekswithblogs.net/JustinGreenwood/archive/2012/03/15/how-to-join-two-collections-with-linq.aspx">How to join two collections with LINQ</a>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-12836944770800320322012-03-12T13:39:00.000-05:002012-03-12T13:39:40.384-05:00remove web transform filesToday I am sharing the process that I used to remove web.config transforms after a build. I wish that I could claim that I was able to implement this in a knowledge vacuum, <a href="http://haacked.com/archive/2011/05/09/compiling-mvc-views-in-a-build-environment.aspx" target="_blank">but I had some help</a>. As you can see, all I am doing is creating a list of all files not named web.config and then deleting them.<br />
<br />
<pre class="brush:xml"> <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<ItemGroup>
<DeleteAfterTransform Include="$(OutDir)_PublishedWebsites\$(TargetName)\Web.*.config" Exclude="$(OutDir)\_PublishedWebsites\$(TargetName)\Web.config" />
</ItemGroup>
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
<Message Text="WebProjectOutputDir: $(WebProjectOutputDir)" Importance="low" />
<Message Text="OutDir: $(OutDir)" Importance="low" />
<Message Text="TargetName: $(TargetName)" Importance="low" />
<Message Text="ProjectConfigTransformFileName: $(ProjectConfigTransformFileName)" Importance="low" />
<TransformXml Source="Web.config" Transform="$(ProjectConfigTransformFileName)" Destination="$(OutDir)\_PublishedWebsites\$(TargetName)\Web.config" />
<Message Text="Preparing to remove config transform files." />
<Message Text="Files: @(DeleteAfterTransform)" />
<Delete Files="@(DeleteAfterTransform)">
<Output TaskParameter="DeletedFiles" PropertyName="deleted" />
</Delete>
<Message Text="Deleted Files: $(deleted)" />
</Target>
</pre>
I hope that you find this post useful.<br />
<script src="http://bryantbrabson.net/sh/scripts/shBrushXml.js" type="text/javascript">
</script><br />
<script language="javascript" type="text/javascript">
<!--
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
-->
</script>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-35716201335629979712011-12-09T09:20:00.002-06:002011-12-12T14:16:09.094-06:00WCF Web API security in a domainI've been building REST services using <a href="http://wcf.codeplex.com/wikipage?title=WCF%20HTTP" target="_blank">WCF Web API</a> for use in an intranet. Upon deployment from my desktop to a server I started experiencing the error below even though the hosting application, <a href="http://www.asp.net/mvc/mvc3" target="_blank">ASP.NET MVC 3</a>, was successfully using Windows authentication.<blockquote><span style="font-size: x-small;"><br />
System.NotSupportedException: Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.</span></blockquote><br />
A <a href="http://lmgtfy.com/?q=System.NotSupportedException%3A+Security+settings+for+this+service+require+%27Anonymous%27+Authentication+but+it+is+not+enabled+for+the+IIS+application+that+hosts+this+service." target="_blank">Google search</a> shows that this isn't a novel situation, but I couldn't get the configuration and incantation right for Web API. Luckily, after a couple of hours of researching and fiddling with the web.config, I <a href="http://wcf.codeplex.com/discussions/281107" target="_blank">came across this post that revealed the solution to me</a>.<br />
<br />
When registering the service route:<br />
<pre class="brush:csharp">var config = new HttpConfiguration();
config.Security = (u, s) => {
s.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
s.Mode = HttpBindingSecurityMode.TransportCredentialOnly;
};
routes.MapServiceRoute<YourType>("YourRoutePrefix", config);
</pre><br />
I hope that this post saves someone some time.<br />
<script src='http://bryantbrabson.net/sh/scripts/shBrushCSharp.js' type='text/javascript'></script><br />
<script language='javascript' type='text/javascript'>
<!--
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
-->
</script>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com2tag:blogger.com,1999:blog-1939334038833612724.post-26361114527975261202011-12-06T13:38:00.000-06:002011-12-06T13:38:16.686-06:00MvcBuildViews in a CI environmentThis post isn't going to break any new ground in the world of computer science, but I still wanted to say a few words about the importance of using <a href="http://blogs.msdn.com/b/jimlamb/archive/2010/04/20/turn-on-compile-time-view-checking-for-asp-net-mvc-projects-in-tfs-build-2010.aspx" target="_blank">MvcBuildViews</a> in your <a href="http://martinfowler.com/articles/continuousIntegration.html" target="_blank">continuous integration</a> environment.<br />
<br />
My team had just finished a quick and slightly dirty <a href="http://www.asp.net/mvc/mvc3" target="_blank">ASP.NET MVC 3</a> project. The three of us rapidly created a very usable internal departmental financial application with two of the members of the team being ASP.NET MVC neophytes. A lot of learning occurred during development, both about the basics of HTTP and client scripting as well as Visual Studio's ASP.NET MVC 3 tooling. <br />
<br />
I was finishing off numerous TODO's toward the end of the project when I entered "/p:MvcBuildViews=true" in the MSBuild arguments section of the <a href="http://msdn.microsoft.com/en-us/library/dd647547.aspx" target="_blank">Team Build process tab</a>. The build crashed immediately due to nonexistent namespace issues. It seems that a family of CRUD Views had been created at some point that used a Model that no longer existed. Apparently the plan had been to go back and clean up dead code, but there was never any follow-up due to other priorities. The dead Views certainly weren't hurting anything. Also, a user could only access them if they somehow typed in the correct URL, a near impossible eventuality. However, I abhor dead code and extra files in a project. It not only distorts the size and complexity of a project but also increases the size of the deployment.<br />
<br />
Using MvcBuildViews helped me remove four Views from our final deployment package. That's a trivial amount for large, enterprise projects. However, for a small department application likes ours, that's 20% of the Views. So not only are there now dramatically fewer Views to manage, the steepness of the learning curve for new developers is reduced.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-88489322302637427282011-12-01T10:15:00.002-06:002011-12-01T10:50:59.395-06:00Anyone looking for work in Kathmandu?I certainly have never been contacted about such an exotic job opportunity!<br />
<br />
<br />
<pre style="overflow:auto">On November 16, 2011 at 1:00 AM Fine Tuners <sachit.finetuners@gmail.com> wrote:
Dear Sir/Madam,
We have explored your company as one of the best ever growing software development company. This is what we are interested in.
FineTuners is a Kathmandu based software development and web development company. Our Outsourcing firm is located at the heart of Nepal, Kathmandu. Nepal is well known for its culture, natural resources and on the top for Mount Everest, the highest pick of the world.
At present we are mainly focusing on the following areas as per the need of ever growing market:
· Web services( Slicing/ Development/ full shop)
· Web applications from simple web portals to the dynamic ecommerce sites)
We are a highly experienced team of intellectuals who are versatile in different development tools. Actually we are providing with different kinds of services, based on your requirement which you can choose. Else you can let us know the brief requirements of your projects such as technology, and services you require.
If this is the interest of yours, we are always standby to assist. You can explore us more via: www.fintuners.com . We are here to provide you with unlimited opportunities.
We offer you a trail project. If you like the work, then you pay us else you don’t have to pay for what is done. This is the best deal we can offer you to build up the trust.
--
--
Best Regards,
Sachit Pokhrel
FineTuners
www.fintuners.com
skype: sunilpokharel1
</pre>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-11029591088826767172011-08-22T15:32:00.000-05:002011-08-22T15:32:37.613-05:00SSRS 2208 Multi-value Default Parameters Not Being UsedI spent about an hour trying to track down what was causing my default multi-values from appearing in <a href="http://msdn.microsoft.com/en-us/library/ms173767.aspx" target="_blank">Business Intelligence Development Studio</a> (BIDS) AKA Visual Studio 2008 (VS2008).<br />
<br />
My dataset is simply a one-dimensional list of names of human beings, such as <a href="http://www.theejohndoe.com/" target="_blank">John Doe</a>. The default values <span style="text-decoration: line-through;">are</span> were a subset of those names but they were not being selected either in Preview in BIDS or on the server. <br />
<br />
<a href="http://social.msdn.microsoft.com/Forums/en-US/sqlreportingservices/thread/18d0638b-65f3-4bfc-9f43-0c57eab2fdc2" target="_blank">This post</a> gave me the idea to check my list of default values against the dataset. I knew that I didn't have NULL values in my dataset, but I realized that I did have some default values that didn't correspond to the list of values in my dataset. The default values had until recently matched their counterparts in the dataset, but staff turnover had changed two of the values from "Firstname Lastname" to "Firstname Lastname (DOMAIN\USERNAME)". As soon as I removed the two non-corresponding values all was well- the default values were selected as desired and the report again started executing as expected.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-53497280332873439742011-08-09T17:19:00.004-05:002011-08-11T12:57:09.786-05:00ELMAH, NuGet, SQL Server Compact 4.0, and EF Code-FirstELMAH + NuGet + SQL Server Compact 4.0 + EF Code-First = Trouble! <br />
<br />
<a href="http://www.hanselman.com/blog/NuGetPackageOfTheWeek7ELMAHErrorLoggingModulesAndHandlersWithSQLServerCompact.aspx" target="_blank">Following Scott Hanselman's directions</a>, I installed ELMAH on <a href="http://www.google.com/search?q=Microsoft+SQL+Server+Compact+4.0">Microsoft SQL Server Compact 4.0</a> (SQL CE). Because of the dependency of 'ELMAH on MS SQL Server Compact' on SQL CE (and I already had the 'Manage NuGet Packages' window open) I let <a href="http://nuget.org/">NuGet</a> install it for me. NuGet installed everything perfectly and soon I was happily logging exceptions and storing them in a *.sdf file. Cool.<br />
<br />
I also used NuGet to install Entity Framework 4.1 and followed <a href="http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx" target="_blank">Scott Guthrie's post on Code-First Development with Entity Framework 4</a>. I created a model, added a connection string to my ASP.MVC 3 application, and soon I was persisting data to a second *.sdf file. Still cool.<br />
<br />
Finally it was time to push my application to a server. This is where things became uncool.<br />
<blockquote><span style="font-size: x-small;"><br />
Could not load file or assembly 'System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.</span></blockquote>After confirming that System.Data.SqlServerCe.Entity was in the bin directory, I started reviewing the versions of the SQL CE files, and then just to be sure I copied all of the files from my local installation of SQL CE to the server again. The problem still persisted.<br />
<br />
I had used NuGet to install the version of SQL CE that ELMAH was using so I decided to research what the expected file versions were. These two <a href="http://erikej.blogspot.com/2011/02/using-sql-server-compact-40-with.html">great</a> <a href="http://erikej.blogspot.com/2011/06/sql-server-compact-private-deployment.html">posts</a> by ErikEJ caused me to formulate a theory that perhaps ELMAH and EF 4.1 were using the wrong or conflicting file versions. I made two changes to my application to test my theory.<br />
<ol><li>Altered DbProviderFactories in my web.config file as described in <a href="http://erikej.blogspot.com/2011/02/using-sql-server-compact-40-with.html" target="_blank">this article</a>.</li>
<li>Set up a binding redirect for System.Data.SqlServerCe as described in <a href="http://erikej.blogspot.com/2011/06/sql-server-compact-private-deployment.html" target="_blank">this article</a>.</li>
</ol>After making these two changes exception logging and data persistance to my two compact databases started working on the server. Maybe it's just me but it seems that a significant percentage of development troubleshooting is pure intuition!Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0Brentwood, TN, USA36.0331164 -86.782777235.9770414 -86.8742887 36.0891914 -86.6912657tag:blogger.com,1999:blog-1939334038833612724.post-65092064873329892622011-06-01T14:17:00.002-05:002011-06-01T15:52:17.257-05:00Installing Rails From Behind A Corporate ProxyI had a little extra time on my hands and wanted to experiment with <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a>. The articles that I had read raved about how easy it was to set up the development environment using <a href="http://rubygems.org/">RubyGems</a>.<br />
<br />
Latest versions of Ruby and RubyGems were downloaded and installed without incident. Where I ran into a big problem was installing Rails and its dependencies. Initially I tried to run "gem install rails" but the operation failed due to proxy authentication issues, and this is a <a href="http://docs.rubygems.org/read/chapter/15#page67" target="_blank">well known limitation</a>.<br />
<br />
I thought that I would manually download and install the gems but this would have taken hours. As usual, <a href="http://stackoverflow.com/questions/4418/how-do-i-update-ruby-gems-from-behind-a-proxy-isa-ntlm">a StackOverflow post</a> provided the inspiration to <a href="http://sourceforge.net/projects/cntlm/">use CNTLM</a>.<br />
<br />
Initially I couldn't get CNTLM to authenticate properly because I didn't know the correct authentication type. The CNTLM manual indicated that there is a switch ("-M") that will test various authentication types using "magic NTLM dialect detection" (!). Using "cntlm -M http://www.google.com" revealed the correct mode that I should use. After making the change in cntlm.ini and restarting the CNTLM service I was able to successfully install rails using the following command:<br />
<br />
<pre class="brush: plain">gem install rails --http-proxy http://localhost:3128
</pre><br />
Here's a sampling of the errors that I experienced as well as a successful download:<br />
<br />
<pre class="brush: plain">C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
C:\Ruby192\bin>gem install rails
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
too many connection resets (http://rubygems.org/gems/abstract-1.0.0.gem)
C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
bad response Not Found 404 (http://rubygems.org/gems/abstract-1.0.0.gem)
C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
bad response Proxy Authorization Required 407 (http://rubygems.org/gems/abstract-1.0.0.gem)
C:\Ruby192\bin>gem install rails --http-proxy http://localhost:3128
Fetching: abstract-1.0.0.gem (100%)
WARNING: abstract-1.0.0 has an invalid nil value for @cert_chain
Fetching: erubis-2.6.6.gem (100%)
Fetching: actionpack-3.0.7.gem (100%)
Fetching: arel-2.0.10.gem (100%)
Fetching: activerecord-3.0.7.gem (100%)
Fetching: activeresource-3.0.7.gem (100%)
Fetching: mime-types-1.16.gem (100%)
Fetching: polyglot-0.3.1.gem (100%)
Fetching: treetop-1.4.9.gem (100%)
Fetching: mail-2.2.19.gem (100%)
Fetching: actionmailer-3.0.7.gem (100%)
Fetching: thor-0.14.6.gem (100%)
Fetching: railties-3.0.7.gem (100%)
Fetching: rails-3.0.7.gem (100%)
Successfully installed abstract-1.0.0
Successfully installed erubis-2.6.6
Successfully installed actionpack-3.0.7
Successfully installed arel-2.0.10
Successfully installed activerecord-3.0.7
Successfully installed activeresource-3.0.7
Successfully installed mime-types-1.16
Successfully installed polyglot-0.3.1
Successfully installed treetop-1.4.9
Successfully installed mail-2.2.19
Successfully installed actionmailer-3.0.7
Successfully installed thor-0.14.6
Successfully installed railties-3.0.7
Successfully installed rails-3.0.7
14 gems installed
Installing ri documentation for abstract-1.0.0...
Installing ri documentation for erubis-2.6.6...
Installing ri documentation for actionpack-3.0.7...
Installing ri documentation for arel-2.0.10...
Installing ri documentation for activerecord-3.0.7...
Installing ri documentation for activeresource-3.0.7...
Installing ri documentation for mime-types-1.16...
Installing ri documentation for polyglot-0.3.1...
Installing ri documentation for treetop-1.4.9...
Installing ri documentation for mail-2.2.19...
Installing ri documentation for actionmailer-3.0.7...
Installing ri documentation for thor-0.14.6...
Installing ri documentation for railties-3.0.7...
Installing ri documentation for rails-3.0.7...
Installing RDoc documentation for abstract-1.0.0...
Installing RDoc documentation for erubis-2.6.6...
Installing RDoc documentation for actionpack-3.0.7...
Installing RDoc documentation for arel-2.0.10...
Installing RDoc documentation for activerecord-3.0.7...
Installing RDoc documentation for activeresource-3.0.7...
Installing RDoc documentation for mime-types-1.16...
Installing RDoc documentation for polyglot-0.3.1...
Installing RDoc documentation for treetop-1.4.9...
Installing RDoc documentation for mail-2.2.19...
Installing RDoc documentation for actionmailer-3.0.7...
Installing RDoc documentation for thor-0.14.6...
Installing RDoc documentation for railties-3.0.7...
Installing RDoc documentation for rails-3.0.7...
</pre><script language='javascript' type='text/javascript'>
<!--
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
-->
</script>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0tag:blogger.com,1999:blog-1939334038833612724.post-18540190707810325432011-02-18T10:07:00.000-06:002011-02-18T10:07:07.812-06:00A FileNotFoundException, Wrapped In A CommunicationExceptionFor some time I've been involved in an effort to run an existing intranet Windows Forms application in an <a href="http://en.wikipedia.org/wiki/Extranet" target="_blank">extranet</a> configuration. It's been quite a struggle because the original app, which I'll refer to as CRAM, was never designed to NOT run in our corporate intranet. The process has required altering firewall rules, server and database configuration, new deployment scripts, and many more things than I care to remember.<br />
<br />
A couple of days ago I thought everything was finally finished. One last error to resolve: <br />
<blockquote><span style="font-size: x-small;">System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.8798782'. </span></blockquote>Surely this was just another WCF configuration issue, right? I fired up <a href="http://www.wireshark.org/" target="_blank">Wireshark</a> to diagnose the problem. Hmmm, Wireshark showed that a call to a <a href="http://www.microsoft.com/sqlserver/2008/en/us/reporting.aspx" target="_blank">SQL Server 2008 R2 Reporting Services</a> (SSRS) web service was being rejected as 401 Unauthorized. Thinking that authentication was failing, I embarked on a journey of discovery where I learned about SSRS web service changes between the 2005 and 2008 versions. At one point I changed the <a href="http://msdn.microsoft.com/en-us/library/ms143504.aspx" target="_blank">account under which the SQL Server services run</a>, thinking that the current accounts didn't have the required network access to properly authenticate web service callers. But after this frenzy of learning and tweaking / hacking CRAM still was throwing the same exception.<br />
<br />
Lucky for me the <a href="http://www.geoffhudik.com/" target="_blank">original developer</a> had the foresight to log the WCF calls. Using <a href="http://msdn.microsoft.com/en-us/library/ms732023.aspx" target="_blank">Service Trace Viewer</a> I was able to get a lot more detail about the communication error but not the root cause. Buried in all of this information was another error that I hadn't seen on the client or Event Log:<br />
<blockquote><span style="font-size: x-small;">System.IO.FileNotFoundException: Could not load file or assembly 'Oracle.DataAccess, Version=2.111.6.20, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. The system cannot find the file specified.</span></blockquote>Must be a deployment issue, I thought. It didn't seem to be directly related to the communication issue, and it was appearing after the communication errors. I decided to fix the FileNotFoundException to reduce the amount of event tracing data for me to process as well as reassure myself that I wasn't a total failure.<br />
<br />
The problem with the Oracle.DataAccess reference is that the required version wasn't present on the application server. I changed the reference's Specific Version property to False, compiled, deployed, and still got the same error. I looked at the installed Oracle client versions on the intranet and extranet application servers and noticed that they were different. I then copied the Oracle.DataAccess.dll (version 2.111.6.20) to CRAM's extranet application server so that it would function as a <a href="http://msdn.microsoft.com/en-us/library/aa375674%28v=vs.85%29.aspx" target="_blank">private assembly</a>. Same result upon running CRAM: FileNotFoundException. Recalling a previous project where I needed to deploy Oracle.DataAccess as a private assembly I copied the same set of dll's to CRAM's executable directory. <br />
<br />
And that was the answer. CRAM required a version of Oracle.DataAccess that was unavailable on the application server. Apparently this caused an exception that set off a chain of events resulting in the System.ServiceModel.CommunicationException that vexed me for so long. What I've learned from this- and I probably should have already known this- is that when troubleshooting WCF errors you can't only look at the error on the client: the server must also be taken into account as well. The sheer disconnected nature of WCF means that one might not be getting the complete set of information if only one side of the client + server equation is examined.<br />
<br />
Further reading:<br />
<a href="http://stackoverflow.com/questions/659341/the-provider-is-not-compatible-with-the-version-of-oracle-client" target="_blank">Copying Oracle.DataAccess as a private assembly</a><br />
<a href="http://www.sqlskills.com/BLOGS/STACIA/post/SQL-Server-2008-Reporting-Services-Configuration-Changes.aspx" target="_blank">SSRS configuration changes</a>Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com1tag:blogger.com,1999:blog-1939334038833612724.post-84243257013260377912010-12-23T13:07:00.000-06:002010-12-23T13:07:04.025-06:00C# language specification installed with Visual StudioDid you know that a copy of the C# language specification is <a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms228593.aspx">installed with Visual Studio</a> 2005-2010? The specification is in Microsoft Word format and is located in the VC#\Specifications\1033 directory under the Visual Studio installation directory.Bryanthttp://www.blogger.com/profile/17264388432507571590noreply@blogger.com0