Skip to content

Commit

Permalink
Frontend operations center begin (#208)
Browse files Browse the repository at this point in the history
* chore: Update RaagService to include SiloRepository (#197)

* Renaming route home to operations-center

* Operations Center updates

* Adding fake endpoints on backends to allow auth

* On 404 error, deliver index.html (SPA)

* Begin using pre-commit to lint over files

* chore: Refactor OpenAiCompatibleV1ApiControllerTest to improve code readability and remove unused imports

* chore: Add ErrorHandlerController to handle errors and deliver index.html on 404 error (SPA)

* Updating frontend dependencies

* chore: Update operations center to fetch numbers on page activation

* refactor: Rename header-banner.vue to infrastructure-overall.vue and card-data.vue to jvm-cards.vue

* Improving how to retrieve env vars for Testing

* Frontend : adding infrastructure overall

* chore: Update npm dependencies to latest versions

* chore: Add error handling for delivering index.html on 404 error (SPA)

* refactor: Update icons in jvm-cards.vue for better visual representation

* chore: Add SystemMonitoringServiceTest for system monitoring functionality
  • Loading branch information
amengus87 authored Aug 2, 2024
1 parent 8dea533 commit 61e6918
Show file tree
Hide file tree
Showing 59 changed files with 812 additions and 729 deletions.
3 changes: 3 additions & 0 deletions .devcontainer/postStart.sh
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
cp .devcontainer/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

echo "Let's go for a dRAGon ride! 🐉"
2 changes: 2 additions & 0 deletions .devcontainer/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
gradle pnpmLint checkstyleMain checkstyleTest --no-daemon --quiet
10 changes: 8 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ jobs:
- name: Set Frontend Version
run: pnpm version from-git --no-git-tag-version --prefix frontend

- name: Lint Frontend
run: gradle pnpmInstall pnpmLint

- name: Lint Backend
run: gradle checkstyleMain checkstyleTest

- name: Test dRAGon
run: gradle pnpmInstall pnpmLint checkstyleMain checkstyleTest test --stacktrace
run: gradle test

- name: Build dRAGon
- name: Package dRAGon
run: gradle bootJar -Pversion=$(gradle cV -q -Prelease.quiet)

- name: Upload coverage reports to Codecov
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ bin
.vscode
.DS_Store
*.class
.pnpm-store
.pnpm-store
.env.local
3 changes: 2 additions & 1 deletion backend/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build
build
.env.local
5 changes: 1 addition & 4 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ dependencies {

implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
implementation 'org.jobrunr:jobrunr-spring-boot-3-starter:7.2.2'
implementation 'me.paulschwarz:spring-dotenv:4.0.0'

testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'org.awaitility:awaitility:4.2.1'
Expand Down Expand Up @@ -130,10 +131,6 @@ tasks.register("bootProdRun") {
}
}

jacoco {
toolVersion = "0.8.12"
}

tasks.register('copyWebApp', Copy) {
dependsOn(':frontend:pnpmBuild')
from "$rootDir/frontend/dist"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ai.dragon.controller;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class ErrorHandlerController implements ErrorController {
// We are using a SPA (Single Page Application) so we need to output the
// index.html file when an error occurs :
@RequestMapping("/error")
public @ResponseBody byte[] getImage() throws IOException {
InputStream in = getClass().getResourceAsStream("/static/index.html");
if (in == null) {
throw new IOException("index.html not found");
}
return IOUtils.toByteArray(in);
}

public String getErrorPath() {
return "/error";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ai.dragon.controller.api.app;

import java.util.List;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import ai.dragon.dto.api.GenericApiResponse;
import ai.dragon.dto.api.SuccessApiResponse;
import ai.dragon.dto.api.app.auth.LoginAuthAppApiData;
import ai.dragon.dto.api.app.auth.UserInfoAuthAppApiData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/api/app/auth")
@Tag(name = "Authentication", description = "Authentication API Endpoints")
public class AuthAppApiController {
@PostMapping("/login")
@Operation(summary = "Login", description = "Login to the application.")
public GenericApiResponse login() {
return SuccessApiResponse.builder().data(LoginAuthAppApiData
.builder()
.token("TOKEN_WILL_BE_HERE")
.refreshToken("REFRESH_TOKEN_WILL_BE_HERE")
.build())
.build();
}

@GetMapping("/getUserInfo")
@Operation(summary = "Get User Info", description = "Get user info.")
public GenericApiResponse getUserInfo() {
return SuccessApiResponse.builder().data(UserInfoAuthAppApiData
.builder()
.userId("TODO")
.userName("dRAGon")
.roles(List.of("R_SUPER"))
.build())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ai.dragon.controller.api.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import ai.dragon.dto.api.GenericApiResponse;
import ai.dragon.dto.api.SuccessApiResponse;
import ai.dragon.dto.api.app.dashboard.NumbersDashboardAppApiData;
import ai.dragon.repository.DocumentRepository;
import ai.dragon.repository.FarmRepository;
import ai.dragon.repository.SiloRepository;
import ai.dragon.service.SystemMonitoringService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

@RestController
@RequestMapping("/api/app/dashboard")
@Tag(name = "Operations Center", description = "Dashboard API Endpoints")
public class DashboardAppApiController {
@Autowired
private SiloRepository siloRepository;

@Autowired
private FarmRepository farmRepository;

@Autowired
private DocumentRepository documentRepository;

@Autowired
private SystemMonitoringService systemMonitoringService;

@GetMapping("/numbers")
@Operation(summary = "Get Dashboard main numbers", description = "Returns the main numbers of the dashboard.")
public GenericApiResponse numbers() {
return SuccessApiResponse.builder().data(NumbersDashboardAppApiData
.builder()
.silos(siloRepository.countAll())
.farms(farmRepository.countAll())
.documents(documentRepository.countAll())
.systemLoadAverage(systemMonitoringService.getSystemLoadAverage())
.availableProcessors(systemMonitoringService.getAvailableProcessors())
.arch(systemMonitoringService.getArch())
.usedMemory(systemMonitoringService.getUsedMemory())
.totalMemory(systemMonitoringService.getTotalMemory())
.freeMemory(systemMonitoringService.getFreeMemory())
.usedMemoryPercentage(systemMonitoringService.getUsedMemoryPercentage())
.freeMemoryPercentage(systemMonitoringService.getFreeMemoryPercentage())
.uptime(systemMonitoringService.getUptime())
.heapMemoryUsage(systemMonitoringService.getHeapMemoryUsage())
.heapMemoryUsagePercentage(systemMonitoringService.getHeapMemoryUsagePercentage())
.nonHeapMemoryUsage(systemMonitoringService.getNonHeapMemoryUsage())
.heapMemoryMax(systemMonitoringService.getHeapMemoryMax())
.heapMemoryCommitted(systemMonitoringService.getHeapMemoryCommitted())
.nonHeapMemoryCommitted(systemMonitoringService.getNonHeapMemoryCommitted())
.heapMemoryInit(systemMonitoringService.getHeapMemoryInit())
.nonHeapMemoryInit(systemMonitoringService.getNonHeapMemoryInit())
.build())
.build();
}
}
5 changes: 5 additions & 0 deletions backend/src/main/java/ai/dragon/dto/api/GenericApiData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ai.dragon.dto.api;

public interface GenericApiData {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ai.dragon.dto.api;

public interface GenericApiResponse {
public GenericApiData getData();
public String getCode();
public String getMsg();
}
17 changes: 17 additions & 0 deletions backend/src/main/java/ai/dragon/dto/api/SuccessApiResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ai.dragon.dto.api;

import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class SuccessApiResponse implements GenericApiResponse {
@Builder.Default
private GenericApiData data = null;

@Builder.Default
private String code = "0000";

@Builder.Default
private String msg = "OK";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ai.dragon.dto.api.app.auth;

import ai.dragon.dto.api.GenericApiData;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class LoginAuthAppApiData implements GenericApiData {
private String token;
private String refreshToken;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ai.dragon.dto.api.app.auth;

import java.util.List;

import ai.dragon.dto.api.GenericApiData;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class UserInfoAuthAppApiData implements GenericApiData {
private String userId;
private String userName;
private List<String> roles;
private List<String> buttons;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ai.dragon.dto.api.app.dashboard;

import ai.dragon.dto.api.GenericApiData;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class NumbersDashboardAppApiData implements GenericApiData {
private Long silos;
private Long farms;
private Long documents;
private Double systemLoadAverage;
private Integer availableProcessors;
private String arch;
private Long usedMemory;
private Long totalMemory;
private Long freeMemory;
private Long usedMemoryPercentage;
private Long freeMemoryPercentage;
private Long uptime;
private Long heapMemoryUsage;
private Long heapMemoryUsagePercentage;
private Long nonHeapMemoryUsage;
private Long heapMemoryMax;
private Long heapMemoryCommitted;
private Long nonHeapMemoryCommitted;
private Long heapMemoryInit;
private Long nonHeapMemoryInit;
}
15 changes: 11 additions & 4 deletions backend/src/main/java/ai/dragon/service/RaagService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
import ai.dragon.dto.openai.completion.OpenAiRequest;
import ai.dragon.dto.openai.model.OpenAiModel;
import ai.dragon.entity.FarmEntity;
import ai.dragon.entity.SiloEntity;
import ai.dragon.properties.embedding.LanguageModelSettings;
import ai.dragon.properties.raag.RetrievalAugmentorSettings;
import ai.dragon.repository.FarmRepository;
import ai.dragon.repository.SiloRepository;
import ai.dragon.util.KVSettingUtil;
import ai.dragon.util.ai.AiAssistant;
import ai.dragon.util.spel.MetadataHeaderFilterExpressionParserUtil;
Expand Down Expand Up @@ -60,6 +62,9 @@ public class RaagService {
@Autowired
private FarmRepository farmRepository;

@Autowired
private SiloRepository siloRepository;

@Autowired
private ChatMessageService chatMessageService;

Expand Down Expand Up @@ -106,18 +111,20 @@ public List<ContentRetriever> buildRetrieverList(FarmEntity farm, HttpServletReq
}
farm.getSilos().forEach(siloUuid -> {
try {
this.buildRetriever(siloUuid, servletRequest).ifPresent(retrievers::add);
SiloEntity silo = siloRepository.getByUuid(siloUuid).orElseThrow();
this.buildSiloRetriever(silo, servletRequest).ifPresent(retrievers::add);
} catch (Exception ex) {
logger.error("Error building Content Retriever for Silo '{}'", siloUuid, ex);
}
});
// TODO Granaries
return retrievers;
}

public Optional<ContentRetriever> buildRetriever(UUID siloUuid, HttpServletRequest servletRequest)
public Optional<ContentRetriever> buildSiloRetriever(SiloEntity silo, HttpServletRequest servletRequest)
throws Exception {
EmbeddingModel embeddingModel = embeddingModelService.modelForSilo(siloUuid);
EmbeddingStore<TextSegment> embeddingStore = embeddingStoreService.retrieveEmbeddingStore(siloUuid);
EmbeddingModel embeddingModel = embeddingModelService.modelForSilo(silo.getUuid());
EmbeddingStore<TextSegment> embeddingStore = embeddingStoreService.retrieveEmbeddingStore(silo.getUuid());
return Optional.of(EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
Expand Down
Loading

0 comments on commit 61e6918

Please sign in to comment.