I thought I would just give an update to this post, as I have managed to accomplish what I wanted to do and I wanted to share some of the pitfalls that I came across while trying to figure this out.
The first issue I had was the fact that when an inbound request is sent to the AIF, the AIF generates an outbound XML response to indicate what it did. My EDI coordinator, who is the person who can send me the formatted XML coming from our third party subscription service, sent me the outbound response document instead of the actual XML coming from the third party service. The format of the response is similar to how the inbound document needs to look, but has significant differences that are outlined in the documentation. Once I was able to get my hands on the inbound XML, much of the documentation immediately made sense and I was able to put together a working proof of concept that used the recId of the main table of the query I had written for my proof of concept service.
This indirectly lead to my second pitfall, which was understanding how the entity keys work. In some ways, using the recId for my entity key was a mistake, as it turns out that most AX tables use the recId as the primary key of their table (this occurs when the table property "CreateRecIdIndex" is set to yes.) However, since this index is created as the result of setting a property, the index itself does not show up in the list of indices in the Indexes node of the table object in the AOT. (If you want to see it, you can do so by looking at the table in SQL Management Studio.) Since the recId index is a unique index, it is possible to use it as an entity key for finding a record, even if you can't see it in the AOT. Once I proved that I could update the record via the AIF, we made matters more complicated as the customer communicating with our third party service would never know the RecId of the record. Unfortunately, when I attempted to use the fields given, it threw an error: " Wrong field ID in the key data container in entity key." After a little research, what I took this to mean was that there actually wasn't a unique index that contained the fields that I was trying to use as the Entity Keys (we'll get to that mistake in a moment). So to resolve the issue, I attempted to create a unique index that had the fields I had been given to use as the Entity Keys. Unfortunately the data was not unique and as such, I couldn't create the index. This lead to a conversation with my Solution manager where she was having difficulty understanding that the index had to be unique across the table, because she was adamant the the customer indicated that one of the fields would always have a unique value. That's great for THAT customer, but not great for SQL, and so we were dead in the water.
This lead me down another rabbit hole, and that was looking into using the AIFQueryCriteria object to try and find the records I was looking for. However, after consulting the documentation, this was a non-starter because the AIFQueryCriteria object is limited in what it can do. AIFQueryCriteria can only be used to do OR clauses in query ranges. We wanted to base our return result on a combination of ranges and we needed all of them to be true. The OR logic will return results if ANY of them are true, so we had to abandon that line of thought.
Amazingly, this somehow lead to a moment of clarity and back to this post. Or more to the point Ievgen's response to my original post, suggesting that I override the getKeyFields method of the Axd<ServiceName> class. I found similar suggestions that had been previously posted to this forum and as Ievgen pointed out, the AxdProjCategory class overrides this method, even though the ProjCategory table does not use DaxIntegrationKey in a unique index on the table. In my proof of concept Axd class, I overrode the method and added three fields to serve as my Entity Keys (again, this is a mistake and more on this in just a moment) and then I tried to pass the keys to the service in the XML I had generated to test it. And I got another error: "Wrong number of elements in key data container in entity key"
This issue presents like you are not able to override the entity key, but actually what was at play here was a fundamental misunderstanding on my part of how the EntityKeys work, and this is largely because of the existence of the AIFEntityKeyList. When you structure the XML to use entity keys, you have to nest the <EntityKey> tags inside an <EntityKeyList> tag. For some reason, this lead me to believe that each field being used for an EntityKey was itself an EntityKey. However, this is wrong, as the message above indicates. The <EntityKey> tag has nested inside of it <KeyData> tags that in turn have nested <KeyField> tags. It is inside the <KeyField> tag which uses <Field> and <Value> tags to define which field is part of the Entity Key and what the value of that field needs to be for the inbound service. As such, the correctly formatted XML for an inbound document using entity keys needs to look like this:
CustAccount
560133-04
FSReleasePullTriggerId
pull_trigger
SalesStatus
BackOrder
Of course, being wired the way I am, I tried to envision a scenario where I would want to pass multiple entity keys as part of an inbound document and I couldn't think of any, but that's not to say they don't exist. However, looking at the internals of the AifEntityKeyList class, it is basically encapsulating an array that holds the entity keys. The fact that it is likely a one position array doesn't matter...your <EntityKey> tags must be nested inside the <EntityKeyList> tag.
Of course, by overriding the GetKeyFields method the way it is done in AxdProjCategory, there is another potential pitfall that I haven't actually seen, but I can definitely speculate on, as it was brought up in other posts about overriding the method. I am going to assume that when using AxdProjCategory, the assumption is that the DAXIntegrationKey value will be unique, but for whatever reason, Microsoft didn't want to set that field as a unique index for the table. As I stated earlier, my solution manager indicated that the customer claimed that one of the three fields here would always be a unique value and I told her that if they violated that, I could not guarantee results. I have not really dug deep into the AIF implementation, but I am going to assume that the AifEntityKeys are applied to the query to return a FirstOnly value and likely use the existing index for efficiency in finding the correct record (because I think the assumption would be that the inbound document has a 1:1 relationship with the query record(s) it wants to update. By overriding the getKeyFields method, you are tricking the framework into thinking you have a predefined index and if the values aren't unique, you may not get back the record you actually want to update. That's a fairly large caveat, but given the choice between being able to update the record with this risk or not update at all, my solution manager was willing to accept the caveat.
I hope you all don't mind me sharing these experiences with you. Documentation is good, but only to a point. I feel like when you can share the struggles you had with a feature of software and getting it to work, you can explain applying the feature to the real world experience of using the software in a production environment. Once I understood how to use the Entity Keys properly, I feel like the AIF is a fairly elegant framework and pretty easy to use once you understand how it works. My employer and previous resources believed that updating these records via the AIF was too difficult a proposition to look into and had believed this for almost a decade (we upgraded to 2012 in mid-2013) and yet I was able to crack the code in about two weeks (and it likely would have been sooner had I been given the right XML to begin with.) I was impressed by how little code I had to write to get this to work, which to me is the sign of something that has been designed well. Thanks again to Ievgen, who put me on the right path here. I hope someone is able to avoid some of my travails in the future by reading this.