Dynamics 365CE (Common Data Service) vs. DevOps – problem brakujących zależności

Procesy DevOps / Continuous Integration na projektach Dynamics 365 (Common Data Service) powoli przestają być czymś niezwykłym. Sytuacje, w których dostosowania systemu, biblioteki .NET oraz wszelkie komponenty zależne są budowane, testowane oraz przenoszone między środowiskami ręcznie, powoli odchodzą do przeszłości. Dzięki udostępnieniu przez Microsoft narzędzia SolutionPackager – przechowywanie „rozpakowanych” dostosowań Dynamics 365 w repozytorium kodu staje się również powoli regułą. Podejście to umożliwia wersjonowanie, śledzenie zmian oraz scalanie plików dostosowań z wielu wykorzystywanych równolegle środowisk. I właśnie na tym ostatnim temacie, a konkretnie na pewnym problemie z nim związanym, chciałbym skoncentrować się w poniższym tekście.

Wyobraźmy sobie sytuację, w której musimy utrzymywać 2 działające równolegle środowiska developerskie Dynamics 365. Pierwsze z nich może być odzwierciedleniem aktualnego środowiska produkcyjnego i być wykorzystywane w procesie naprawiania błędów. Drugie środowisko może służyć nam do tworzenia nowych funkcjonalności, które nie powinny być przenoszone na „produkcje” w ramach okresowych aktualizacji. Na początku oba środowiska posiadają zainstalowany identyczny zestaw dostosowań. W miarę upływu czasu i kolejnych, wykonywanych na nich prac, zaczynają się one jednak znacząco od siebie różnić. W końcu, w określonym momencie musimy dokonać scalenia dostosowań z obu źródeł. Teoretycznie, ponieważ posiadamy wszystkie pliki w rozpakowanej formie w repozytorium kodu, nie powinno być to trudne. Teoretycznie…

Pierwszą dyskusyjną kwestią, o której warto wspomnieć, jest format „rozpakowanych” dostosowań Dynamics 365. Są to, jak powszechnie wiadomo, pliki XML. Każdy, kto kiedykolwiek pracował z tym formatem, zdaje sobie sprawę, na jakie trudności można natrafić w czasie scalania kilku wersji pojedynczego pliku. Oczywiście nie jest to problem nie do przejścia. Musimy liczyć się jednak z faktem, że przy bardziej skomplikowanych projektach, spędzimy sporą ilość czasu z wybranym narzędziem umożliwiającym porównywania oraz ręczne rozwiązywanie konfliktów i scalanie wspomnianych plików.

Drugim, w moim przekonaniu znacznie poważniejszym problemem, który pojawił się w czasie integracji dostosowań z 2 działających niezależnie organizacji Dynamics 365, jest generowane w czasie eksportu drzewo brakujących zależności naszego rozwiązania. Czym jest omawiana struktura danych? Otóż zawiera ona listę komponentów, które nie są częścią eksportowanego rozwiązania, natomiast są wymagane do jego instalacji na środowisku docelowym. Każdemu brakującemu komponentowi zostaje nadany klucz, który (o zgrozo) może się różnić w przypadku 2 organizacji. Przykładowo – jeżeli do instalacji rozwiązania wymagana jest encja X, która nie jest jego częścią, w przypadku eksportu tego rozwiązania ze środowiska A może mieć ona Key=1, a w przypadku środowiska B – Key=666 (lub dowolną inną). Ponieważ dodatkowo lista zależności jest strukturą danych typu „drzewo”, brakujące zależności są od siebie wzajemnie zależne (relacja „rodzic-dziecko”), a dwa różne brakujące komponenty mogą posiadać w pliku eksportu identyczne (!) identyfikatory, automatyczne scalenie tej listy (dla przypomnienia – zapisanej w formacie XML) staje się praktycznie niewykonalne, a ręczne, w przypadku bardziej skomplikowanych solucji, urasta do rangi wielogodzinnego zadania.  

Oczywiście, możliwa jest implementacja narzędzia, które wczyta listy z wielu źródeł do pamięci, „przemieli” dostępne informacje, a następnie zapisze je w pliku wynikowym, który będziemy mogli zapisać w repozytorium. Co, jeżeli jednak nie dysponujemy taką aplikacją, a czas nas nagli, ponieważ potrzebujemy scalonego rozwiązania „na wczoraj”? Otóż możemy… usunąć zupełnie omawianą listę brakujących, zależnych komponentów z pliku solucji. Konkretnie, z obu wersji pliku Solution.xml, który pochodzi z 2 gałęzi w repozytorium kodu. Następnie dokonujemy scalenia wspomnianych wersji, pozbawionych kłopotliwych danych. Scalony plik wykorzystujemy do ponownego „spakowania” rozwiązania Dynamics 365CE (Common Data Service) do formatu ZIP.    

Jaki będzie efekt powyższej operacji? Lista brakujących zależności wykorzystywana jest przez mechanizm importu rozwiązania do walidacji poprawności importowanej struktury obiektów oraz rozszerzeń systemu. Walidacja następuje przed rozpoczęciem procesu importu. W przypadku ręcznego importu rozwiązania na środowisko, na którym przykładowo brakuje wymaganej encji A (która to widnieje na liście brakujących komponentów w pliku importowanego rozwiązania) – wynik importu będzie następujący:

Co w przypadku, w którym usuniemy encję A z listy wymaganych, brakujących komponentów? W tej sytuacji system pozwoli na rozpoczęcie procesu importu rozwiązania. Proces ten jednak zakończy się niepowodzeniem.

Błąd zwracany przez system jest następujący: „Could not find PrimaryField for entity new_a”.

Widzimy więc, że w obu przypadkach nie będziemy w stanie zaimportować do systemu naszego rozwiązania. W pierwszym przypadku – system powiadomi nas o nieprawidłowościach już na etapie walidacji poprawności rozwiązania, przed rozpoczęciem faktycznego procesu jego importu. W przypadku braku informacji o wymaganych komponentach proces importu rozpocznie się, jednak nie będzie zakończony sukcesem. Niestety, jak widać na powyższym przykładzie, informacja o błędzie nie w pełni oddaje charakter problemu, który wystąpił. Obawiam się, że w przypadku bardziej skomplikowanych zależności, komunikaty błędu mogą być mocno mylące, a przez to szukanie faktycznej przyczyny problemu może być mocno czasochłonne.

Podsumowując – aktualnie nie mamy dostępnego żadnego gotowego rozwiązania, a także obejścia, gwarantującego nam stuprocentowy sukces operacji importu scalanego rozwiązania. Problem jest ewidentnie związany ze sposobem, w jaki Dynamics 365 (Common Data Service) generują listę brakujących zależności dla eksportowanej solucji. Czemu nie zdecydowano się na użycie, chociażby dostępnych, niezależnych od środowiska unikalnych identyfikatorów (GUID)? Tego niestety nie wiem. Microsofcie! Napraw to proszę!

Total Views: 808 ,
Be the first to comment

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *