From 9e6d7c2b4aa4016d4f32c91cbf8887b9ba01ec5d Mon Sep 17 00:00:00 2001 From: Peter Maquiran Date: Thu, 25 Jul 2024 08:51:04 +0100 Subject: [PATCH] fix chat estracture --- gabinete-digital-fo.code-workspace | 4 --- src/app/app.module.ts | 10 ++++++ .../list/rooms/roomListChangeDetector.ts | 16 +++++----- .../async/socket/message-async.service.ts | 2 +- .../message-local-data-source.service.ts | 3 +- .../room/rooom-local-data-source.service.ts | 4 +++ .../user-typing-live-data-source.service.ts | 8 +++-- .../chat/data/dto/room/roomByIdOutputDTO.ts | 4 +-- .../chat/data/dto/room/roomListOutputDTO.ts | 16 ++++++---- .../repository/message-respository.service.ts | 32 +++++++++++++------ .../repository/room-repository.service.ts | 25 ++++++++------- .../chat/infra/socket/signal-r.service.ts | 4 +-- src/app/module/chat/infra/socket/signalR.ts | 10 ++++-- .../monitoring/opentelemetry/matrix.ts | 19 +++++++++-- .../monitoring/opentelemetry/opentelemetry.ts | 4 +-- .../monitoring/opentelemetry/tracer.ts | 28 ++++++++++------ src/app/shared/chat/messages/messages.page.ts | 8 +++-- 17 files changed, 132 insertions(+), 65 deletions(-) diff --git a/gabinete-digital-fo.code-workspace b/gabinete-digital-fo.code-workspace index ea33f72b6..3ed675959 100644 --- a/gabinete-digital-fo.code-workspace +++ b/gabinete-digital-fo.code-workspace @@ -4,10 +4,6 @@ "name": "gabinete-digital-fo", "path": "." }, - { - "name": "oo", - "path": "../../../Downloads/oo" - }, { "name": "socket-server", "path": "../socket-server" diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2eddd8002..cab5111ac 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -106,6 +106,16 @@ import { typingReducer } from './module/chat/data/data-source/userTyping/user-ty import { FirebaseX } from '@ionic-native/firebase-x/ngx'; */ //import { FCM } from 'cordova-plugin-fcm-with-dependecy-updated/ionic/ngx'; + +// import { WebTracerProvider } from '@opentelemetry/web'; +// import { SimpleSpanProcessor } from '@opentelemetry/tracing'; +// import { ConsoleSpanExporter } from '@opentelemetry/tracing'; + + +// const provider = new WebTracerProvider(); +// provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter())); +// provider.register(); + Sentry.init( { dsn: 'https://5b345a3ae70b4e4da463da65881b4aaa@o4504340905525248.ingest.sentry.io/4504345615794176', diff --git a/src/app/module/chat/data/async/list/rooms/roomListChangeDetector.ts b/src/app/module/chat/data/async/list/rooms/roomListChangeDetector.ts index 8b17e5eea..83a9aac30 100644 --- a/src/app/module/chat/data/async/list/rooms/roomListChangeDetector.ts +++ b/src/app/module/chat/data/async/list/rooms/roomListChangeDetector.ts @@ -2,18 +2,18 @@ import { TableRoom } from "../../../data-source/room/rooom-local-data-source.ser import { RoomListItemOutPutDTO, RoomListOutPutDTO } from "../../../dto/room/roomListOutputDTO"; export function roomListDetermineChanges(serverRooms: RoomListItemOutPutDTO[], localRooms: TableRoom[]) { - const serverRoomMap = new Map(serverRooms.map(room => [room.id, room])); + const serverRoomMap = new Map(serverRooms.map(room => [room.chatRoom.id, room])); const localRoomMap = new Map(localRooms.map(room => [room.id, room])); - const roomsToInsert = serverRooms.filter(room => !localRoomMap.has(room.id)); + const roomsToInsert = serverRooms.filter(room => !localRoomMap.has(room.chatRoom.id)); const roomsToUpdate = serverRooms.filter(room => { - const localRoom = localRoomMap.get(room.id); + const localRoom = localRoomMap.get(room.chatRoom.id); return localRoom && ( - room.roomName !== localRoom.roomName || - room.createdBy.wxUserId !== localRoom.createdBy.wxUserId || - room.createdAt !== localRoom.createdAt || - room.expirationDate !== localRoom.expirationDate || - room.roomType !== localRoom.roomType + room.chatRoom.roomName !== localRoom.roomName || + room.chatRoom.createdBy.wxUserId !== localRoom.createdBy.wxUserId || + room.chatRoom.createdAt !== localRoom.createdAt || + room.chatRoom.expirationDate !== localRoom.expirationDate || + room.chatRoom.roomType !== localRoom.roomType ); }); const roomsToDelete = localRooms.filter(room => !serverRoomMap.has(room.id)); diff --git a/src/app/module/chat/data/async/socket/message-async.service.ts b/src/app/module/chat/data/async/socket/message-async.service.ts index 468328efd..6c8a25b20 100644 --- a/src/app/module/chat/data/async/socket/message-async.service.ts +++ b/src/app/module/chat/data/async/socket/message-async.service.ts @@ -23,7 +23,7 @@ export class MessageAsyncService { filter((message: any) => { return !message?.requestId?.startsWith(InstanceId) && message?.requestId }) - ).subscribe(async (message: any) => { + ).subscribe(async (message) => { console.log('message async ', message) diff --git a/src/app/module/chat/data/data-source/message/message-local-data-source.service.ts b/src/app/module/chat/data/data-source/message/message-local-data-source.service.ts index 6abab9515..841d7c6bd 100644 --- a/src/app/module/chat/data/data-source/message/message-local-data-source.service.ts +++ b/src/app/module/chat/data/data-source/message/message-local-data-source.service.ts @@ -75,6 +75,7 @@ export class MessageLocalDataSourceService { async getLastMessageByRoomId(roomId: string): Promise> { try { + console.log({roomId}) const lastMessage = await messageDataSource.message .where('roomId') .equals(roomId) @@ -107,7 +108,7 @@ export class MessageLocalDataSourceService { } - // @ValidateSchema(tableSchema) + // @ValidateSchema(tableSchema) async createMessage(data: MessageInputDTO) { try { diff --git a/src/app/module/chat/data/data-source/room/rooom-local-data-source.service.ts b/src/app/module/chat/data/data-source/room/rooom-local-data-source.service.ts index b0db889f5..49054f8e4 100644 --- a/src/app/module/chat/data/data-source/room/rooom-local-data-source.service.ts +++ b/src/app/module/chat/data/data-source/room/rooom-local-data-source.service.ts @@ -179,6 +179,10 @@ export class RoomLocalDataSourceService { return await roomDataSource.room.toArray() } + getMemberLive(data: {roomId, wxUserId}) { + const $roomIdUserId = data.roomId + data.wxUserId + return liveQuery(() => roomDataSource.memberList.get($roomIdUserId)) as any; + } getItemsLive(): Observable { return liveQuery(() => roomDataSource.room.toArray()) as any; diff --git a/src/app/module/chat/data/data-source/userTyping/user-typing-live-data-source.service.ts b/src/app/module/chat/data/data-source/userTyping/user-typing-live-data-source.service.ts index 80445132b..1935edee6 100644 --- a/src/app/module/chat/data/data-source/userTyping/user-typing-live-data-source.service.ts +++ b/src/app/module/chat/data/data-source/userTyping/user-typing-live-data-source.service.ts @@ -11,8 +11,12 @@ export class UserTypingLiveDataSourceService { private SignalRLiveDataSourceService: SignalRService ) { } - sendTyping(roomId) { - return this.SignalRLiveDataSourceService.sendTyping({roomId, UserName:SessionStore.user.FullName}) + sendTyping(roomId, ) { + return this.SignalRLiveDataSourceService.sendTyping({ + roomId, + UserName:SessionStore.user.FullName, + userId:SessionStore.user.UserId + }) } } diff --git a/src/app/module/chat/data/dto/room/roomByIdOutputDTO.ts b/src/app/module/chat/data/dto/room/roomByIdOutputDTO.ts index 4e5dc7e01..58ec40c50 100644 --- a/src/app/module/chat/data/dto/room/roomByIdOutputDTO.ts +++ b/src/app/module/chat/data/dto/room/roomByIdOutputDTO.ts @@ -11,6 +11,7 @@ const MemberSchema = z.object({ id: z.string(), user: UserSchema, joinAt: z.string(), + isAdmin: z.boolean() }); export const RoomByIdOutputDTOSchema = z.object({ @@ -27,6 +28,5 @@ export const RoomByIdOutputDTOSchema = z.object({ }), }) - export type RoomByIdMemberItemOutputDTO = z.infer -export type RoomByIdOutputDTO = z.infer +export type RoomByIdOutputDTO = z.infer \ No newline at end of file diff --git a/src/app/module/chat/data/dto/room/roomListOutputDTO.ts b/src/app/module/chat/data/dto/room/roomListOutputDTO.ts index 148614230..70a563372 100644 --- a/src/app/module/chat/data/dto/room/roomListOutputDTO.ts +++ b/src/app/module/chat/data/dto/room/roomListOutputDTO.ts @@ -8,12 +8,16 @@ const CreatedBySchema = z.object({ }); const RoomListItemOutPutDTOSchema = z.object({ - id: z.string(), - roomName: z.string(), - createdBy: CreatedBySchema, - createdAt: z.string(), - expirationDate: z.string().nullable(), // api check - roomType: z.number() + + chatRoom: z.object({ + id: z.string(), + roomName: z.string(), + createdBy: CreatedBySchema, + createdAt: z.string(), + expirationDate: z.string().nullable(), // api check + roomType: z.number() + }), + joinAt: z.string() }) diff --git a/src/app/module/chat/data/repository/message-respository.service.ts b/src/app/module/chat/data/repository/message-respository.service.ts index acd679e12..dd1e30dc0 100644 --- a/src/app/module/chat/data/repository/message-respository.service.ts +++ b/src/app/module/chat/data/repository/message-respository.service.ts @@ -42,7 +42,8 @@ export class MessageRepositoryService { data['requestId'] = InstanceId +'@'+ uuidv4(); - const localActionResult = await this.messageLocalDataSourceService.sendMessage(data) + const localActionResult = await this.messageLocalDataSourceService.sendMessage({...data}) + console.log('create message', data) // this.messageLiveDataSourceService.sendMessage({ // type: 'sendMessage', @@ -63,17 +64,20 @@ export class MessageRepositoryService { delete sendMessageResult.value.sender } - let clone: TableMessage = { - ...sendMessageResult.value, - messageId: sendMessageResult.value.id, - id : localActionResult.value - } + // let clone: TableMessage = { + // ...sendMessageResult.value, + // messageId: sendMessageResult.value.id, + // id : localActionResult.value + // } - return this.messageLocalDataSourceService.update({...clone, sending: false}) + // console.log({clone}) + console.log('update message') + //return this.messageLocalDataSourceService.update({...clone, sending: false}) + return ok(true) } } else { - return this.messageLocalDataSourceService.update({sending: false}) + // return this.messageLocalDataSourceService.update({sending: false}) } } @@ -82,7 +86,7 @@ export class MessageRepositoryService { if(result.isOk()) { if(result.value) { - return await this.messageLiveSignalRDataSourceService.sendReadAt({roomId, memberId: SessionStore.user.UserId, chatMessageId: result.value.messageId}) + // return await this.messageLiveSignalRDataSourceService.sendReadAt({roomId, memberId: SessionStore.user.UserId, chatMessageId: result.value.messageId}) } return ok(true) } @@ -116,6 +120,14 @@ export class MessageRepositoryService { } sendTyping(roomId) { - return this.messageLiveSignalRDataSourceService.sendTyping({roomId, UserName:SessionStore.user.FullName}) + return this.messageLiveSignalRDataSourceService.sendTyping({ + roomId, + UserName:SessionStore.user.FullName, + userId: SessionStore.user.UserId + }) + } + + getMemberByLive({roomId, userId}) { + } } diff --git a/src/app/module/chat/data/repository/room-repository.service.ts b/src/app/module/chat/data/repository/room-repository.service.ts index 5bdd88347..d76ed1428 100644 --- a/src/app/module/chat/data/repository/room-repository.service.ts +++ b/src/app/module/chat/data/repository/room-repository.service.ts @@ -64,7 +64,7 @@ export class RoomRepositoryService { // }, // } - this.roomLocalDataSourceService.createRoom(roomData) + this.roomLocalDataSourceService.createRoom(roomData.chatRoom) } for( const roomData of roomsToUpdate) { @@ -78,7 +78,7 @@ export class RoomRepositoryService { // }, // } - this.roomLocalDataSourceService.updateRoom(roomData) + this.roomLocalDataSourceService.updateRoom(roomData.chatRoom) } for( const roomData of roomsToDelete) { @@ -105,15 +105,15 @@ export class RoomRepositoryService { if(result.isOk()) { const localList = await this.roomLocalDataSourceService.getRoomList() - const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges([result.value.data], localList) + // const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges([result.value.data], localList) - for( const roomData of roomsToUpdate) { - if(!roomData.createdBy?.wxUserId) { - delete roomData.createdBy; - } + // for( const roomData of roomsToUpdate) { + // if(!roomData.chatRoom.createdBy?.wxUserId) { + // delete roomData.chatRoom.createdBy; + // } - this.roomLocalDataSourceService.updateRoom(roomData) - } + // this.roomLocalDataSourceService.updateRoom(roomData.chatRoom) + // } } @@ -127,10 +127,13 @@ export class RoomRepositoryService { if(result.isOk()) { const localListRoom = await this.roomLocalDataSourceService.getRoomList() - const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges([result.value.data], localListRoom) + const object = { + chatRoom: result.value.data + } + const { roomsToDelete, roomsToInsert, roomsToUpdate } = roomListDetermineChanges([object], localListRoom) for( const roomData of roomsToUpdate) { - this.roomLocalDataSourceService.updateRoom(roomData) + this.roomLocalDataSourceService.updateRoom(roomData.chatRoom) } // ============================ diff --git a/src/app/module/chat/infra/socket/signal-r.service.ts b/src/app/module/chat/infra/socket/signal-r.service.ts index 0df841b0e..c497a31b8 100644 --- a/src/app/module/chat/infra/socket/signal-r.service.ts +++ b/src/app/module/chat/infra/socket/signal-r.service.ts @@ -88,8 +88,8 @@ export class SignalRService { this.establishConnection() } - async sendTyping({roomId, UserName}) { - return await this.connection.typing({ roomId, UserName}) + async sendTyping({roomId, UserName, userId}) { + return await this.connection.typing({ roomId, UserName, userId}) } async sendReadAt({ roomId, memberId, chatMessageId}) { diff --git a/src/app/module/chat/infra/socket/signalR.ts b/src/app/module/chat/infra/socket/signalR.ts index e1097b486..3fab3a0ce 100644 --- a/src/app/module/chat/infra/socket/signalR.ts +++ b/src/app/module/chat/infra/socket/signalR.ts @@ -108,14 +108,20 @@ export class SignalRConnection { }) } - public async typing(data: Object & { roomId, UserName}):Promise> { + public async typing(data: Object & { roomId, UserName, userId }):Promise> { return new Promise((resolve, reject) => { const requestId = uuidv4() if(this.connectionStateSubject.value == true) { + console.log('send typing', data) try { - this.hubConnection.invoke("Typing", {userName: data.UserName, roomId: data.roomId, requestId} as any) + this.hubConnection.invoke("Typing", { + userName: data.UserName, + roomId: data.roomId, + userId: data.userId +'', + requestId + } as any) } catch (error) {} diff --git a/src/app/services/monitoring/opentelemetry/matrix.ts b/src/app/services/monitoring/opentelemetry/matrix.ts index ad038fd5f..8c246873a 100644 --- a/src/app/services/monitoring/opentelemetry/matrix.ts +++ b/src/app/services/monitoring/opentelemetry/matrix.ts @@ -1,6 +1,8 @@ import { metrics } from '@opentelemetry/api'; import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'; import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; +import { Subject } from 'rxjs'; +import { throttleTime } from 'rxjs/operators'; import { environment } from 'src/environments/environment'; // Initialize OpenTelemetry metrics @@ -10,15 +12,28 @@ metrics.setGlobalMeterProvider(meterProvider); if (window.location.protocol !== 'https:' && environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') { const metricReader = new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter({ - url: 'http://5-180-182-151.cloud-xip.com:4318/v1/metrics', + url: 'https://5-180-182-151.cloud-xip.com:85/collector2/v1/metrics', // headers: { // 'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'), // } }), - exportIntervalMillis: 3000, + exportIntervalMillis: 30000, }); meterProvider.addMetricReader(metricReader); + + const subject = new Subject() + + subject + .pipe( + throttleTime(5000) // 5000 milliseconds = 5 seconds + ) + .subscribe(() => { + metricReader.forceFlush().then(() => { + console.log('Metrics exported'); + }); + }); + } export const meter = meterProvider.getMeter('example-exporter-collector'); export const RequestCounter = meter.createCounter('post_requests', { diff --git a/src/app/services/monitoring/opentelemetry/opentelemetry.ts b/src/app/services/monitoring/opentelemetry/opentelemetry.ts index 991acda00..fa1461e83 100644 --- a/src/app/services/monitoring/opentelemetry/opentelemetry.ts +++ b/src/app/services/monitoring/opentelemetry/opentelemetry.ts @@ -3,6 +3,7 @@ import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions' import { Resource } from '@opentelemetry/resources'; +import { OTLPTraceExporter } from '@opentelemetry/exporter-otlp-http'; import { context, trace, propagation } from '@opentelemetry/api'; function createProvider(serviceName) { @@ -35,7 +36,6 @@ export const OpentelemetryInterceptorProvider = createProvider('FO-interceptor') export const OpentelemetryPublicationProvider = createProvider('FO-publication-service'); export const OpentelemetryLogging = createProvider('logging'); - const tracerInstance = OpentelemetryAgendaProvider.getTracer('example-tracer-hole', '111', {}) @@ -84,4 +84,4 @@ function childSpanExample(parentContext) { }, 500); } -parentSpanExample() +// parentSpanExample() diff --git a/src/app/services/monitoring/opentelemetry/tracer.ts b/src/app/services/monitoring/opentelemetry/tracer.ts index b09f863b9..cfc0bfc76 100644 --- a/src/app/services/monitoring/opentelemetry/tracer.ts +++ b/src/app/services/monitoring/opentelemetry/tracer.ts @@ -8,7 +8,9 @@ import { environment } from 'src/environments/environment'; import { UseCaseCounter } from './matrix'; import { openTelemetryLogging } from './logging'; // import { context, propagation } from '@opentelemetry/api'; - +import { + SpanStatus, SpanStatusCode +} from '@opentelemetry/api'; const tracerInstance = OpentelemetryAgendaProvider.getTracer('example-tracer-hole', '111', {}) const tracerNotificationInstance = OpentelemetryNotificationProvider.getTracer('example-tracer-hole', '111', {}) // const logger: ILoggerAdapter = new ColoredLoggerService() @@ -53,15 +55,16 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp const data = { event: {}, - tags: {} + tags: {}, + status: {} as any, } - return { + const returnObject = { span: span as any, tracer: tracerInstance, tracerId: requestId, attributes: SemanticAttributes, - setStatus: (status: any) => { + setStatus: (status: SpanStatus) => { span.setStatus(status); }, addEvent: (context: string, message?: any, obj?: any) => { @@ -79,7 +82,7 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp span.setAttribute(key, value); if(key =='outcome' && value == 'failed') { - span.setAttribute('error', 'true') + returnObject.hasError('error') } }, log(message: string, data: Object) { @@ -110,18 +113,25 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp finish: () => { if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') { span.end(); - UseCaseCounter.add(1, {user: SessionStore?.user?.FullName, outcome:data.tags['outcome'], usecase: name}) + UseCaseCounter.add(1, {user: SessionStore?.user?.FullName, outcome:data.tags['outcome'] || data.status?.code , usecase: name}) } - if(bugPrint && data.tags['outcome'] == 'failed') { + if(bugPrint && (data.tags['outcome'] == 'failed' || data.status?.code == SpanStatusCode.ERROR)) { console.error(name, data) } }, - bugFlag:() => {}, + hasError:(message: string) => { + if(data.status?.code != SpanStatusCode.ERROR) { + data.status = {code: SpanStatusCode.ERROR, message} + span.setStatus({code: SpanStatusCode.ERROR, message}) + span.setAttribute('outcome','failed') + } + }, createSpan: (name, parent?: any) => { return tracerInstance.startSpan(name, { root: false }, parent) as Span; } } + return returnObject } export function XTracerAsync({ name, bugPrint, module = null, autoFinish = true, daley =0 }) { @@ -221,7 +231,7 @@ export type TracingType = { getAttribute: (key: string) => string; LocalLogEvent: (name: string, attributesOrStartTime: any, obj?:any) => void; finish: () => void; - bugFlag:() => void; + hasError:(message: string) => void; createSpan:(name, parent?: any) => Span; }; diff --git a/src/app/shared/chat/messages/messages.page.ts b/src/app/shared/chat/messages/messages.page.ts index a11f7b6e8..8fcfe9b4e 100644 --- a/src/app/shared/chat/messages/messages.page.ts +++ b/src/app/shared/chat/messages/messages.page.ts @@ -153,6 +153,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy } ngOnChanges(changes: SimpleChanges): void { + console.log('change ¬!!') this.roomData$ = this.roomRepositoryService.getItemByIdLive(this.roomId) this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId) this.roomMembers$ = this.roomRepositoryService.getRoomMemberByIdLive(this.roomId) as any @@ -179,9 +180,10 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy this.scrollToBottomClicked() }, 200) - this.messageRepositoryService.sendReadAt({roomId: this.roomId}).then((e) => { - console.log(e) - }) + console.log('new message==============') + // this.messageRepositoryService.sendReadAt({roomId: this.roomId}).then((e) => { + // console.log(e) + // }) })