010
OUT Migration Kafka концепт
011
012
Каким образом производится внешняя миграция
013 через Apache Kafka?
014
015
Внешняя миграция через кафку производится таким способом, что в
016 кафке создаётся топик с каким-то названием, дальше этот топик
017 регистрируется в системе и после регистрации, система обращается в
018 данный топик и начинает записывать различные события (создание
019 новой инстанции, обновление инстанции и тд.) в виде JSON
020 определенного ниже формата по выбранным бизнес объектам (БО) в
021 настройках out миграции,
022
023
Детальнее это показано здесь
025
026
Важные нюансы миграции:
027
028
029 -
030
Уникальные поля передаются всегда, вне зависимости выбрали ли вы
031 их в настройках или нет, и вне взависимости есть ли по ним какие-то
032 изменения или нет. Если по ним нет изменении, они передаются как
033 unchangedUniqueFields или
034 unchangedUniqueBoFields, если изменения есть то
035 они передаются как обычно в fields или
036 boFields. Но учтите, что в случае если у
037 уникального поля нет значения или если она системная, то она не
038 передается.
039
040
041 -
042
Важно понимать, что система не имеет возможности отличить
043 создание инстанции БО от её изменения, поэтому информации этом в
044 выгружаемых JSON-данных не поступает. Поэтому в данными стоит
045 работать в режиме
046
047
048 UPSERT или
049 INSERT-ON-DUPLICATE-UPDATE
050
051
052
053
054
055 Режим UPSERT
предполагает, что вначале нужно
056 проверить наличие инстанции, если таковая есть, то обновить её.
057 Иначе - создать новую.
058
059 Режим INSERT-ON-DUPLICATE-UPDATE
предполагает, что
060 всегда нужно создавать новую запись. Предварительно нужно
061 предусмотреть чтобы идентификатор инстанции является уникальным
062 полем (например первичным ключом). При этом стоит ожидать ошибку,
063 что такая запись уже есть. И если эта ошибка появилась, то подавить
064 её и выполнить обновление инстанции.
065
066
067
068
Структура JSON, каким оно должно быть.
069
070
071 {
072 "recordId": "12345",
073 "externalId": "bfsseVCjGC225bM@",
074 "id": "dgL9~4keReK7Z1qi",
075 "boCode": "BO",
076 "fields": [
077 {
078 "code": "textField",
079 "apiValue": "someValue"
080 },
081 {
082 "code": "textField2",
083 "apiValue": "someValue2"
084 }
085 ],
086 "boFields": [
087 {
088 "fieldCode": "boTextField",
089 "toBoCode": "BO2",
090 "toFieldCode": "textFieldOfBO2",
091 "apiValue": "015252634519"
092 },
093 {
094 "fieldCode": "boTextField",
095 "toBoCode": "BO3",
096 "toFieldCode": "textFieldOfBO3",
097 "apiValue": "015256324519"
098 }
099 ],
100 "unchangedUniqueFields": [
101 {
102 "code": "uniqueDynamicField",
103 "apiValue": "someValue"
104 }
105 ],
106 "unchangedUniqueBoFields": [
107 {
108 "fieldCode": "uniqueBoField",
109 "toBoCode": "BO2",
110 "toFieldCode": "textFieldOfBO2",
111 "apiValue": "015252634519"
112 }
113 ],
114 "state": "ACTUAL"
115 }
116
117
118
119
120
121
122
Подробнее о полях
123
124
125 recordId:Строка - Идентификатор данной записи, он должен быть уникальным в рамках всего топика.
126 Он используется для того чтобы запись обрабатывалась всего одни раз его затем,
127 система его запоминает и при повторной записи система его игнорирует.
128
129 externalId:Строка - Идентификатор внешней системы, которая загрузила данные на платформу MyBPM. Если инстанция была
130 создана внутри платформы, то данный идентификатор будет пустым.
131
132 id:Строка - Идентификатор инстанции БО - внутренний для платформы MyBPM.
133
134 boCode:Строка - Код бизнес объекта в которой, должны записаться данные.
135
136 fields:Массив - Поля со значениями для мигрированния .
137 code:Строка - Код поля в бизнес объекте .
138 apiValue:Строка - Значение из REST API.
139
140 boFields:Массив - Бизнес поля для миграций (вложенный бизнес объект).
141 fieldCode:Строка - Код поля, который принадлежит с кодом boCode.
142 toBoCode:Строка - Код бизнес объекта на которое указывает данное поле.
143 toFieldCode:Строка - Код поля у бизнес объекта toBoCode. Это поле должно быть уникальное
144 apiValue:Строка - Значение поле toFieldCode у бизнес объекта с кодом toBoCode.
145
146 unchangedUniqueFields:Массив - Объекты как в fields, но только для неизмененных уникальных полей.
147 code:Строка - Код поля в бизнес объекте .
148 apiValue:Строка - Значение из REST API.
149
150 unchangedUniqueBoFields:Массив - Объекты как в boFields, но только для неизмененных уникальных полей.
151 fieldCode:Строка - Код поля, который принадлежит с кодом boCode.
152 toBoCode:Строка - Код бизнес объекта на которое указывает данное поле.
153 toFieldCode:Строка - Код поля у бизнес объекта toBoCode. Это поле должно быть уникальное
154 apiValue:Строка - Значение поле toFieldCode у бизнес объекта с кодом toBoCode.
155
156 state:Строка - Состояние записи могут быть (ACTUAL, REMOVED, ARCHIVED, TEST), может отсутствовать,
157 если записи нету то state станет ACTUAL, а если запись есть то ничего не измениться
158 ACTUAL - Это актуальная запись которая доступна для работы.
159 REMOVED - Удалённая запись.
160 ARCHIVED - Архивированная запись.
161 TEST - Запись предназначена для режима тестирования
162
163
164
165
166
167
at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:80)
at kz.greetgo.md_reader.core.MdConverter.prepareHtmlFileFrom(MdConverter.java:136)
at kz.greetgo.md_reader.core.MdConverter.convert(MdConverter.java:208)
at kz.greetgo.md_reader.controller.RenderController.downloadToc(RenderController.java:360)
at kz.greetgo.md_reader.controller.RenderController.request(RenderController.java:108)
at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at kz.greetgo.md_reader.interceptors.TextReplaceFilter.doFilter(TextReplaceFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.io.IOException: Server returned HTTP response code: 429 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:2000)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1397)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1333)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.startPE(XMLDTDScannerImpl.java:732)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2101)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2064)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:299)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1165)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1040)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:943)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:247)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342)
at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122)
at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:71)
... 48 more