Web Statistics

Thursday, October 20, 2011

EmpireAvenue

{EAV_BLOG_VER:64cd2d883e87737c}

Wednesday, August 12, 2009

SOA Metric: Entrprise Adoption Rate

Here's another useful metric when reporting on how your SOA initiative is progressing.

Tracking how services are leveraged across each organizational unit and rolling that information up to the enterprise level provides the enterprise adoption rate. This metric indicates how pervasive the use of services is across an enterprise. However, this metric is not necessarily easy to quantify. For example, given an enterprise that comprises five organizational units, if only two of the units are leveraging services, is the adoption rate of our enterprise at 40 percent? What if 80 percent of the total IT spend is within these two organizational units? Is the adoption rate of our enterprise now at 80 percent?

A more accurate and measurable approach for reporting the enterprise adoption rate begins with a catalog of IT resources that span the enterprise. After determining how many of the applications within the catalog are actually leveraging services, determine the total number of applications that are candidates for an SOA implementation or integration. The product of this review (applications using services/total candidate applications for leveraging services) is a realistic enterprise adoption rate.

If the data is available, integrating this metric with actual IT spend provides the weighted enterprise adoption rate, which is an even more compelling value-based metric.

I also bring this out in the September 2009 edition of Microsoft's The Enterprise Journal (http://msdn.microsoft.com/en-us/architecture/aa699435.aspx)

Tuesday, August 11, 2009

SOA Metric: Consumer-to-Service Ratio

The next time you're asked to provide insight into how your SOA initiative is moving along, try using the Consumer-to-Service ratio.

This is a useful metric to track primarily because each reuse averts the costs of developing, operating, and maintaining a new single-purpose service. The idea is that as the number of consumers increases for a service, the return on the costs—both initial and ongoing—that is attributed to that service increases.

However, use caution when you report this metric. As the number of consumers increases for a service, the reliance on that service increases, which exposes the enterprise to an increased consequence of failure. Because scalability is the result of design, implementation, and infrastructure choices and investments, as more consumers begin to employ and rely on a service, the workload of that service increases and could potentially move beyond the limits that the service was expecting—thus, increasing the likelihood of failure. Finally, with consumers converging into a single point, the ability of a service to mature over time becomes increasingly more challenging and costly, as any change to the service requires an increased investment in impact analysis, regression testing, and coordination across the enterprise.

I also bring this out in the September 2009 edition of Microsoft's The Enterprise Journal (http://msdn.microsoft.com/en-us/architecture/aa699435.aspx)

Saturday, July 11, 2009

Get NDepend metrics for a particular method or type

Looking for NDepend info on a particular method or type? Here's a simple CQL query that will return a few of the common metrics. Just enter a portion of what you're looking for in the NameLike criteria and off you go. The sample here will pull back Methods. If you're looking for Type information, replace METHODS with TYPES.

// Get metrics for a particular Method or Type
SELECT METHODS WHERE
(
    NbLinesOfCode > 1
    AND
    (
        CyclomaticComplexity > 1 OR
        ILCyclomaticComplexity > 1
    )

    AND

    ILNestingDepth > 1
)
AND
    PercentageComment < 100

AND
    NameLike "Foo"

Sunday, July 05, 2009

Worst Offenders using NDepend

Here's the basic CQL query I use when beginning to look for areas of code that need some work. The metrics in this query tend to let the worst offenders bubble up to the top. However, I tend to favor ILNestingDepth and CyclomaticComplexity as the two main drivers. As always...this is just the 'smell'...with what's returned from query, the work begins.

Have fun!

// High-Impact candidates for Refactoring
SELECT METHODS WHERE
(
    NbLinesOfCode > 10
    AND
    (
        CyclomaticComplexity > 15 OR
        ILCyclomaticComplexity > 30
    )

    AND

    ILNestingDepth > 5
)
AND
    PercentageComment < 30

AND
(
    !(NameLike "^.ctor")
)
ORDER BY CyclomaticComplexity DESC, NbLinesOfCode DESC

Thursday, May 21, 2009

Testing private members with NUnit

For those using MSTest, private accessors are created for you so that testing private members is trivial. If you’re using NUnit, however, there’s a bit more work involved.

First, repeat after me… Reflection is good. Reflection is good. Reflection is good.

We can use System.Type.GetMethod to get access to a methods metadata and then use System.Reflection.MethodBase.Invoke to execute the method.

So, given a class FooMaster with a private, static method Foo

    1 public class FooMaster

    2 {

    3     private static bool Foo(string myString, int myInt)

    4     {

    5         //init the result

    6         bool result = false;

    7 

    8         //does the length of string match the int passed in?

    9         if (myString != null)

   10         {

   11             result = myString.Length == myInt;

   12         }

   13         else if (myInt == 0)

   14         {

   15             result = true;

   16         }

   17 

   18         return result;

   19     }

   20 }


a unit test would look something like this
    1 [Test]
    2 public void Foo1()
    3 {
    4     System.Reflection.MethodInfo fooMethod =
    5         typeof(FooMaster).GetMethod("Foo",
    6             (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static));
    7 
    8     object[] parameterValues = { "my test string", 14 };
    9 
   10     bool result = (bool)fooMethod.Invoke(null, parameterValues);
   11 
   12     Assert.IsTrue(result, "Foo did not return the expected result!");
   13 }

In this case, because FooMaster.Foo is a private, static method, we need to include the
System.Reflection.BindingFlags.NonPublic
and
System.Reflection.BindingFlags.Static
BindingFlags. Otherwise, the GetMethod call will throw a System.NullReferenceException exception.

The array of System.Object
object[] parameterValues = { "my test string", 14 };
contains the list of parameter values that we'll pass to the method when we execute it.

When executing with the Invoke method
bool result = (bool)fooMethod.Invoke(null, parameterValues);
we need to cast the result accordingly and then apply the appropriate Assert.

¡Hay Chimba! Life is good...until an overload is introduced. Now we need to do a little bit more work.

Introducing an overload of Foo that looks like this
    1 private static bool Foo(string myString, byte myByte)
    2 {
    3     return Foo(myString, Convert.ToInt32(myByte));
    4 }

will cause our unit test to throw a System.Reflection.AmbiguousMatchException exception since FooMaster now has two methods named Foo.

So, we need to update our unit test a bit to include an array of Type objects that represent the number, order, and type of parameters for the method that we're trying to get a reference to.
    1 [Test]
    2 public void Foo1()
    3 {
    4     System.Reflection.MethodInfo fooMethod =
    5         typeof(FooMaster).GetMethod("Foo",
    6             (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static),
    7             null, new Type[] { typeof(string), typeof(int) }, null);
    8 
    9     object[] parameterValues = { "my test string", 14 };
   10 
   11     bool result = (bool)fooMethod.Invoke(null, parameterValues);
   12 
   13     Assert.IsTrue(result, "Foo did not return the expected result!");
   14 }
   15 
   16 [Test]
   17 public void Foo2()
   18 {
   19     System.Reflection.MethodInfo fooMethod =
   20         typeof(FooMaster).GetMethod("Foo",
   21             (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static),
   22             null, new Type[] { typeof(string), typeof(byte) }, null);
   23 
   24     object[] parameterValues = { "my test string", (byte)14 };
   25 
   26     bool result = (bool)fooMethod.Invoke(null, parameterValues);
   27 
   28     Assert.IsTrue(result, "Foo did not return the expected result!");
   29 }

You can see here that our unit tests include an array of Type
new Type[] { typeof(string), typeof(int) }
and
new Type[] { typeof(string), typeof(byte) }

to futher specify which Foo method to get a reference to.

Very cool. Remember...Reflection is good.

Saturday, April 19, 2008

Classic ASP & Anti-Bot support

So, try as you might, the 'net is sated with bots crawling about trying to inspect and infect nearly anything and everything. Feedback pages can be a torturous for companies. It’s not that odd to see the signal-to-noise ratio waaaay too noisy for any value.

Enter CAPTCHA…yep, it’s an acronym (Completely Automated Public Turing test to tell Computers and Humans Apart.) Here’s some good background http://en.wikipedia.org/wiki/CAPTCHA if you’re really interested.

reCAPTCHA (http://recaptcha.net/) is a “free” system & service developed by Carnegie Mellon University to help them digitize textbooks while providing you with a challenge/response mechanism that most bots have trouble with. It works like this; reCAPTCHA gives a challenge to you that includes a known, control word along with the CAPTCHA (a questionable word that the OCR is having trouble with). The idea is that if a human response matches up the control word, then the CAPTCHA must be correct too.

The net effect is…you get a decent human vs. bot confirmation process and reCAPTCHA gets some of their OCR’ed text cleaned up.

There are a variety of ways (they call them plugins) to use the reCAPTCHA system listed on their site but using it with Classic ASP is a bit of a chore. Here’s a quick and easy fix that uses the reCAPTCHA API directly.

Include these two VBScript functions in your ASP code:

01 <%

02 'builds & returns reCAPTCHA challenge web part (JavaScript)

03 'needs the reCAPTCHA Public Key

04 'uses the reCAPTCHA Client API Challenge web service

05 Function RecaptchaChallengeWriter(recaptchaPublicKey)

06

07 'build challenge

08 Dim webPart

09 webPart = "<script type=""text/javascript"">" & _

10 "var RecaptchaOptions = {" & _

11 " theme : 'white'," & _

12 " lang : 'en'," & _

13 " tabindex : 0" & _

14 "};" & _

15 "</script>" & _

16 "<script type=""text/javascript"" src=""http://api.recaptcha.net/challenge?k=" & recaptchaPublicKey & """></script>" & _

17 "<noscript>" & _

18 "<iframe src=""http://api.recaptcha.net/noscript?k=" & recaptchaPublicKey & """ frameborder=""1""></iframe><br>" & _

19 "<textarea name=""recaptchaChallenge"" rows=""3"" cols=""40""></textarea>" & _

20 "<input type=""hidden"" name=""recaptchaResponse"" value=""manual_challenge"">" & _

21 "</noscript>"

22

23 'return the challenge

24 RecaptchaChallengeWriter = webPart

25

26 End Function

27

28 'validate the reCAPTCHA info entered by the user

29 'needs the ReCAPTCHA Private key along with the challenge and response form fields

30 'uses the reCAPTCHA Client API Verify web service

31 Function RecaptchaValidate(privateKey, challenge, response)

32

33 'our function result holder

34 Dim validateMessage

35

36 'build the request string

37 Dim httpRequestString

38 httpRequestString = "privatekey=" & privateKey & _

39 "&remoteip=" & Request.ServerVariables("REMOTE_ADDR") & _

40 "&challenge=" & challenge & _

41 "&response=" & response

42

43 'using ServerXMLHTTP to post the request

44 Dim xmlHttp

45 Set xmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")

46

47 'for the request

48 xmlHttp.open "POST", "http://api-verify.recaptcha.net/verify", False

49 xmlHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

50 xmlHttp.send httpRequestString

51

52 'save the response

53 Dim verifyResponse

54 verifyResponse = split(xmlHttp.responseText, vblf)

55

56 'release th ServerXMLHTTP object

57 Set xmlHttp = Nothing

58

59 'user response validated?

60 If verifyResponse(0) = "true" Then

61

62 'good response...we'll pass back goodness

63 validateMessage = ""

64

65 Else

66

67 'something's not correct...send back the message

68 validateMessage = verifyResponse(1)

69

70 End If

71

72 'set return code

73 RecaptchaValidate = validateMessage

74

75 End Function

76 %>

And whereever you'd like to see the CAPTCHA box on your form, use this:

1 <%=RecaptchaChallengeWriter("your reCAPTCHA public key goes here")%>

Then when you're ready to see if a post is validated, use this:

1 'let's make sure it ain't no robot

2 Dim isRecaptchaValid

3 isRecaptchaValid = RecaptchaValidate("your reCAPTCHA private key goes here", Form.Item("recaptchaChallenge"), Form.Item("recaptchaResponse"))

4

5 'anything other than a blank coming back is badness

6 if (isRecaptchaValid = "") Then

Simple as that. I've used it a few times now on different sites both with Classic ASP and beyond...never a problem.