Wednesday, February 5, 2014

AxTech2014 - day 2

Hi,

Here's what I'd like to share with you today:

Keynote
The opening keynote today had one big message:
Today's the business needs it's productivity gain when they think of an idea. Therefor they want solutions delivered 'yesterday'. Once we managed to implement the required solution, the business has evolved and demands a equally evolved solution. Or in short: the customer life-cycle is getting shorter and shorter.
Constant change is what makes companies competitive today.
How do we plan to fit Ax in?
  • Envision: understand customers challenges and translate them to match a CxO's vision
  • Pre-sales: demonstrate the capabilities to meet business needs
  • Implementation: quality development that quickly delivers business value
  • Support: easily maintainable, adaptable to fast changing business needs
Life cycle services (LCS) is the key concept and the cloud based Azure solution is the future of all the above . It was repeatedly  stated: with the Ax2012 R3 release, the foundation of the next generation is laid.

Ohyeah, the keynote session also had the most amazing novelty I've seen over the last two days: when using LCS to report incidents, it actually creates you a virtual Ax environment (hosted in Azure … where else) on the exact version/kernel you submitted, where you can reproduce and record the bug you're reporting.
Big applause in the Grand Ballroom of the Hyatt Regency hotel in Bellevue!

As mentionned before, MS makes a smart move here imho: the life cycle services and Azure concept actually enables them to collect telemetry (as they call it) about Ax. Or in other words: they get an excellent insight in how Ax is used, where customizations are applied, which functionality is heavily/not used, where performance issues occur, …. It actually looks like a win-win situation: the Ax partner gets a brand new set of tools to improve quality, monitor solutions, get updates quicker, …. While MS gets virtually all the info they need to take Ax to the next level. Because - as was stated subtle: 'some of these tools talk back to MS'. In the same breath MS stresses it only collects telemetry data: no actual business data is involved in all this in any way. The idea and intention behind this is to act preventative: spot potential problems and act on it . So if the user or customer then reports it, we can bring the message across it was already detected and picked for improvement or solving. Perfectly matches the 'big message' from the keynote.

Further on we attended the session on master data management. A short recap of what I've captured:
  • based on change tracking in Ax
  • pushes changes in the own environment to SQL MDS (master data service)
  • pulls changes in other environments from SQL MDS
  • includes conflict resolution
  • support for different flavours on how you want to set up the sync (bi-directional, recurrence, …)

Next up was the 'optimize your Ax application life cycle with LCS' session. A few new things heard there:
  • set-based support for queries (applicable with slow performing SSRS reports)
  • Overcoming the parameter sniffing issue, do check this blogpost
  • Batch task created at runtime apparently get the 'empty batch group' by default (unless intentionally set otherwise in code), therefor it is important to link this batch group to the appropriate server
  • The possibility to use plan guides in SQL 2012 (I did not know about this) to directly impact the execution plan of a SQL statement without changing the actual query.

In the early afternoon the 'Create compelling designs - advanced reporting solutions in MS Ax 2012 R3' by TJ Vassar (by far the coolest session-host of the conference). What we've learned here was:
  • the SSRS/BI team has a series of blog posts (here and here) on best practices and how to improve performance on SSRS reports
  • R3 has some very useful improvements in the print management
  • since R2 CU7 a compare tool on SSRS reports was introduced (to facilitate upgrading reports)
  • A nice trick to provide any SSRS report with the data you want, or as TJ puts it 'to set you up for success':
    • set the table(s) used in the report to tableType 'regular' (if not already)
    • create a job to populate the required tables with the data you prefer
    • comment out the 'super()' call in the processReport method of the DP class of your choice
    • run your report in visual studio
    • Don't forget to undo the commenting-out and table-type stuff after you're done
  • A 'refresh report server' entry in the Tools > Caches menu in the developer workspace
  • improved report deployment (now does a delete  + create instead of update … which eliminates various issues with the report not reflecting the applied changes) + a flag to re-activate the default (update only) behaviour

And then there was the 'Technical deep dive - warehouse management' session. OMG, impressed what MS did there. Looks really great and would for sure solve some performance issues we experienced over the last years (especially when using serial numbers). I'm not a functional guy, but let me try to summarize what I made out of it:
  • Pre Ax212 R3: all dimensions were specified at the moment of reservation, this made the complexity of optimizing high
  • From R3 on, the reservation system is designed to support WHS (warehouse hierarchy system):
    • a warehouse can be set to be WHS enabled or not (all below implies WHS to be 'on')
    • the location dimension is a key player in WHS
    • inventory dimensions above the location are set during order entry (in case of SO for example)
    • inventory dimension location and further down are decided by WMS when it's time to do so
    • this results in a physical reservation without a location
    • the 'work' concept is introduced: 'work' is what, where and how an action in the warehouse needs to be done (typical types of work would be: pick, pack, move)
    • for 'work' to exist, all dimensions must know
    • 'work' assumes it can update the reservation hierarchy from the location level and down
    • 'work' has it's own set of inventory transactions
    • based on source documents (=demand) a load is generated into a shipment (=search strategy) and further into a wave (=work template)
    • a wave consist out of work and will - once completed - update the source document(s)
    • a hierarchy defines the order of the inventory dimensions (for example: batch above or below location) and helps to decide which items will be used for the 'work' in the warehouse
    • an item can have one hierarchy per company
This is all pretty scary and freaky if you hear it for the first time. But I'm sure once you get your hands on some slides of this, it will all become much more clear. This does requires a whole new mindset compared to WMS was working in pre Ax2012 R3 versions. Not only for the consultants, customers and users, because the inventory data in Ax needs to be interpreted in another way now at some points. But also for the developers since the new WHS approach comes with a brand new data model to support it. Nevertheless, the extendability of the WHS framework was also illustrated in a live demo. It looks very promising if you'd ask me. A few questions regarding upgrading and data migration from the audience were raised. In that area the team was looking a the possible solutions.

Last day at the conference tomorrow, looking forward to the 'Ask the experts' sessions and the 'Next generation servicing and update experience in MS Dynamics Ax 2012 R3'.

Also worth mentioning: for those who have access to InformationSource, the first recordings from the conference are available!

bye

Tuesday, February 4, 2014

AxTech2014 - day 1

Hi,

These are the facts I picked up during the first day of the Ax Technical Conference 2014 today.

Best practices
Use best practices. Not partially, or just the ones that are easy to follow, or as far as you feel like following them. Do it all the way. Sooner or later, the effort you put in to best practices, will pay of. And with best practices, think wider than just the X++ best practice compiler checks. Think about best practices throughout the whole  process of development:
  • Start by using source control and have each developer work on it's own development environment. The white paper on this topic can be found here.
  • Make sure coding guidelines are respected (Top best practices to consider (Ax2012) is probably a good place to start reading. I said 'start' on purpose, because definitely need to go a lot further into detail).
  • Make sure code reviews take place. Don't see this as a check or supervision on what the developer did. Make this into a constructive and spontaneous event. Explaining your own code to someone else often makes you re-think your own approach. You'd be surprised how many times you can think of ways to improve your own solution. Although you considered it 'done'.
  • Use tools such as the trace parser to analyse your code. Is it running on the tier you intended it to run on? Is your sql statement executed as expected, or does was it 'suddenly' enriched by the kernel because of XDS policies, RLS, valid time state tables, data sharing, …? Did you limit the fields selected?
I don't think you've heard much shocking so far. Nevertheless: ask yourself to what extent you living up to the above?

LCS - Life Cycle services
Something that wàs new (at least to me) are the life cycle services (LCS).  Googling Ax2012 LCS gives you a reasonable number of hits, so details can easily found online. This link provides you with a good overview.
LCS offers a number of services including 'customisation analysis service'. Huh? How does this differ from the BP's then? You can think of it as a bunch of BP checks, but it is cloud-based: so always using the latest available updates, constantly extended and improved based on …. input from everyone using the LCS customisation analysis service. Smart move MS!
This customisation analysis service is not the process you want to trigger with each compilation or build. But it is advised to have your solution (model file) analysed by LCS when you finished a major feature or releasing a new version.
Another service of LCS is the system diagnostics service: a very helpful tool for administrators to monitor one or more Ax environments. It's intention is not to scan live systems and give instant feedback. It is purpose is to provide the required info so that potential problems can be detected before they occur. Ideally before the users notice.
There are a bunch of other aspects to LCS (hardware sizing , license sizing, issue/hotfix/KB searching, ….), whom I intend to cover in a later post.

Build optimization
A classic slide on Ax technical conferences is the one with tips and tricks to optimize the build process. You probably have seen this before, I'll sum it up once again:
  • all components (AOS, SQL, client) on one machine
  • install KB2844240 (if you're on a pre CU6 R2 version)
  • make sure the build machine has at least 16 Gb of memory
  • equip the build machine with SSD drives
  • do not constraint SQL memory consumption
  • assign fast CPU's
  • an increased number of CPU cores won't affect overall compile time.
    Do make sure there are at least 4 cores so that the OS, SQL and Ax client do not have to share a core.
What I didn't hear before were numbers regarding optimization on pre R2 CU7 environment (so without axBuild) : you could reduce the compile time from around 2,5 hours to less than 1 hour following the advice above. Since most of us are in this scenario, I thought this was worth mentioning.
The above are the recommendations for the 'classic' build process.
Since the famous axBuild was introduced in R2 CU7, the above is still valid, and on top of that a higher number of CPU cores (because of parallel compiler threads) does decrease the overall compile time. A scalable Ax build! The team that created the axBuild timed a full compile at less than 10 minutes. On the same hardware, a 'classic' compile took about 2 hours and 10 minutes. 
The audience challenged the the session hosts during the presentation with questions such as 'Is there a sort-a-like optimization planned for a data dictionary sync?' and 'How about the x-references? Any plans on optimizing those?'. On the first question the answer was 'no plans on that'. The X-ref update was already improved (by moving it from client to server, which should be a 30% improvement, just like the X++ compiler was moved from client to server).

MDS - Master Data Services
Master Data Services is an SQL service that is exploited by Ax 2012 R3 and enables the synchronization of entities across different Ax environments. Think of 'entity' as in Data Import Export Framework (DIXF) entities. This can be very powerful in global Ax implementations consisting of multiple Ax environments.

DIXF - Data Import Export Framework
The Data Import Export Framework has been enhanced in R3 as well. For starters is't become an integral part of the foundation layer. Xml and excel have been added as data source. The number of out-of-the-box entities is raised from about 80 to 150. Who already used DIXF might have experienced performance issues since there is still some X++ logic being executed. This issue has been addressed by introducing parallel executing during of the X++ logic.
The practical application of DIXF I liked most is the ability to move 'system configuration data'. This makes it possible to restore for example a production DB over a test environment, and then restore the system configuration data of the test again (portal and reporting server references, AIF settings, …).

Hope to report more tomorrow.


bye

Monday, February 3, 2014

AxTech2014 - Keynote session

Hi,

Just want to share some of the key thoughts that stuck with me after the keynote on the Ax technical conference.
While Ax7, the next big one, will be more of a technical release that moves Ax further to the cloud.
The R3 release is now officially labeled a 'functional release'. And to give you an idea about how functional it is, the addition in functionally in R3 compared to R2 is 'the size of Ax2009'. Pretty impressive weight MS gives to the R3 release, you've got to give em that. Undeserved? As always a grain of salt may be required, demo's only show what they want you to see. Nevertheless there were some quite impressive improvements in warehouse management and retail.
Not to mention the Azure service bus, Master data management, life cycle management services, … So, yes, there certainly will be some functional knowledge upgrading required.

Secondly - and not completely out of the blue - we're going 'cloud'.
Azure ('ezjur' as I now learned to pronounce it, yes I dare to confess) is the way to go.
Are you spending lots of time and money setting up demo environments over and over again.
Wel Azure can help you out: basically you're provided with a full blown Ax environment (think AOS, SQL, SharePoint, Exchange, Lync, Office, ...) that can be customized, is accessible from anywhere and has the latest patches and updates. You even get a load of demo scenarios on top.
Actually, it's not limited to demo purposes. You can use is for virtually (get it ;-)) any purpose.
You can even think out loud about whole production Ax environments on Azure. Of go all fancy and make Azure your standby/failover for your on premise installation. Costly? Don't know, not according to MS: use the Azure capacity when you need it. If you don't need it, just shut it down and it won't cost you anything at that time.

Hope to report some more from the conference soon.


Wednesday, October 30, 2013

Custom box

hi all,

Don't know about you, but I've been using the Box class quite often. But sometimes I need a dialog with other options than the ones out-of-the-box Ax provides. Some situations just don't get covered by a Yes/No choice. That's where my CustomBox class kicks in: you get the look and feel of the standard Ax box, but with custom buttons.

It comes with only two public method, so it's pretty simple:
- a public static 'construct' method to create the object
- a public instance 'prompt' method to  ... well, to prompt the dialog.

The constructor takes 5 parameters:
- the message/question itself 
- a container holding the button labels: for each element in the container a button will be created using the provided label
- an integer indicating which of the elements of the container should be the default button. This one is optional, the first button is the default ... by default
- the title to be used. This one is optional, by default it states 'Microsoft Dynamics' on top of the dialog
- a boolean to make the dialog modal. This one is also optional but 'true' by default.

The prompt method doesn't take any parameters but does make sure to prompt the dialog and that the number of the button that was pressed is returned.

The example below should make the above more clear:

static void CustomBox_TryOut(Args _args)
{
    CustomBox       box;
    int             retValue;
    ;

    box = CustomBox::construct("Press one of my buttons",
                               ["I will", "I won't", "Not sure"], 

                               2, 
                               "Pick a button");
    info(strFmt("you pressed button %1", box.prompt()));

}

The dialog triggered by the prompt method would look like this:

And the result in the infolog:


Source code of the class and a tryout job bundled in a private project can be downloaded here.

As with the standard Ax Box class, this class is also running on the client. So make sure it's not included in any server side batch or CIL code.

Enjoy!

Wednesday, January 25, 2012

AxUtil and the application log

hi there,

During the set up some 2012 environments lately, we got warnings like

An error occured in writing to the event log on machine <DBServer>: cannot open log for source 'Microsoft Dynamics AX - AXUtil. You may not have write access.

when we're using the axUtil or perform actions where the axUtil tool is used behind the scenes.

It seems the problem occurs when the account running the AOS instance does not have sufficient privileges on the database server hosting the AX database.

You can go all wild add the AOS service account to the administrators group on the DB server. Or you can handle it more suble by just granting that AOS service account write access to the application log.

Windows comes with a nifty tools (called 'wevtutil') to regulate this. You can read all about it here.
What we did to solve the issue is:
- open an elevated command prompt on the DB server
- run 'wevtutil gl appication > c:\temp\out.txt', which will give you a textfile containing the security settings for the application log
- from that texfile, you copy the (seemingly uncomprehensable, but all part of MS's security descriptor definition language (SDDL)) expression that's after the 'channelAccess: ' keyword. This is the string that actually defines who has (or hasn't) access to the application log
- now you need to make sure the AOS service account is added to that string. I took the easy way and gave all 'authenticated users' the 'file write' permission by adding '(A;;FW;;;AU)'.
- the last step is to send that modification back into the system using the 'sl /ca' option on the wevtutil command: 'wevtutil sl Application /ca:<the modified channelAccess string>'

I got my inspiration on 'The Raven Report' blog, so it's only fair to mention that.

bye

Monday, January 23, 2012

Name based versus Id based

hi guys,

I'm programming some new functionallity that requires setup based on tables, fields, methods and classes. At first my solution used tableIds, fieldIds and classIds on the setup tables to store the required values. But then I figured out there will be a point in time the user will come with the question 'how he can copy the setup from the test to the production environment?'. And then it hit me: there's no guarantee whatsoever that a specific table.field combination in two environments will have the same tableId and fieldId. Same goes for classes: a class does not necesseraly have the same Id in different environments.
Or in other words: I'd had to disappoint the poor guy who putted all the effort in setting up and testing the solution in a pre-production environment.

Hey, but wait a minute! Maybe I don't have to disappoint him ...

What about this ID-issue they'd solved in Ax2012? Is that not helping me then?
Sure it is: each object gets an installation specific ID that will never ever change. That is: if you honour the best practices and don't intentionally ty to mess it up ... . Ok then, but will this solve my data export/import issue? Yes it does: the standard Ax data import/export functions have been improved to handle this. Check the full details on  http://blogs.msdn.com/b/mfp/archive/2011/07/11/the-solution-to-the-element-id-problem.aspx.
So Ax2012 does offer great advantages over previous versions regarding object ID's. And the poor guy testing my solution can export his setup from test to production.

In the end I did decide to rewrite my solution and make it name based over ID based.
Why? Because I figured it could as well be name based: this would make the code more clear to read, understand, debug and export/import would still work fine.
And also because I do have the  impression there's a shift to name based in Ax2012:
- new constructor methods 'newName' on for instance SysDictClass, sysDictTable and sysDictField
- the typical dimension[1, 2, 3] fields are gone and replaced by a new dimension framework and the corresponding bitwise-shifting-methods like fieldId2ext and fieldExt2Id are far less used throughout the application. All this makes name-based usage easier.

So should you code ID based or name based? I'm going for name based with Ax2012.
But I think there's no general rule on which of the two is better.
It's worth taking a minute or two to evaluate your situation (think about export/import, maintainability) before taking the decision.

bye

The model store has been modified

hi folks,

I've been involved in creating build scritps for Ax2012 over the last few months and have encountered (and conquered) a number of ... well, let's cal them 'obstacles'.

One of them is the 'the model store had been modified' dialog that pops up the first time you start an Ax client after the model store was modified. It actually gives you some options (start checklists, compile and sync or just skip the whole affair).
But  sometimes this happens: you don't manage to select any option. I mean: you can click an option, but it does not get selected. In fact: the (modal) dialog (including the OK/cancel/close buttons) does not react at all.

My workaround is to start the Ax client directly in a developer workspace (ax32.exe -development), where you get the same 'modelstore modified' dialog, but it does react when you click it.

Another option is to undo the installmode setting on the modelstore (axutil.exe set /noinstallmode) which prevents the modelstore modified dialog from popping up, and fire the compilation, CIL generation an synchronisation (or any option you whould have chosen) manually.


Don't know why this happens, I just hope I save someone some valuable time with this workaround.


bye!