Monday, November 22, 2010

Check eConnect 2010 Service Status Programmatically

The number one eConnect 2010 issue that I've been asked to resolve has been the following error that I discussed back in September:

There was no endpoint listening at net.pipe://localhost/Microsoft/Dynamics/GP/eConnect/EntityOperations that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

The problem with this eConnect error is that it is useless for the average GP user, presumably because it is just a lower level WCF error being communicated up through eConnect.  Not only is it too technical, but it is misleading at best.  If a user runs your eConnect 2010 integration and sees this error, they will e-mail you or pick up the phone.  I've also found that it's useless for many GP consultants, as I've received several inquiries from consultants as well, repeatedly asking about this error.

What is frustrating is that the issue is so simple:  The error is almost always caused because the eConnect 2010 Integration Service is not running.

Unfortunately, I don't know why the service is stopping on the client servers, but since I can't directly control all of my clients' servers, I can only try and deal with the error more gracefully and give them enough information to resolve it without having to call me.

And so I wondered, can I just put some code in my integrations that can detect the status of the eConnect 2010 service before I even try and call it?  I've never tried checking the status of a Windows service, and although I assumed it was possible, I didn't know how difficult it would be.  Well, after receiving yet another e-mail about this issue tonight, I finally took a few seconds and read how to detect the status of a Windows service using .NET.

This great tutorial article told me all that I needed to know to check the service status in less than 60 seconds.

It's wonderfully simple--in just a few lines of code, you can tell if the eConnect 2010 service is running. Here is a basic example:

ServiceController byConstructor = new ServiceController("DynGP11eConnect");

if (byConstructor.Status != ServiceControllerStatus.Running)
    MessageBox.Show("The eConnect 2010 Integration service is NOT running.");
    MessageBox.Show("The eConnect 2010 Integration service IS running.");

Other than those few lines, just make sure to add a reference to System.ServiceProcess, and then add using System.ServiceProcess; to your class.

It's that easy!

I would personally recommend adding this service status check to any eConnect 2010 integration.  I'll be adding it to my standard Functions library that I use with all of my integrations.

Steve Endow is a Dynamics GP Certified Trainer and Dynamics GP Certified Professional.  He is also the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

Tuesday, November 16, 2010

See the Forest for the Weeds

Everyone has heard the trite saying, "See the forest for the trees".  We often get caught up in details and miss the bigger picture or the context of those details.  Another interpretation might be that it means focusing too much on tactics without focusing enough on strategy.  Well, sometimes I'd be happy if it were just forests and trees, as I've found on some of my projects, there are forests and trees, but also weeds.

If we are in the middle of a complex Dynamics GP implementation, we may be so focused on complex and highly detailed configuration or technical issues that we neglect or avoid other important higher-level project management tasks, such as communication, original requirements, priorities, deadlines, risks, and perhaps even customer satisfaction.

After doing consulting work for almost 15 years, I've observed something about myself and how my brain seems to work in different roles on projects.  I observed that I can write code, research technical issues, reverse engineer complex processes, and work on excruciatingly detailed tasks.  I also observed that I can manage projects, manage resources, manage budgets, manage teams, manage client communications, and coordinate dozens of tasks simultaneously.  I'm pretty comfortable that I can handle both of those roles.

But several times, to my surprise, interest, and frustration, I have found that I can't seem to do both of those simultaneously on the same project.  Maybe to some extent I can manage a project and handle a small subset of detailed tasks, or help jump into a complex issue to help resolve it.  But, for instance, I found that it is very difficult for me to handle 120 hours of development on a complex integration while simultaneously managing multiple tasks, resources, or deadlines that are completely separate from those development tasks.

I recently had a project management conference call for a project where I had been working evenings and weekends to develop an application, make dozens of modifications as requirements rapidly changed, and perform hours of testing on dozens of test case scenarios.  I have been deep in the weeds for several weeks.  When we started discussing other tasks on the project, I literally didn't remember some items that were discussed in previous conference calls.  I had been so focused on one application and its code that I seem to have forgotten or ignored the subsequent tasks, which were no less critical, but were things that I had not yet started working on.

My only interpretation at this point is that when I am swimming through 3,000 lines of code, my brain is extremely focused on hundreds of details, "loading" many of those details into memory as I scan and jump through the code.  Writing code, I have to be able to trace processes throughout an application, from querying a database, to transforming data, to validating field values, to inserting transactions, along with error handling and configuration files, all of which requires extraordinary attention to detail, since programming languages won't forgive an incorrect character, missing line, or improperly placed parenthesis.  I have to enter a "zone" to navigate the code, which takes time and concentration, but once I'm in that zone, I'm able to efficiently work at that level of detail.

But when I have to manage a project, it seems to be a very different mindset or set of mental skills.  It involves synthesizing more discrete elements, such as resources, tasks, dates, dependencies, or meetings.  It involves a lot more mental "task switching" that seems to require fundamentally different thought processes than coding.  Managing projects and delegating tasks, I'm typically able to stay out of many of the details, which I speculate allows me to perform that task switching without having to enter a "zone".

I've spoken with colleagues about this observation, and they generally seem to agree with the concept, and I've noticed this with consultants that I've managed.  While they are working on a detailed, task, if I ask them about other tasks and how they are going to prioritize them, I see the familiar blank stare.  They were so busy fighting with Integration Manager for the last hour that they haven't been able to step back and look at all of the pending tasks.

I also find that this affects how I transition from one task to another.  After I finish some code, complete the documentation, and make a backup of everything, I find it is sometimes difficult to move on to a completely different task, whether detailed or high level.

I think the lesson here is that if you have similar observations and experiences, try and keep this concept in mind when managing a project.  Your project managers will likely become frustrated with your consultants and developers as the consultants and developers are dealing with mental whiplash trying to transition between tasks.  And your developers and consultants may need to develop some practices to help them manage their assigned tasks and lower the cost of transitioning from one task to another.

As someone who often develops and goes deep into "the zone", I think I need to develop better practices to make sure to allocate some time on a daily, or at least weekly basis, where I focus on the trees and the forests before I dive into the weeds.

Steve Endow is a Dynamics GP Certified Trainer and Dynamics GP Certified Professional.  He is also the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

Friday, November 12, 2010

What kind of pilot are you?

This past summer I co-trained a Sure Step class with Ross Allen from Salesworks.  I learned a lot from the experience, but there was one analogy that Ross used that has really stuck with me.

Those of us who work as application consultants, project managers, and business analysts often complain of being left out of the pre-sales process (the Diagnostic phase in Sure Step).  We complain about salespeople not communicating requirements, minimizing scope inappropriately, or worse.  But have we ever stopped to wonder why salespeople keep us away from their process?  Maybe, if we are willing to look at ourselves critically, we might find that we contribute to the lack of cooperation.

When I ask students in Sure Step classes why they want to be involved in the pre-sales process, inevitably they respond with a variety of reasons-
  • to “inject” reality in the process
  • to advise the prospect of the complexity/risks involved
  • ensure that the prospect understands the danger
But is this appropriate during pre-sales?  ERP implementations inherently have risks and complexities.  Isn’t the point more that we know how to manage these?  Yes, it is complex and there are dangers, but aren’t we the experts?

So, to use Ross’ metaphor, what kind of pilot do you want to be?  Imagine you are boarding a flight.  The weather is  stormy out, and there is some nervousness amongst the passengers (not unlike the customer as they are trying to choose an ERP solution).  Which of the following scenarios would make you feel better?
  1. As the plane taxis to the runway, the pilot gets on the intercom and says “Wow, it looks rough out there.  I have flown in a lot of bad storms, but I think this may just be the worst.  I will try my best, but I really can’t guarantee anything at this point.”
  2. As you are boarding the plane, the salesperson who sold the plane to the airline says “This plane can survive anything, you will be fine!”
  3. As you settle in to your seat, the pilot comes over the intercom and says “Your copilot and I are well prepared to deal with storms like this.  Control is working with us to route around the storms out there, so we can avoid the worst bumps.  So relax, enjoy the flight, and we will get you to your destination safely.”
Okay, so #1 is not comforting…agree?  And brings in to doubt the pilot’s qualifications and professionalism.  And #2 is not who we want to assure us, as he is not the expert in flying the plane (like implementing the software).  But #3 hopefully does provide some level of comfort.  Customers (and airline passengers) don’t always recognize the risks of what they are undertaking.  But with us at the helm, we can help reduce those risks by applying our implementation experience as well as product and industry knowledge.

When Ross first used this metaphor it was an “A-ha” moment for me, and really changed my perspective when I am asked to participate in the pre-sales Diagnostic phase.  Keeping this in mind, as well as the goal of pre-sales (to close the sale!), I think I am a much more effective asset to the sales team.

And this news story from the past week drove home for me how a pilot’s demeanor can affect the experience for the passengers.  This is the sort of pilot I want to be!

So, sit down with your sales folks, and figure out how as a team you can increase prospect confidence in your solution while decreasing risk to both you and the prospect by being a confident pilot.  It’s a win/win.

Thursday, November 11, 2010

Configuring DTC on Windows Server 2008 for eConnect 9 or 10

This evening I received an e-mail from a client who was getting DTC error messages when they tried to run an eConnect 9 import.

In theory, that shouldn't be too difficult.  But there were a lot of red herrings.

First, the error they were receiving was "An error occurred while enlisting in a distributed transaction".  That is all I had to go on at first.  But then their GP partner told me that these errors seemed to start when they transferred their Dynamics GP databases to a new SQL Server.  Okay, that's good to know.

So I connect to their SQL Server, and I am reminded that they are running a Windows 2008 R2 Enterprise clustered server.  Okay....  I've never had to deploy an eConnect 9 or eConnect 10 integration on a cluster before--only eConnect 2010--so this should be interesting.  After researching DTC on clusters, I found several articles on cluster configuration that were well outside of my comfort zone, so I thought I might have to defer to a Windows cluster expert.

But then I thought I should just try and check the basics to see if there was anything else I can identify that might help to troubleshoot the issue.  So I start with the basics:  Check the MSDTC configuration.  On the SQL Server, I open Component Services.  When I right click on My Computer and view Properties, I'm greeted with an unfamiliar version of the window--there are no MSDTC options.

I forgot that on Server 2008, the DTC configuration is located in a different place in Component Services--it's under a separate folder called "Distributed Transaction Coordinator".  Hiding in plain sight, very sneaky.

When I checked the DTC security options, all seemed well.

Just to verify connectivity, I used osql.exe at the command line on the GP Terminal Server to verify that I could connect to the new SQL Server.  That worked fine, and GP was running fine, so the general network connectivity seemed okay.

Given that the error appeared to be related to DTC, I put a copy of dtcping on both the application server and database server.  When I tried to have the application server ping the SQL Server, dtcping would time out with an error.

Invoking RPC method on APP1
Problem:fail to invoke remote RPC method
Error(0x6D9) at dtcping.cpp @303
-->RPC pinging exception
-->1753(There are no more endpoints available from the endpoint mapper.)
RPC test failed

Based on excellent information from this fantastic Microsoft article on troubleshooting DTCPing errors, this error itself is misleading.  It implies that DTCPing was unable to retrieve a port, but it actually means that a firewall is blocking the DTC traffic.

I then switched directions, using the SQL Server to ping the application server.  When I did that, I received a response!

Received Bind call from SQL1
Trying Reverse Bind to SQL1
Error(0x6D9) at ServerManager.cpp @453
-->RPC reverse BIND failed
But when the application server tried to "reverse bind" back to the SQL Server, it failed.

So this told me that something was blocking the DTC traffic from the application server to the SQL Server, but the SQL Server could send DTC traffic to the application server.

I then decided to check the SQL Server to confirm that the Windows Firewall was disabled.  Alas, the firewall was enabled.  Aha!  When I turned off the firewall, sure enough, DTC Ping operated fine in both directions between the app and SQL server.  And I also found that the option to "Notify me when Windows Firewall blocks a new program" was unchecked, which is why I didn't receive a dialog when DTCPing was blocked.  When I enabled notifications, I received this message when I launched DTCPing.

So, now the fun hunt for the Windows Firewall Rule that would enable inbound DTC traffic on the SQL Server.

After some searching, I learned that DTC has pre-defined rules on the Windows Server 2008 firewall.  Under the Windows Firewall "Advanced Settings", if you click on Inbound Rules, there are dedicated Distributed Transaction Coordinator rules.  But there are 3 separate rules for different DTC protocols.

Remembering that the DTC properties window listed only TCP/IP, I guessed that the TCP firewall rule would do the trick.

Sure enough, once I enabled that inbound firewall rule, DTCPing worked fine.

I then fired up an eConnect integration, and transactions started flowing.

So, if you are configuring eConnect 9 or eConnect 10 on Windows Server 2008 (or any machine with the newer version of Windows Firewall), if the firewall is enabled, check to see if inbound DTC traffic is allowed.

Steve Endow is a Dynamics GP Certified Trainer and Dynamics GP Certified Professional.  He is also the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

Wednesday, November 3, 2010

Book Recommendations: Accounting for IT Professionals

I often get asked for book recommendations by IT folks who need/want to learn the language of accounting to better support their GP users.  I often do focused Dynamics GP trainings for IT professionals, to help them better support and manage their Dynamics GP system.  And I always recommend the same to books, so when I got asked the question again today, I thought I would share my standard recommendations.

McGraw-Hill 36 Hour Accounting Course
A great introduction, very thorough and concise.  And it's great because you can do a snippet at a time, working through it slowly.

Accounting for Dummies
I know this is a bit cliche, but it is a great "light" overview of accounting principles and terms.  A very easy read for those that might get bogged down in the McGraw Hill book.

Please feel free to add your own recommendations!

Formatting Notes Using eConnect 2010 - Challenge!

Just when I thought I was comfortable with Dynamics GP integrations, along comes eConnect 2010.

The change from COM and DTC to a Windows Service took a little while to understand, but I've adjusted and am now pretty comfortable with the service and how to troubleshoot it.

Using eConnect within Visual Studio is very similar, except to a few changes to the final call to eConnect, but that wasn't difficult to accomodate.

But now I've run into a change that has me stumped for the moment.  It's minor, but as with many "minor" things, it's an annoyance that just seems to be challenging me to figure it out and find a solution.

When importing notes into GP using eConnect 9 and 10, I have previously used "\r" or vbCr (carriage return) to produce line breaks in the note text.  Worked like a charm.

When I had to send a note line break using GP 10 Web Services, I figured out that you need to send the UTF-8 escaped version of carriage return, which is & #13. (I've had to add a space to prevent the blog publishing from thinking it is HTML)

Great, problem solved, mission accomplished, non-issue.

But then comes eConnect 2010.  When testing an integration that I upgraded to 2010, I noticed that my notes now had the vertical bar in the note instead of a line break.  Hmmm.

I tried \r, \n, and \r\n, but all produced the same result.  So then I tried & #13, but that just put the literal text of "& #13" in the note!

Just to make sure I wasn't going crazy, I queried the text of a GP note with manually entered line breaks and was able to confirm that "\r" is still the line break being used and stored in SQL.

So now I'm stumped.  I need to do more testing with \r to see why that doesn't seem to work, and how that value is being stored in the database when it is saved by eConnect 2010.  I'm guessing it is escaping the character somehow and that is causing the problem, but I haven't had time to trace the SQL or query the resulting note text to figure out what character is being stored.

If any eConnect 2010 gurus out there know the answer, post a comment and impress us!

UPDATE:  So I have done some more testing, and what I'm seeing with notes created using eConnect 2010 is pretty strange.   I'm still reviewing my import to make sure that I don't have a bug in my code, but here is what I'm seeing.

When I assign text to the eConnect customer NOTETEXT field, I am making sure that the text contains "\r" for line breaks.  When I view the serialized XML just prior to sending it over to eConnect, there are line breaks in the XML.

But after the note is saved and I query the TXTFIELD value from the SY03900 table, I am seeing "\n" characters for line breaks, which is causing the display problem in GP.

Here is the value being passed to eConnect:

City: Las Vegas\rPostal Code: 3658\r\r\rLas Vegas\r3658

And here is what I am querying from SY03900 after it is saved:

City: Las Vegas\nPostal Code: 3658\n\n\nLas Vegas\n3658

So it seems that somehow, for some reason, eConnect is replacing \r with \n in Notes.

Steve Endow is a Dynamics GP Certified Trainer and Dynamics GP Certified Professional.  He is also the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.

Tuesday, November 2, 2010

Learning Dynamics GP Database Table Names

Today at the MS Dynamics World Decisions Fall 2010 virtual conference, I gave a presentation on the Dynamics GP Developer's Toolkit.  After the presentation, I had about 30 minutes to answer questions from attendees.

One of the attendees asked  if I knew of any good diagram or documentation, other than the SDK, of the Dynamics GP database tables.  The attendee wanted to know how to learn the Dynamics GP database tables so that he could start developing customizations and integrations.

My recommendation was to first understand the history and design behind the GP table naming convention.  Once he had that knowledge, he could then more effectively use something like the Resource Descriptions windows within GP to locate specific tables.

I referred him to David Musgrave's excellent discussion on the topic:

David's discussion was much broader in scope than just the table names, but in the post above, he does an excellent job of describing the history and design of the table and field naming conventions.  With this information, a developer can have a very good understanding of how most of the company database is structured and how to find specific tables.

Steve Endow is a Dynamics GP Certified Trainer and Dynamics GP Certified Professional.  He is also the owner of Precipio Services, which provides Dynamics GP integrations, customizations, and automation solutions.