From 577700f11f66f22ff1b6a0bfcb03f3ddec94989e Mon Sep 17 00:00:00 2001 From: abidknashtech Date: Wed, 17 Jan 2024 17:15:32 +0530 Subject: [PATCH] readme file added and code coverage completed --- documentation/saga.png | Bin 0 -> 48758 bytes order-service/README.md | 5 + order-service/pom.xml | 2 +- .../nashtech/order}/OrderApplication.java | 4 +- .../order}/aggregate/OrderAggregate.java | 13 +- .../order}/commands/ApproveOrderCommand.java | 4 +- .../order}/commands/CreateOrderCommand.java | 4 +- .../order}/commands/RejectOrderCommand.java | 6 +- .../CreateOrderCommandInterceptor.java | 3 +- .../order}/config/AxonXStreamConfig.java | 0 .../nashtech/order}/config/CorsConfig.java | 0 .../order}/events/OrderApprovedEvent.java | 4 +- .../order}/events/OrderCancelledEvent.java | 4 +- .../order}/events/OrderCreatedEvent.java | 4 +- .../order}/exception/CompensateOrder.java | 6 +- .../order}/exception/ErrorMessage.java | 8 +- .../exception}/OrderServiceErrorHandler.java | 2 +- .../OrderServiceEventsErrorHandler.java | 2 +- .../order}/handler/OrderEventsHandler.java | 1 + .../handler/OrderLookupEventsHandler.java | 0 .../nashtech/order}/query/FindOrderQuery.java | 2 - .../order}/query/FindOrdersByUserQuery.java | 6 +- .../query/handler}/OrderQueriesHandler.java | 4 +- .../repository/FailedOrderRepository.java | 0 .../repository/OrderLookupRepository.java | 0 .../order}/repository/OrderRepository.java | 0 .../repository/entity/FailedOrderEntity.java | 6 +- .../order}/repository/entity/OrderEntity.java | 2 +- .../repository/entity/OrderLookupEntity.java | 2 - .../restapi/OrdersCommandController.java | 8 +- .../restapi/request/OrderCreateRequest.java | 4 +- .../order}/restapi/response/OrderSummary.java | 8 +- .../nashtech/order}/saga/OrderSaga.java | 38 ++- .../nashtech/order/OrderApplicationTest.java | 35 +++ .../order/OrderEventsHandlerTest.java | 81 ------ .../order/OrderQueriesHandlerTest.java | 55 ---- .../com/nashtech/order/OrderSagaTest.java | 63 ----- .../{ => aggregate}/OrderAggregateTest.java | 3 +- .../CreateOrderCommandInterceptorTest.java | 57 ++++ .../order/config/AxonXStreamConfigTest.java | 24 ++ .../nashtech/order/config/CorsConfigTest.java | 28 ++ .../OrderServiceErrorHandlerTest.java | 80 ++++++ .../order/handler/OrderEventsHandlerTest.java | 163 +++++++++++ .../handler/OrderLookupEventsHandlerTest.java | 71 +++++ .../order/query/FindOrderQueryTest.java | 18 ++ .../order/query/OrderQueriesHandlerTest.java | 49 ++++ .../order/{ => restapi}/RestTest.java | 16 +- .../nashtech/order/saga/OrderSagaTest.java | 266 ++++++++++++++++++ 48 files changed, 884 insertions(+), 277 deletions(-) create mode 100644 documentation/saga.png rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/OrderApplication.java (88%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/aggregate/OrderAggregate.java (94%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/commands/ApproveOrderCommand.java (92%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/commands/CreateOrderCommand.java (90%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/commands/RejectOrderCommand.java (83%) rename order-service/src/main/java/{com.nashtech.order/commands => com/nashtech/order/commands/handler}/CreateOrderCommandInterceptor.java (94%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/config/AxonXStreamConfig.java (100%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/config/CorsConfig.java (100%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/events/OrderApprovedEvent.java (89%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/events/OrderCancelledEvent.java (91%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/events/OrderCreatedEvent.java (89%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/exception/CompensateOrder.java (83%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/exception/ErrorMessage.java (69%) rename order-service/src/main/java/{com.nashtech.order/exception/handler => com/nashtech/order/exception}/OrderServiceErrorHandler.java (96%) rename order-service/src/main/java/{com.nashtech.order/exception/handler => com/nashtech/order/exception}/OrderServiceEventsErrorHandler.java (93%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/handler/OrderEventsHandler.java (98%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/handler/OrderLookupEventsHandler.java (100%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/query/FindOrderQuery.java (88%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/query/FindOrdersByUserQuery.java (65%) rename order-service/src/main/java/{com.nashtech.order/query => com/nashtech/order/query/handler}/OrderQueriesHandler.java (87%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/repository/FailedOrderRepository.java (100%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/repository/OrderLookupRepository.java (100%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/repository/OrderRepository.java (100%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/repository/entity/FailedOrderEntity.java (88%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/repository/entity/OrderEntity.java (92%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/repository/entity/OrderLookupEntity.java (93%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/restapi/OrdersCommandController.java (87%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/restapi/request/OrderCreateRequest.java (95%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/restapi/response/OrderSummary.java (59%) rename order-service/src/main/java/{com.nashtech.order => com/nashtech/order}/saga/OrderSaga.java (90%) create mode 100644 order-service/src/test/java/com/nashtech/order/OrderApplicationTest.java delete mode 100644 order-service/src/test/java/com/nashtech/order/OrderEventsHandlerTest.java delete mode 100644 order-service/src/test/java/com/nashtech/order/OrderQueriesHandlerTest.java delete mode 100644 order-service/src/test/java/com/nashtech/order/OrderSagaTest.java rename order-service/src/test/java/com/nashtech/order/{ => aggregate}/OrderAggregateTest.java (98%) create mode 100644 order-service/src/test/java/com/nashtech/order/commands/CreateOrderCommandInterceptorTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/config/AxonXStreamConfigTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/config/CorsConfigTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/exception/OrderServiceErrorHandlerTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/handler/OrderEventsHandlerTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/handler/OrderLookupEventsHandlerTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/query/FindOrderQueryTest.java create mode 100644 order-service/src/test/java/com/nashtech/order/query/OrderQueriesHandlerTest.java rename order-service/src/test/java/com/nashtech/order/{ => restapi}/RestTest.java (81%) create mode 100644 order-service/src/test/java/com/nashtech/order/saga/OrderSagaTest.java diff --git a/documentation/saga.png b/documentation/saga.png new file mode 100644 index 0000000000000000000000000000000000000000..4203c685a4ffd55c64c061acd1348268064a11f3 GIT binary patch literal 48758 zcmce-1yGzp*S1L@1h*hT1_&XzyF+jd?(XjHkl-GIySuv%1P|`+I=H*d4td|NwzleD zsjaQ0YKobjp7uU{&eiu5CNC?Ff{2d@1qFp7DIuZ=1qJ;Ic`3kufTZv-)cu6~d+#J9 zsSFSK^M*GLg?z?y7FBmvvNLsdGjKG4GPAX_F`;uZax^iqbuzbeK7;Axhl2VHB`G4P z?4EwS>ZLt)2OhY9YpA4A5~9SeRHbCwJ+IhF#$y&Uby@**j2Psh*o+n7?y)+NAN$+v zo$rDeNkQhQ4LS10@n5DboOP(O)``_ZvGH66Z(7%F=TB61&U&t{TEgdVTGq10i{f)B z5ryDM0?~y+lQb=a;n4r{0gI37Iq2VeMrg%*q_^+k4c_OUfBN@zH@w6q!&?$bAjYrm zPAH7+BZbmoSy%b{Yi8a5qvLiie@g!_uXSek1EK+ zLreR`lhGyQN5ob>DJ@_rMQp4wIW5h|_DBMVN?c=ahd?=3N1A+SAq%{~72vF+s62_NnA zxC0~?(xV#E)a{ClzUv3=T zBI=>N{v6s+)NmIf$;X{WgkraT4M!ImnD$d!Vh`8L9^Y~%W!J2qo16=a6g{$%O z1hThoPl&mz=PKd-2 zRS;Xj71a^?pbw zqez&K+YdwPBW&cA8^5%VA}KuH%11Rgr;*WNqoc)WjIuAycZUE3#{%V&%V)P$44e)< zG%X~jp|*OX<0`U^ILv=bM}c!FF27s>x?G;}sO0*IT}E=`ZW6zVKYip*}9($1@&S z8mkTzRcOm>`8hca^rUfTJc9UBRm$R*cv!X96cbUc253vNjb$uR1$t^E&0=gBw($N@ z(Tg({5rnnh#rf6;MdmUJGq$S0@b#Pd)jFrmyKs%A=cJ`lvCTs=``nkbZWSIB?F79Ct!ldEA8ovbI$ zqg8Ja(l`&xdVP|+rA$$~rKEZET3cVkCXl11g56P$j+{J`ZaN+MX{ScnqjhlSbeE-w zMb_!S%t86iM8O`vGH_MldU<_Fs%u8-;uyPpB$Y)B!Cr|bd5QAfI{BV$Sp+m?>XNV2 zpJI)n@)#d1nrYr;>VI2Os-5D~t5o5~2HI~9RFGW76{~U}uQcJcR-uMQ;kmZF(k;o$q}Il^H4l=uo5ZbedGX0)^dhLe zJ}gq|7dWpc%kAQ^NM9&`=xm8y9pini#|J5}MJ1JS>Zdv}&eQztZdW+q3h_<;R<2xZ zvs3mwT`N6~uH@xYq9OXF*;>UzCM2H6V91^VYldIS{yM;>_OL-va&SbMnMElc1z3J< zC$@z}=FpLqD^_tIiKL`>N*SJ;PpL2{Y_VIS#5uKSW0G}#T_uzw){oWVWmaxrT=3|@Jztk1nJ$IFo2-8c=`Rs7rD zxxF;KgFs8|N4w9|dtaAT#|+&W1gsT%;2*X~m)NX(L-my2(OApK)tZj^m8h)&oFc?z z_)xM%%YtU^ITh==hF0Ue%1-$RJaflbB5WRHx;v1_|Exl?d8tiLcGqdA?8#S$E8|^0UHW?GrG$bXgbblDkTMl|nE)sO2?VlXP{lV5w#`2LO~aJeN}{-!hmEu; z>sskfzx3hAg=MZ|L25wyEi3vf8ATO^_}FXZa5MMA$)b7g*_j?&W#-LwRaglfehA$E ztecK*y|L+jOfY{>N`p0w!DN`o=ylKG89a_J@W;$T(Dgn~+DS>~dpoYd!B7k%389{ z`-ObK*Jdu6RaYVhjsDf71|CGqcx&kP_}z`6jB_#svUkC%`9#{oGw7os1H?CA&I@xSN zX@_V|axx?N<@JM057D*N=FfCoh7DVCJJ~^xP}fa4mtvl1|I6{w$)3^2;NX!pdgOG7_HX zeXk6Lirr4T#{Aul2CTh!)wCu0g;XKSQv9eUH2yVy^O+Q5(=sYOoO;PgK$yZdhb4}c zYsSu2f(^36&t}4$^pPu5;im--A_ozX{GTOAzGrY78q2UYmbt!Jyi--#4%RDtH(aDd z$6hBjaU$k|C#PW%+L!;%z-~(3n&WBKiyqas#FGdfrL%Ye-_yol_}>?z<+rN4J0pl^ z3AZMag|1`KP5qLf({Mf-*ua!11Xd#Tfqndz78$laiEvO%+^^rYxIjks{-s6=2>rQ)7p zm~UBKa*&T?K?x5t_9?H~W++)UGdwCmGp9UiYtbUImgIEpTwy3x?iqU=zvXE}Gwun^>>hum4T|DE&Xlk^Wf!O~ifozjAAdya>UPapc%)(MfY!c0kdW#~Tzv;eQ?` zZp#4CMHZ)nAyc0_m(6PH?8JZj0EOrPT0_7j#}bcD`u*SHw?s*-{vUhIdjHCYC;c4s z-|mWi`+wTr|CJlg$mR@nVb~J;tGj>&Avl^u>R0+Ppme6XFt{uuCl71r^$KjZ58wUQ zqTEWM;%8lsQ9G;Qwo;4dHcnH$n>?0q5f!geoML>FywYm_&!OF6T<&PbkBavZA;(%^ zf&!_8-1LTmoV?JFTT5Ak`Py;}OhJA_6-UMd+<}am94wW&HI*j&xMZ31G$DGvPjS^s zVexg0MT!q<3T3+Qr0}>kb5?&e2196*-aPl!i>0)63&?!7z8iAJbn6 zouM_`H`Ki{5u3T#ci*|-a*T+<#NpoQLN}tz#N_<-;`eX1S7`r*zr)(xao-5-9_}@; zWS63lbGwZ!=5_^wqrU_)exw-FF}sPTOl7mr)qp8V%H4;vudn*cQ^Cu~#MMf6X`I&SV=gIFCMUBBsMrM~XfHIwBlZo|Yc7IE)hf-ZJ-x6_(pqwA z%Jla+MZ4#fgm)1Wz3WJqCKP(5r4aqPUT->cO1Ax7W-lSXkqRw7SEpW7`!oB*CM=F2 zgd6r9j(#dP2UCRxxB|*%yPWvt%acZ0go#2Z+8&sH&f!SmnzbjZiYn_;M!+3TNm8lX z+&^kn!g@9}F`*EMF1B@?MU}ta5ztmw0h#-V$4b;=E)2VU+%2-NL7f;80$IIhPve`1 zWJiypn=4~~cdjRKQ{5h7Xpu05u+ri{RZ4ZO7upy7UHyonKcvGBAWhU|R=g)D;c2zL zeR(EuY0qHtQ!&}+%nb}hj49BSRx9l=m>t?}PEIy`tCTdT zGj<7lWv5(Q=3gO($f>}|gpnklz?7GnRhE+nPZBvY>U<*Y1e?`Otu~iVP@*Y3fX;wN z^&B;EP>pL#Ua&beQDRQf>XS-bWZU!=0#pEuy+WtjP8$eVpG5sZ3keulGb4Hs}1-l?q&LN8)*RL zNMCoi0STKYI^)vqzwU+BRji<}qa{&<+Nt{^^ZJF0%O~t}&COfAqGG3+|82kw;n|-Wq zTkqy8@$o&rh=yw-58M#u`5a;R3|TvWTaxy( zbg#^xE=FRsk15y8iPc^bnOuAF;HJsQM1F;pT?--*pGDmDn`X9~j;7 zZ9aBv4X+MJ$|VO1pMyA0hKuw@sDot}BpeGYIaMYv?=R_tcY$I(*EiQqF!T&L%kPt0 zy0chV#IC*rvV*vZM+}Y$EWB5(KF+793cFq4GfB?kau=Z;AgMZRiEss1mUKT8*@|BN z#@>-}N0ud;wRd)-obv!zv^asLaz&BIWs?8Qlqlh`m?CHSK3ZG^GdA?p{eWGjUxg}f zxqngq$#D?ltL2HJFZJtFt4Ge#}p9H;0j=h)3c*M2@;Sp5E~11InmK zbO)x6^z9RHx>|)$GymS-e-8-QW2(gq9Dj~{2yrQ%Fgy@Q#3OD+=gWaByXbyYg+^e) zbC1j%4$;*BBm@3FV^SZpMXRqt4;VhXFtJM~(VJZE3_2gqgjq}%Ztf`eX7MADoW_y9 zitSA7VHOV;7wfiJPRiYyA*%sa9X$8D8K~2>OVPbHnUlK{0;!R8YJS~0&M^zrGF_?p zjZcl^=YF4n=I$2Si@lYFKT0eIg$O1-SDTX_kpJmpUFokfld@|5ot+mg-4Ft5ERHNd zKpW4|ls>mLGp$q~Z&g9M;Nb}{F(cu^^M>&=UA?>+u_Nl?ST@YoC2nnPnZBt*s2?1x z%8CZAm;darQooxO;xBg27|8P7m5C_SL?v!V{pPqpVm|fTvCZuKd&)Oe25_cJL~C4! zHIV_gKW;JKj}*N?bnQFzv}onc6M8y_dpZ4@PcKQiTP=BQ!g;ruecWet=a-kcq7gVN ztu7I19CpkG-S4SY%hlVnpjN{7=3nqQ=W2p`qr6*IV+RF-s~vlgQ`0lYOQ-RU!TiuM zcqHY|4k&RvB@&$_q~4o~Q(j|6yG!V*zLtaii_6!;2DJ>?HyK?+8*8j3AIE;E`y-L9(ityYc=G)_;(Pm5dvbHj^v=G> zaZWv1sDG}YoSE>?7V)PVM-QHlru1aI1fTKR#TY#va8q@42hLJ4WOR8`nx>i@KBF?u z#-^K!XKAn`bM&TywX(*v>d09b{>H*+k$&b$i450CsUZnW5J2hkT;=X|d3?dCvg})U z%RQ2+#~~_o{2?*(+;A^gbR=!($8BwS8NHMfXsmB#B|XdUHAS<*lF5GKTcu8$>At!U zE-crU9`tA?U)npE5BdfM3j6#uu}Lk?c-n&`#J$t>V(BZW` zI^nbV1=Pc~NuE7^$boZV#ov@U?pNvsqzj(0JQiATC6r_#Zba5ay#6gND8N2wLUB?F zsVBfo=fdw{P!PDfDP%zYy}2$WCnsK^8kdqXxb6o=`Lj@Cl)`8Ly-s*vDzP^sT4}0( z6!j~Q^nuzPHLW||lo~#YoSHoKf)Dj@xxjSOaW=B)d5Fnc{quocQ?A96tNY@bzKb#R zX6%n^9jVi^cDBK0{}R5;QyhQT(dQuytkgdtsFTN?$D((w9HHsydIDAxgd4-II_l8= zWR*a2mVT7x((WlBeRSbB8P-91yA4A`{g4o?4`oKq+MHSbz%&|aC^R(fnOIocry!+I zHFtk)maQpS(%x+@6S2CFtRK83R%II z-D3&H?Dp@(xzKnsX65d&&en&=#!P356^y@{VoxH2*BY$mtLy4|Mn;fXSXgvDb`!ol zv>NmT$1~_b zNX}mz9aIfoX%A^CQ#&b>LnU%rD3?dKBi~#CZsa(}Bv(rA{sIoc-eZRwiM-A37Tf}; zT9Kzf6j~c&$;U!p=a)FYd$Z1AS}?g>KsyC*YJ>4{Yf!z1GY3y&@7bQ=ZNK3DNq^+b zx7M)mN8-ThdZo2C`Tp|;s&@EK>U@|)0VhYh@ZLv8!r~s5NApz_+>c#!XTynf5h*En zd|tP-wOlGhzz0hkj&ezTox5*atCmh@3`!?YOc5Y9pB)#S-tpJTz_Z7MSs?pIpfPiD zhZqQtCyCv=#|fJ;;JhN7UvF!le&v@#$S8DP^2E-(im$`fj1WDesU(9-h-{n; zsq{|W4AxR@7p{2p8Z~YhlaMs zGI$<*Gg49{H8q!vmUr%4*0RVbD3nT-sUTC#qXiyjb34_h*KPkBBk*dz!AH_NER6{M zXuec$5eb>(#X2(oPpj8wer^I3vzsal@mh=rk(=2pCKXwRp5)@*#2^r{-#XXY2S*@+CD;du}NbM9cz z^o&Ov%VAfZ#%V+7s|)RBKZ&Uif7lTW`#uub%d&No)eeoqwkcmB#rc+AFQT+e;NZZr zbWw9pmkq?q-L?{Q|GmMy4(V_n4ld2gIz~3cl6owiv)@IN-`6j>dGjvoh!$m0*fVe3 z0eVWu@?)D9$3X^kb-Pdc?z(Q#_Md@t=ZrjI@r!nW=&#&uRP==iBAE?;3epgtv~IOI3480Wxfui1o@&MT`vjb*#(AT<+>J;#_j7%fPNd2)a3 z6oA&5FD$MU$MhHuvTc+<2O$N;Cq|Fm3Mezf>fHN&sS2l}sdi z??Fd2&h7V3=KJ@H8yk@ZM258}%;hFKJ=&}Mq9P+Bqk!D~Ds>|hlfDcdxBKg9IXrf2 z^%`UJZuK`i;d41i@g5G&>1yx0|3Jq(&Wj_9Q{&wY#aqpe>?jpKS4auQ!_gm7z#W}xlKmt@z$vZ6RdWXhgZ(P_Lm zY=5D9t@=+S-OiC~gE6M)3=IR*;`79gO|8s05(e}yJqkha&Zgp}1f5 zrBwlCu4s)#@2G(=0o6D|rCqhy!Xd@y=Y)dyp`SgEQ z0Xp>CVx#T!9SlOUBKR{wzx{9t>?)qfvBc?(U(z>tdS{1{EEO|$yD;Cd-Jo{k)H&Ig zIt~pJW?vlW1N(yE9dRp+*X+mZvqT4bV|AUf8B{9tp|WU?#k>$UBEXZy$rFcV;4b?{ zPye=*?>m?$fXNr9xHe?U4D9{^cn4z~Ft9)9o>C~_wRtuht%_te+4LlKjNdNm1`a5H zG~^%#-3@GG{RtuJ!JVTAcn!2Jw8$Gv`@EOQR%Yln z%MfZ`k)pa=a|GQPpAOh>t(RyvP=|$uiL(11Ock_v-JQOijgE{!Zo&0eTV0@fv*Zlt z-9ju@a^6|C@KjL-F5{&DmK*`#j!~)ORS&<{2QyS6-oI*kyPb)U%`ByCnyB35O0{P! z^asL!%(rjXkUV-jIkkbF35T;~MrLLM#R_@%=RIghvuE2aPq<6K!8n2r5!nIqSdS;1 zRjpZ8XRM2lv1N}~Ii)IPj?ecFSfU=MG2z%WYYdO0qoWFCv+rSHYpfTUp-%T}7w@j@ zW-eS4bM>$^mECD?H0P*lL`MsRH3@u{znTSEDHV~79wvO{sobOYm;1UjAH6I z1LTlq@J2t|Lw7>`5U>CM?G2abI7~&(<^#^}YqsY8#<^dI#)kGrAdCk%{Yz~)g@8Ny z4X}oXV!e`0oNx9ZdE0^?*X^%Lf=q&H`;sN%jm^4^>@SOh^V$O5@Jt|jF8rWkR?^>` zQ40Aa1qGn13WQRT^%fMnLq^MDW^MWnItjrm^yZ)YN%o4p4nh#*%mw?HbZ=Nuk|$|E z@w%bKoM>VY0;H(^Z;0TeZ(>7qw_xu`?zOSx@0<{U<>V%~^wgFxQUk9m1!dfcA3Y|hAU9bFhy zB!0^Wfl~iB(D;7^VSjc1e@u1%Zwf5Qfq^FxkxWcUA31n%YVlx)@I?`X4HhGu#ONwK z?qKw83CTC1#`wlaZWWc8QP0u4j5mh(r&28aD;2k9xGzbd;J+Tgtg{r6vmatF5!U&m-QBu3|K+#zAlghMaV@$(pAeARZe&oBovp(s4b+W>|ZxtLBu zmwG(O>*g^*_9(P8r$hR(g+((et~q3nz`y&aGm+a}X)0r)(@C{l<9}n3`UeOX+6yl< zF2UZ`Z@C<@-T=IUL|6!#f7QFohzI-f{Tt8d-N}7x<Pzyc!iXtypjB7lctvhXJN)Jrp zjc6^!;mf6dp@?7O1M5%RL2h3;Lt7&-t80d?g3Ddy*yX&Q2Df>;US6zKnr|-#e1*N9 z*j=7(I>B{4A!tf@VkpPQ$C*q~=t8^%RL>|oLkTq6oxT~5H%Aa!jJ}01R*BdpQ_$Tt z%rh=GT6}Y=c6?SP(8b|$hLy^&Ah_&dr&NH;Ec&`GC*pe5Hw?{qW%Agn&z%Zo?BKe~ z*jmXiwsRib_bdPNoO4EXrbkfNgfoCA4caf`CCMp8p=>!|e#@h^GYd)KzDTDzK{=j3xeaLrDilURxLQvLAdeFq7nC zB~?B|;fv3gsx9(*eUPSqr+L25mU%!om9oa+rX^)j{kR%A-ia3(f{<^El>6OUF8X#v zf2;nCD>cFG32{ws{&s99;B0FHn^4&|%>#42@b*WIJNSZL+>75lDOJz*RsV4x@Az+x zu+s3)ue3x@seyj80WGr9_cuLS0_2}Fkbh#(HGaH42n-C=H#8JltToZ7F$~HvLLed9KBH0NtTQHYX>%Re zNl+tNzFpch(w<^13`Y2c8Pd3k@7gF|a~8q>wLzVY+14sv1~F1BcPv7vs_7_vIjpVG&Orr25JpdbDlUbp7y0{s-?qSv{os*ei3OH3ebO19mkN z-q*FtK9Jsr$#%mJ0+B?250&g#UWk_g1HZi;!SZ`v>^$#l?c9Y!(?i_$xAg?7Oi^0u zH*rf&o~y(8M%Ji1p5uWjXm^(CwdMdenO8%X4T-%BtG^x5k ziv?<#FVFWaW8hkt0#6kFR1UCjS5{nH4^35jx7QgkBqCyX8zRDcJO2DIBBG;BFSh#1 zb%Ci<1=3D;r#h!=z=))zPZe5C?9RLwSRYUUe`m`c^8&+jd24(OmT(Peg-0|Lue1sZ z8LcKl;+^dOf);7VY>>OXI(;$PO2ZkZ1D5nf0m%!SI>XS-QafbQyq;53{+>EZjc<4?Fc{ep*cID?aLj`#lE(He8Z{$@O%iHlBScbXL5-Xv zZ}7;wLm#k)gD{eY(`%W4Cuzn~9J?O8&Yxs=>coXGQ>>%qM;~x>=zV<6A8HCD z9l@$W(#k+$G8&o)dZa}A?S2%c_YrtC`(J z5XKf6Ib^~JIBWqI7Z*D_JHO)MV7@_i4+0umkxUA6JiSh;Vu2L);|1$U!O4|Plkpw$$Vk$``u_aAIQ`i$W89K^{5xhSD*;nq!q9nPr_QmlSsQpXf!Ex1D{JY5!j9qqGzV3u=;rzL{^9r0?OPIO3Ne|<>3xgObN6P1 zrW-%Y>NR-dDzWPpxN6|ikd_L)9Yg#QZZ^`6%XyzFvgf-~*{c{#okRd^(P@*WQlgwl zdnh03JaVgEQF{5{DDQ7PB4-4^JL5ee=P6ui;3M=u*9X(Y+*?@?urZ#=S8(npMm)X> zxsw)Z$AZ`$L#09)gS*q!a-B9De;$anI+~+eBiLxYue?og>y`shW0 zYd_O%-@*BZ5tU!5sj$fow<{Wo=RwT)mTAv1q-uZ4`c+h8bl(&Ed?4qpUj(O5<_&!2 zeHt~AEbBuq*F-|Q%32^u3sR$Fp+C_c9JA!J@O_{dn>&ykz&TT#KL(7VY3HlLpqSke zkv9kvl-q*4+SxevZ_P<`3Yct?yV~_w&JUhjeLLoD8P66}pskcey-xjPVtg{fP7s?t zqv!*a%O};}l?*IAgrI8fPFKpjw(xK%?;bDKnJ=>i3cP-1ev(v^XYOgUuqm{A%9P&o zrLBPHoXx%c*#iKcNMAAI9cw=b%;!jwi@3Bipji`51_ zFL9n{z<2itMOnCfp7peMkgMi&tXI*IzP_MLJ}+j=8Ooml0UDjYd~RoJWW2oTkgGdy zA7VZxId}sJJU`v7kttF4TkotXa_|=Vx$ubjnjIq##fM2#ieGso_VL7)A)UA?W?yv# zIK`qYPiO3*>ExTfYbh3?$l z6A;7CgO|VIRac$Iy@d)!*4_jH*G_VB;~{HM5GN=>7wGBme1Gxt4&tR@1t<;~;WQ^w ztCUV08TSdWnNRpbf=hnq!Lj1v;wL*O03jjd08f91iAX}^a$Sd^?CRQI=?eo1i5RMf z#k(bdu2I2pKeHB8E4RVN{F!YrIjdM+pXt%m8FWZ1~7^_g4PW84iATx8mzcHF29zkRxmpQNJNMfhH;b%wYjJs`-}>D z`y9xgDQyD;=#{+PAVC*N;9u-ckecFn zdX8z@0Idp!*qN*;Imi#P9tDLNs}uoEmY8y+T>02GFraGYYQ7g9j%=Hwch*q>#TKXa z8TQwLJx4SLV9!sDYwuSV6Cyp92|N2w>upwp`ks_-Y-D4KjM_fWjU0=D@9?J^9gGUk zq<+?am%*Ta9h!4Ac#&VTJC#|6{Lse>>PYU0K@FRDD!lQ>cFN3H${qQ4 zP~QA<9sh-3Wawbb&d1!)x5$Oj^WYPMz3G9WWuvXmKFvFXZRgjdj0JWpL2NrN`zs;l zANM^N%8%AG!yEv^)H@8E3Z8JQqsD4KQj8V~%c8S&!FV;OQCdfmgFox$NwSYL>Ln|!ldXrkx2rs8Z9+(zPnri=WqU#eoxde~cc|qC z#og?41l_oIGM{w@J9#P{ytq8i{&sjlRj@&+vK~$RL|W#+K(luxeX3iYYPFp_K_Vf7 zXlKy7i!(IZ{cGpulyAz--U3M1t8UnjvP1(m=i-nCXMVdWeaxa*N%fpwk{g(uFqc>! z?vOy!e9{oqq(0!_U~X+;@#P=8e`p`PV@kH=;7Uz1 zRKhGN*OoMZIJ{Cs`vQI5(HyJeU~e$*>TLI6gKAz4t53pr6(W;48miQj5b(?NJoD3k zYfPfcQKGL7_zy{O1q~i|^nDVqRuh@e9%?Qth6pRXz7SV-I!dBS8_VW~cRO)K=opTz z_Auh^WQG(O;WcareHd#7S0%P1!48o6yv*icf;LoCiz8ys5+#GLrngQ=EJtZq-tUZU4xD~;s( z-kvT_OmhEZJw>DmVyTwq)DNi+I{PT?VFtBpxjws9iFhZib{f#ULX=ww&etj=L*Q7} zoJ;0>KY{}1Ti_cR{W~sCZ~kmOx>m&+nNYm_4?Q8b1QiRmtWFywEOb{bT&uTr4bvHL zN_v1w_MEsYlhe1Lc~Q(l-41oR8mL>r?7uu8cv^B_vm)wM2(1;;|uUoAv|J zWsMMxSiw50JhAhz??#xURIF-Ql-NztH<+qW?Wtv$g9$6Mf&i4gD<&2$tzsZA?dPQ8SHN z$M1a_&A6~SmL0hJx!`hE*+x=fPQaNdd6Mp7H|5Ol3FJGf62Rp){K-RDB>J(l6^XED zKj!`jqM$u@9lK|9E3BCcWem&YxxvtH5?{S@Asph(!W6L7*2hZ>0@%jR~Twc34TD-(NA38 zbjDwEC|?%*s`SVChZvqzSgk-8`jy8LI4F9NyXQuML_B@ao$%yQ8j_B#Uui;o1T~xJ z0*Sc$_7*dbpLj!Gnvkmn0{;sCNB7t+V!dB`|G93tjO(gLe(kQNzscp(o^6aUTt4xd zV7!^$nu8LI{(1>dWh@V;XBDLzT6V*SKjEf!kLWd4a0gIkjZQN&kR^X9<6^-hKCL;? zT7sRu*Wjy#ptF`FmDE^w=84qmJO!2QcqDdI>b2P{QI7GG9a+*tBu)@dv^_Hm|8#2(7KBp8eC%OJwqZTbC9=JGkaR=}>+yX&uh(wP?XUZE2qnllH=jq zB9{~K%*xFew-%uFV(NSImhEs*7R7&Wgo0-wP7esJ%`qkoTnVbol8LkthZiaR573+-}f$(Q(V zQa`wK`+`xOD`4z>uJ?f@Z~K@yR$n~N16U(wpuL?Y&lbvA^(k_7%L;D=GC-GP#H5SLU4{-2PU zvR)vs((!P@@Zxnk&mN=@bNtmxxISJCV z-U!h*JL3M+s5AYGR#H@*8Oob~+zb&r78~mkap;-7wJp@|A5teGJ$2?)5H~W>>2%Mf z0bxpZJ~WjdeG+P~-g(oHEBJRR+0~sDt=rpaBPFyfPNSh;VZQ=ZbL*(!{G+MsAI#Z} z){AeijWW^$!TtT#Xto;n{PUkoG zjds7o9c;kEsC7f}ZD3=rrRepcP_qtjLNp6pj6#c~QRZDA+w|+u#>}SEdt{$D#RBP7 zu!o}JM|O7haSwI~fOp#o?fjwL;hkc;+B(^2qxIG&Ed8^XO=Y*5yjq_=Kfd50(qF{v z#QNiVFaXVkFq$jV>Z@BPzC6YdX3PREPh{wG;#M$?fhy*P65MMiVK zH^7AY2yoE>G6tSrjo>Vm&1V!R@Qelv!Kc9 zw{K5Mjg!_#9v4;tZIvH5hu(}KHFnCu$tuVh)v-HLv-YLAqHy*$*ua6ql=m0f-P(5>GwLnVZB1f>N?W5Gq!-5$0QORgJ>^u= zoH;NyvTUuTvMgoG+5jB7+}958$K56$*l+`ns!2v4zLyjKVd;JLcczu+ zppnQ)Z%pw_pQQeIAh`q3g3b9;6-JzLRE`t*#`&-_dsg#En8nx#V4g4pbX}Xt??{w} zKiBNZQ)4+xO)i@*p{a?lp`qdZax*_}fdg5_u8Q}c;*dVkGx|I_t5#@={^uH%9ugLs zLR5>v(d3yhq6(S+xJc3IRr@1Bsh#A|i<%*|pBRPynf35%amIU8qE~HSIcEni&e+Wn zC@X(f!(nH`r|$m!Ml^%`14ec_yU4?SG5+T>-fm5qZ+D~A`%ix5UOm4Tc25>B%zlt! z;xK0%Ww2M5G=#^|2$&3HtsX4(r_jtr+}{gOyH@%&i(jstq&K>48(|U}kX%W4nV}q| zs^{`>g;hqdPc<%6`7)mL6z;wjGe=)_Rij;fL?LZcIGqBJ1_<;SA zG_Jd=x@7bF`}TzS+Vaeq$m>IG$Q1JUt!Y z=;+AE!jcCGY-x4dlOYiArA!<$8(^39Ex?mU)Xf)DDJiL3;Sf|25s`NJ7Tw#6@LIjZ zQ&gr-z3xU&GO4t9&r9Na%zasg%>cLg!%l_S{ONlJ^ZcK2{&8Ny%70S!uQ+FX2(kSe zcx-WwLcg~L)8`R*ubvEN|kk^4W20ashdqFw>t&uaW8Zljv^?}J%NtI5(k?%@Ps?x3>2Pj4mW zKl$CB^3s1lcIDr@V{PH6esW~@b?CHV%9{v;vTDj9k5O4yeJG~<% z10E_Az{?lm$wh1Z-K(=HxgOvi`rsROwRYiA&(r(*tgAO?=e<$^8^<8Z!D^(wgPw_O zJ(j|t8n@QKW%bHbc8r2f0;>y{wIT(LWwfAW6OhHiSZeqGn=5Y)(Sv*euRSGuG7K(@uPG}lz* zc*2wHp9U9jXXVY-pq3dYiQ=lp3x6E$0P1h&9vZXCJ1BMKP)%gdDZ{-XW(2Rx|LpXM zOij|wwP9-w9xIA@nxzZ&xuOYSuQGkey*p@aCBD-9aUmca`rM4C#@9`Y-^_Z~A_0^7 z7-_b+=fis|Abl(#_&-_znC}CLLHF%TFMZclR~|mDqqyvM(wd)I_Q>2>^A1YjbARiP zE(RmJhFpL7a0p}#u;@~gRa_eYHQF-}*ST(X!@BmJ=1GD+d?j#;b>vRj9*BvHjeYk` zRTW29S2r*?ciLicP4j4{f_-KQcWm(M-8#WEK0fDDm9@BZc<>$cy0IbT?{* ze>R;zihFVZiT!4EEN5s%YL<3keBqp1=ogZ6WX0>@ayElh-Uo^(ax8Y&;&*`D zL@SX!FS!DX0j-oIv03aGC!Y z^%qCC`qFV9#R^Tfj@L)4t*tHh(-sgTE^_jyDMY+!c3|$9gm@U8s6O}F+_^w}S0p-j zti-)6 zatsWv`{gcLNqs#}*LaiJ!dkGi4+I^otpQ@ZQ#Q+D^ql%@d0+Of@_pGdi;>+gXVETR zw_ScdITs%Fjw+Yl;0A}sIP5JaA)L;p*uH=iZ-YQ38W$eHE<8P;D(6D2s-zUN%l_rp z$9bdT`ADg>q;Gk9Em_X-!(}@BRcMYOkG#{#ri2VH7J}=_^18-NfI(eZLq z3`DH202wrEYiswDhWXQHkuP6hNA|i=Y}J+)7WQrTbc*#l`KJrN=RpYT{K;~I)u*%e zD^$o*)!!XTz>%Q%l9bLB+x09tTrxkC#*8hc!5xidSQL{*;;I1{N3|ABL5$|$b-g`a ze1_agBNOvK^A~uzLpDL`yK#gA7<>8KXN7IG*m=SOAopnqR4GR<(wGh|&Y- z7>@HtRf+@OMLSm}1h~M}RxkX}JYZ0vsKB=vBEC~$YK&N|q8$D&hO>q^HaVd-7`*LB zmOsQj)K9cKlcX|tOLW&?AkX}SVhK?{i}qTctUCV6Ck!b$D2kcd?f>mcNIo1dnz!+o z82#moiUsaYR-@UTEkFHumcm!-U+9 z^=}Onyp;bNb#ECIXVZlZLP&545Zr+sk+8NqrMXxl3u|>*xg)El%Fe04R(3ZUu@Rnq&2XW1PFlEpoJxmJ=RaH_WtMW?d354Q>T86sY3 z4^Ajn^W8J!pCu*Hqoz-ZaEne4E-d@i7^SSwtW*+|bpTtazyb2iXH_6@ROvn%M6d=dt-FiyDH0a6_H0o^h^C>fC=i zK(86cmLBIG))MORb=y965fI$3r&TF`n)`6sZ1uT(x-gY-R*H=lA?JHcN`jA1qci=_ zZ?7b4Di0sd>wu2=fv3tV5W(o!fbDQdfN7+mQTYuL(?<_mmzt|M{+*w@NR;kDm7^u9 zArJW;_WhqRGF^Nn^L|<5Brc;e!A7x_dD~h?NB(VL{aCMk{PQMt-oGPk{%CfzH&=@s zIRm9*x=GC6Sj6YjNf7X3&Pbm3)Drq8l4r|C0q8FzH`OPL^a&-#Xa@C~lUrkw3Y6T4 z$d4kmgr@c6MSSAfPQx7CS$lLwrrS#`aph&=!xH})1<26TJCVA2$6xcbRs6>HMwB-w6Nl2{0xN4Nft0X^fha zTeT}@9LiUE*f*e~a81O2=8c9%{oOx3hldmV`!tR5i+`s4|A&w0$fLXj)?!>3L`#(~ z(iksdA^GEW{drQ%`KTkK(XSQ@txWsPc3M6@kIArq*Dce_oxwSUTO$_st&gX=MGdn= z{F*}J60~d^xWX-;c^;5-p+xgSB4 zG!hFOwnK6G^tu8Kz3U2z;iOcheVmKZTAy-j&V6;0qUOs##-MqzUc4vL9qpbJbNY$p z^I%L>fpEI;f4hH7s(kF@FqiFfa^ckW zObG@}LhtV}(ah(jY|#K-#`GklydT77bK2E4-q*l}Cx7~`1l)O+3 zlO)je4+;5q$^SClx$lfJ@K7ymU}>qLtaAM+tX>)=N|8QoKGQx?yyP`I?nFsGSE1l# z!n)TkUT%J8WbA%yaiv3`DOiqk9!oUHr0YGrv$OX8#e^1h&eN9vme3(xaWR`1I3`%s zrrUqCM2G1J^+=eEHPH173Vv$b4-%K`0babXq-ti+%96>_bp_}&uCxd+fb(AnchnJILsMR-Jx1HQ6^)2>@aiU$eZF9hs zIUX_w@-j@EX5{j#8(MMVwQnY}v%~T?UirNVvc%&|Iq^g4^`uUrM|@Ocx9O@^xmkP& zE8ygHWeHq4`~?Qbb;c==Z3LxGW-O6O;L1iv6!zfUU5|=Jcl-Obf2*-_g&v~LRTOL5 z{OYq1d+B|uJLjYT;(r#FO{O(5*&Aq;eCzd2p{!D@h*);3}Pj>?3so3DUO& z5EGj&LvN?MKQAz`qSnt=iw9jMMa`Z?!LDjnUObpagopPc(QX`qeh$1^uXyE=9bCbf zT5!&M@33vj$^uKuHA`4*JRo<6gMLcKf0`!kiVkm}y77DTtg|Y$VKIq30O!_F(*=Pv_vaSA>pI222jAYF7Vw=4SH)Lj4Qt?RtyJ=XkV$ z3%jhdu`moc+j5yoW?OBhZ7P4-?qO~9S(7dbcLl8y5V};49ECZP<~$H+c%@s z-?~{i*r~mkzlFay2^V!y)^`g0{O=}*gMFOs!H?}v}&!{%i$Z>okd>anVJDk@V;cU&GGWW?Wq6y0%r{_VolMg zMVzpNG^}TCI&3+s84KVefNv@aV_LL&=Z zt5@?M$ERLzj_kTFP`u=s@QIosN~ZN}s-F>A`E0HSx(;Q)p{buig3rwYzD+Alo*s(! z4LIjZXEIuJ6hr6N)3fAuWl?>4=hl1|%|bwP6Cd|kz@J-^68XuGf(B=E1!-^?J6+Ha z!ucq(uyRvt-hopR5T8 z3Uc{eJ2oSFz9Zl#+$v@ocsg}bcPbg}S-oWJYW~KC_bzdJt{z~;`J252U%aK^VM*{? z3~J|TY@f;Ysl0fO-1hQ>Id}QA`*HW!=M2ibK4|!RHnSbSVa;vZgC6H5O#nZ|MR%9i zi*7{in+3ED?cNI=lO9RGEY{R9Ve$a{c1Rp&IV^%)An?mx+X}KzSWIEr4SoZM^)PrX zn#<6<^E;8|xa%u+1HTW}_&Am8_=1KD;YwnCwvqCi@7#r@6_0}u*seBk1y;^gNMv)ibbh;euBh6Xcy>(={wyrdx@83ZHK9*iREF3l1Z2(L&{;8 zhR@1cXh|0NGOUziTa1z}a2oL=IFu~#B9xsAd@U@nZRZtz;*pvQV)HM6>-wFF{Xq?N?f2V*P3;S3ucVWxESa~1y^ARx` zo;JV-dmj}=EO&SD=04MOSeO<8rOo>#tvHT_W;51(!*ql@2XD{YUmQjpjqyIcQOV$e zDH3@hBL@tU$U?4xt1mPySsjCWN3z)IJ)ySt@h@HnO~xOQ5K;~sX06s=9vY&z;$2qN$1MfZB*Hmth3-o!awHLNH( z69MrBZnKp*eL`vy9CQ!3ZWR8wAWL5R#T1U#`}pY+9sHLs+ki|BG*r|&eg+=+FvF1$ z4*>#-b(26mP7}4CnA+88pRdAwi>FF++J+g%>epBgQ^X!18xq`c zMt!#7WU|Lr?`qMi+9T9Pq_62?3Rc>dsx243UfGFonr>G_Px_pH-;2^4G(~3THcU>C z?MZe2$>o|O)n-aq{C1*gk*e#C*CGIM-A?cHuQdX>Bjet;wecBjdhB%NmsH6z(oF&V zYFER}=?=%c@1(cizR*^BOg?Rkk<>ky>TT9HYd&GF59rEm!>U3cc03*QbNp-H`uf?lu4(mNii=cJ=aPa#zPnnK73u_9-v@cVNd00KmM&B_|}a0lZ7vL-PY z64IH>%eRhp_A43b@;cr3AE?KCJlmy)TtFg8K9p1Gnp zp5$7ar`LSsSnJS&J3dkAc;eU{klOXb-?43y(Id>m#U~cW;_S2m({D$;RL&l1!-Ku+ z6GShlm4aBdGjHVS#2bgWv8M&0jBzkLBf}RsomN1exm-P&FG*?S>v0sxtW)4<_!3aJ zP(KV3Oo*xP@OP|zaUNRJMG;1N(~NfR*v%vs*mcZmhbLwL_?KdRYS=n6utoAKV{yB0_+2t=?-Zt|VSV0w|m~U@ezR=$b zoKao!r1vIG*r|D4T!g}QZ#cDbbW-2#kLI(|AVy2Kx#t;~k<^l~&Oa z@I#Q6iN?9P{;|_v*POBuou(;!q*6*Z$J3m)u-o1e5+PScVD$iJ$M035dK6ps#nmbq zGBPq>UJwz$vX4|-P5jm<%LMQt&1kR7{R*=ILQ2pkF0jy~bETt+`D}?15fNFJ`O;;+ z5j%QZ)w(JS3@Dk~AAcImp26XW|LP`mE+C9kmg}&wmK3A1tN2qO4yZ?S8TtZVoZslg zu9~)QKMdoVd*HI@qu0kNm6}uOW}}dzRB71YpuvgmjwGt`hS^j4UVJ9yv-PZBO|~J| zez(iwBIoNxx5j*%{}KdS@?fKQznNVCM7oru0Oqe&qWuGqwi4X)tNg*I)o`tJMaRXh zANl94Hvu;4q?p$LI%Bzqs1G0!|GQ{Ibxdox<_|WMnewew(x;eDb-I0O99L5EY293U z{#C-s{5#P(&IN?BtRMb~X#a1WI3SAuU(hS{%crnDuF;+QoLD%49{`-DELBP#?7;u= zV_z6AWW#ff_n3ibeN@=%_CIh}MKLLXFB`>L_7#{ZI=2vK@v}}efWZA9`~DYU_%AZ{ zKf$xO4i2lgSr@y5s*fd>TPuOfRIJovwtJsI@;?_d0?)Yt{7dLxbS=-3$HBxo%gWRh zdk1pKqKQktUOXg}R&w#JZM`V+uZ%M_h*V ze$tFttfGO4oX?y3e|z`{o)~%1oObUi(45K*S05h^1}ZiJ?$NKAi#XnuSN&Cy6enzP zAC2$PL>g*3UlPgq_;6EFuVLChBkNc;agHKEq9>onHt{jwz?A2xk!QFZMXc10p}9B1 z!REl+YW~wF;9a-+fiSV=L~0-i`UL3#m|ju?2T7Q={;Wa$m|?6c+Un>tF|E~()nkj7 zrxUV1#`Nb)N&%QE^0gM4o&rI>emjkl2B9HgJcIn11~cXXC8?7<>=$XAnI|(D*KU47 zM+{MPB3(f%L=GW`YTW&IaVA$q%fMs!97qB!FBADgVmTv|om z7xt0_%V4%`46c2+kqiEJT)jay1|om-hfXVBIJQHCgL-|ee7DA-th*bceMewT)2*31U>0@LX-n(l<3A2ulz~6dwLg$1-edpFq+G zz`GLIG&K_Q4lot5T*F+IjJ~D3cWN!`WP5T!fW|cWv#7z*Se2ZibkS0Y&fW!@RD9U9 zKw^gl_fy@ZXQ;n&zuva;sho~{ZxDii1v2m%SYDmA8Oh3UOGwZP{SRU_iHSHe3YDcZ zI>&Pf8%;^jdH|wIWd^Z1t@!`EkJd;Lk#fS=zC!(1T9hkGK^%4dhD}RF8rxOq}ByRHL z{V`Lxc+rd!8OZAvTyAS~yOZ&EAMT&&?t^!3YW+EF4y}FCx1EaZC>omWN80R{v{Wj% z^$A4I{1Xh{^8su@-S=Z9GBW#e9s3-=hg*eozNftn08@b=S;A;~d`TdgNzskp0zf<* zU6O3qFITk_*}g1}e}?w<4Vw6n-H{A6H|hxWOB^|0P(CdCsf3#PVP(RcT|5mauP#6Te;l83~7 zU>6lkWiuGb`S3|qUIz4=L?rC&;Vf>l{6(c|_``+Pvgd)S^*wiDe@Mx=T*^RVi2e1S z6C#W!+%irlF(b8axNps~*8d|wrl{5SNp@7e@oashkD2-l&;*y|Y_SF_%acn~Qin{h zg(H4Y)&7e1|B}Y{`(rY{g>xI`_S>@Y>M3GuUHg=-!9qQdhZSk$UENtvq3ZQ-4~z!h zVyRf=WL)8+FUz~*-}wTSxm?njz*! zEZ--$Xaf?@9Fue#hpT4CJyCY zM`eEEIZoS~Pab#2jpPWl?g1b(Myl>x9xg8`n`xlr8CS4e16QG;D2HhzdgD%gQ@;qDlx9Da zfuyJoBYUa>+m=@}-)2=uc$}`7Ti|PUnDC5_`JaYjYs+`2LBO2$gle0XF&QDa!eV z!!fj8C2>g{wSA(crY|$nNy8u5z~Z)|Xtp3H0c9%>U3v01mxI17gfugw-io+!>9R5U zofVf{BH1)b_V4?zj(#eL1RU3)CB+!O9YizPRk@j1bg-pxy7bM&>0D_iSoM6xBNI(6 zbV@$^;nqOLY4?R;SD6IoHmt?upmA&NVd4F~0a}9yblI>@fU8axO0|(sQCq(-^pk!= z4Nts9bp~9TB$tH{fA?DCyshqO_2Xl$%o!^ zP8flhb}I6_XzX?YazUAd!msu&AVpd~>WMu^9|67lqVej_7~6R$V_oO;S(vxg-N%}Y zde0=nr(UDikJtjcrX%%A1|Oepqp-*C*oa_36XNrg5J@{>SyJi#8BChG8DUJ{IUI6U6XF7}`AKX#1#7=vSpLsLW9RGM$?hvJSEXNYhXjY? z7`Q0s|Ki$`Nm6QiI6_t=55oz0_unRkFcDau-+l^hnZhb-%}u$`#vsLtqA6K*Sx&1C z!Q8!O#!df-D{{!6#GhDO@ zZ&klJ&d~czqxJxPBce8o^BsKf>Uh>O#@n_11LtIR#qCSV6F%>&!?k=s;{qT@PZ_I# z;6_EtKRc;oJ_0u->%ihP$6(X1?qNmRf0*W?N^_hUW<1tVX1U?&bk}D1;h7G%l{RYD z)qJlkM2`0id(9BWxh%*R!WGs~!R$^KBaXe=z2*`j@6y#eAbhPm;j2AJhwQ@{Vz!{t z))%%)oyBuwMin*Z6g=(Frnvx4T@;JqGUympWZ8pV|Cp=A^M6L3bp+|13355E6D12a zsJcv9JlOVAM*p0P@)D0k>cclQ$iCgKxDod;N)n2SCSM*3wL#g=uM&oK2`>{&sul$0f*~dO)hhBd%!>FaCmpXZ7T| zcB;+iuM1B_NIJv0T*8OGx(E{N5pe&^jAdU^0P4t^6CrSU-+123CxG;B zo7;;Vn%coDei&^x=Q|*vXw1!O5Dv7?p&k-5ycvz1P5%258(+p-ODMY6*9q8h=czsy z!^uPpj^PetIIF~xaD6{X%x|>Tm+yCt^N7D+4ZO<9+*8){@L!Cl^(-}bUa|ER?XG|- zbAg8Vq-JmB6_X37#s+nu|6-$Ps@X~RnqG9-6IW&=I`~Fk;ciE_!1kbL6z%=4qRso8b5qlMZ;hjl5Daob=ipee z+g*1!y5uHh#ZX^6YG^@qU z9D)#OZG}iSHpL3tN8L@dlbfhNzVRfmah&&=JY|y3$5!yE!>TIl(5hb~d?>Vmm>j z1-T}W?)M{_s`mmeOv3ea*c&B6AMGxbS2?O|-i78cQ{@b#O%0+GJ3()8@ha zCB^7XgM56gdH*HkrpEkchGCb0^8JW2Lxj({7M{JU-T-f2&4ghRL!j~x%p?dM{_Ie~ zZtqNKE4#_xom0|Ve9%q9B52Itiu*V|N}-_E9%+;C9>Lw+UF5V2KZ^A2{@M3AvIm%b zZ2gii;EuQ1@|kdoc!KLA8&Sqs8Bd_Xe@D|f_^w*+{3Iz~gAJ~;6p*6Semg#dkDhHY zBUI$&7u+|Vo-PObp7LeBoBzpG3||Nz`5xD_G>@OA@e9@w5)7@Mg?+1MmFHULIiYBn zatYdhK)bC(aoH(l7zDrSMo`di!pD^^YqGBtpARiJ@c-3OhuWe;`M$Sl@kJxK4f2G; zqN#K(d#nkhY@D7iS__YCDgpND+uX^0xP8`lel@QEM{u~XTiIg$aOZ+K- z6)FaZa&(g$$#y?aV&MN}5RG4)l{n+}Cv(S!5fwOYptH@%0NiM3V&XF82cSln$emk9 z{I|y$lrDw7fMV-AkPaS!;@CGvD+qJ!$n2GX)?)ZWxMKn$a>G;*z(rU2bW|^*1k~$t zm_0liebnar7X4o^C$`qD)QW6nL_7XD5qC;k6ntJ&4!<_eZ4DI1iFdZLPR=E>=f6gs z)f7#ES-dzGqaVNO!maT^H<2DRv*n<5+pw6}9tjD?yiGJq$Bs|JGBvpGqGpJ$=AkcV zQw~8V5@tCD%KnS(@l*7c**$_XeXq27Vko?qK2ZVxg08Nv=hhF6GY3{0*wC_IRbOvk zj`OHqX|FL+TV0uWfk|8uKf@r^2rC4pdFtmD6}COEKozp zXa`))tQj|ICisjaQK=8N!z6~Nfa5BH2_)tXH+Q@YB`CPKnDr6X3a>Eji$|%fV;?kU zTe90j1ync-nTrRrjHqxK>a{{9)~59yF~B%x_T==r40cFMXZ8mvI!#oH^|PFJujORm zddJfhx-Z(oSH6EaoUNvXDR+puD;)Q1f$?f@;I~Qc)OdA4H#8$IeLB>C}Z;=;B~wpq^{S8;%!k2Uqc@|(b!V#tEoFMmC&|D!v`Ht_E4uIJ#5gmJGE%t^RZKVD%9TqpB z{Hx)?V07m`j-YBQK+!rIuH)u`XKdmu{zjlN<7Cf9Ajx3CCbr50!p0DBjgKG`zT~vI z9s7xS=KFNl%NAxdxOvU-e#2rZ3&Xj-O1-n$*}zNHdf?=k`i`ycD9Ej zay`o&Q}IJJkKR3?OgZ}aZb|!sm^Wc5^~DsNTkQA3R|gz|PyRHpv7@s6b5D*A&zNPL{cU6<`}!|sMQj0pe0jEc80J?$QTcIf`(Z5H%j(^A~6ff z8oVx|+694LiAwRcyAos7denE{#Oo3!5nSS6ldJdJK<{h&Aqrmp=m#7tT#cU>g24B& zkbHgwdF@&PJKGvHdFG0ZK^D)g*w zqJll82;9zJ)_4a(^#Q#W1^`TZqvaA{&%(EQ%h@?b^J0X3%O7R)^Mn zdN@gv1>QFF+BWGxIy~?55E)^o(7CXXy&~6colI}jB5}1_32;`t~ z&i|MplFaEgcu+@E13G%+UC=U@KJ75PYN!SC7cc4kW+V$9z83M=Q}$?J7kH+YS7ShU zUOQ9ZR?^tS4t5^nXy8qqxf==uiKWggEoGFo+%2o zI=$iuiD`iqs_8bygcg7CmOzM$1{| z#&8@&+j^qii<4K4YPKvth2cZq@TxcigUHaJL}*HX*JzJX{m49|6(qr^=f&1lv$No8 zPawIJ1{KhKWSEycM5(#%6-k}LpI`N%{}!7`5@2+X9Xc7YP75DC#LgVK$bK(ii=92x z$Z76I>}E&p>t``veArcqD$~Q?%XXhNKbabHexE9KN5O2tz7d2?J*&L<9!|?KZf^ae z<(fLG;f;#sjXSNmC)@hnBfmbMT1e}njmHT>Sy(cY7s3}7wVe0h3f2Ykfet5C%`CgF zR?w)Z*Wdhb&3@n{yV*I^8X$N;AjmS`|LJg}1%z)NTc-LtSJq86K6W_SUbj!1Bs-MF9pyugMYiU31WE!j%wYO^*5n z_G|4D8gUTtb!LhoHACn19%u4kYS(V*<*T<9Zi=sd2w&#f%eB>tumuIl>XCJ?-Fdx{ zEG>kf>9-RL#5?rla|x`gX4(iK=N2)%KYnQ2Y_U&@p{IGVJ8rtnpw`vLRtLP39*fTb z&`oD^bt&2pzhMkVR{5K;(=5VmlacA%A-d_$kLwVPzm?Z2FHD6{>^MqAZFJ(}-*DK2 zFLS@B@@!0ZN#sAz+3>M^yVk!DKp&IEwf1R!1$-2WC;d8l!(x2))=WN4T7NOl7u!XP zf4u7R)*C{%1#v$dSS}>P@*3(<>_0OuD7mT6G|F(^FL69>s=qR}arSeNB}9=FWx5!0 zI1x&k?*bO6Lm7LxG~9-L+j!@WbtvzBb~dSaao$p3;({67%~r8bm>}bnY$aE1ZW_ zRBSE_E5}gMQb_p4zd@JZ3z!y`bF(IP9??%Unp0*>9Y_L&s#3YdLmJw%47dhS+QJP? z{Ke9El9xCz0V&5frzK=V;^w%=p|1dVl(3W$rji>Rfpq>MRf0q8&})P1(YfX*fj+*L zfwFTe*68`_;i($Ah{!)YYH!R)C)387Q9XgrW}x$4Uz2wG&ii%Qfmr`7g;~c?K8&q$ z5>B;W(h2&2M2mkoz@^t!2$MvT2yT+XwLWjkNaeMCzL!-(Rgy-YH{c`Qa(#b0=ZD>% z#Y6unwQMI4;`;G3c*eBnIkD3!eot3x-{|%iITTE2J7((d9Ju;J!jJCha;{gtd8jQ< z=(kdK<-tx!;vc>Ac?X<^+$(VN-`GW=l6_hg&%+F!^r&X<6KtsI9^)B;Y*b8#DfegC zgV7U%UN`qw42Qd9A8C7{Fam=ts5yb>M>-!M9{oVOU}`+WfdQJ#MSrXBdlYjw2JkBt z=raDXJ+8OBW2cQzlqN!cbJGdv7ztntE13PM#3XfRHT%_zhBpwg*eD7|IrH-?4w6Fz z?ruNVEMRy{B?EwS1-fEOnib%x(Zt7A186E18D!(}v2L=+VNW2WXN8IB@D_v^TjPxm z#-=!K5dT*{ZOrvYhYz3MNMvfEI`=1-fAe3ctlA}KGC$}rD21;|yhW-|NZ?J^w z{dK+3wVi*=EZBPGK2OkQ_ol=Bc8KKKAq$j2LXP*kE4 z=`9Tr|NM}@T*qhQmyGBP;QCK&Ql!8wMB823M{a1AZUzg76~*|qH>#C0%tv^D9N z4EOq(ZY#~fQDgM^a?%qPwdFhz;&1)oStH?n_(&sl;`up8Iq|*k21(sIDng7{bLxB< zVvGft$9~r{X{&Bke<}0Tp#zr{-dc0#>IN#Z`g81|>`Mrz+eg)P`WTD-_ifL`I6}GE z88e)kJLRl)zcTGTKZUTIJznp~My4nqs(X74yUFI!N?)koHLJ|Y2WH^i!B^9jZ+Q`OLFdrNwuZBu(#1=(630{M)B zk@acv4XEFO6@F+nZa!F-!hrS{$8`TUr&v)<9H>Ic)t4Rte9N&?y(?Z#oz(hBBp-w$ zL+Ck%^TeYA4K|k9oBDIPK0`>a!3egS3!+LS==^S68-G=We1E_(i&xOT^PIk|xcIu3J3 zj7ne5YU{xgq^O9g9>&rlOpscA=W%sk8Frn5Dx|N=%Fb4Z=~sxjczRI{u$Ie#)m0>5 zSH1XYX_x&`YSO6d6yvS_C6)Arr&JK2K_fE^6nYY!gMs0mh96<|e`-YN8EQ5!eu#1O zvj08YG?LXBeS`@zQfe8BoH`yEp?y|&HfBp!tABd>&Yf^`(`C8roOt7y@?HAGO8Nb3 zR`HntTzkiYaEeEcV6L*x9}=PQ#2T;8Ky@bKTscI4R6CqB-xD|`PU+(t)vF{0upuS>#hdf|0Of7`8 z$oz$lni>(`aK0s@?r=fCBW}Oi-Z6eFjw|m5c@0gi465|O7SjsB0*o)_iv_Wtl!+lx zrA*%-;-Dc*_twAoFY^~R49{rq8O33=HVM+WD}*-XHk9mnx}ujXW3JUiXI|K(DO?lT z2>2d3Z3%Igx(IFDUgo;3yrdbLI;{wEX4C(55XkxLu0?7DYc+KSDV_tH>kI@P&w{$@ zeHWISEtF$hSI>G~ULlMS^M7`pDb6T9O&3e{f!*}jM?)L&z3*1WAO)#<9 z*~Ochda3_i7WIdQ)UBbAH)}}UsR`4=^+p}Py)m$vg$mLJEw$b&{F!(A{isrQ=dS;+ zd?D^xa;9fMiIIuZ=^yzw2IBG%CSGpkyr&Jkj@K>*!jo})Q2*s$Za+|{-j~b?zely+ ziidgfv;x?e0g_$fP`fUmf5dI0V%iRRck|z8<+R}bw&}cx$4VosYD*L2PUz7Icd!bZ zc4bePe*$_msSe$LOu_UrOry;Bm_P1XWQ76(Sz-k?Yk^u96z?RqZU$4-VK+8@nCgFN z+=mr^$W4_+#2p{}?N!O=Kh{%LoW`$WrtI%Gm%SDL`&8Rr6)VMi`*#Qb4E+Dg%$I)> zQa~>sctLL00a#Gyw`7^(i-NGs#ZBCLu8o z|C;v?;4`cAcEcUSrEICFcLjkw0zi+W@bstHW^4S!PvP=ig-%#N${#C*40^@G!sF&K zkA>AzRoqijny!=yAV{{Sae`1ACwHwa%mcbM;V1g}uuN1&Ak7uX(&XQXqiF!st9$~I zDdU>c6MDt6O!gRY692j_SuQWZ&tOkSiv6mkF*8eR#F{wU!Rn{m&re;jZjIm{&i(A2 zcu4=8W6C8D0c4rBx)ni_5`~tR#wGx(ZJ0+X)?KjT{;9}ls;KtBJvhW}uCg1@`Or}n z#uio?UkUk;datQfOtMvTR{4}O)M)b+XhC{-ZB|lhj}^=Y=DaB{LsQ)!Dq<#CYV$aJ zGqkbvSMTr%F@D6lw)i*mOeDN^)3>mGdy%ho*8_hfxu*z2U+0BPQvTU$nylCei2YfPSX<%B5n5GP~ zBo+s>p-JI^&%@-FF&Bk&OlZi~+zRd8)R*K>Y2&|{7?~Xt&;7(Gcc^s_?$(~I`Ia8s zHMa!Y3%=_cAG4j!w5)G{_62y%ys_20n;4p@9N~Usu1CZeTBc-FvErleAt+= z+0bv9jNSq&N%qz7Nfv(|EUUO*Dd<$Q`Go5o){(@%Q{lK3A90cu^XYhNKe0sZHs*4F zKVii0dJX02z7$tiUiyTHI9i$Y)m6j2O36*W^bhWz@AnEBbt(oW$h+TN&Tq+~N55E{ zJ=gLtc*r6_Q4n~0hf_8GI2<4rwpV4#I%UUG+T{^-*xps`G+0RaMl~lwU{89L#a=Ru zie^0z!&fZz{Q#c1aSKKJu3H6yz!(2mtK(?~^N$Nr59|Qo`*y2X}EqCHJp#r?nWqH|0s~9+(Lz?MYc>?&V?odt#6XJ?z@LPTmIcIB+olR zLlH9hpC$|iF*eHMiM4~Rx|ADQRMJEHhyyDY>q(NB0ohmH3f^y%s2@y7%54RH*tTE$ zatKMoOnkwn1=_r3D4JEwu6b(Jbq#&8!Gye738dIO23b(aGPx8C&kp2Ewc*x=7!2 z{WLn)X#6wLK&ssEs>W3?Hss=>6>SAqF26zSdYV0Xi?3llOZmxy&z?Qoov&drGBP5L zmPRLHAN)=&!K#-QzGyzNuJ?-X)pq@UCJu;>He1*q(%giTm({LWj8gSMz5KAXld=9x z{_2(0N5gugVmLwDU}i=IuRRF@UBd2SAR0aq_q+p3q|&rWM^}hKu~YaL?sC*w+ubSlzQX0WA~843hBavX>auInQZaW& zN0r}Clnk#l+1iF~tO84wVVHhXkBaZPf7sYG0vbItEWLd))?xyBs7v^eHm0Ny_wIu^ zEPs42UqN?g_&2=t_2vM{^TYIxoGL}D!-n+2b6WrZY60vZJR|Q}-O|;~M>YoU&0@U{-6_$FrMXWD2*KF(XAA<*t9&dZh!RQ(?V zpSHSpG=Zw2Zu^tj0H}Pw0)L?D{zjm>O9VpLQD&&JI%WUMf0gUWL?oYlK6~v3!R^1U z``qkwwUp!9El$M?+(77icjW}+XOj&8mW!&Y;;~z(9dd8I1DP5sfrlbZ#FUO!MruFJc&Nihm@1QD6^za+#@FIck*1b z=@IpYuU{`kB(e4L_@5*G{ytb+rMRb#IB0`a=k1NKx~Yrj0FLVG`1!5gu*LT43T?Q6 zUwF1J_?h8HzBLb_+=Fjmhn`F4pagtfpsMIXlIDJk7FAIDyHyO@lv>dw{zgv($O7q%`re&qAG-8ApneV$3X&-A5C?|mt+;0pk__U`Y z3Y&nyuFrMw_a~N)F^win=J3ZNl_CRq@y&zCA{cVz&a9)sY^%iY0+NwP*is^H3W!R; zW}z-9O$O;h#To|_4U4+9Qty^7N+c5}jh19Q3aE-zmWKVJ z85Sr^=R(4vg7KItjk?7=-=Ex*Fg2xt$(LOcbJ(SR!#-X%+83^7;plrGy#>@C zZB+jE@132w5j4v5^Cctjd`{X?=Aa%&^EKoY;)M&M=nL8n4=8h2zztxDEXkK_JWQHV z45}6Nrm^ry9G>uEx{@AS^A9Bpgz#H5eE%zx$0o`;mw{ggLKpT z@89TLzi=#Xe3Lo9JoinaWGz_1_AK`0-GErz6?+Ar5d~RCf}Da^#57OfKwp<=O=cat zFVD0^3{u^t6=-k9AoZ;-yvV4$buLCQvhbju&-$y;p}KJsO?c6K#D48dbB)Xx6ZO%% zX)>k-6u1k748pzoF#kdQvbkzQd5K6Q1wMi3Cnp}D+_^@qiSkC9$4g&2`A<4TKWVFe z01K=%YUbcDGF7AjuMlHni++5#n`rfiH!;1&;kBJTY4H=+?oU35)ogg)M>|uhXR?u# zQTKzXy{aXDZBQLRo#aw*>ukTCWuyu;p#1oz*)V>PBc6Xr)=n%huyU_wtC2-5&oFjo zWFt})Ig0VtN^Na9nK>quf%ikQr((W58QA)>fyYl$k7wRIH zAPUbHHwHYsveBSLNx1RqnbQs=ZJ$V5X$&fb=M^r|k=LjFKkioff_NH{W`zuu_z{%^ zg;&6RKYy{DWE3DgsZ^XcdT4@ z#7%K`W!ww@lI=aAxjmw*jQ6QIj!L@mwt8^y`!n!x)PCZi1spv`HCCUM|7L9`WvI4R zY?86&$7dvZytCX0cRTxtsan5k8?*y{DI}%3!cvpoJH0&to}`%OdDAXq9E%+B11T7# zp5_);xIGva;CwLnJ$WPLx~$aom@5UTre}Nzr7cL>ZKxO<=a=VQTmVO#z}5No~+i}Mdt!nc}OveR_k>!qWNi~ zzh!%7W{+0v!moF~2wh?uTmB9t&76Z*xWdk9x$=l|!HaO!Xl{mG>$!&zGJMw>`=vDC zAb7fm$9n2-NJ0X>|HCEGMo)C(@kXR(5yc9W;j;e=^HeVe`4U5(R&ba3$X$)I-q}cm~2C zE-NLTq~Y;vq2{q45exWL`bqc}$>TdUefRDU*afF|`qi0EuMgZgSo6JO+ZD37Q?idy zaIf1xuCv*6JFvs0?zX>muhlNt+)+m%we{UujFTV<|^;EDMm?T=j zcVgFT*!A#XzjJ=T)r}f;L~(XsbOyoLwf9 zF#(=2h5OPy-VPKSW3(gmTbeAuy$!4XD5V!%EbAo!^)(w^C%B#4pl4+j%DHmu~Zp z?O*(Xuk~82cdU^pSl7JS&^}yODz|WTMS~nYRVvKnDouBtqU~_d|ETUOqpEt_H$gfC zX%GYj0qK+uMLMNBq*1!NQ5va3w}1%J-5_x2Bi(S|&>hlnn0@@c@4WM$Z!>GnnwkCS zEcRya=h;u}JFe@xU486!M$%dEO~TfA8xT;8w|!^ zp&T*(2?+)`BPG#T&F*5IsD@4b({al=_C*aAdJkWkfAOhbUWCyL5#<-FE@$SJ!o(T3 zo5{lb<6EMz;w&DDFh4ewr31(Tmq-e#tmE=2>La}aucZJ^rS_HXucQsONpPgZT+8!Z zWRpqlPZ2l^-F-*mxiFAFYtF3DkVS)02>;dj$XcZM*9ia0*Ttn)c>8(n zzYhH~I zlOlPV&)L`8i-bapI$St`Hf~1(ZOmHC$W_2@)@R%%j9+we2`-nPQ~7N{+4=S4fI_ql zMJbx%%t0XKsIxW?*~BV;YK`d+MRjxn^=Km*7ZUpJ#nYjBRYObz8yipIBSQmhqyQ)_|mj?NP>ZPWE=Zwb_iDU zp;U;^+3z;=%Sc)HLennN)`OydI979y-d!_K0%H!dM8V8Q{bu5(F!W2YW%lA!9Z?^g zLopRAky2yl_2cYb3ANoO!nN_4i? zn$iA{p7`eI*9cZKHT$2CW`GiqEKn&JY#b1ouh^s}`QSZ1zR^#&f437gOUj-E!*Y^* zX$2R2o3h?>4;Ydh*nk=kN$Y*iM)jB^0k~|dfn;EP?dD~BU0Y?{l#)~YVghh&0Lqfn zND1(vn?H9*fFZiq1&H|sN0riXxMMb6eg;w(r56rDifW73!VKF9`}DmzTgQh5t&1I4 zqx97o>G$v*=g$aA#Ck;dQU}rf5KZ%V01dTeaJi4_-?T!!K?>qAA(2hfnuWP7&I5Pv ziCmYW5WNBTJmvD?g1CQSjIr=>leePwR;3wWEXhSJ%M z7niTGNvf+{Dbxa)5P`dXvx3wDWEg#7;ZQ%(K+15Vh)w1HaPrp~g_SZry?%4F0h!MY zt%bahX)#3sJ^oIy0uWxNrt~-JZL)6dPIF-bvD0fyJrh?N!KP<3{7mfl&$D%GjD|w| zzNqK{H*jG+q>>|p=YOc<2C++F3;gYsR~hdyM~pgwuscJ zKq0vMS?A}VBff`7A11QF#wO_gcA#CJ%vtkh-6s?IHu<&d4gqQp5b(k2s$@q_V!HlT zs6fP$2SubA;(it(Q}dQ-eKw9|Ak6xzc(>#7?cv^9Y-n(3MsUwvOc^=VSri%VsO>|E$;O9jUcEmz~lms9_&~D zj-388z5u7~Zvz0SpucxTknR2%T0lhT|Hqq{SnWLen}m?@T{GT~6Z$na8}-t#RdIL9 zRUswGEDU=NYB1SZQSL-al(M5G1 z2k_2nscvtNK9O^z2_&1F`&{MN&iW*{b9k<90ow>SDuu3T6bPK6(rCKu@{;VYytqGkRw-^SVD7MAc` z%pcmWU`R_+;n0AlkwqlzW-_ttc84D~%+719qqa~X;gMp94`Te|FFJmXX&gJVIOd5b znyI3U>}r{8#F7(^!Yy{3zagn3MlW7w+JSL2KFKy8WZZR#uD;lW3DIU7>T9b)tOm}1 zR)hIHmD5x4qhdBg>GtD*a$Xs@fXu0}B`~MZlKyF0HLXfExHQ^Le7bA4RV!^?!EFCv!mvnruE9Yg4wurkW!D0aK%--Sv~D%`Ka-58N#c{<(&v@5jQ-O_-6 zpTYXSlra|%OWH4h=Y~~OY(LCrysh!E*8%toPMnMuYsaT!m1}=eFp23`ATo-8+b%J{Q|=xa zi2;c3W|&zJiPz0N?)#ndiCn&o$n-<+D8v)@46$N zG!0$h=qpRSV|t5w8QiP@s(r;{MGR@baq0>h@bNCb@+AAmmrRG`B>>+I;C!Bx_Ho)8 zJt{XUWKv>I8m^%sYwAtqGD{WqV7G!;E>hkAj0$pLcUC}#WUcLT87SwZpDT-80L}R_ zK0c0#gF{Cz)etRps@~#$pwr^cCS5>KFy;w+{O0}pCnP9_E=_gBglofB^{?(By`%Jw zsFfjCI@%0n6cO6v+&4cjP46E1)cX!uSK6+rjir4@khWgpa>T9g)f+wGiqaNeR*Zux z*Ius345kK5@QP;K&$}1Q{orbytfhKvR3>%6$1zqb9TDxAMH)Bez~J&lh)|3#yij+EKL>*VLk^A{Fix2xo^~=2-UWu2O zxcQU@l6uCGAkmsf!2`ZFUFQ4DUfR9GQzfdI5<1~!>a$N){;Q}mk10BT*pOVR}8GipADn${PA1hE;Y})P{joNCxneHUUjP6;*vt``n*W`ZibfQ=Z zX0UJUHQ60fQ&-o!yiD!m;{yc3ePJ-4wrts|>Voqk(Tmy=KA_00!t7~h{1uZJahfGb2 z>2yZR=%CN^Zw~a!Z@~BR0wl*@0#NP0cpq_lY(_owL%~~$<`z||s45q|jU9S!mG)0oe%wr!`b%Wo1uK&*K5c97jMdUE~0EbgM^+YwRc4UolhR%6Mot zEli|K;iqqXa^A~g%D9?>q;_Sag?XFM<;g|D7{^V{>2e3oq8g%Fu(s;X1TFbn`ahiu z^T&x>A%Ff!j6g+APTRo6S#C>G00V-ONzXkPn4*2rb#HWTH3FADvVGTvS1U-;J-IRS z=`|w&=Hq0rm+#!)i_&%#h_^w)3Y8ID+sg>iJM7I2CeW5ALm54S6{BqK9}Np67r4$l z#nKyAykIp7i9H+W3__7pP=KA!7&8h9rK^bF{{j8xplwppzLWa)h5{g=Nkx%b0G~3i zrxy=hEyC)I#oTU+WO|t>xA_*HC&udJbF&2gtrjiC3q0R$$r;+GqptC0Fu+0~upv7W z6BTdxc9_G0va4(cq-AmyD$vDSfQYMUF&fEab;a$U%5$ zSW`>~F2?(|5`h{m=66-g+*8pC7Mq(4U@f&f7*st^+fm%t4aVwPqB!0_vWx*fS2-ET zGJ|c4U($}Wdrh>1kl&i6UU>iI=aUbHV$V^X`3p>K778h(&E|<)_a=s?a%1CZ-Wl}>bDUAy!e&vC44|p-tiogRT z%ajH#hVMtmr2t37e}d%SqO$)BZbsZ0F+pi!Dxr+2d}iSgpaVLf4Or-=nuASR)vj2k zy#`UBT30Mu(_X-3>G{F?>LH;}0l2CP^S?Tw|Bt&p!U|;1X-{7%%(llQe$t93q;c3$ zTjyFGs}*eby8%pLf_Pzsvt|x6{c|Ka43FMj@`h?O*A@=N%VcuB2r?%18<+slHqC&z zFe_pdWJ$-_4QWlM6`5NnwepM)nMTZMKmHQBTlObQIfdvpQvuf@+;8*MV=Eq}!wsnt zW=%H3ND=gWzB2H^wRe*J_tJaX(`|(B*fesaKzeq$G35E$)*R6+M_->;VcDL+r-m!F zu7FsHMIg;TiRdE&By{F;=aCBX3ISXuUwU$I+JJX0g)(xmYC*yrNYxOgq?G(2Y*D#B0`f z`_-F3Q&|YY;nomh`ReA#0#jv zIRqH%Du7kyyt++G>m}1Ao@0*g4-^Azzu9GpBxdRc*p6(5pztZ5uU)NV{1A&GI~6`Q zY)f!{g)Wgb!+OSjYW2cu@0jg=mdeuGag|E%UVFGKh8q6K>hCZETb`J*z(+i3p8J^zuEyL@&|A!5ZL9a#ImPt-UE3YeEsIV;h9zuuj-%m)Zn1<`b~ z>(!%I$)`8*$4N;`b6bs4k#ZPC$HY9gv9Xz*oqgY6Z}^mdn$46zq1nxH`Ich%6JG{b zVF;EZ(xP6hrI|t?k>l&+V+ZN6!(%2mr{;%KFp7 zIF<2-#f z0xJ^Ivtc>Ow;CUA7geK|at4V~oou+Hzp_J4K9Pc{4jmx9_g#OoTB4$MpyMXb&%CvQ zekqU(c<_@UCn|_C#O+1~Xl)4&9pG_!^$_!YOX)iklu?Fx&bYK6O|bi}iNgb4PuoV-jF1#E4URI^};lRiqt6R}|#kLxqNqFZdO;-+=u65a5X3oe#nz^I8QI3~}Rjkj}a4r`Yf9h(_ z+oivmQqHdZp`Q3TMt`i_`2?`nvpajS)peI3@qRqboE{F$Y>#I=YI!BV=`d}d&!xuYstBC>8=)&7j{7be7lKjyH_LJo51xo+CJlBuoq=oz7w6(8y? zHZmIv_D)h-fpnIyREk>js#v%U4=NAe-f2IDGp4rNGh(Jy1|LMkO8WVSgAzB#s{|y` zF3q5qF>~AQ3j^}vU9GJ3`bOqhrArvqevV3*IdWNc9zeF9a&kTH=)$E+$;`miooH7p z&S6|@VhedxVJ`Ddago7=^9X++pbEO7-3XYRz`imfPEi<=rvt_(CTe`|0fT+6 zyd}r(a7zb})!G_P%k;1xEbWlHbXnvw>*I9apQW{e09W^Pbxjg)5?%>lV+n z?@xA8&0~wjvqZ;T{TMU-OGj4Hr_rfznsPRe&CH2U+=HSYQ>#3);*>$-@t$Dly(|+3M9u@;3C;WihAcK{E?})}DJ%!qs}V1EH$%OPk>sT??S&H4a~= zL3E7_MUWl62C*hKG{OZ3yNFc(_<8UnX-8ZB$Qs!GZoJwQZTBpbYSmeOv;%#C zurW1-(|7wR6|QAIJNfrSbi_;;+QL*hH~&g$vL|VvDe1d^h3xrR7S z1IELU3>L(+rCF4_wuo1Oh<||4(!VvPzAc4P z-Tl%(+n$r4Ayu#`z^FQ2FqMCIn+sT9^I65>FC|e8%(N(*5viHu0S2fpzFV{Yu)q zJR8qC%S|#vL~~}DA-KQ29R9I^x^KFt%lMhj{ki3!V=#2a*yQxbG^-~G^f|_aWtHcS zMgpjz@FZ6bccn26ExTBEY%Y#oyj>-$QykO(Nc`pHRlMCZQ7#$9wUOm_C5;<6%<~d= zharvr4=6aj@PWyhh$ilb6{O#o$b5;U1Yfr3>ThqYm zDwRjyiR!K+S8ub;uB|FmLGN&nn%6gDJp?z!ldOj)A?Rwi)86ko2FBcP#o8=Fo%BBT z2@cGrcH*~NT8=E>t0jXpH>+=;ScBA+#T%h(PtHxYHvE@_Qau!A_#>jC%mAlmID;Qw zUtfRNk_VuWvg%f&@;5B3T#GbQZ(=_bID(rEa%gn+1;5aHCDwVcM{L`AP%JR!|X=y zl>Au6H%yD7+1;M-M|V}(2N5ybG^qs8$NpK?CyFlhG=Y(UT^*t$IiuFa(N;{+t7NC} zp72E=L$yf+2+jh5y@=@OZ$Oa1pvgH5D9oYT%t}ytcFc2DRPFRpWu8sk$t zDkWEgH0U1BsiXRmwo?#~x~4c-2Jg|2OBW4+=8U!!WVKoH*3g4FqaMCR%r3mw#(A(b zdfZ#M_s^1I9Z@slqXXGabHy%=YTiQIE>}-7@th6Nv0nylwnnAsAjAo&7?Xl4@@o`i z^`Ym5gc?~2U^J2e@0RLA$P*HhFf7hzLXw{ISuOBHQ8%NqHpdb)BL=+bR^fddXr$Kq|zKFfSIfYWanz{4qW1sE)OlLL6 zSHXz4f^jmM*-yEb<#1oL5WfLwOq@{X7vm%L!-f?Ozim)4X*{>j%K9~u;gR+*lgMEz z(vd*$*w6Z|6+b4&VKf2wj6gEVX&|dK{CAS9faiCnyGa>HKqu{Zv9Al5m8P21uAE2W za}%dod7&yUokr=`+G2#qb)Zx8*vNhpZd;v3Ue(ct7zP1@0|SCUQVE{)nM33Z-=Kq>V-| z2}TJu(Es@MHIqjAWyh>Ri-L?WC1r-e_7|%*08^SO9w7Gm<76e^3utj1jMHD>(FFUv z3EW`V5o-ACPN$YC*s+K5m^1k<(USXQD52LAt*u#_St&s-47Qw~_53D{4 z@L5Oik$SA-W_>`!O0&$d7xZmk8z!#lzl8?*{Cm1F}dMR&d zpTQp<;J`yu$Bwr3E=_pH>PHOq+a}EsYcjZ4i&g!j=S=IHTNq$1OM|fr9nn9dTP9LH znVW+f3a<8AVh~7$4$a@Bac-K|hQGDtvP@F4#cqvbfxE;1+_^p(b^wh{ZEcM8T-6n&pDlT?%rugO zwo1Z+hPXGMJsDsGfV*E@dyUt}j&Boszuoy0cXVC=&J;BYxZ#T_ciQ)hu2%{vrsvgd zYdI{6cfVV3GxWe`UeFNt`ys#PH4ZPizabExtFBg4rRt}{EVOFx|7H}D1ydU&O8M}) zQnkyZHcgBG|I1P^RavrcDtLKgo>E(Gy1I4i<+P=H(vlcW9c@IqyLp+Y>k^C!<)WH_<; z?k*iI+Gvir9oTjC(E=TS?j!cXB|bav4VaY$T)UEIl@$H1*kmfjAsws5svx?$g$Za$h8=}=+fd`m)069R>-wJ=fxpI= zhvzW*G~bc84kT7l7R*)p@feOgeCX-!zY`;&)%}|kj(^nk-bW;=gW_#rkLK`>exkP~ z^Vw#{mgBL=SJKgoXL!5;1tjH2qcNBtZB34*kN14Um9j`<93Oq3&qlX3^C9k(a=#;2 zuABbJJ&kO#2CdIwn)t!9f%~RPD|)Ur=WU%5)gq~U)5ZPwP2Ab!d@mEa1ou$FoC+(6 zm!Ee3QtHq?CmJ)}C>=?PcY4w$(G=n3UJB#c>fG@%ZK)g|bogGq;JHsNf3t@}L9-wT z+xPWrGJK}T%g5uT|FTi0N^~)Ybi&ZyrdQIm8ml;;pAnsx*bRw2A=NiNq$XoRVErbt zmL*jIG}3sRJ4sJkMDrFQ*NMdLY`XwSz1LSgxq<34LZn^2gujxAb_;^E2*9Q!+pmw1 z?(gguUbFp)EztZlh7Fs1Om!mC-xYWf?S?+iJtG9&-w!;wLwgQ;9CQtlO^EbVt4_t4 zT3#7gJ1jii-Xr#M{MRJwuF`DtvRbE#&FpB0j$`>7RA+x1geSQi7k@zE$Uw7-x(hC|Ou+^+6;QiQdH(fs?q_4AV(1mH<$=j+Ak zD*o6CB$`MizGkOOzcE3@%?`rNSZj_CkGXP9py?Pcq+s2`fO<(>4<6|{MD1e$V z{%3nENcZeg-5c8=pbBSpjwqYPuUQ0s@5^L^7E+ zuC&fLG{KQ|Y}}&Xtb4lriJ^3>qG~ZCqCYxJz@`?DQE4}4ggrMuUSvfFWW3{oeznAz zzEac4GnQnPM|9|L0`losQ)-e#@(l^_Z$LN=k810v#u+vR+IdK! zi~(?NTkHwWu=n`TL1P94UFqKaHNY#X4g2wgU?80u&_zy&sV&{H)vJx-UM_UxcyK-B zcl077!te`jT9KIMKkxi%Zw|>c!X@A9JheG+8Y#4l&S2nKxe(Q2`x%EUt0$g{Jmfxh z`m?N|Ld+3u%BAGMc8>qUTKZh=@IfBo&X}!Edvc%K9xNU5i*tMe&Tv;O%RF<|)d13l z^Rd$=pdccXbF<{tM8(C~-wa6NLG1|$YX>QKfIIhxdYW& zz&B3GAvc^KwX6uOE==_rkuRvhtQRtdtc7$2J}} z!{L|NkzovpsZ(QLL=)3bq`dv)(~0C1WsCYc!&>!8{wFdOnCV6VJ=#z%p%i1;o?+NS zlx~dG(+pM7=B?b8M0x_N^Z6Vp-8?9t5Up&NHAzE_5R2i@x*W|^4?*-W*%kZG^ynQp5txsD^7VJAnZ?CRE;^woSC<5AGM`20XBst^wnS`m7`e_r>XpRhp}xP+SVQeNuDE zIVN2E`@SJsDRDwU4MrP?FV;@skdc{bz-iQeyAat*NK%B=EV+JyK$$s50cgjMb;ppi z`o%WU@CD)^0(^TBmRI+jUsP_OXSRLC=sxeJg^P_JX39mLfy;6mw%GRAS$j=9AHB1r z@u(rF$s$q~JNN1>7OOzL`CWV_-z{_-#70q}Xfs#qlC^rV(NN~`{dMNo2qpWb5Q3p# zsX3~JcB}%B#Ta-6fN?`0^nXxoTMTkuWSi8!eqXR4v5B#KBUxxIRuf`7s@yI}O#trg zF`sW+A`S$S?+7ufwcaQ;gS7DeEX1r{Z@$aU9Xgi4*Q0(2wb3`N;NUtP3T6tuaWBeR zu%i^;3;N`W%C*xOX1FhA`AFpZy36OKTkZ>f88(ZX%dv(7YX;YG1=k0m8_Ub=Ssg-! zMpbT%0AxbCZti(SLB&64_=^hWRA&vxzfzIUjtF{^nc{rV#9QeAa)}^p57Uq{PL#>M zF-7Rts;pU`*oRxWR_%~_f8O%s{^>A%u4%g%e&~UIcB-g8=OY8L&S0;-qti)h6ue7# zwX>A(u#IV)rQ&Z3GaP^h+BG$myfKtg1IU{B{*aJ-xdr$elBnS^H;Dk3pjesZ;VvV0 z=t<{S74(z2=mwk9CM={&J<-(H`L8{ONuhHQ$o_5H6EiVvH#B*c(*4MI8tZ`;6Fi#&}D`x)MLbb|z)bR~b+jXv=c%uO|ptFe2*RX!I(T6vx)UE&n|6xvs- z>sOK_bF_k>SDaUnrQY{iDW-9w0TH8w#6+8gdNu%#F_Q6FN|HKw1i-JBTeOV#eQqfO z`CwvVng9?jAh-St_+s}PzU{{H?zLS=E5@eH=`PzSQWXa0`? zMZGH!ml&QpVbJ6oF*-5`Jh#%Ly-@w==Nv9ouRCHW#O*4;fW`TQla0zuiIy&wam7H`0DmsIUMkRRQ9i zsEJGkrJ#ZWx`+Ft0Gqk$!mv^{a_$NMPVn+2Dv@iT0H zoGzmPn5bpCHRu5W0SLqf@Y1gVSQD#3Nx1AZ@g3Vs28PcF(n713%lNo`fPZ%QdfiUftYO+b;^*EOJ zyCmQh{l_+2w+$`_q=y0C(P*pJ*)~u_NKBKFHo*lOe!V{3`7otz91j9XuXcw~h$#TZ!2Il=0mzEeS7U{nzQ4b#(g7N0VKFfyG4`St z7Z<3gsGM%Q8aUdFrlO;nA_~646q%8t12=x9HH$^9TP~9&ptG-xXxf9<9kNYVWCu6= zy~}x(g+l}Yksguiex1#{F}%^CNKUn1vsCnbf~c`kEGp4-{gGHr?i3j^c6rM1)*TfR(?QH5s6o+2?cEP@bD=$ng`#tg99ai zZWSLN?|Lv#A}lP7$VOeAz}NsrFmM2v$_HQfJ<33U2TwpsS_Jk&nDq}0E&&y^H-gpJ4fk=77qF0p#A)=h(Ct>7oRbmC+$b{-A-5s)2MSK6Wm$^8~8 zj`SO(6U!?5tQN!{{@L$RM{;HOLDd z#O2Of?rwd{t8OJ$oe68P;z&s5&^Sgo33F#~HDn1et#gqU1yh0;(e5nK$DSmnashtech https://sonarcloud.io b47aeba29df2889126c736ee7012a5a490edc34a - ${sonarConfig} + ${sonarConfig} target/coverage-reports/jacoco.exec **/*config*/**, diff --git a/order-service/src/main/java/com.nashtech.order/OrderApplication.java b/order-service/src/main/java/com/nashtech/order/OrderApplication.java similarity index 88% rename from order-service/src/main/java/com.nashtech.order/OrderApplication.java rename to order-service/src/main/java/com/nashtech/order/OrderApplication.java index 4d2fd339..91ba4b23 100644 --- a/order-service/src/main/java/com.nashtech.order/OrderApplication.java +++ b/order-service/src/main/java/com/nashtech/order/OrderApplication.java @@ -1,7 +1,7 @@ package com.nashtech.order; -import com.nashtech.order.commands.CreateOrderCommandInterceptor; -import com.nashtech.order.exception.handler.OrderServiceEventsErrorHandler; +import com.nashtech.order.commands.handler.CreateOrderCommandInterceptor; +import com.nashtech.order.exception.OrderServiceEventsErrorHandler; import org.axonframework.commandhandling.CommandBus; import org.axonframework.config.EventProcessingConfigurer; import org.springframework.beans.factory.annotation.Autowired; diff --git a/order-service/src/main/java/com.nashtech.order/aggregate/OrderAggregate.java b/order-service/src/main/java/com/nashtech/order/aggregate/OrderAggregate.java similarity index 94% rename from order-service/src/main/java/com.nashtech.order/aggregate/OrderAggregate.java rename to order-service/src/main/java/com/nashtech/order/aggregate/OrderAggregate.java index 6a91516a..3ec07c47 100644 --- a/order-service/src/main/java/com.nashtech.order/aggregate/OrderAggregate.java +++ b/order-service/src/main/java/com/nashtech/order/aggregate/OrderAggregate.java @@ -20,13 +20,12 @@ public class OrderAggregate { @AggregateIdentifier private String orderId; - private String productId; - private String userId; - private String paymentId; - private String shipmentId; - private OrderStatus orderStatus; - - private String reasonToRejectedOrder; + String productId; + String userId; + String paymentId; + String shipmentId; + OrderStatus orderStatus; + String reasonToRejectedOrder; public OrderAggregate() { } diff --git a/order-service/src/main/java/com.nashtech.order/commands/ApproveOrderCommand.java b/order-service/src/main/java/com/nashtech/order/commands/ApproveOrderCommand.java similarity index 92% rename from order-service/src/main/java/com.nashtech.order/commands/ApproveOrderCommand.java rename to order-service/src/main/java/com/nashtech/order/commands/ApproveOrderCommand.java index 8fa0fc45..b6ec5180 100644 --- a/order-service/src/main/java/com.nashtech.order/commands/ApproveOrderCommand.java +++ b/order-service/src/main/java/com/nashtech/order/commands/ApproveOrderCommand.java @@ -2,11 +2,11 @@ import com.nashtech.common.utils.OrderStatus; import lombok.Builder; -import lombok.Value; +import lombok.Getter; import org.axonframework.modelling.command.TargetAggregateIdentifier; -@Value @Builder +@Getter public class ApproveOrderCommand { @TargetAggregateIdentifier String orderId; diff --git a/order-service/src/main/java/com.nashtech.order/commands/CreateOrderCommand.java b/order-service/src/main/java/com/nashtech/order/commands/CreateOrderCommand.java similarity index 90% rename from order-service/src/main/java/com.nashtech.order/commands/CreateOrderCommand.java rename to order-service/src/main/java/com/nashtech/order/commands/CreateOrderCommand.java index 2b3e4adf..1707d63a 100644 --- a/order-service/src/main/java/com.nashtech.order/commands/CreateOrderCommand.java +++ b/order-service/src/main/java/com/nashtech/order/commands/CreateOrderCommand.java @@ -1,11 +1,11 @@ package com.nashtech.order.commands; import lombok.Builder; -import lombok.Value; +import lombok.Getter; import org.axonframework.modelling.command.TargetAggregateIdentifier; -@Value @Builder +@Getter public class CreateOrderCommand { @TargetAggregateIdentifier String orderId; diff --git a/order-service/src/main/java/com.nashtech.order/commands/RejectOrderCommand.java b/order-service/src/main/java/com/nashtech/order/commands/RejectOrderCommand.java similarity index 83% rename from order-service/src/main/java/com.nashtech.order/commands/RejectOrderCommand.java rename to order-service/src/main/java/com/nashtech/order/commands/RejectOrderCommand.java index 3d00f1ed..cb2322f4 100644 --- a/order-service/src/main/java/com.nashtech.order/commands/RejectOrderCommand.java +++ b/order-service/src/main/java/com/nashtech/order/commands/RejectOrderCommand.java @@ -2,13 +2,13 @@ import com.nashtech.common.utils.OrderStatus; import lombok.Builder; -import lombok.Value; +import lombok.Getter; import org.axonframework.modelling.command.TargetAggregateIdentifier; import java.util.Date; -@Value @Builder +@Getter public class RejectOrderCommand { @TargetAggregateIdentifier String orderId; @@ -16,8 +16,6 @@ public class RejectOrderCommand { String productId; String paymentId; String shipmentId; - Date timestamp = new Date(); String reasonToFailed; - String errorMessage; OrderStatus orderStatus; } \ No newline at end of file diff --git a/order-service/src/main/java/com.nashtech.order/commands/CreateOrderCommandInterceptor.java b/order-service/src/main/java/com/nashtech/order/commands/handler/CreateOrderCommandInterceptor.java similarity index 94% rename from order-service/src/main/java/com.nashtech.order/commands/CreateOrderCommandInterceptor.java rename to order-service/src/main/java/com/nashtech/order/commands/handler/CreateOrderCommandInterceptor.java index 2632a3df..4cfed918 100644 --- a/order-service/src/main/java/com.nashtech.order/commands/CreateOrderCommandInterceptor.java +++ b/order-service/src/main/java/com/nashtech/order/commands/handler/CreateOrderCommandInterceptor.java @@ -1,5 +1,6 @@ -package com.nashtech.order.commands; +package com.nashtech.order.commands.handler; +import com.nashtech.order.commands.CreateOrderCommand; import com.nashtech.order.repository.OrderLookupRepository; import com.nashtech.order.repository.entity.OrderLookupEntity; import lombok.extern.slf4j.Slf4j; diff --git a/order-service/src/main/java/com.nashtech.order/config/AxonXStreamConfig.java b/order-service/src/main/java/com/nashtech/order/config/AxonXStreamConfig.java similarity index 100% rename from order-service/src/main/java/com.nashtech.order/config/AxonXStreamConfig.java rename to order-service/src/main/java/com/nashtech/order/config/AxonXStreamConfig.java diff --git a/order-service/src/main/java/com.nashtech.order/config/CorsConfig.java b/order-service/src/main/java/com/nashtech/order/config/CorsConfig.java similarity index 100% rename from order-service/src/main/java/com.nashtech.order/config/CorsConfig.java rename to order-service/src/main/java/com/nashtech/order/config/CorsConfig.java diff --git a/order-service/src/main/java/com.nashtech.order/events/OrderApprovedEvent.java b/order-service/src/main/java/com/nashtech/order/events/OrderApprovedEvent.java similarity index 89% rename from order-service/src/main/java/com.nashtech.order/events/OrderApprovedEvent.java rename to order-service/src/main/java/com/nashtech/order/events/OrderApprovedEvent.java index af3ebb66..fdd6cc58 100644 --- a/order-service/src/main/java/com.nashtech.order/events/OrderApprovedEvent.java +++ b/order-service/src/main/java/com/nashtech/order/events/OrderApprovedEvent.java @@ -2,9 +2,9 @@ import com.nashtech.common.utils.OrderStatus; import lombok.Builder; -import lombok.Value; +import lombok.Getter; -@Value +@Getter @Builder public class OrderApprovedEvent { String orderId; diff --git a/order-service/src/main/java/com.nashtech.order/events/OrderCancelledEvent.java b/order-service/src/main/java/com/nashtech/order/events/OrderCancelledEvent.java similarity index 91% rename from order-service/src/main/java/com.nashtech.order/events/OrderCancelledEvent.java rename to order-service/src/main/java/com/nashtech/order/events/OrderCancelledEvent.java index ef9b788a..57cbe6c4 100644 --- a/order-service/src/main/java/com.nashtech.order/events/OrderCancelledEvent.java +++ b/order-service/src/main/java/com/nashtech/order/events/OrderCancelledEvent.java @@ -2,10 +2,10 @@ import com.nashtech.common.utils.OrderStatus; import lombok.Builder; -import lombok.Value; +import lombok.Getter; -@Value @Builder +@Getter public class OrderCancelledEvent { String orderId; String productId; diff --git a/order-service/src/main/java/com.nashtech.order/events/OrderCreatedEvent.java b/order-service/src/main/java/com/nashtech/order/events/OrderCreatedEvent.java similarity index 89% rename from order-service/src/main/java/com.nashtech.order/events/OrderCreatedEvent.java rename to order-service/src/main/java/com/nashtech/order/events/OrderCreatedEvent.java index 9cf671f1..e8bbb80e 100644 --- a/order-service/src/main/java/com.nashtech.order/events/OrderCreatedEvent.java +++ b/order-service/src/main/java/com/nashtech/order/events/OrderCreatedEvent.java @@ -2,9 +2,9 @@ import com.nashtech.common.utils.OrderStatus; import lombok.Builder; -import lombok.Value; +import lombok.Getter; -@Value +@Getter @Builder public class OrderCreatedEvent { String orderId; diff --git a/order-service/src/main/java/com.nashtech.order/exception/CompensateOrder.java b/order-service/src/main/java/com/nashtech/order/exception/CompensateOrder.java similarity index 83% rename from order-service/src/main/java/com.nashtech.order/exception/CompensateOrder.java rename to order-service/src/main/java/com/nashtech/order/exception/CompensateOrder.java index fc2c5d97..174da09c 100644 --- a/order-service/src/main/java/com.nashtech.order/exception/CompensateOrder.java +++ b/order-service/src/main/java/com/nashtech/order/exception/CompensateOrder.java @@ -1,10 +1,12 @@ package com.nashtech.order.exception; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; -@Data @NoArgsConstructor +@Setter +@Getter public class CompensateOrder { private String orderId; private String userId; diff --git a/order-service/src/main/java/com.nashtech.order/exception/ErrorMessage.java b/order-service/src/main/java/com/nashtech/order/exception/ErrorMessage.java similarity index 69% rename from order-service/src/main/java/com.nashtech.order/exception/ErrorMessage.java rename to order-service/src/main/java/com/nashtech/order/exception/ErrorMessage.java index 824cbbd2..27467273 100644 --- a/order-service/src/main/java/com.nashtech.order/exception/ErrorMessage.java +++ b/order-service/src/main/java/com/nashtech/order/exception/ErrorMessage.java @@ -1,14 +1,14 @@ package com.nashtech.order.exception; import lombok.AllArgsConstructor; -import lombok.Data; +import lombok.Getter; import java.util.Date; -@Data @AllArgsConstructor +@Getter public class ErrorMessage { - private final Date timestamp; - private final String message; + private Date timestamp; + private String message; } \ No newline at end of file diff --git a/order-service/src/main/java/com.nashtech.order/exception/handler/OrderServiceErrorHandler.java b/order-service/src/main/java/com/nashtech/order/exception/OrderServiceErrorHandler.java similarity index 96% rename from order-service/src/main/java/com.nashtech.order/exception/handler/OrderServiceErrorHandler.java rename to order-service/src/main/java/com/nashtech/order/exception/OrderServiceErrorHandler.java index fa82cc00..5be769f6 100644 --- a/order-service/src/main/java/com.nashtech.order/exception/handler/OrderServiceErrorHandler.java +++ b/order-service/src/main/java/com/nashtech/order/exception/OrderServiceErrorHandler.java @@ -1,4 +1,4 @@ -package com.nashtech.order.exception.handler; +package com.nashtech.order.exception; import com.nashtech.order.exception.ErrorMessage; import org.springframework.http.HttpHeaders; diff --git a/order-service/src/main/java/com.nashtech.order/exception/handler/OrderServiceEventsErrorHandler.java b/order-service/src/main/java/com/nashtech/order/exception/OrderServiceEventsErrorHandler.java similarity index 93% rename from order-service/src/main/java/com.nashtech.order/exception/handler/OrderServiceEventsErrorHandler.java rename to order-service/src/main/java/com/nashtech/order/exception/OrderServiceEventsErrorHandler.java index 5d27bd70..277b1650 100644 --- a/order-service/src/main/java/com.nashtech.order/exception/handler/OrderServiceEventsErrorHandler.java +++ b/order-service/src/main/java/com/nashtech/order/exception/OrderServiceEventsErrorHandler.java @@ -1,4 +1,4 @@ -package com.nashtech.order.exception.handler; +package com.nashtech.order.exception; import lombok.extern.slf4j.Slf4j; import org.axonframework.eventhandling.EventMessage; diff --git a/order-service/src/main/java/com.nashtech.order/handler/OrderEventsHandler.java b/order-service/src/main/java/com/nashtech/order/handler/OrderEventsHandler.java similarity index 98% rename from order-service/src/main/java/com.nashtech.order/handler/OrderEventsHandler.java rename to order-service/src/main/java/com/nashtech/order/handler/OrderEventsHandler.java index 11d79e7d..1a59c9dc 100644 --- a/order-service/src/main/java/com.nashtech.order/handler/OrderEventsHandler.java +++ b/order-service/src/main/java/com/nashtech/order/handler/OrderEventsHandler.java @@ -37,6 +37,7 @@ public void on(OrderCreatedEvent event) { FailedOrderEntity failedOrder = new FailedOrderEntity(); failedOrder.setOrderId(event.getOrderId()); + failedOrder.setTimestamp(new Date()); failedOrderRepository.save(failedOrder); } diff --git a/order-service/src/main/java/com.nashtech.order/handler/OrderLookupEventsHandler.java b/order-service/src/main/java/com/nashtech/order/handler/OrderLookupEventsHandler.java similarity index 100% rename from order-service/src/main/java/com.nashtech.order/handler/OrderLookupEventsHandler.java rename to order-service/src/main/java/com/nashtech/order/handler/OrderLookupEventsHandler.java diff --git a/order-service/src/main/java/com.nashtech.order/query/FindOrderQuery.java b/order-service/src/main/java/com/nashtech/order/query/FindOrderQuery.java similarity index 88% rename from order-service/src/main/java/com.nashtech.order/query/FindOrderQuery.java rename to order-service/src/main/java/com/nashtech/order/query/FindOrderQuery.java index 65210fc0..6d0fa651 100644 --- a/order-service/src/main/java/com.nashtech.order/query/FindOrderQuery.java +++ b/order-service/src/main/java/com/nashtech/order/query/FindOrderQuery.java @@ -1,12 +1,10 @@ package com.nashtech.order.query; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor -@Data public class FindOrderQuery { String orderId; } diff --git a/order-service/src/main/java/com.nashtech.order/query/FindOrdersByUserQuery.java b/order-service/src/main/java/com/nashtech/order/query/FindOrdersByUserQuery.java similarity index 65% rename from order-service/src/main/java/com.nashtech.order/query/FindOrdersByUserQuery.java rename to order-service/src/main/java/com/nashtech/order/query/FindOrdersByUserQuery.java index 7e11aa26..c52513d0 100644 --- a/order-service/src/main/java/com.nashtech.order/query/FindOrdersByUserQuery.java +++ b/order-service/src/main/java/com/nashtech/order/query/FindOrdersByUserQuery.java @@ -1,12 +1,10 @@ package com.nashtech.order.query; import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.Getter; @AllArgsConstructor -@NoArgsConstructor -@Data +@Getter public class FindOrdersByUserQuery { String userId; } \ No newline at end of file diff --git a/order-service/src/main/java/com.nashtech.order/query/OrderQueriesHandler.java b/order-service/src/main/java/com/nashtech/order/query/handler/OrderQueriesHandler.java similarity index 87% rename from order-service/src/main/java/com.nashtech.order/query/OrderQueriesHandler.java rename to order-service/src/main/java/com/nashtech/order/query/handler/OrderQueriesHandler.java index dd7c0703..931b20e7 100644 --- a/order-service/src/main/java/com.nashtech.order/query/OrderQueriesHandler.java +++ b/order-service/src/main/java/com/nashtech/order/query/handler/OrderQueriesHandler.java @@ -1,9 +1,11 @@ -package com.nashtech.order.query; +package com.nashtech.order.query.handler; +import com.nashtech.order.query.FindOrdersByUserQuery; import com.nashtech.order.repository.OrderRepository; import com.nashtech.order.repository.entity.OrderEntity; import org.axonframework.queryhandling.QueryHandler; import org.springframework.stereotype.Component; + import java.util.List; @Component diff --git a/order-service/src/main/java/com.nashtech.order/repository/FailedOrderRepository.java b/order-service/src/main/java/com/nashtech/order/repository/FailedOrderRepository.java similarity index 100% rename from order-service/src/main/java/com.nashtech.order/repository/FailedOrderRepository.java rename to order-service/src/main/java/com/nashtech/order/repository/FailedOrderRepository.java diff --git a/order-service/src/main/java/com.nashtech.order/repository/OrderLookupRepository.java b/order-service/src/main/java/com/nashtech/order/repository/OrderLookupRepository.java similarity index 100% rename from order-service/src/main/java/com.nashtech.order/repository/OrderLookupRepository.java rename to order-service/src/main/java/com/nashtech/order/repository/OrderLookupRepository.java diff --git a/order-service/src/main/java/com.nashtech.order/repository/OrderRepository.java b/order-service/src/main/java/com/nashtech/order/repository/OrderRepository.java similarity index 100% rename from order-service/src/main/java/com.nashtech.order/repository/OrderRepository.java rename to order-service/src/main/java/com/nashtech/order/repository/OrderRepository.java diff --git a/order-service/src/main/java/com.nashtech.order/repository/entity/FailedOrderEntity.java b/order-service/src/main/java/com/nashtech/order/repository/entity/FailedOrderEntity.java similarity index 88% rename from order-service/src/main/java/com.nashtech.order/repository/entity/FailedOrderEntity.java rename to order-service/src/main/java/com/nashtech/order/repository/entity/FailedOrderEntity.java index aa6e9717..a6e91939 100644 --- a/order-service/src/main/java/com.nashtech.order/repository/entity/FailedOrderEntity.java +++ b/order-service/src/main/java/com/nashtech/order/repository/entity/FailedOrderEntity.java @@ -3,12 +3,12 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.NoArgsConstructor; +import lombok.Setter; import java.util.Date; -@Data +@Setter @NoArgsConstructor @AllArgsConstructor @Entity(name = "failed_orders") @@ -19,7 +19,7 @@ public class FailedOrderEntity { private String productId; private String paymentId; private String shipmentId; - private Date timestamp = new Date(); + private Date timestamp; private String reasonToFailed; private String orderStatus; } diff --git a/order-service/src/main/java/com.nashtech.order/repository/entity/OrderEntity.java b/order-service/src/main/java/com/nashtech/order/repository/entity/OrderEntity.java similarity index 92% rename from order-service/src/main/java/com.nashtech.order/repository/entity/OrderEntity.java rename to order-service/src/main/java/com/nashtech/order/repository/entity/OrderEntity.java index 35f98135..22e399bf 100644 --- a/order-service/src/main/java/com.nashtech.order/repository/entity/OrderEntity.java +++ b/order-service/src/main/java/com/nashtech/order/repository/entity/OrderEntity.java @@ -20,6 +20,6 @@ public class OrderEntity { private String productId; private String paymentId; private String shipmentId; - private Date timestamp = new Date(); + private Date timestamp; private String orderStatus; } \ No newline at end of file diff --git a/order-service/src/main/java/com.nashtech.order/repository/entity/OrderLookupEntity.java b/order-service/src/main/java/com/nashtech/order/repository/entity/OrderLookupEntity.java similarity index 93% rename from order-service/src/main/java/com.nashtech.order/repository/entity/OrderLookupEntity.java rename to order-service/src/main/java/com/nashtech/order/repository/entity/OrderLookupEntity.java index 65b725b1..4a3905c5 100644 --- a/order-service/src/main/java/com.nashtech.order/repository/entity/OrderLookupEntity.java +++ b/order-service/src/main/java/com/nashtech/order/repository/entity/OrderLookupEntity.java @@ -3,13 +3,11 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import lombok.AllArgsConstructor; -import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; -@Data @NoArgsConstructor @AllArgsConstructor @Entity diff --git a/order-service/src/main/java/com.nashtech.order/restapi/OrdersCommandController.java b/order-service/src/main/java/com/nashtech/order/restapi/OrdersCommandController.java similarity index 87% rename from order-service/src/main/java/com.nashtech.order/restapi/OrdersCommandController.java rename to order-service/src/main/java/com/nashtech/order/restapi/OrdersCommandController.java index f5a6af09..ba8afc02 100644 --- a/order-service/src/main/java/com.nashtech.order/restapi/OrdersCommandController.java +++ b/order-service/src/main/java/com/nashtech/order/restapi/OrdersCommandController.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; + import javax.validation.Valid; import java.util.List; import java.util.UUID; @@ -46,13 +47,6 @@ public OrderSummary createOrder(@Valid @RequestBody OrderCreateRequest orderRequ .quantity(orderRequest.getQuantity()).orderId(orderId) .build(); -/* try (SubscriptionQueryResult queryResult = queryGateway.subscriptionQuery( - new FindOrderQuery(orderId), ResponseTypes.instanceOf(OrderSummary.class), - ResponseTypes.instanceOf(OrderSummary.class))) { - commandGateway.send(createOrderCommand); - return queryResult.updates().blockFirst(); - }*/ - commandGateway.send(createOrderCommand); return OrderSummary.builder() .orderId(orderId) diff --git a/order-service/src/main/java/com.nashtech.order/restapi/request/OrderCreateRequest.java b/order-service/src/main/java/com/nashtech/order/restapi/request/OrderCreateRequest.java similarity index 95% rename from order-service/src/main/java/com.nashtech.order/restapi/request/OrderCreateRequest.java rename to order-service/src/main/java/com/nashtech/order/restapi/request/OrderCreateRequest.java index 3df1c022..e263734b 100644 --- a/order-service/src/main/java/com.nashtech.order/restapi/request/OrderCreateRequest.java +++ b/order-service/src/main/java/com/nashtech/order/restapi/request/OrderCreateRequest.java @@ -2,13 +2,13 @@ import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; -@Data +@Getter @Builder @AllArgsConstructor @NoArgsConstructor diff --git a/order-service/src/main/java/com.nashtech.order/restapi/response/OrderSummary.java b/order-service/src/main/java/com/nashtech/order/restapi/response/OrderSummary.java similarity index 59% rename from order-service/src/main/java/com.nashtech.order/restapi/response/OrderSummary.java rename to order-service/src/main/java/com/nashtech/order/restapi/response/OrderSummary.java index 2c78a6d4..035cfd4f 100644 --- a/order-service/src/main/java/com.nashtech.order/restapi/response/OrderSummary.java +++ b/order-service/src/main/java/com/nashtech/order/restapi/response/OrderSummary.java @@ -1,10 +1,14 @@ package com.nashtech.order.restapi.response; +import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; -@Data @Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter public class OrderSummary { private String orderId; private String orderStatus; diff --git a/order-service/src/main/java/com.nashtech.order/saga/OrderSaga.java b/order-service/src/main/java/com/nashtech/order/saga/OrderSaga.java similarity index 90% rename from order-service/src/main/java/com.nashtech.order/saga/OrderSaga.java rename to order-service/src/main/java/com/nashtech/order/saga/OrderSaga.java index 63e55173..9daa8a2a 100644 --- a/order-service/src/main/java/com.nashtech.order/saga/OrderSaga.java +++ b/order-service/src/main/java/com/nashtech/order/saga/OrderSaga.java @@ -1,7 +1,16 @@ package com.nashtech.order.saga; -import com.nashtech.common.command.*; -import com.nashtech.common.event.*; +import com.nashtech.common.command.CancelPaymentCommand; +import com.nashtech.common.command.CancelProductReserveCommand; +import com.nashtech.common.command.CreateShipmentCommand; +import com.nashtech.common.command.ProcessPaymentCommand; +import com.nashtech.common.command.ReserveProductCommand; +import com.nashtech.common.event.OrderShippedEvent; +import com.nashtech.common.event.PaymentApprovedEvent; +import com.nashtech.common.event.PaymentCancelledEvent; +import com.nashtech.common.event.ProductReserveFailedEvent; +import com.nashtech.common.event.ProductReservedEvent; +import com.nashtech.common.event.ShipmentCancelledEvent; import com.nashtech.common.utils.OderFailure; import com.nashtech.common.utils.OrderStatus; import com.nashtech.order.commands.ApproveOrderCommand; @@ -18,7 +27,6 @@ import org.axonframework.modelling.saga.EndSaga; import org.axonframework.modelling.saga.SagaEventHandler; import org.axonframework.modelling.saga.StartSaga; -import org.axonframework.queryhandling.QueryGateway; import org.axonframework.queryhandling.QueryUpdateEmitter; import org.axonframework.spring.stereotype.Saga; import org.springframework.beans.factory.annotation.Autowired; @@ -30,18 +38,19 @@ @Slf4j public class OrderSaga { - @Autowired - private transient CommandGateway commandGateway; + private final CommandGateway commandGateway; - @Autowired - private transient QueryGateway queryGateway; + private final QueryUpdateEmitter queryUpdateEmitter; @Autowired - private transient QueryUpdateEmitter queryUpdateEmitter; + public OrderSaga(CommandGateway commandGateway,QueryUpdateEmitter queryUpdateEmitter) { + this.commandGateway = commandGateway; + this.queryUpdateEmitter = queryUpdateEmitter; + } @StartSaga @SagaEventHandler(associationProperty = "orderId") - private void handle(OrderCreatedEvent orderCreatedEvent) { + public void handle(OrderCreatedEvent orderCreatedEvent) { log.info("Order Saga started for Order Id : {}", orderCreatedEvent.getOrderId()); ReserveProductCommand reserveProductCommand = ReserveProductCommand.builder() @@ -110,7 +119,7 @@ public void handle(ProductReservedEvent productReservedEvent) { } @SagaEventHandler(associationProperty = "orderId") - private void handle(ProductReserveFailedEvent productReserveFailedEvent) { + public void handle(ProductReserveFailedEvent productReserveFailedEvent) { // Start the compensating transaction log.info("ProductReserveFailedEvent started for orderId : {}", productReserveFailedEvent.getOrderId()); CompensateOrder compensateOrder = new CompensateOrder(); @@ -122,7 +131,7 @@ private void handle(ProductReserveFailedEvent productReserveFailedEvent) { } @SagaEventHandler(associationProperty = "orderId") - private void handle(PaymentApprovedEvent paymentApprovedEvent) { + public void handle(PaymentApprovedEvent paymentApprovedEvent) { log.info("PaymentProcessedEvent started for paymentId : {}", paymentApprovedEvent.getPaymentId()); CreateShipmentCommand createShipmentCommand = CreateShipmentCommand.builder() @@ -160,7 +169,7 @@ private void handle(PaymentApprovedEvent paymentApprovedEvent) { } @SagaEventHandler(associationProperty = "orderId") - private void handle(PaymentCancelledEvent paymentCancelledEvent) { + public void handle(PaymentCancelledEvent paymentCancelledEvent) { log.info("Payment is not approved!"); // Start a compensating transaction CancelProductReserveCommand cancelProductReserveCommand = CancelProductReserveCommand.builder() @@ -195,7 +204,7 @@ public void handle(OrderShippedEvent orderShippedEvent) { } @SagaEventHandler(associationProperty = "orderId") - private void handle(ShipmentCancelledEvent shipmentCancelledEvent) { + public void handle(ShipmentCancelledEvent shipmentCancelledEvent) { log.info("Start a compensating transaction from Shipment"); // Start a compensating transaction CancelPaymentCommand cancelPaymentCommand = CancelPaymentCommand.builder() @@ -231,7 +240,7 @@ private void handle(ShipmentCancelledEvent shipmentCancelledEvent) { @SagaEventHandler(associationProperty = "orderId") @EndSaga - public void on(OrderApprovedEvent event) { + public void handle(OrderApprovedEvent event) { log.info("Order is approved. Order Saga is complete for orderId: " + event.getOrderId()); OrderSummary orderSummary = OrderSummary.builder() .orderId(event.getOrderId()) @@ -267,6 +276,7 @@ private void orderRejectedCommand(CompensateOrder compensateOrder) { commandGateway.send(rejectOrderCommand); } + @SuppressWarnings("java:S3740") private String simplifyErrorMessage(CommandResultMessage commandResultMessage, OderFailure errorMessage) { return commandResultMessage.exceptionResult().getMessage() != null && commandResultMessage.exceptionResult().getMessage().contains("No Handler for command:")? diff --git a/order-service/src/test/java/com/nashtech/order/OrderApplicationTest.java b/order-service/src/test/java/com/nashtech/order/OrderApplicationTest.java new file mode 100644 index 00000000..f6ec5f07 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/OrderApplicationTest.java @@ -0,0 +1,35 @@ +package com.nashtech.order; + +import com.nashtech.order.commands.handler.CreateOrderCommandInterceptor; +import com.nashtech.order.repository.OrderLookupRepository; +import org.axonframework.commandhandling.CommandBus; +import org.axonframework.test.utils.RecordingCommandBus; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.mockito.Mockito.*; + +public class OrderApplicationTest { + /** + * Method under test: + * {@link OrderApplication#registerCreateProductCommandInterceptor(ApplicationContext, CommandBus)} + */ + @Test + public void testRegisterCreateProductCommandInterceptor() throws BeansException { + // Arrange + OrderApplication orderApplication = new OrderApplication(); + AnnotationConfigApplicationContext context = mock(AnnotationConfigApplicationContext.class); + when(context.getBean(Mockito.>any())) + .thenReturn(new CreateOrderCommandInterceptor(mock(OrderLookupRepository.class))); + + // Act + orderApplication.registerCreateProductCommandInterceptor(context, new RecordingCommandBus()); + + // Assert that nothing has changed + verify(context).getBean(Mockito.>any()); + } + +} diff --git a/order-service/src/test/java/com/nashtech/order/OrderEventsHandlerTest.java b/order-service/src/test/java/com/nashtech/order/OrderEventsHandlerTest.java deleted file mode 100644 index 07bc2305..00000000 --- a/order-service/src/test/java/com/nashtech/order/OrderEventsHandlerTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.nashtech.order; - -import com.nashtech.common.utils.OrderStatus; -import com.nashtech.order.events.OrderApprovedEvent; -import com.nashtech.order.events.OrderCancelledEvent; -import com.nashtech.order.events.OrderCreatedEvent; -import com.nashtech.order.handler.OrderEventsHandler; -import com.nashtech.order.repository.FailedOrderRepository; -import com.nashtech.order.repository.OrderRepository; -import com.nashtech.order.repository.entity.OrderEntity; -import org.junit.Before; -import org.junit.Test; - -import java.util.Date; -import java.util.UUID; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class OrderEventsHandlerTest { - private static final String ORDER_ID = UUID.randomUUID().toString(); - private static final String PRODUCT_ID = UUID.randomUUID().toString(); - private static final String PAYMENT_ID = UUID.randomUUID().toString(); - private static final String SHIPMENT_ID = UUID.randomUUID().toString(); - private static final String USER_ID = "1652"; - - - private OrderRepository orderRepository = mock(OrderRepository.class); - - private FailedOrderRepository failedOrderRepository = mock(FailedOrderRepository.class); - - // @Autowired - private OrderEventsHandler handler; - - @Before - public void setUp() { - handler = new OrderEventsHandler(orderRepository, failedOrderRepository); - } - - - @Test - public void testOrderCreatedEventHandler() { - OrderCreatedEvent orderCreatedEvent = OrderCreatedEvent.builder() - .orderId(ORDER_ID) - .productId(PRODUCT_ID) - .quantity(2) - .userId(USER_ID) - .orderStatus(OrderStatus.ORDER_PLACED) - .build(); - handler.on(orderCreatedEvent); - } - - @Test - public void testOrderApprovedEventHandler() { - OrderApprovedEvent orderApprovedEvent = OrderApprovedEvent.builder() - .orderId(ORDER_ID) - .paymentId(PAYMENT_ID) - .shipmentId(SHIPMENT_ID) - .orderStatus(OrderStatus.ORDER_PLACED) - .build(); - - OrderEntity order = new OrderEntity(orderApprovedEvent.getOrderId(), USER_ID, PRODUCT_ID, - null, null, new Date(), orderApprovedEvent.getOrderStatus().toString()); - - when(orderRepository.findByOrderId(ORDER_ID)).thenReturn(order); - - handler.on(orderApprovedEvent); - } - - @Test - public void testOrderCancelledEventHandler() { - OrderCancelledEvent orderCancelledEvent = OrderCancelledEvent.builder() - .orderId(ORDER_ID) - .userId(USER_ID) - .productId(PRODUCT_ID) - .reasonToFailed("Car quantity not sufficient in inventory") - .orderStatus(OrderStatus.ORDER_NOT_APPROVED) - .build(); - handler.on(orderCancelledEvent); - } -} diff --git a/order-service/src/test/java/com/nashtech/order/OrderQueriesHandlerTest.java b/order-service/src/test/java/com/nashtech/order/OrderQueriesHandlerTest.java deleted file mode 100644 index c5832dc6..00000000 --- a/order-service/src/test/java/com/nashtech/order/OrderQueriesHandlerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.nashtech.order; - -import com.nashtech.common.utils.OrderStatus; -import com.nashtech.order.query.FindOrdersByUserQuery; -import com.nashtech.order.query.OrderQueriesHandler; -import com.nashtech.order.repository.OrderRepository; -import com.nashtech.order.repository.entity.OrderEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.UUID; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class OrderQueriesHandlerTest { - - private static final String ORDER_ID1 = UUID.randomUUID().toString(); - private static final String ORDER_ID2 = UUID.randomUUID().toString(); - private static final String PRODUCT_ID = UUID.randomUUID().toString(); - private static final String USER_ID = "1652"; - - private final OrderRepository orderRepository = mock(OrderRepository.class); - - private OrderQueriesHandler queriesHandler; - - @Before - public void setUp() { - queriesHandler = new OrderQueriesHandler(orderRepository); - } - - @Test - public void testOrderCreatedEventHandler() { - FindOrdersByUserQuery findOrdersByUserQuery = new FindOrdersByUserQuery(USER_ID); - - List orderEntityList = new ArrayList<>(); - OrderEntity order1 = new OrderEntity(ORDER_ID1, USER_ID, PRODUCT_ID, - null, null, new Date(), OrderStatus.ORDER_APPROVED.toString()); - orderEntityList.add(order1); - OrderEntity order2= new OrderEntity(ORDER_ID2, USER_ID, PRODUCT_ID, - null, null, new Date(), OrderStatus.ORDER_APPROVED.toString()); - orderEntityList.add(order2); - when(orderRepository.findByUserId(USER_ID)).thenReturn(orderEntityList); - - List orders = queriesHandler.findOrders(findOrdersByUserQuery); - - Assert.assertEquals(2,orders.size()); - Assert.assertEquals(ORDER_ID1,orders.get(0).getOrderId()); - Assert.assertEquals(ORDER_ID2,orders.get(1).getOrderId()); - } -} diff --git a/order-service/src/test/java/com/nashtech/order/OrderSagaTest.java b/order-service/src/test/java/com/nashtech/order/OrderSagaTest.java deleted file mode 100644 index 4d489169..00000000 --- a/order-service/src/test/java/com/nashtech/order/OrderSagaTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.nashtech.order; - -import com.nashtech.common.event.ProductReservedEvent; -import com.nashtech.common.utils.OrderStatus; -import com.nashtech.order.events.OrderCreatedEvent; -import com.nashtech.order.saga.OrderSaga; -import org.axonframework.test.matchers.Matchers; -import org.axonframework.test.saga.FixtureConfiguration; -import org.axonframework.test.saga.SagaTestFixture; -import org.junit.Test; - -import java.time.Duration; -import java.util.UUID; - -public class OrderSagaTest { - private static final String ORDER_ID = UUID.randomUUID().toString(); - private static final String PRODUCT_ID = UUID.randomUUID().toString(); - private static final String PAYMENT_ID = UUID.randomUUID().toString(); - private static final String SHIPMENT_ID = UUID.randomUUID().toString(); - private static final String USER_ID = "1652"; - private static final FixtureConfiguration fixture = new SagaTestFixture<>(OrderSaga.class); - - @Test - public void testOrderCreatedEvent() { - OrderCreatedEvent orderCreatedEvent = OrderCreatedEvent.builder() - .orderId(ORDER_ID) - .productId(PRODUCT_ID) - .quantity(2) - .userId(USER_ID) - .orderStatus(OrderStatus.ORDER_PARTIALLY_APPROVED) - .build(); - - fixture.givenAggregate(ORDER_ID) - .published(orderCreatedEvent) - .whenTimeElapses(Duration.ofDays(31)) - .expectDispatchedCommandsMatching(Matchers.listWithAllOf()); - } - - @Test - public void testProductReservedEvent() { - ProductReservedEvent productReservedEvent = ProductReservedEvent.builder() - .orderId(ORDER_ID) - .productId(PRODUCT_ID) - .userId(USER_ID) - .quantity(2) - .brand("Tata") - .basePrice(30000.0) - .tax(0.03f) - .totalTax(0.06f) - .subTotal(60000.0) - .total(60000.06) - .model("model") - .mileage(12d) - .color("Red") - .year(2024) - .build(); - - fixture.givenAggregate(ORDER_ID) - .published(productReservedEvent) - .whenTimeElapses(Duration.ofDays(31)) - .expectDispatchedCommandsMatching(Matchers.listWithAllOf()); - } -} diff --git a/order-service/src/test/java/com/nashtech/order/OrderAggregateTest.java b/order-service/src/test/java/com/nashtech/order/aggregate/OrderAggregateTest.java similarity index 98% rename from order-service/src/test/java/com/nashtech/order/OrderAggregateTest.java rename to order-service/src/test/java/com/nashtech/order/aggregate/OrderAggregateTest.java index 244dcb00..1c28e44b 100644 --- a/order-service/src/test/java/com/nashtech/order/OrderAggregateTest.java +++ b/order-service/src/test/java/com/nashtech/order/aggregate/OrderAggregateTest.java @@ -1,7 +1,6 @@ -package com.nashtech.order; +package com.nashtech.order.aggregate; import com.nashtech.common.utils.OrderStatus; -import com.nashtech.order.aggregate.OrderAggregate; import com.nashtech.order.commands.ApproveOrderCommand; import com.nashtech.order.commands.CreateOrderCommand; import com.nashtech.order.commands.RejectOrderCommand; diff --git a/order-service/src/test/java/com/nashtech/order/commands/CreateOrderCommandInterceptorTest.java b/order-service/src/test/java/com/nashtech/order/commands/CreateOrderCommandInterceptorTest.java new file mode 100644 index 00000000..d79f5aaa --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/commands/CreateOrderCommandInterceptorTest.java @@ -0,0 +1,57 @@ +package com.nashtech.order.commands; + +import com.nashtech.order.commands.handler.CreateOrderCommandInterceptor; +import com.nashtech.order.repository.OrderLookupRepository; +import io.axoniq.axonserver.grpc.command.Command; +import org.axonframework.axonserver.connector.command.GrpcBackedCommandMessage; +import org.axonframework.axonserver.connector.event.axon.GrpcMetaDataAwareSerializer; +import org.axonframework.commandhandling.CommandMessage; +import org.axonframework.serialization.SerializedType; +import org.axonframework.serialization.Serializer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ContextConfiguration(classes = {CreateOrderCommandInterceptor.class}) +@ExtendWith(SpringExtension.class) +class CreateOrderCommandInterceptorTest { + @Autowired + private CreateOrderCommandInterceptor createOrderCommandInterceptor; + + @MockBean + private OrderLookupRepository orderLookupRepository; + + /** + * Method under test: {@link CreateOrderCommandInterceptor#handle(List)} + */ + @Test + void testCreateOrderCommandInterceptorHandle() { + // Arrange + Serializer delegate = mock(Serializer.class); + Class forNameResult = Object.class; + when(delegate.classForType(Mockito.any())).thenReturn(forNameResult); + GrpcMetaDataAwareSerializer serializer = new GrpcMetaDataAwareSerializer(delegate); + GrpcBackedCommandMessage grpcBackedCommandMessage = new GrpcBackedCommandMessage<>(Command.getDefaultInstance(), + serializer); + + ArrayList> messages = new ArrayList<>(); + messages.add(grpcBackedCommandMessage); + + // Act + createOrderCommandInterceptor.handle(messages); + + // Assert + verify(delegate).classForType(Mockito.any()); + } +} diff --git a/order-service/src/test/java/com/nashtech/order/config/AxonXStreamConfigTest.java b/order-service/src/test/java/com/nashtech/order/config/AxonXStreamConfigTest.java new file mode 100644 index 00000000..28a65a8a --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/config/AxonXStreamConfigTest.java @@ -0,0 +1,24 @@ +package com.nashtech.order.config; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider; +import com.thoughtworks.xstream.mapper.CachingMapper; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class AxonXStreamConfigTest { + /** + * Method under test: {@link AxonXStreamConfig#xStream()} + */ + @Test + void testXStream() { + XStream actualXStreamResult = (new AxonXStreamConfig()).xStream(); + // Assert + assertInstanceOf(SunUnsafeReflectionProvider.class, actualXStreamResult.getReflectionProvider()); + assertInstanceOf(CachingMapper.class, actualXStreamResult.getMapper()); + assertNotNull(actualXStreamResult.getClassLoader()); + assertNotNull(actualXStreamResult.getClassLoaderReference().getReference()); + } +} diff --git a/order-service/src/test/java/com/nashtech/order/config/CorsConfigTest.java b/order-service/src/test/java/com/nashtech/order/config/CorsConfigTest.java new file mode 100644 index 00000000..1494b4c7 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/config/CorsConfigTest.java @@ -0,0 +1,28 @@ +package com.nashtech.order.config; + +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.web.servlet.config.annotation.CorsRegistration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class CorsConfigTest { + /** + * Method under test: {@link CorsConfig#addCorsMappings(CorsRegistry)} + */ + @Test + void testAddCorsMappings() { + CorsConfig corsConfig = new CorsConfig(); + CorsRegistry registry = mock(CorsRegistry.class); + when(registry.addMapping(Mockito.any())).thenReturn(new CorsRegistration("Path Pattern")); + + // Act + corsConfig.addCorsMappings(registry); + + // Assert that nothing has changed + verify(registry).addMapping(Mockito.any()); + } +} diff --git a/order-service/src/test/java/com/nashtech/order/exception/OrderServiceErrorHandlerTest.java b/order-service/src/test/java/com/nashtech/order/exception/OrderServiceErrorHandlerTest.java new file mode 100644 index 00000000..7a073d4f --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/exception/OrderServiceErrorHandlerTest.java @@ -0,0 +1,80 @@ +package com.nashtech.order.exception; + +import org.junit.Test; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.context.request.WebRequest; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class OrderServiceErrorHandlerTest { + /** + * Method under test: + * {@link OrderServiceErrorHandler#handleIllegalStateException(IllegalStateException, WebRequest)} + */ + @Test + public void testHandleIllegalStateException() { + // Arrange + OrderServiceErrorHandler orderServiceErrorHandler = new OrderServiceErrorHandler(); + IllegalStateException ex = new IllegalStateException("foo"); + + // Act + ResponseEntity actualHandleIllegalStateExceptionResult = orderServiceErrorHandler + .handleIllegalStateException(ex, new ServletWebRequest(new MockHttpServletRequest())); + + // Assert + assertEquals("foo", ((ErrorMessage) actualHandleIllegalStateExceptionResult.getBody()).getMessage()); + + Date current = new Date(); + Date expectedDate = ((ErrorMessage) actualHandleIllegalStateExceptionResult.getBody()).getTimestamp(); + assertDate(current,expectedDate); + + assertEquals(500, actualHandleIllegalStateExceptionResult.getStatusCodeValue()); + assertTrue(actualHandleIllegalStateExceptionResult.hasBody()); + assertTrue(actualHandleIllegalStateExceptionResult.getHeaders().isEmpty()); + } + + /** + * Method under test: + * {@link OrderServiceErrorHandler#handleOtherExceptions(Exception, WebRequest)} + */ + @Test + public void testHandleOtherExceptions() { + // Arrange + OrderServiceErrorHandler orderServiceErrorHandler = new OrderServiceErrorHandler(); + Exception ex = new Exception("foo"); + + // Act + ResponseEntity actualHandleOtherExceptionsResult = orderServiceErrorHandler.handleOtherExceptions(ex, + new ServletWebRequest(new MockHttpServletRequest())); + + // Assert + assertEquals("foo", ((ErrorMessage) actualHandleOtherExceptionsResult.getBody()).getMessage()); + + Date current = new Date(); + Date expectedDate = ((ErrorMessage) actualHandleOtherExceptionsResult.getBody()).getTimestamp(); + assertDate(current,expectedDate); + + assertEquals(500, actualHandleOtherExceptionsResult.getStatusCodeValue()); + assertTrue(actualHandleOtherExceptionsResult.hasBody()); + assertTrue(actualHandleOtherExceptionsResult.getHeaders().isEmpty()); + } + + public void assertDate(Date currentDate, Date expectedDate) { + Calendar currentCal = new GregorianCalendar(); + currentCal.setTime(currentDate); + + Calendar expectedCal = new GregorianCalendar(); + currentCal.setTime(expectedDate); + + assertEquals("month", expectedCal.get(Calendar.MONTH), currentCal.get(Calendar.MONTH)); + assertEquals("day", expectedCal.get(Calendar.DATE), currentCal.get(Calendar.DATE)); + assertEquals("year", expectedCal.get(Calendar.YEAR), currentCal.get(Calendar.YEAR)); + } +} diff --git a/order-service/src/test/java/com/nashtech/order/handler/OrderEventsHandlerTest.java b/order-service/src/test/java/com/nashtech/order/handler/OrderEventsHandlerTest.java new file mode 100644 index 00000000..6a223df2 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/handler/OrderEventsHandlerTest.java @@ -0,0 +1,163 @@ +package com.nashtech.order.handler; + +import com.nashtech.common.utils.OrderStatus; +import com.nashtech.order.events.OrderApprovedEvent; +import com.nashtech.order.events.OrderCancelledEvent; +import com.nashtech.order.events.OrderCreatedEvent; +import com.nashtech.order.repository.FailedOrderRepository; +import com.nashtech.order.repository.OrderRepository; +import com.nashtech.order.repository.entity.FailedOrderEntity; +import com.nashtech.order.repository.entity.OrderEntity; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.util.Date; +import java.util.Optional; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ContextConfiguration(classes = {OrderEventsHandler.class}) +@ExtendWith(SpringExtension.class) +class OrderEventsHandlerTest { + @MockBean + private FailedOrderRepository failedOrderRepository; + + @Autowired + private OrderEventsHandler orderEventsHandler; + + @MockBean + private OrderRepository orderRepository; + + /** + * Method under test: {@link OrderEventsHandler#on(OrderApprovedEvent)} + */ + @Test + void testOrderApprovedEventHandler() { + // Arrange + OrderEntity orderEntity = new OrderEntity(); + orderEntity.setOrderId("42"); + orderEntity.setOrderStatus("Order Status"); + orderEntity.setPaymentId("42"); + orderEntity.setProductId("42"); + orderEntity.setShipmentId("42"); + orderEntity.setTimestamp(Date.from(LocalDate.of(1970, 1, 1).atStartOfDay().atZone(ZoneOffset.UTC).toInstant())); + orderEntity.setUserId("42"); + + OrderEntity orderEntity2 = new OrderEntity(); + orderEntity2.setOrderId("42"); + orderEntity2.setOrderStatus("Order Status"); + orderEntity2.setPaymentId("42"); + orderEntity2.setProductId("42"); + orderEntity2.setShipmentId("42"); + orderEntity2.setTimestamp(Date.from(LocalDate.of(1970, 1, 1).atStartOfDay().atZone(ZoneOffset.UTC).toInstant())); + orderEntity2.setUserId("42"); + when(orderRepository.save(Mockito.any())).thenReturn(orderEntity2); + when(orderRepository.findByOrderId(Mockito.any())).thenReturn(orderEntity); + doNothing().when(failedOrderRepository).delete(Mockito.any()); + OrderApprovedEvent orderApprovedEvent = OrderApprovedEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_NOT_APPROVED) + .paymentId("42") + .shipmentId("42") + .build(); + + // Act + orderEventsHandler.on(orderApprovedEvent); + + // Assert + verify(orderRepository).findByOrderId(Mockito.any()); + verify(failedOrderRepository).delete(Mockito.any()); + verify(orderRepository).save(Mockito.any()); + } + + /** + * Method under test: {@link OrderEventsHandler#on(OrderCancelledEvent)} + */ + @Test + void testOrderCancelledEventHandler() { + // Arrange + Optional emptyResult = Optional.empty(); + when(failedOrderRepository.findById(Mockito.any())).thenReturn(emptyResult); + OrderCancelledEvent event = OrderCancelledEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_NOT_APPROVED) + .paymentId("42") + .productId("42") + .reasonToFailed("Just cause") + .shipmentId("42") + .userId("42") + .build(); + + // Act + orderEventsHandler.on(event); + + // Assert that nothing has changed + verify(failedOrderRepository).findById(Mockito.any()); + } + + /** + * Method under test: {@link OrderEventsHandler#on(OrderCreatedEvent)} + */ + @Test + void testOrderCreatedEventHandler() { + // Arrange + OrderEntity orderEntity = new OrderEntity(); + orderEntity.setOrderId("42"); + orderEntity.setOrderStatus("Order Status"); + orderEntity.setPaymentId("42"); + orderEntity.setProductId("42"); + orderEntity.setShipmentId("42"); + orderEntity.setTimestamp(Date.from(LocalDate.of(1970, 1, 1).atStartOfDay().atZone(ZoneOffset.UTC).toInstant())); + orderEntity.setUserId("42"); + when(orderRepository.save(Mockito.any())).thenReturn(orderEntity); + + FailedOrderEntity failedOrderEntity = new FailedOrderEntity(); + failedOrderEntity.setOrderId("42"); + failedOrderEntity.setOrderStatus("Order Status"); + failedOrderEntity.setPaymentId("42"); + failedOrderEntity.setProductId("42"); + failedOrderEntity.setReasonToFailed("Just cause"); + failedOrderEntity.setShipmentId("42"); + failedOrderEntity + .setTimestamp(Date.from(LocalDate.of(1970, 1, 1).atStartOfDay().atZone(ZoneOffset.UTC).toInstant())); + failedOrderEntity.setUserId("42"); + when(failedOrderRepository.save(Mockito.any())).thenReturn(failedOrderEntity); + OrderCreatedEvent event = OrderCreatedEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_NOT_APPROVED) + .productId("42") + .quantity(1) + .userId("42") + .build(); + + // Act + orderEventsHandler.on(event); + + // Assert + verify(failedOrderRepository).save(Mockito.any()); + verify(orderRepository).save(Mockito.any()); + } + + /** + * Method under test: {@link OrderEventsHandler#handle(Exception)} + */ + @Test + void testExceptionHandle() { + Exception exception = new Exception("foo"); + try { + Assertions.assertEquals("foo", exception.getMessage()); + orderEventsHandler.handle(exception); + }catch (Exception e){} + + } +} diff --git a/order-service/src/test/java/com/nashtech/order/handler/OrderLookupEventsHandlerTest.java b/order-service/src/test/java/com/nashtech/order/handler/OrderLookupEventsHandlerTest.java new file mode 100644 index 00000000..46bd8ef8 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/handler/OrderLookupEventsHandlerTest.java @@ -0,0 +1,71 @@ +package com.nashtech.order.handler; + +import com.nashtech.common.utils.OrderStatus; +import com.nashtech.order.events.OrderCreatedEvent; +import com.nashtech.order.repository.OrderLookupRepository; +import com.nashtech.order.repository.entity.OrderLookupEntity; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.util.Date; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ContextConfiguration(classes = {OrderLookupEventsHandler.class}) +@ExtendWith(SpringExtension.class) +class OrderLookupEventsHandlerTest { + @Autowired + private OrderLookupEventsHandler orderLookupEventsHandler; + + @MockBean + private OrderLookupRepository orderLookupRepository; + + /** + * Method under test: {@link OrderLookupEventsHandler#on(OrderCreatedEvent)} + */ + @Test + void testOrderCreatedEventEventHandler() { + // Arrange + OrderLookupEntity orderLookupEntity = new OrderLookupEntity("42", + Date.from(LocalDate.of(1970, 1, 1).atStartOfDay().atZone(ZoneOffset.UTC).toInstant())); + + when(orderLookupRepository.save(Mockito.any())).thenReturn(orderLookupEntity); + OrderCreatedEvent event = OrderCreatedEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_NOT_APPROVED) + .productId("42") + .quantity(1) + .userId("42") + .build(); + + // Act + orderLookupEventsHandler.on(event); + + // Assert + verify(orderLookupRepository).save(Mockito.any()); + } + + /** + * Method under test: {@link OrderLookupEventsHandler#handle(Exception)} + */ + @Test + void testExceptionHandle() { + Exception exception = new Exception("foo"); + try { + Assertions.assertEquals("foo", exception.getMessage()); + orderLookupEventsHandler.handle(exception); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/order-service/src/test/java/com/nashtech/order/query/FindOrderQueryTest.java b/order-service/src/test/java/com/nashtech/order/query/FindOrderQueryTest.java new file mode 100644 index 00000000..7965f1e0 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/query/FindOrderQueryTest.java @@ -0,0 +1,18 @@ +package com.nashtech.order.query; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class FindOrderQueryTest { + /** + * Method under test: {@link FindOrderQuery#FindOrderQuery()} + */ + @Test + void testNewFindOrderQuery() { + // Arrange, Act and Assert + assertNull((new FindOrderQuery()).orderId); + assertEquals("42", (new FindOrderQuery("42")).orderId); + } +} diff --git a/order-service/src/test/java/com/nashtech/order/query/OrderQueriesHandlerTest.java b/order-service/src/test/java/com/nashtech/order/query/OrderQueriesHandlerTest.java new file mode 100644 index 00000000..326faf43 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/query/OrderQueriesHandlerTest.java @@ -0,0 +1,49 @@ +package com.nashtech.order.query; + +import com.nashtech.order.query.handler.OrderQueriesHandler; +import com.nashtech.order.repository.OrderRepository; +import com.nashtech.order.repository.entity.OrderEntity; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ContextConfiguration(classes = {OrderQueriesHandler.class}) +@RunWith(SpringJUnit4ClassRunner.class) +public class OrderQueriesHandlerTest { + @Autowired + private OrderQueriesHandler orderQueriesHandler; + + @MockBean + private OrderRepository orderRepository; + + /** + * Method under test: + * {@link OrderQueriesHandler#findOrders(FindOrdersByUserQuery)} + */ + @Test + public void testFindOrders() { + // Arrange + ArrayList orderEntityList = new ArrayList<>(); + when(orderRepository.findByUserId(Mockito.any())).thenReturn(orderEntityList); + + // Act + List actualFindOrdersResult = orderQueriesHandler.findOrders(new FindOrdersByUserQuery("42")); + + // Assert + verify(orderRepository).findByUserId(Mockito.any()); + assertTrue(actualFindOrdersResult.isEmpty()); + assertSame(orderEntityList, actualFindOrdersResult); + } +} diff --git a/order-service/src/test/java/com/nashtech/order/RestTest.java b/order-service/src/test/java/com/nashtech/order/restapi/RestTest.java similarity index 81% rename from order-service/src/test/java/com/nashtech/order/RestTest.java rename to order-service/src/test/java/com/nashtech/order/restapi/RestTest.java index 6a8f0586..b5a9d4a8 100644 --- a/order-service/src/test/java/com/nashtech/order/RestTest.java +++ b/order-service/src/test/java/com/nashtech/order/restapi/RestTest.java @@ -1,7 +1,8 @@ -package com.nashtech.order; +package com.nashtech.order.restapi; import com.fasterxml.jackson.databind.ObjectMapper; import com.nashtech.order.restapi.request.OrderCreateRequest; +import com.nashtech.order.restapi.response.OrderSummary; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -14,12 +15,13 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import java.util.Collection; import java.util.Objects; import static org.hamcrest.MatcherAssert.assertThat; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -34,10 +36,11 @@ public class RestTest { @Test public void testCreateOrder() throws Exception { + ObjectMapper objectMapper= new ObjectMapper(); OrderCreateRequest orderRequest = OrderCreateRequest.builder().build(); MvcResult result = mvc.perform(post("/orders/create") .contentType(MediaType.APPLICATION_JSON) - .content(new ObjectMapper().writeValueAsString(orderRequest)) + .content(objectMapper.writeValueAsString(orderRequest)) .characterEncoding("utf-8")) .andExpect(status().isOk()) .andDo(print()) @@ -49,6 +52,10 @@ public void testCreateOrder() throws Exception { Objects.requireNonNull(mockResponse.getContentType()).contains("application/json")); Assert.assertFalse(mockResponse.getContentAsString().isEmpty()); + OrderSummary orderSummary = objectMapper.readValue(mockResponse.getContentAsString(), OrderSummary.class); + + assertEquals("ORDER_PLACED", orderSummary.getOrderStatus()); + Collection responseHeaders = mockResponse.getHeaderNames(); Assert.assertNotNull(responseHeaders); Assert.assertFalse(responseHeaders.isEmpty()); @@ -58,13 +65,12 @@ public void testCreateOrder() throws Exception { public void testGetOrdersByUser() throws Exception { MvcResult result = mvc - .perform(get("/orders/1652")) + .perform(MockMvcRequestBuilders.get("/orders/{userId}", "1652")) .andExpect(status().isOk()) .andDo(print()) .andReturn(); MockHttpServletResponse mockResponse = result.getResponse(); - Assert.assertEquals(200, mockResponse.getStatus()); assertThat(mockResponse.getContentType(), Objects.requireNonNull(mockResponse.getContentType()).contains("application/json")); diff --git a/order-service/src/test/java/com/nashtech/order/saga/OrderSagaTest.java b/order-service/src/test/java/com/nashtech/order/saga/OrderSagaTest.java new file mode 100644 index 00000000..58cd7d60 --- /dev/null +++ b/order-service/src/test/java/com/nashtech/order/saga/OrderSagaTest.java @@ -0,0 +1,266 @@ +package com.nashtech.order.saga; + +import com.nashtech.common.event.*; +import com.nashtech.common.model.ShipmentStatus; +import com.nashtech.common.model.User; +import com.nashtech.common.utils.OrderStatus; +import com.nashtech.order.events.OrderApprovedEvent; +import com.nashtech.order.events.OrderCancelledEvent; +import com.nashtech.order.events.OrderCreatedEvent; +import org.axonframework.commandhandling.CommandCallback; +import org.axonframework.commandhandling.gateway.CommandGateway; +import org.axonframework.queryhandling.QueryUpdateEmitter; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.concurrent.CompletableFuture; +import java.util.function.Predicate; + +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ContextConfiguration(classes = {OrderSaga.class}) +@RunWith(SpringJUnit4ClassRunner.class) +public class OrderSagaTest { + @MockBean + private CommandGateway commandGateway; + + @Autowired + private OrderSaga orderSaga; + + + @MockBean + private QueryUpdateEmitter queryUpdateEmitter; + + /** + * Method under test: {@link OrderSaga#handle(OrderShippedEvent)} + */ + @Test + public void testOrderShippedEventHandlerSaga() { + // Arrange + when(commandGateway.send(Mockito.any())).thenReturn(new CompletableFuture<>()); + OrderShippedEvent orderShippedEvent = OrderShippedEvent.builder() + .orderId("42") + .paymentId("42") + .shipmentId("42") + .build(); + + // Act + orderSaga.handle(orderShippedEvent); + + // Assert + verify(commandGateway).send(Mockito.any()); + } + + /** + * Method under test: {@link OrderSaga#handle(PaymentApprovedEvent)} + */ + @Test + public void testPaymentApprovedEventHandlerSaga() { + // Arrange + doNothing().when(commandGateway).send(Mockito.any(), Mockito.>any()); + PaymentApprovedEvent.PaymentApprovedEventBuilder totalTaxResult = PaymentApprovedEvent.builder() + .basePrice(10.0d) + .brand("Brand") + .orderId("42") + .paymentId("42") + .productId("42") + .quantity(1) + .subTotal(10.0d) + .tax(10.0f) + .total(10.0d) + .totalTax(10.0f); + User user = User.builder().emailId("42").firstName("Jane").lastName("Doe").mobileNumber("42").userId("42").build(); + PaymentApprovedEvent paymentApprovedEvent = totalTaxResult.user(user).build(); + + // Act + orderSaga.handle(paymentApprovedEvent); + + // Assert + verify(commandGateway).send(Mockito.any(), Mockito.>any()); + } + + /** + * Method under test: {@link OrderSaga#handle(PaymentCancelledEvent)} + */ + @Test + public void testPaymentCancelledEventHandlerSaga() { + // Arrange + when(commandGateway.send(Mockito.any())).thenReturn(new CompletableFuture<>()); + PaymentCancelledEvent paymentCancelledEvent = PaymentCancelledEvent.builder() + .orderId("42") + .paymentId("42") + .productId("42") + .quantity(1) + .reasonToFailed("Just cause") + .userId("42") + .build(); + + // Act + orderSaga.handle(paymentCancelledEvent); + + // Assert + verify(commandGateway, atLeast(1)).send(Mockito.any()); + } + + /** + * Method under test: {@link OrderSaga#handle(ProductReserveFailedEvent)} + */ + @Test + public void testProductReserveFailedEventHandlerSaga() { + // Arrange + when(commandGateway.send(Mockito.any())).thenReturn(new CompletableFuture<>()); + ProductReserveFailedEvent productReserveFailedEvent = ProductReserveFailedEvent.builder() + .orderId("42") + .productId("42") + .reasonToFailed("Just cause") + .userId("42") + .build(); + + // Act + orderSaga.handle(productReserveFailedEvent); + + // Assert + verify(commandGateway).send(Mockito.any()); + } + + /** + * Method under test: {@link OrderSaga#handle(ProductReservedEvent)} + */ + @Test + public void testProductReservedEventHandlerSaga() { + // Arrange + doNothing().when(commandGateway).send(Mockito.any(), Mockito.>any()); + ProductReservedEvent productReservedEvent = ProductReservedEvent.builder() + .basePrice(10.0d) + .brand("Brand") + .color("Color") + .mileage(10.0d) + .model("Model") + .orderId("42") + .productId("42") + .quantity(1) + .subTotal(10.0d) + .tax(10.0f) + .total(10.0d) + .totalTax(10.0f) + .userId("42") + .year(1) + .build(); + + // Act + orderSaga.handle(productReservedEvent); + + // Assert + verify(commandGateway).send(Mockito.any(), Mockito.>any()); + } + + /** + * Method under test: {@link OrderSaga#handle(ShipmentCancelledEvent)} + */ + @Test + public void testShipmentCancelledEventHandlerSaga() { + // Arrange + when(commandGateway.send(Mockito.any())).thenReturn(new CompletableFuture<>()); + ShipmentCancelledEvent shipmentCancelledEvent = ShipmentCancelledEvent.builder() + .firstName("Jane") + .grandTotal(10.0d) + .lastName("Doe") + .orderId("42") + .paymentId("42") + .price(10.0d) + .productId("42") + .quantity(1) + .reasonToFailed("Just cause") + .shipmentId("42") + .shipmentStatus(ShipmentStatus.SHIPMENT_CREATED) + .subTotal(10.0d) + .tax(10.0f) + .userId("42") + .build(); + + // Act + orderSaga.handle(shipmentCancelledEvent); + + // Assert + verify(commandGateway, atLeast(1)).send(Mockito.any()); + } + + /** + * Method under test: {@link OrderSaga#handle(OrderApprovedEvent)} + */ + @Test + public void testOrderApprovedEventHandlerSaga() { + // Arrange + doNothing().when(queryUpdateEmitter) + .emit(Mockito.>any(), Mockito.>any(), Mockito.any()); + OrderApprovedEvent event = OrderApprovedEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_NOT_APPROVED) + .paymentId("42") + .shipmentId("42") + .build(); + + // Act + orderSaga.handle(event); + + // Assert + verify(queryUpdateEmitter).emit(Mockito.>any(), Mockito.>any(), + Mockito.any()); + } + + /** + * Method under test: {@link OrderSaga#handle(OrderCancelledEvent)} + */ + @Test + public void testOrderCancelledEventHandlerSaga() { + // Arrange + doNothing().when(queryUpdateEmitter) + .emit(Mockito.>any(), Mockito.>any(), Mockito.any()); + OrderCancelledEvent event = OrderCancelledEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_NOT_APPROVED) + .paymentId("42") + .productId("42") + .reasonToFailed("Just cause") + .shipmentId("42") + .userId("42") + .build(); + + // Act + orderSaga.handle(event); + + // Assert + verify(queryUpdateEmitter).emit(Mockito.>any(), Mockito.>any(), + Mockito.any()); + } + + /** + * Method under test: {@link OrderSaga#handle(OrderCreatedEvent)} + */ + @Test + public void testOrderCreatedEventHandlerSaga() { + // Arrange + doNothing().when(commandGateway).send(Mockito.any(), Mockito.>any()); + OrderCreatedEvent orderCreatedEvent = OrderCreatedEvent.builder() + .orderId("42") + .orderStatus(OrderStatus.ORDER_PLACED) + .productId("42") + .quantity(1) + .userId("42") + .build(); + + // Act + orderSaga.handle(orderCreatedEvent); + + // Assert + verify(commandGateway).send(Mockito.any(), Mockito.>any()); + } +}