Freitag, März 30, 2007

DAX 4.0 Clustering question

Rob asked me in a comment to a previous post (Link):

"Wouldn't the session manager take care of directing a request to a certain
AOS ? (I.e. load balancing).When not using the session manager, how is
determined which AOS in the cluster to use ?"

Well: I can only assume that it makes the same as Axapta 3.0 (but better): the client tries to connect to all AOS servers in it's configuration. Each AOS server tells the number of users connected, the client connects to the one with the lowest user count.

Hmm, if anybody from Microsoft is reading this and knows how it works, please give us some feedback.

Freitag, März 16, 2007

Send message to online user in Dynamics AX 4.0 (quick & dirty)

I am missing the functionality to send messages to online users that existed in Axapta 3.0 and is now gone. Well, I thought you could use the "Alert" functionality introduced in DAX 4.0.
What to do:
1. make sure the user options are configured correctly (that means: set "Time poll interval" to 1 minute, set "Show popup" to "For all event rules")
2. make a button in the online user form that will open a dialog where you could enter your text
3. send the message to all users selected in the online user form datasource

Here is a little job that creates an alert for a user. Remember this is a quick & dirty solution, so there are some drawbacks:
* you will get an error in the alert form on the second tab
* the message will only be displayed about 15 sec and disappears afterwards (you can check FRM EventAttentionGrabber to change that. Check methods fadeIn and fadeOut for variable opacity. This should give you a hint on how to display the form longer)
* the message will stay as unread until the user marks it as read

So you see there's lot of room to improve it... 8-)

Remember also to replace the "curuserid()" with the user id you want the alert to be sent to.

This is merely meant as an idea on how you can achieve sending messages to a user.

static void sendAlert(Args _args)
{
EventInbox inbox;
EventInboxId inboxId;

inboxId = EventInbox::nextEventId();

inbox.initValue();

inbox.ShowPopup = NoYes::Yes;
inbox.Subject = "Message to online user";
inbox.Message = "Message you want to send to user";
inbox.SendEmail = false;
inbox.UserId = curUserID();

inbox.InboxId = inboxId;

inbox.AlertCreatedDate = systemdateget();

inbox.AlertCreateTime = timeNow();

inbox.insert();

}

Donnerstag, März 15, 2007

Roadmap for Dynamics AX

Googling around for more info on Dynamics AX 5.0, I stumbled over this interesting link: http://blogs.zdnet.com/microsoft/?p=325 which tells us the following scheduled dates:

* Dynamics AX 4.0 Service Pack (SP) 2: Summer 2007

* Dynamics AX 4.0 extensions, including CRM integration and Lean Manufacturing methodology integration: Q4 2007

* Dynamics AX 5.0: Second half of 2008

* Dynamics AX 6.0: 2010

Mittwoch, März 14, 2007

Dynamics AX 4.1 renamed to Dynamics AX 5.0

I've just read on the UK partner website that AX 4.1 will be renamed to AX 5.0. The scheduled release date is Q1/2008 (well it says 2008 but I've read somewhere that it could be released in Q1). There should be more info on Partnersource, but I don't have access to that.
Link: https://partner.microsoft.com/UK/40032627

Donnerstag, März 08, 2007

Using global search for virtual tables

The global search is a feature in Dynamics Ax 4.0 which allows you to search for a string in several tables (like a full text search). You setup some tables and fields to be searched in and start a data crawler that collects the data to be searched.

Now, if some of your tables that are searched belong to a virtual company, the data crawler will mark them as records of the company it is running in. That means that if you want to search for your virtual data from a different company, it will return no results.

Example: you have the companies xxx and yyy and a virtual company vir. Table CustTable is virtual (dataareaid of the records is vir). The data crawler runs in company xxx and will mark the CustTable records as belonging to company xxx .
Now, if you start a search in company yyy, it will not find the Custtable records as they seem to belong to a different company. You could only set up a second data crwaler for company yyy which would collect exactly the same records and you would need to store them twice in your database.

The following changes will circumvent that: you will be able to see data from different companies. There are some drawbacks, however: you will be able to see search results from your "data crawler company". But it the data is from a non-virtual table, you will not be able to see the results. But I hope it will lead you to a way where you can make your own modifications to get the best out of the global search. Remember: all changes you make are at your own risk.

Here are the changes you have to do:

Class SysGSSearchStart, method startSearch
comment the following line:
infolog.add(Exception::Warning,"@SYS98793");

With that, there will be no warning if you are working in a company where the data crawler is not running.

Class SysSearch, method search:

at line 28, just after "if (!searchname)" add:
select firstonly RecId from sysSearchName
where sysSearchName.Design == 'SDS_xxx_default'
&& sysSearchName.LanguageId == this.languageId();

if (!sysSearchName)


replace the xxx in the 'SDS_xxx_default' with the company id where the data crawler is running.

Class SysSearch, methods searchWord and searchExactWord:

at line 11, replace the "where sysSearchName.Design == this.design() &&" with:
where (sysSearchName.Design == this.design()
sysSearchName.Design == 'SDS_xxx_default') &&

again, replace the xxx in the 'SDS_xxx_default' with the company id where the data crawler is running.

Class SysSearchDoDataSearch, method buildItemListXML:

at line 11, after a while select indextable from sysDataSearch block, add the following code:

changecompany('xxx')
{
sysDataSearch = null;
while select IndexTable from sysDataSearch
{
dictTable = new DictTable(sysDataSearch.IndexTable);
if (dictTable.rights() != AccessType::NoAccess)
searchTableMap.insert(dictTable.id(),0);
}
}
sysDataSearch = null;

Replace 'xxx' with the company id where the data crawler is running.

At line 77, after select sysDataSearch where sysDataSearch.SearchGroupId == m_eSearchGroupDef && sysDataSearch.IndexTable == tableid; add the following code:

if (!sysDataSearch)
{
changecompany('xxx')
{
sysDataSearch = null;
select sysDataSearch
where sysDataSearch.SearchGroupId == SearchGroupDef
&& sysDataSearch.IndexTable == tableid;
}
}

Replace 'xxx' with the company id where the data crawler is running.

Dienstag, März 06, 2007

Ax 4.0 SP1: new clustering functionality

In Ax 4.0 SP1, the new "session manager" for AOS clustering was introduced (so you do not need NLB anymore). This, however, means a new single point of failure, because if the session manager crashes, clients will not be able to login to AX anymore.
The good news, though, is that you do not need the session manager!

Make the following setup: several instances of AX, mark all with the flag "Make this AOS instance part of the load balancing cluster". In the client config, add all your AOS instances on the various servers. The client will connect to one of the available servers. And the good thing is: this setup will work, even if one or some of the AOS instances are not running (this did not work in Axapta 3.0: there the client would have said that it cannot connect to the AOS server).

What I do not know right now: what do I need the session manager for?

Donnerstag, März 01, 2007

Ax 4.0 SP1: Client still quits if AOS stops

I 've read somewhere that it might be possible in Dynamics AX 4.0 SP1, using the new "Session Manager" for AOS, the following could be working:
the client logged in on Server1, the server stops and the client automatically connects to Server2 (both in the new styled AOS clustering using the session manager).
Well I just tested it and it's not working like that. If the server on which the client logged on has a problem (e.g. service stops), the client is still kicked out of Dynamics AX.