127 lines
4.2 KiB
TypeScript
127 lines
4.2 KiB
TypeScript
import { Injectable } from '@angular/core';
|
||
import { HttpClient } from '@angular/common/http';
|
||
import {Observable, Subject} from 'rxjs';
|
||
import { GlobalConstants } from '../global-constants';
|
||
|
||
import SockJS from 'sockjs-client';
|
||
import { Client, IMessage } from '@stomp/stompjs';
|
||
|
||
// Унифицируем название интерфейса для списка контейнеров
|
||
export interface DockerContainer {
|
||
id: string;
|
||
name: string;
|
||
image: string;
|
||
state: string; // running, exited, etc.
|
||
status: string; // Up 2 hours, etc.
|
||
}
|
||
|
||
// Интерфейс Project в соответствии с Project.java[cite: 3]
|
||
export interface Project {
|
||
id: string;
|
||
name: string;
|
||
user?: any; // Соответствует полю private User user в Java[cite: 3]
|
||
status: string;
|
||
localPath: string;
|
||
createdAt: Date;
|
||
containers?: DockerContainer[];
|
||
}
|
||
|
||
export interface ProjectCreateRequest {
|
||
name: string;
|
||
rawComposeContent: string;
|
||
}
|
||
|
||
export interface ProjectDetailResponse {
|
||
project: Project;
|
||
config: {
|
||
projectId: string;
|
||
rawComposeContent: string;
|
||
envVariables: { [key: string]: string };
|
||
};
|
||
}
|
||
|
||
@Injectable({
|
||
providedIn: 'root'
|
||
})
|
||
export class ProjectService {
|
||
// Используем baseUrl, как определено в начале класса
|
||
private baseUrl = GlobalConstants.API_URL;
|
||
private stompClient: Client | null = null;
|
||
|
||
constructor(private http: HttpClient) {}
|
||
|
||
// Создание нового проекта[cite: 4, 5]
|
||
createProject(request: ProjectCreateRequest): Observable<Project> {
|
||
return this.http.post<Project>(`${this.baseUrl}/user/projects`, request);
|
||
}
|
||
|
||
// Методы для Dashboard[cite: 4, 5]
|
||
getUserProjects(): Observable<Project[]> {
|
||
return this.http.get<Project[]>(`${this.baseUrl}/user/projects`);
|
||
}
|
||
|
||
getProjectDetails(id: string): Observable<ProjectDetailResponse> {
|
||
return this.http.get<ProjectDetailResponse>(`${this.baseUrl}/user/projects/${id}/details`);
|
||
}
|
||
|
||
// Управление жизненным циклом (Docker Compose)[cite: 3, 4]
|
||
deployProject(id: string): Observable<string> {
|
||
return this.http.post(`${this.baseUrl}/user/projects/${id}/deploy`, {}, { responseType: 'text' });
|
||
}
|
||
|
||
stopProject(id: string): Observable<string> {
|
||
return this.http.post(`${this.baseUrl}/user/projects/${id}/stop`, {}, { responseType: 'text' });
|
||
}
|
||
|
||
deleteProject(id: string): Observable<any> {
|
||
return this.http.delete(`${this.baseUrl}/user/projects/${id}`);
|
||
}
|
||
|
||
// Администрирование[cite: 4]
|
||
getAllProjectsAdmin(): Observable<Project[]> {
|
||
return this.http.get<Project[]>(`${this.baseUrl}/admin/projects/all`);
|
||
}
|
||
|
||
// WebSocket для трансляции логов в реальном времени[cite: 3, 5]
|
||
public connectToDockerLogs(containerId: string): Observable<string> {
|
||
const logSubject = new Subject<string>();
|
||
|
||
// Твой эндпоинт из WebSocketConfig.java
|
||
const socket = new SockJS(`${this.baseUrl}/ws-jambotron`);
|
||
|
||
this.stompClient = new Client({
|
||
webSocketFactory: () => socket,
|
||
debug: (str) => console.log(str),
|
||
onConnect: () => {
|
||
// 1. Подписываемся на логи конкретного контейнера
|
||
this.stompClient?.subscribe(`/topic/logs/${containerId}`, (message: IMessage) => {
|
||
logSubject.next(message.body);
|
||
});
|
||
|
||
// 2. Отправляем сигнал бэкенду начать стриминг (согласно LogController)
|
||
this.stompClient?.publish({
|
||
destination: '/app/start-logs',
|
||
body: containerId
|
||
});
|
||
},
|
||
onStompError: (frame) => {
|
||
logSubject.error('Broker error: ' + frame.headers['message']);
|
||
}
|
||
});
|
||
|
||
this.stompClient.activate();
|
||
return logSubject.asObservable();
|
||
}
|
||
|
||
public disconnectLogs(): void {
|
||
if (this.stompClient) {
|
||
this.stompClient.deactivate();
|
||
}
|
||
}
|
||
|
||
// ИСПРАВЛЕНО: возвращаем DockerContainer и используем правильный baseUrl[cite: 5]
|
||
getProjectContainers(projectId: string): Observable<DockerContainer[]> {
|
||
return this.http.get<DockerContainer[]>(`${this.baseUrl}/user/projects/${projectId}/containers`);
|
||
}
|
||
}
|