Monday, December 24, 2012

SharePoint 2010 Site Home Page

In SharePoint 2010, if you add a new page called "Home" (Home.aspx for the real file name) to your website, it automatically becomes the default home page of your "SitePages" directory. If you open the URL "http://yoursite/SitePages", it will lead to the new home page "Home.aspx".

If you intended to hide the original default page "http://yoursite/SitePages/Forms/AllPages.aspx", this is fine, of course. You just have to remember that it breaks the link "Site Pages" on the "All Site Content" page, or anywhere else for that matter. When you click on "Site Pages", instead of showing your site pages, it will now hop over to your "Home.aspx".

 


 


 


 


Wednesday, December 19, 2012

Problems When Renewing a Multi-domain SSL Certificate on IIS 7

Last weekend, I needed to renew my multiple domain SSL certificate on my IIS 7 server. The IIS manager just did not work right, and the process was a little complicated. So I would like to share my experience here, hoping that it will help others faced with the same situation.
First of all, how do I know which version of IIS I was running? When you are hosting multiple domains, the default IIS website home page is not likely going to be the IIS start page. So checking the default website home page usually does not work. I opened Windows Task Manager, and selected "Show processes from all users":


  
Then I right clicked on "w3wp.exe", and on its popup menu, I clicked on "Properties":


  
Then I clicked on the "Details" tab:


  
I see that the version number is 7.5…

Now about the SSL certificate installation.

First I installed my new multi-domain certificate by clicking on the "Server Certificates" icon in the IIS Manager Home pane.



The certificate is not applied to any of the websites at this point. I went to the "Bindings…" menu of each website, and edited the https port 443 bindings. I selected the new certificate for each website. I ran into a problem immediately. IIS started to shut down my sites, saying that the port 443 was in use. This is because the "Host name:" field for https binding is always read-only and always blank, even though I had a valid host header value for port 443 before. After the certificate selection, IIS actually changed the host headers to blanks! As a result, all my sites tried to respond to all requests on port 443.

At this point, I had to fix them from the command line. First, I navigated into the "C:\Windows\System32\inetsrv" directory, and then I ran the following command:

appcmd set site /site.name:"IIS Site Name" /-bindings.[protocol='https',bindingInformation='*:443:']

The "IIS Site Name" came from the left pane of the IIS manager. The "-binding" switch removes the binding that does not have a header value specified. Then I ran the following:

appcmd set site /site.name:"IIS Site Name" /+bindings.[protocol='https',bindingInformation='*:443:www.*******.com']

Here www.*******.com is the root of each website URL, in my case each has the form of www.*******.com.

That completed the renewal.

Sunday, December 2, 2012

The Choices for Intra-System Data Communication

In the .NET world, WCF has been the de facto data communication standard for quite some time. When designing a distributed multi-tier software system, most software designers would choose to use WCF to connect the various subsystems. For example, in Figure 2 of my previous post, the communication between the website ("Website") and the backend service ("Service") is usually handled by WCF.

WCF client is very easy to setup. C# code can be generated with a few mouse clicks from WSDL provided by the WCF server. But it has several problems when used for this task:

  1. Maximum WCF message size is pre-determined. When handling data of unpredictable sizes, it may hit a message size ceiling and stop working. The standard solution is not pretty: once you have determined that the maximum message size is the problem, you will need to re-configure it and the system will restart. If you go to a streaming solution, you will lose some very important WCF security features.
  2. WCF messages are transmitted in XML over HTTP, so HTTP load balancers cannot easily perform some of its basic tasks such as retrying WCF operations. For example, if the XML contents of the WCF message command the service tier to create a new object, a retry without interrogating the service tier would end up creating redundant objects. In contrast, a RESTful communication layer can be easily understood by HTTP load balancers. The balancers would know which operations they can safely retry without interrogating the service tier.
  3. The data objects that are transmitted to the recipients are "raw". Consuming these data objects will require a lot of work.
  4. When running under IIS, it has all of the limitations of the HTTP server in addition to those of its own. For example, the maximum download limit that exists for other services still applies.

Software designers are moving to RESTful services for some very good reasons:

  1. Its message sizes are only limited by the HTTP server that it runs on.
  2. By staying with HTTP verbs that the HTTP load balancers can understand, load balancing is quite straightforward.
  3. The payload is smaller for the same data objects.
  4. When RIA service is configured as a RESTful service, the recipient can handle data objects as if they are local. Although one can use RIA service as a WCF service as well, but the RESTful approach is much more appealing.

There are other reasons RIA RESTful service should be the best choice for Intra-System Data Communication, but these should be compelling enough.

Saturday, December 1, 2012

Software Architecture and Ease of Implementation

A complicated software system can be designed in many different ways. Even though there may be many design choices that will lead to the same system feature set, the same user interface, and even the same quality, these designs may require very different amounts of development effort. In other words, the cost of implementing these designs in terms of time and money can vary quite substantially.

This claim itself is not very hard to understand. The million dollar question is: how do you design a system so that it can be implemented quickly, easily, reliably, and completely?

Again, at the top level, this is not a very hard question. Some answers would come to mind right away: the KISS principle, canonical forms that can be reused, advanced algorithms that cut down complexity, utilization of existing solutions, etc.

There may not be an exhaustive list of answers to this question. Here, I would like to start with one of the most important: designing the system with your development team in mind. If the design cannot be carried out by your development team quickly and reliably, it is not a practical design, and it is not a good design. Ease of implementation of a design does not mean it is easy for your architect to carry out the design work or how easy it would be if your architect were to write the code; it is supposed to be easy for your development team.

What is taking so long?

Let us start with a basic "CRUD system" that performs the basic operations of "create(C)", "retrieve(R)", "update(U)", and "delete(D)" on a data object with a dozen various attributes from a database:

Figure 1 Basic 3-Tier System
 
If you ask a programmer on your development team to implement such a basic system with Microsoft MVC .NET or ASP .NET using EDM from scratch, he should be able to complete it in no more than 10 minutes. If you ask the star programmer on your development team, it would be even quicker. Even if you demand detailed data validations on all attributes with localization, it would still take no more than half an hour.

Of course, in practice, a system is never this simple. For security and scalability, additional tiers are needed:

 
Figure 2 Distributed Multi-tier System
 
Here, the part of the system that is responsible for binding the view to the data object, namely the website or the presentation tier, is separated from the rest of the system by a remote access connection to the service tier. This separation provides mainly the following benefits:
  1. A compromised website will not expose the data tier directly to the intruder.
  2. Multiple websites and multiple service servers can be load balanced.
The connection between the service tier and the data tier is abstracted so that it can be either local or remote, depending on the data source. This separation provides mainly the following benefits:
  1. Data format complexity is hidden from the service tier. Complete different data sources can be used the same way.
  2. Multiple database shards can be used for load distribution.
After this seemingly simple change, if you ask a programmer on your development team to implement the same "CRUD" operation again, the time it takes will increase from half an hour to two weeks or even longer!

Unfortunately, this separation of responsibilities is not the end of real world design escalation. In many cases, more complicated delegates instead of functions are needed to further increase system flexibility. The system described in Figure 2 will change like a chameleon depending on the object that is being operated on. Now if you ask a programmer on your development team to implement the same "CRUD" operation again, the time it takes will increase to half a year or more, or perhaps never!

Can we keep it simple?

It is the architect's responsibility to stay with design patterns that a programmer on your team can understand. In Figure 1, binding an EDM entity to an HTML control is something that every programmer can easily do with Visual Studio scaffolding. Can we handle the data binding in Figure 2 the same way, and get it done with the same speed?

The answer is yes, of course. A good example is Microsoft RIA service. It hides the complexities of remote object handling in WCF, and exposes a programming interface to the object in question that can be treated exactly like it is local. If the architect can design the system this way for each implementation task, your implementation speed will increase tremendously.

A service like Microsoft RIA not just takes programmers back to a familiar pattern. It provides many other benefits:
  1. A canonical form requires virtually no programmer training.
  2. It is much less error prone.
  3. It provides data validation and presentation localization features that could otherwise be challenging to your programmers.
The list can go on further. But we can sum it up by saying that a pattern that is familiar to your programmers will allow them to get their jobs done quickly, easily, reliably, and completely.

Some may argue that Microsoft RIA service is only one example. There must be other cases where this example does not apply, right?

It is a devil's staircase

With a devil's staircase, if you put a small section of it under a microscope, you will find that it looks just like section that you were looking at earlier without the microscope. With the stretched version of the "CRUD" system in Figure 2, if you zoom into a small section of it, you will still find patterns like the one in Figure 1:

Figure 3 3-Tier Input/Output Pattern
 
These simple patterns can easily be implemented by programmers on your team. If we design with these simple patterns to build bigger simple patterns at the next level, the entire system will be implemented quickly, easily, and reliably.

Over design/Under design

Microsoft RIA is a great service. It should serve as an example for architects who are trying to implement systems depicted in Figure 2. However, it does not solve the problem of over design or under design. Because software architecture is a devil's staircase, its complexity can grow exponentially. By following the simple 3-tier input/output pattern, one can easily see this exponential growth in action. An over designed system will become impossible to complete mathematically. At that point, a copy-paste solution that spread linearly might seem wasteful, but it will be the only sensible thing to do: your programmers cannot even count 4 billion patterns before your deadline if your patterns are 32 levels deep. A number 32 may seem small until you put in the exponent!

Microsoft RIA would have been a perfect service if it were implemented for a single class of software applications. However, using it without EDM is extremely difficult. So it is under designed as a general purpose service. In the past I have developed a system that allows you to access data RIA service even if the data is not from an EDM data source. It is used in the Online Business Pro software system that I developed.

 


Thursday, August 23, 2012

Installshield LE and Visual Studio 2012 Release

Microsoft has formally released Visual Studio 2012, and it is time to go through some project migrations from the RC(Release Candidate) version of Visual Studio 2012.

It seems to me that transitioning from pre-release software to release version is never trouble-free. Although this time around the transitions are actually much smoother than before, there bound to be some glitches here and there still.

For me, one of the things that was broken was a Installshield LE project. Microsoft has killed off their own setup projects, so Installshield LE is the only choice for a free setup. I created an Installshield LE project with the RC version of Visual Studio 2012. After upgrading to the release version, the project could no longer build because InstallShield could no longer find a merge module for "Microsoft_VC110_CRT_x86....".

The fix turned out to be quite straightforward: First you may need to fix Installshield LE from the control panel. Then in Visual Studio, expand the Installshield project in the "Solution Explorer", expand "2. Specify Application Data", and then select "Redistributables". Deselect the old "Visual C++ 11.0 CRT (x86)" at the bottom of the list that has a yellow exclamation mark next to it. It will disappear instantly. Then select the new "Visual C++ 11.0 CRT (x86)" higher up in the list.

Problem solved.

Thursday, July 19, 2012

An nVidia Beta Driver Saved the Day

I have a Samsung NP-RF711 notebook computer. It has an nVidia GeForce GT 540M video card, in addition to its integrated Intel HD Graphics 3000. It has been working OK running Windows 7 64 bit with SP1 for about a year, until my son updated its nVidia video driver to version 301.42.

First he noticed that some of the 3D images in his game were distorted. Then I noticed that the computer was getting BSOD (the blue screen of death) while refreshing Windows Experience Index.

I removed the version 301.42 nVidia driver. Then I tried all other WHQL certified versions of nVidia drivers available from the nVidia website. I also tried the older version from the Samsung website. None worked.

I so turned off the nVidia adaptor in Windows Device Manager, and set the machine to use the Intel adaptor and CPU exclusively from the nVidia Control Panel, thinking that this card was dead.

This morning, I thought to myself: why not try the latest Beta driver, since it cannot really make anything worse? So I installed the version 304.79 beta driver from nVidia:

http://www.geforce.com/drivers/beta-legacy
To my surprise, it fixed the problem.

Update: Apparently the video card is having hardware problems: even though the computer no longer "blue screens" while running refreshing Windows Experience Index, there are still artifacts on the screen while running 3D games. 

Saturday, July 7, 2012

Exchange Server 2010 Autodiscover Activation Exception

My Exchange Server 2010 installation kept generating errors in the event log that looked like this:

Exception: System.ServiceModel.ServiceActivationException: The service '/Autodiscover/autodiscover.xml' cannot be activated due to an exception during compilation. The exception message is: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.

Indeed in my IIS installation I have multiple websites that share the same port number. In fact, the default website that hosts the auto discover service supports several different domain names in its header.

After a little googling around, I found a solution here:

http://stackoverflow.com/questions/561823/wcf-error-this-collection-already-contains-an-address-with-scheme-http

Essentially what I needed to do was to open up the "web.config" file in "C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\Autodiscover", and add the following lines in the
"system.serviceMode/serviceHostingEnvironment" section:

<baseaddressprefixfilters>
<add prefix="http://programount.com"></add> </baseaddressprefixfilters>

There were similiar errors for some other Exchange 2010 services, and the same fix worked for those as well.

Trouble with NAT in Windows 2008 R2 RRAS

IP address and port forwarding in the Network Address Translation (NAT) feature of Windows 2008 R2 Server's Remote and Routing Access Service (RRAS) is surprisingly difficult to setup. Unlike previous versions of Windows Servers that I used before, the graphical user interface for NAT is simply broken in this version.

With previous versions of Windows Servers, I could right click on the public interface under NAT, select "Properties" from the popup menu, go to the "Services and Ports" tab, and then specify how I wanted certain ports to be forwarded to another machine on the LAN. With Windows 2008 R2, however, the settings in on this tab do not seem to work. In fact, other than forwarding to local loop back address of 127.0.0.1, turning on anything here will only break things. Outgoing internet connection sharing works, but incoming port forwarding settings through this GUI are completely useless.
Do not select anything here
It turns out that you now need to use a command line tool to do this. The mappings cannot seem to be named, but at least you can get port/address forwarding to work ( http://www.rickwargo.com /2011/01/08/ port-forwarding-port-mapping-on-windows-server-2008-r2/). The command is

netsh interface portproxy add v4tov4 listenport=<public port>  listenaddress=<public address> connectport=<private port> connectaddress=<private address>

This "netsh" command actually does many other things. There is just no GUI for it. For example, you can run the following command to see what port forwarding settings are in place:

netsh interface portproxy show v4tov4 

When deleting a particular port from the forwarding list, you need to specify both the port number and the address on the command line:

netsh interface portproxy delete v4tov4 listenport=<public port>  listenaddress=<public address>

We came to Windows from DOS, now apparently we are moving backwards.

Thursday, June 14, 2012

Setting up Git(olite)

Git is a version control system. The creator of Linux created Git (the letter g is supposed to be pronounced as the "g" in the word "get" or "guy") because he hates CVS, and he does not like like SVN, either ( http://en.wikipedia.org/wiki/Git_(software) ).

A lot of people seem to like Git. Probably as many as those who like Linux:-). So since I am developing in Java for a FreeBSD system (Mac OS X server), I figure that I would give Git a try.

Like everything else related to Linux, Git is a little confusing. To start, is the "g" pronouced like "the "g" in "get", or is it like the "g" in "gif"? The answer is always simple when you find out, but it always takes two steps.

Git itself does not offer a server. For a version control system, that is a little unusual. If you know how bad SourceSafe is, you would probably start to wonder: is this going to be as bad as SourceSafe. The answer is no. Actually there are a few Git remote repository applications available, such as Gitolite.

There are several version of Gitolite. The latest version is version 3. To continue the tradition of keeping people confused, the different versions must be installed differently. What I describe here are applicable to version 3. It does not apply to early versions, and it will most likely not applicable to future versions.

To install Gitolite, you must first install Git. This part is surprisingly easy. You go to http://git-scm.com/download/mac, and download a .dmg file. You then open the .dmg file, and then click on the .pkg file inside to complete the installation.

Only if the whole process is that easy.

Of course not. To install Gitolite, you need to create a user account.  Gitolite will monoplize this user account to act like a server. You probably want to name this user account with the user name "git" since that is what it will be used for. Ideally you would want to set it up in such a way that it does not accept actual login for OS shell access, but during the setup process, I find it much easier logged in as "git".

Step 1. From the home directory of "git" I ran

                  git clone git://github.com/sitaramc/gitolite
This actually copies Gitolite into git's home directory under "gitolite". To complete the initalization, you would run
                  sudo ./gitolite/install -ln /usr/local/bin

This creates a file called ".gitolite.rc", a directory called ".gitolite", and a directory called "repositories". The first two are hidden since they start with "." in their names. A constantly used "gitolite.conf" file is in the hidden directory .gitolite under "conf".

Even though the command used here is called "install", I would say it can only qualify as an initializor, not an installer.

Step 2. Create a repository. Open up .gitolite/conf/gitolite.conf, and add a section for your new repository:

             repo MyRepository
                  RW+ = user1
                  R = user2
                     ...
Here the user names "user1" and "user2" are not users with system accounts. They are just users that you want to give access to the repository.
At this point you do not actually have a repository yet. The official Gitolite instruction says that you must pull the default "gitolite-admin" repository, change it to "MyRepository", and add it back. It turns out that you can run "gitolite setup" to create the empty repository. It seems to know that this is necessary since "MyRepository" is listed in gitolite.conf, but the directory does not exist under "repositories", or if it is empty if you create it yourself there.

Step 3. Setting up users. Even though you would have listed a bunch of users in the "gitolite.conf" file for your repository, they do not yet have access to the repository. In fact, you would wonder: how would these users login into the server?

It turns out that they all login under the user account "git". To differentiate these different users after they login, each would store a different public key in the .ssh directory of "git". So you can run the following command to create the keys needed for each user of "MyRepository":

              ssh-keygen -t rsa

When prompted for a file name, you would enter a user name for "MyRepository". You will then need to distribute the private key file to the user. For example, if the the file name is "user1", you would give it to user1.

After each key pair is created, you would run the "setup" command to update the ".ssh/authorized_keys" file automatically:

              gitolite setup -pk .ssh/user1.pub

At this point, user1 can connect to the the repository via ssh.

Step 4. Configure your Git client to access the repository. I use NetBeans. When prompted for user name, you would enter "git" since that is what we used for the user account. So the URL is

         ssh://git@myserver.name/MyRepository

You would then enter a file path to the private key generated earlier. This key is what actually tell Gitolite who you really are. If you used a pass phrase while generating the keys, you would enter it here as well.

Step 5. Test your connection. I used PuTTY. The key generated from ssh-keygen needs to be converted with puttygen.exe first before it can be used. The file puttygen.exe is a separate download from PuTTY. Once I connected, I got a bunch of errors. It turned out that the default shell used by Mac OS X server does not have the right paths. So I added a .bashrc file that contained a single line:

        export PATH=$PATH:/usr/local/git/bin

This fixed the problem.

Monday, February 20, 2012

Gotcha’s in gSOAP Version 2.8.7

Nowadays it appears that few people are using C/C++ to do network programming. Microsoft has deprecated its SOAP toolkit. gSOAP of Genivia Inc. seems to be the only way to create C/C++ code from WSDL. Unfortunately, the C++ code that gSOAP generates has a lot of problems. But no one seems to care. I googled for solutions to some of these problems, but I found nothing.
1. The header file generated by wsdl2h can have syntax errors. For example, the class definition of a common class like xsd__base64Binary looks like this:
/// Built-in type "xs:base64Binary".
class xsd__base64Binary unsigned char *__ptr; int __size;

The curly brackets are missing. It turns out that the configuration file had it listed that way. wsdl2h does not care about that, and spits it out without complaints.  The same thing happens to an enum definition:
/// Built-in type "xs:boolean".
enum xsd__boolean false_, true_ ;

The name of the enum type is then later used as a class name.
Obviously the code will not even build.
2. The C++ file generated by soapcpp2 incorrect merges two WSDLs into one.
Fortunately wsdl2h allows more than one WSDL. It is a rather common situation that one would need to access more than one SOAP service, and being able to generate code from multiple WSDL’s is quite critical.
But then soapcpp2 would merge them all into one. If you have ServiceA and ServiceB, you will get only ServiceA, with the members of ServiceB actually contained in ServiceA. The default endpoint URL is a concatination of the two service URLs in one:
endpoint = "http://serviceA http://serviceB";
Of course, calling the methods in these proxy classes would be problematic.
Although some of the big name companies like IBM are using gSOAP, but I don’t know how they can be using it as is, unless they are all coding in plain C, not C++.
So we have to go either all the way to a managed language such as Java or C#, or we have to stay with plain old C.

Friday, January 20, 2012

Updating to CentOS 5.7 on a HP Proliant DL380 G5 Server–The Saga Continues

Recently we updated our CentOS server from version 5.5 to 5.7. Many updates were accumulated since the original installation, so I decided to bite the bullet and install them all.

The installation of the updates were straightforward. I did it from the desktop of the GUI, and everything installed without any problems.

But restarting the server was not so straight forward. Since we installed HP PSP, and it was tweaked to work with CentOS 5.5, I certainly did not expect it to work so easily.

Sure enough, the server would reboot itself when it tried to load the IPMI driver.

So at the startup of Linux, I hit the “I” key to go into interactive start up mode. I skipped all of the HP drivers, and the server booted all the way up.

Then I uninstalled all of the HP PSP packages. I downloaded the latest version 8.7 HP PSP and installed it. HP has moved the installation instruction, so the link in my previous post no longer works. Now you can find the same instructions here:

http://h30499.www3.hp.com/t5/ProLiant-Servers-ML-DL-SL/HOWTO-Guide-Instructions-Install-HP-PSP-On-CentOS-5/m-p/4652208/highlight/true#M103665

The new version of PSP actually works better than the older one: it works right after installation. No tweaking was required.

There is one thing, however: SNMP had to be re-configured. Before re-configuring SNMP, the management webpage on port 2381 showed a bunch of blank rectangles.

I checked the messages log in /var/log. It showed a couple of bogus errors:

  1. The “Network Manager” does recognize bonded network adapter type, and logs errors in the messages log. So I removed “TYPE=BOND” from the /etc/sysconfig/network-scripts/ifcfg-bond0. This line was inserted by the CentOS Network Manager GUI, and its absence has no effect on the adapter.
  2. The slave adapters of the bonded adapter, namely eth0 and eth1, had configurations that caused the “Network Manager” to log errors in the messages log. Although the slave adapters do not have IP addresses, the “Network Manager” looks for them in the configuration files anyway. Somehow it grabbed the MAC address lines and thought that they were the IP addresses. Since the MAC addresses start with “0”, the “Network Manager” logged errors saying that “IP addresses cannot start with 0”. Again since the CentOS Network Manager GUI put the MAC addresses in the configuration itself, I tried to remove them to see if the errors would go away. Well they did not. The “Network Manager” complained that “IP addresses were missing”, even though none are needed for the slave adapters. So I put the MAC addresses back and then set DHCP to be “on” for these slave adapters. These adapters will never go out and acquire IP addresses since they are inactive, but this made the “Network Manager” stop logging errors in the messages log.

On the “System Management Homepage” on port 2381, I wanted to test SNMP traps. Unfortunately the test does actually simulate any hardware trap that the HP SNMP Agents would take notice. Even though in /opt/hp/hp-snmp-agents/cma.conf we setup the trapmail line to send emails, none was sent when I clicked on the test button. Only when I unplugged one of the two network cables that generated traps that the HP SNMP Agent would take notice, I got 60 emails in a fraction of a second.

So the test button on the “System Management Homepage” SNMP settings page only tests notification mechanisms that are not really relevant to the HP SNMP Agents. In order to see the trap messages for this test, one needs to run “snmptrapd –f –Le <hostname>” on the command line, and watch the output on the screen. Please note that in the /etc/snmp directory, there needs to be a file named “snmptrapd.conf”, and it needs to contain the line “disableAuthorization yes”. Otherwise “snmptrapd” would not show anything. The “<hostname>” part must match exactly what is in the “snmpd.conf” file. Using IP address or other aliases will not work.

The HP SNMP monitoring is not very reliable. From time to time the “System Management Homepage” on port 2381 would show a bunch of empty box and indicate the system status is ok. After a reboot, all the boxes will be populated again and everything would go back to normal.

It looks like that we just need to watch this server very closely.