You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@hertzbeat.apache.org by go...@apache.org on 2024/09/05 14:27:10 UTC

(hertzbeat) 02/02: [bugfix] remove serviceaccount and servicetoken pojo

This is an automated email from the ASF dual-hosted git repository.

gongchao pushed a commit to branch grafana-update
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git

commit 378d1d0ec46915bd20f8ddaed16c6fdedbe888ca
Author: tomsun28 <to...@outlook.com>
AuthorDate: Thu Sep 5 14:35:06 2024 +0800

    [bugfix] remove serviceaccount and servicetoken pojo
    
    Signed-off-by: tomsun28 <to...@outlook.com>
---
 .../common/entity/grafana/ServiceAccount.java      |  67 -------
 .../apache/hertzbeat/common/util/CommonUtil.java   |  37 ++++
 .../hertzbeat/grafana/common/GrafanaConstants.java |  29 +--
 .../hertzbeat/grafana/config/GrafanaInit.java      |  22 +--
 .../grafana/controller/DashboardController.java    |   4 -
 .../controller/ServiceAccountController.java       | 119 ------------
 ...{ServiceTokenDao.java => GrafanaConfigDao.java} |  23 ++-
 .../hertzbeat/grafana/dao/ServiceAccountDao.java   |  38 ----
 .../hertzbeat/grafana/dto/GrafanaConfig.java       |  29 +--
 .../grafana/service/DashboardService.java          |   4 +-
 .../grafana/service/DatasourceService.java         |  96 +++-------
 .../grafana/service/ServiceAccountService.java     | 202 ++++++---------------
 12 files changed, 158 insertions(+), 512 deletions(-)

diff --git a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceAccount.java b/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceAccount.java
deleted file mode 100644
index c201a279f..000000000
--- a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceAccount.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.common.entity.grafana;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-
-/**
- * Grafana service account entity
- */
-@Entity
-@Table(name = "hzb_grafana_service_account")
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-@Schema(description = "Grafana service account entity")
-public class ServiceAccount {
-
-    @Id
-    @Schema(description = "Service account id")
-    private Long id;
-
-    @Schema(description = "Service account name")
-    private String name;
-
-    @Schema(description = "Service account role")
-    private String role;
-    
-    @Schema(description = "Service account is disabled")
-    private Boolean isDisabled;
-    
-    @Schema(description = "Service account tokens")
-    private Integer tokens;
-    
-    @Schema(description = "Service account avatar url")
-    private String avatarUrl;
-    
-    @Schema(description = "Service account login")
-    private String login;
-    
-    @Schema(description = "Service account orgId")
-    private Integer orgId;
-
-}
diff --git a/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java b/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java
index 88c0e7167..35d6a5762 100644
--- a/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java
+++ b/common/src/main/java/org/apache/hertzbeat/common/util/CommonUtil.java
@@ -23,6 +23,7 @@ import java.time.LocalTime;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import lombok.extern.slf4j.Slf4j;
@@ -223,4 +224,40 @@ public final class CommonUtil {
         }
     }
 
+    /**
+     * generate random word
+     * @param length length
+     * @return words
+     */
+    public static String generateRandomWord(int length) {
+        StringBuilder word = new StringBuilder();
+        Random random = new Random();
+        // 'a' ASCII
+        int minVowel = 97;
+        // 'z' ASCII
+        int maxVowel = 122;
+        // 'A' ASCII
+        int minConsonant = 65;
+        // 'Z' ASCII
+        int maxConsonant = 90;
+        // '0' ASCII
+        int minDigit = 48;
+        // '9' ASCII
+        int maxDigit = 57;
+        word.append((char) (minVowel + random.nextInt(5)));
+        for (int i = 1; i < length; i++) {
+            switch (random.nextInt(3)) {
+                case 0:
+                    word.append((char) (minVowel + random.nextInt(5)));
+                    break;
+                case 1:
+                    word.append((char) (minDigit + random.nextInt(10)));
+                    break;
+                default:
+                    word.append((char) (minConsonant + random.nextInt(26)));
+                    break;
+            }
+        }
+        return word.toString();
+    }
 }
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java
index f61507664..36712c1a4 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/common/GrafanaConstants.java
@@ -21,6 +21,7 @@ package org.apache.hertzbeat.grafana.common;
  * Grafana Common Constants
  */
 public interface GrafanaConstants {
+    
     String HTTP = "http://";
 
     String HTTPS = "https://";
@@ -30,10 +31,6 @@ public interface GrafanaConstants {
     String REFRESH = "&refresh=15s";
 
     String INSTANCE = "&var-instance=";
-
-    String AUTHORIZATION = "Authorization";
-    
-    String BEARER = "Bearer ";
     
     String CREATE_DASHBOARD_API = "/api/dashboards/db";
     
@@ -41,37 +38,29 @@ public interface GrafanaConstants {
     
     String DATASOURCE_NAME = "hertzbeat-victoria-metrics";
     
+    String USE_DATASOURCE = "&var-ds=" + DATASOURCE_NAME;
+    
     String DATASOURCE_TYPE = "prometheus";
     
     String DATASOURCE_ACCESS = "proxy";
     
-    String CREATE_DATASOURCE_API = "%s:%s@%s/api/datasources";
+    String CREATE_DATASOURCE_API = "/api/datasources";
     
-    String DELETE_DATASOURCE_API = "%s:%s@%s/api/datasources/name/%s";  
+    String QUERY_DATASOURCE_API = "/api/datasources/name/" + DATASOURCE_NAME;
     
+    String GET_SERVICE_ACCOUNTS_API = "%s:%s@%s/api/serviceaccounts/search";
+
     String ACCOUNT_NAME = "hertzbeat";
     
     String ACCOUNT_ROLE = "Admin";
     
-    String ACCOUNT_TOKEN_NAME = "hertzbeat-token";
-    
     String CREATE_SERVICE_ACCOUNT_API = "%s:%s@%s/api/serviceaccounts";
     
-    String GET_SERVICE_ACCOUNTS_API = "%s:%s@%s/api/serviceaccounts/search";
-    
-    String DELETE_SERVICE_ACCOUNT_API = "%s:%s@%s/api/serviceaccounts/%d";
-    
     String CREATE_SERVICE_TOKEN_API = "%s:%s@%s/api/serviceaccounts/%d/tokens";
-    
-    String GET_SERVICE_TOKENS_API = "%s:%s@%s/api/serviceaccounts/%d/tokens";
-
-    String NAME = "name";
 
     String APPLICATION_JSON = "application/json";
-    
-    String HERTZBEAT_TOKEN = "hertzbeat-token";
-
-    String TYPE = "type";
 
     String URL = "url";
+
+    String GRAFANA_CONFIG = "grafanaConfig";
 }
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java
index 4da2bf863..7b8537c52 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/config/GrafanaInit.java
@@ -42,21 +42,17 @@ public class GrafanaInit implements CommandLineRunner {
     //3. Determine whether there is a token, if not, create and ensure that the account is unique.
     @Override
     public void run(String... args) throws Exception {
-        if (grafanaProperties.enabled() && grafanaProperties.url() != null && grafanaProperties.username() != null && grafanaProperties.password() != null) {
+        if (grafanaProperties.enabled()) {
+            log.info("grafana init start");
             try {
-                serviceAccountService.getAccount();
-            } catch (RuntimeException e) {
-                log.error("service account is not exist, create service account");
-                serviceAccountService.createServiceAccount();
+                String token = serviceAccountService.getToken();
+                if (token == null) {
+                    token = serviceAccountService.applyForToken();
+                }
+                datasourceService.existOrCreateDatasource(token);   
+            } catch (Exception e) {
+                log.error("grafana init error", e);
             }
-            try {
-                serviceAccountService.getToken();
-            } catch (RuntimeException e) {
-                log.error("service token is not exist, create service token");
-                serviceAccountService.createToken();
-            }
-            datasourceService.deleteDatasource();
-            datasourceService.createDatasource();
         }
     }
 
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
index a1a462ba2..0201566f3 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/DashboardController.java
@@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.common.entity.dto.Message;
 import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
-import org.apache.hertzbeat.grafana.config.GrafanaProperties;
 import org.apache.hertzbeat.grafana.service.DashboardService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
@@ -48,9 +47,6 @@ public class DashboardController {
     @Autowired
     private DashboardService dashboardService;
 
-    @Autowired
-    private GrafanaProperties grafanaProperties;
-
     /**
      * Creates a new Grafana dashboard.
      *
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/ServiceAccountController.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/ServiceAccountController.java
deleted file mode 100644
index 983fab1e3..000000000
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/controller/ServiceAccountController.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.grafana.controller;
-
-import static org.apache.hertzbeat.common.constants.CommonConstants.FAIL_CODE;
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.apache.hertzbeat.common.entity.dto.Message;
-import org.apache.hertzbeat.grafana.service.ServiceAccountService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-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;
-
-/**
- * Controller for managing Grafana service accounts and tokens via API.
- */
-@Tag(name = "Service Account API")
-@RestController
-@RequestMapping(path = "/api/grafana/service-account", produces = {APPLICATION_JSON_VALUE})
-public class ServiceAccountController {
-
-    @Autowired
-    private ServiceAccountService serviceAccountService;
-
-    /**
-     * Creates a new service admin account.
-     *
-     * @return ResponseEntity containing the result of the account creation
-     */
-    @PostMapping(path = "/account")
-    @Operation(summary = "Create service account", description = "Create service account")
-    public ResponseEntity<Message<?>> createServiceAccount() {
-        try {
-            ResponseEntity<String> response = serviceAccountService.createServiceAccount();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    /**
-     * Retrieves all service accounts.
-     *
-     * @return ResponseEntity containing the list of service accounts
-     */
-    @GetMapping(path = "/accounts")
-    @Operation(summary = "Get service account", description = "Get service account")
-    public ResponseEntity<Message<?>> getServiceAccount() {
-        try {
-            ResponseEntity<String> response = serviceAccountService.getAccounts();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    /**
-     * Creates a new API token for a service account.
-     *
-     * @return ResponseEntity containing the result of the token creation
-     */
-    @PostMapping(path = "/token")
-    @Operation(summary = "Create service account token", description = "Create service account token")
-    public ResponseEntity<Message<?>> createToken() {
-        try {
-            ResponseEntity<String> response = serviceAccountService.createToken();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    /**
-     * Retrieves all API tokens for service accounts.
-     *
-     * @return ResponseEntity containing the list of tokens
-     */
-    @GetMapping(path = "/tokens")
-    @Operation(summary = "Get service account token", description = "Get service account token")
-    public ResponseEntity<Message<?>> getToken() {
-        try {
-            ResponseEntity<String> response = serviceAccountService.getTokens();
-            return handleResponse(response);
-        } catch (Exception e) {
-            return handleException(e);
-        }
-    }
-
-    private ResponseEntity<Message<?>> handleResponse(ResponseEntity<String> response) {
-        if (response.getStatusCode().is2xxSuccessful()) {
-            return ResponseEntity.ok(Message.success(response.getBody()));
-        }
-        return ResponseEntity.ok(Message.fail(FAIL_CODE, response.getBody()));
-    }
-
-    private ResponseEntity<Message<?>> handleException(Exception e) {
-        return ResponseEntity.ok(Message.fail(FAIL_CODE, e.getMessage()));
-    }
-}
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceTokenDao.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/GrafanaConfigDao.java
similarity index 63%
rename from grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceTokenDao.java
rename to grafana/src/main/java/org/apache/hertzbeat/grafana/dao/GrafanaConfigDao.java
index bb7d67e56..1a74bb05b 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceTokenDao.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/GrafanaConfigDao.java
@@ -17,21 +17,20 @@
 
 package org.apache.hertzbeat.grafana.dao;
 
-import org.apache.hertzbeat.common.entity.grafana.ServiceToken;
+import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
- * ServiceAccount Dao
+ * Public server configuration Dao
+ * <p>This interface inherits the two interfaces JpaRepository and JpaSpecificationExecutor, providing basic CRUD operations and specification query capabilities.</p>
  */
-public interface ServiceTokenDao extends JpaRepository<ServiceToken, Long>, JpaSpecificationExecutor<ServiceToken> {
-    ServiceToken findByName(String name);
-
-    @Transactional
-    @Modifying
-    @Query(value = "truncate table hzb_grafana_service_token", nativeQuery = true)
-    void truncate();
+public interface GrafanaConfigDao extends JpaRepository<GeneralConfig, Long>, JpaSpecificationExecutor<GeneralConfig> {
+    
+    /**
+     * Query by type
+     * @param type type
+     * @return Return the queried configuration information
+     */
+    GeneralConfig findByType(String type);
 }
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceAccountDao.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceAccountDao.java
deleted file mode 100644
index ec47f495f..000000000
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/dao/ServiceAccountDao.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.grafana.dao;
-
-import org.apache.hertzbeat.common.entity.grafana.ServiceAccount;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * ServiceAccount Dao
- */
-public interface ServiceAccountDao extends JpaRepository<ServiceAccount, Long>, JpaSpecificationExecutor<ServiceAccount> {
-
-    ServiceAccount findByName(String name);
-
-    @Transactional
-    @Modifying
-    @Query(value = "truncate table hzb_grafana_service_account", nativeQuery = true)
-    void truncate();
-}
diff --git a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceToken.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/dto/GrafanaConfig.java
similarity index 59%
rename from common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceToken.java
rename to grafana/src/main/java/org/apache/hertzbeat/grafana/dto/GrafanaConfig.java
index 6e79eecf9..337997693 100644
--- a/common/src/main/java/org/apache/hertzbeat/common/entity/grafana/ServiceToken.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/dto/GrafanaConfig.java
@@ -15,39 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.hertzbeat.common.entity.grafana;
+package org.apache.hertzbeat.grafana.dto;
 
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-
 /**
- * Grafana service token entity
+ * System Configuration
  */
-@Entity
-@Table(name = "hzb_grafana_service_token")
 @Data
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
-@Schema(description = "Grafana service token entity")
-public class ServiceToken {
-    
-    @Id
-    @Schema(description = "Service token id")
-    private Long id;
-    
-    @Schema(description = "Service token name")
-    private String name;
+public class GrafanaConfig {
     
-    @Schema(description = "Service token key")
-    @Column(name = "`key`")
-    private String key;
+    /**
+     * api token
+     */
+    private String token;
 }
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
index ecfa810da..e5168c299 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DashboardService.java
@@ -22,6 +22,7 @@ import static org.apache.hertzbeat.grafana.common.GrafanaConstants.DELETE_DASHBO
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.INSTANCE;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.KIOSK;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.REFRESH;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.USE_DATASOURCE;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -90,7 +91,8 @@ public class DashboardService {
                 if (grafanaDashboard != null) {
                     grafanaDashboard.setEnabled(true);
                     grafanaDashboard.setUrl(grafanaProperties.getPrefix() + grafanaProperties.getUrl()
-                            + grafanaDashboard.getUrl().replace(grafanaProperties.getUrl(), "") + KIOSK + REFRESH + INSTANCE + monitorId);
+                            + grafanaDashboard.getUrl().replace(grafanaProperties.getUrl(), "")
+                            + KIOSK + REFRESH + INSTANCE + monitorId + USE_DATASOURCE);
                     grafanaDashboard.setMonitorId(monitorId);
                     dashboardDao.save(grafanaDashboard);
                     log.info("create dashboard success, token: {}", response.getBody());
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
index 90a6f5b3b..656529dcc 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/DatasourceService.java
@@ -22,9 +22,7 @@ import static org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_DATASO
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.DATASOURCE_ACCESS;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.DATASOURCE_NAME;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.DATASOURCE_TYPE;
-import static org.apache.hertzbeat.grafana.common.GrafanaConstants.DELETE_DATASOURCE_API;
-import jakarta.annotation.PostConstruct;
-import java.util.Base64;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.QUERY_DATASOURCE_API;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.grafana.config.GrafanaProperties;
 import org.apache.hertzbeat.warehouse.store.history.vm.VictoriaMetricsProperties;
@@ -35,21 +33,16 @@ import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.RestTemplate;
 
 /**
- * Service for managing Grafana datasources.
+ * Service for managing Grafana datasource.
  */
 @Service
 @Slf4j
 public class DatasourceService {
 
-    private String grafanaUrl;
-    private String username;
-    private String password;
-    private String prefix;
-    private String victoriaMetricsUrl;
-
     private final GrafanaProperties grafanaProperties;
     private final VictoriaMetricsProperties warehouseProperties;
     private final RestTemplate restTemplate;
@@ -65,70 +58,39 @@ public class DatasourceService {
         this.restTemplate = restTemplate;
     }
 
-    @PostConstruct
-    public void init() {
-        this.grafanaUrl = grafanaProperties.getUrl();
-        this.username = grafanaProperties.username();
-        this.password = grafanaProperties.password();
-        this.prefix = grafanaProperties.getPrefix();
-        this.victoriaMetricsUrl = warehouseProperties.url();
-    }
-
     /**
      * Create a new datasource in Grafana.
      */
-    public void createDatasource() {
-        String url = String.format(prefix + CREATE_DATASOURCE_API, username, password, grafanaUrl);
-
-        HttpHeaders headers = createHeaders();
-
-        String body = String.format(
-                "{\"name\":\"%s\",\"type\":\"%s\",\"access\":\"%s\",\"url\":\"%s\",\"basicAuth\":%s}",
-                DATASOURCE_NAME, DATASOURCE_TYPE, DATASOURCE_ACCESS, victoriaMetricsUrl, false
-        );
-
-        HttpEntity<String> entity = new HttpEntity<>(body, headers);
-
-        try {
-            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Create datasource success");
-            }
-        } catch (Exception ex) {
-            log.error("Create datasource error", ex);
-            throw new RuntimeException("Create datasource error", ex);
-        }
-    }
-
-    /**
-     * Delete a datasource in Grafana.
-     */
-    public void deleteDatasource() {
-        String url = String.format(prefix + DELETE_DATASOURCE_API, username, password, grafanaUrl, DATASOURCE_NAME);
-
-        HttpHeaders headers = createHeaders();
-
+    public void existOrCreateDatasource(String token) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        headers.setBearerAuth(token);
+        // query if exist this datasource
+        String queryUrl = grafanaProperties.getPrefix() + grafanaProperties.getUrl() + QUERY_DATASOURCE_API;
         HttpEntity<Void> entity = new HttpEntity<>(headers);
-
         try {
-            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, entity, String.class);
+            ResponseEntity<String> response = restTemplate.exchange(queryUrl, HttpMethod.GET, entity, String.class);
             if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Delete datasource success");
+                log.info("{} datasource exist", DATASOURCE_NAME);
             }
-
-        } catch (Exception ex) {
-            log.error("Delete datasource error", ex);
+        } catch (HttpClientErrorException.NotFound notFound) {
+            String createUrl = grafanaProperties.getPrefix() + grafanaProperties.getUrl() + CREATE_DATASOURCE_API;
+            String body = String.format(
+                    "{\"name\":\"%s\",\"type\":\"%s\",\"access\":\"%s\",\"url\":\"%s\",\"basicAuth\":%s}",
+                    DATASOURCE_NAME, DATASOURCE_TYPE, DATASOURCE_ACCESS, warehouseProperties.url(), false
+            );
+            HttpEntity<String> createEntity = new HttpEntity<>(body, headers);
+            try {
+                ResponseEntity<String> createResponse = restTemplate.postForEntity(createUrl, createEntity, String.class);
+                if (createResponse.getStatusCode().is2xxSuccessful()) {
+                    log.info("Create datasource success");
+                }
+            } catch (Exception e) {
+                log.error("Create datasource error", e);
+            }
+        } catch (Exception e) {
+            log.error("Query datasource error", e);
         }
-    }
-
-    private HttpHeaders createHeaders() {
-        String auth = username + ":" + password;
-        byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
-        String authHeader = "Basic " + new String(encodedAuth);
-
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_JSON);
-        headers.set("Authorization", authHeader);
-        return headers;
+        
     }
 }
diff --git a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
index ce5af69f4..4d4080952 100644
--- a/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
+++ b/grafana/src/main/java/org/apache/hertzbeat/grafana/service/ServiceAccountService.java
@@ -19,25 +19,21 @@ package org.apache.hertzbeat.grafana.service;
 
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.ACCOUNT_NAME;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.ACCOUNT_ROLE;
-import static org.apache.hertzbeat.grafana.common.GrafanaConstants.ACCOUNT_TOKEN_NAME;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_SERVICE_ACCOUNT_API;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.CREATE_SERVICE_TOKEN_API;
-import static org.apache.hertzbeat.grafana.common.GrafanaConstants.DELETE_SERVICE_ACCOUNT_API;
 import static org.apache.hertzbeat.grafana.common.GrafanaConstants.GET_SERVICE_ACCOUNTS_API;
-import static org.apache.hertzbeat.grafana.common.GrafanaConstants.GET_SERVICE_TOKENS_API;
-import static org.apache.hertzbeat.grafana.common.GrafanaConstants.HERTZBEAT_TOKEN;
+import static org.apache.hertzbeat.grafana.common.GrafanaConstants.GRAFANA_CONFIG;
 import com.fasterxml.jackson.databind.JsonNode;
 import jakarta.annotation.PostConstruct;
 import java.util.Base64;
-import java.util.List;
 import java.util.Objects;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.hertzbeat.common.entity.grafana.ServiceAccount;
-import org.apache.hertzbeat.common.entity.grafana.ServiceToken;
+import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
+import org.apache.hertzbeat.common.util.CommonUtil;
 import org.apache.hertzbeat.common.util.JsonUtil;
 import org.apache.hertzbeat.grafana.config.GrafanaProperties;
-import org.apache.hertzbeat.grafana.dao.ServiceAccountDao;
-import org.apache.hertzbeat.grafana.dao.ServiceTokenDao;
+import org.apache.hertzbeat.grafana.dao.GrafanaConfigDao;
+import org.apache.hertzbeat.grafana.dto.GrafanaConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
@@ -56,8 +52,7 @@ import org.springframework.web.client.RestTemplate;
 public class ServiceAccountService {
 
     private final GrafanaProperties grafanaProperties;
-    private final ServiceAccountDao serviceAccountDao;
-    private final ServiceTokenDao serviceTokenDao;
+    private final GrafanaConfigDao grafanaConfigDao;
     private final RestTemplate restTemplate;
 
     private String url;
@@ -68,13 +63,11 @@ public class ServiceAccountService {
     @Autowired
     public ServiceAccountService(
             GrafanaProperties grafanaProperties,
-            ServiceAccountDao serviceAccountDao,
-            ServiceTokenDao serviceTokenDao,
+            GrafanaConfigDao grafanaConfigDao,
             RestTemplate restTemplate
     ) {
         this.grafanaProperties = grafanaProperties;
-        this.serviceAccountDao = serviceAccountDao;
-        this.serviceTokenDao = serviceTokenDao;
+        this.grafanaConfigDao = grafanaConfigDao;
         this.restTemplate = restTemplate;
     }
 
@@ -84,18 +77,20 @@ public class ServiceAccountService {
         this.username = grafanaProperties.username();
         this.password = grafanaProperties.password();
         this.prefix = grafanaProperties.getPrefix();
-        ServiceToken serviceToken = serviceTokenDao.findByName(ACCOUNT_TOKEN_NAME);
-        if (serviceToken == null) {
-            log.error("Service token {} not found", ACCOUNT_TOKEN_NAME);
-        }
     }
 
     /**
-     * Creates a new service admin account.
+     * Creates a new service admin account id.
      *
      * @return ResponseEntity containing the result of the account creation
      */
-    public ResponseEntity<String> createServiceAccount() {
+    public Long createServiceAccount() {
+        JsonNode accounts = Objects.requireNonNull(JsonUtil.fromJson(getAccounts().getBody())).path("serviceAccounts");
+        for (JsonNode account : accounts) {
+            if (account.get("name").asText().equals(ACCOUNT_NAME)) {
+                return account.get("id").asLong();
+            }
+        }
         String endpoint = String.format(prefix + CREATE_SERVICE_ACCOUNT_API, username, password, url);
         HttpHeaders headers = createHeaders();
         String body = String.format("{\"name\":\"%s\",\"role\":\"%s\",\"isDisabled\":false}", ACCOUNT_NAME, ACCOUNT_ROLE);
@@ -104,72 +99,71 @@ public class ServiceAccountService {
         try {
             ResponseEntity<String> response = restTemplate.postForEntity(endpoint, request, String.class);
             if (response.getStatusCode().is2xxSuccessful()) {
-                ServiceAccount serviceAccount = JsonUtil.fromJson(response.getBody(), ServiceAccount.class);
-                if (serviceAccount != null) {
-                    serviceAccountDao.save(serviceAccount);
-                    log.info("Create service account success: {}", serviceAccount);
+                JsonNode jsonNode = JsonUtil.fromJson(response.getBody());
+                if (jsonNode != null && jsonNode.has("id")) {
+                    return jsonNode.get("id").asLong();
                 }
             }
-            return response;
         } catch (Exception e) {
             log.error("Service account creation failed", e);
             throw new RuntimeException("Service account creation failed");
         }
-    }
-
-    /**
-     * Deletes a service account by ID.
-     *
-     * @param id ID of the service account to delete
-     * @return ResponseEntity containing the result of the deletion
-     */
-    public ResponseEntity<String> deleteAccount(Long id) {
-        String endpoint = String.format(prefix + DELETE_SERVICE_ACCOUNT_API, username, password, url, id);
-        HttpHeaders headers = createHeaders();
-
-        HttpEntity<String> request = new HttpEntity<>(headers);
-        try {
-            ResponseEntity<String> response = restTemplate.exchange(endpoint, HttpMethod.DELETE, request, String.class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Delete service account success");
-            }
-            return response;
-        } catch (Exception e) {
-            log.error("Delete service account error", e);
-            throw new RuntimeException("Delete service account error");
-        }
+        return null;
     }
 
     /**
      * Creates a new API token for a service account.
      *
-     * @return ResponseEntity containing the result of the token creation
      */
-    public ResponseEntity<String> createToken() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
+    public String applyForToken() {
+        Long accountId = createServiceAccount();
+        if (accountId == null) {
             log.error("Service account not found");
             throw new RuntimeException("Service account not found");
         }
-        String endpoint = String.format(prefix + CREATE_SERVICE_TOKEN_API, username, password, url, hertzbeat.getId());
+        String endpoint = String.format(prefix + CREATE_SERVICE_TOKEN_API, username, password, url, accountId);
         HttpHeaders headers = createHeaders();
-        String body = String.format("{\"name\":\"%s\"}", HERTZBEAT_TOKEN);
+        String body = String.format("{\"name\":\"%s\"}", CommonUtil.generateRandomWord(6));
 
         HttpEntity<String> request = new HttpEntity<>(body, headers);
         try {
             ResponseEntity<String> response = restTemplate.postForEntity(endpoint, request, String.class);
             if (response.getStatusCode().is2xxSuccessful()) {
-                ServiceToken serviceToken = JsonUtil.fromJson(response.getBody(), ServiceToken.class);
-                if (serviceToken != null) {
-                    serviceTokenDao.save(serviceToken);
+                JsonNode jsonNode = JsonUtil.fromJson(response.getBody());
+                if (jsonNode != null && jsonNode.has("key")) {
+                    String token = jsonNode.get("key").asText();
+                    GrafanaConfig grafanaConfig = GrafanaConfig.builder().token(token).build();
+                    GeneralConfig generalConfig = GeneralConfig.builder().type(GRAFANA_CONFIG)
+                            .content(JsonUtil.toJson(grafanaConfig)).build();
+                    grafanaConfigDao.save(generalConfig);
+                    return token;
                 }
                 log.info("Create token success: {}", response.getBody());
             }
-            return response;
         } catch (Exception e) {
             log.error("Create token error", e);
             throw new RuntimeException("Create token error");
         }
+        return null;
+    }
+
+    /**
+     * Retrieves the token for a service account.
+     *
+     * @return The token key
+     */
+    public String getToken() {
+        GeneralConfig generalConfig = grafanaConfigDao.findByType(GRAFANA_CONFIG);
+        if (generalConfig == null) {
+            log.error("Service token not found");
+            return null;
+        }
+        GrafanaConfig grafanaConfig = JsonUtil.fromJson(generalConfig.getContent(), GrafanaConfig.class);
+        if (grafanaConfig == null) {
+            log.error("Service token not found");
+            return null;
+        }
+        return grafanaConfig.getToken();
     }
 
     /**
@@ -194,96 +188,6 @@ public class ServiceAccountService {
         }
     }
 
-    /**
-     * Retrieves all API tokens for service accounts.
-     *
-     * @return ResponseEntity containing the list of tokens
-     */
-    public ResponseEntity<String> getTokens() {
-        String endpoint = String.format(prefix + GET_SERVICE_TOKENS_API, username, password, url, getAccountId());
-        HttpHeaders headers = createHeaders();
-
-        HttpEntity<String> request = new HttpEntity<>(headers);
-        try {
-            ResponseEntity<String> response = restTemplate.exchange(endpoint, HttpMethod.GET, request, String.class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                log.info("Get tokens success");
-            }
-            return response;
-        } catch (Exception e) {
-            log.error("Get tokens error", e);
-            throw new RuntimeException("Get tokens error");
-        }
-    }
-
-    /**
-     * Retrieves the token for a service account.
-     *
-     * @return The token key
-     */
-    public String getToken() {
-        ServiceToken hertzbeatToken = serviceTokenDao.findByName(ACCOUNT_TOKEN_NAME);
-        if (hertzbeatToken == null) {
-            log.error("Service token not found");
-            throw new RuntimeException("Service token not found");
-        }
-        return hertzbeatToken.getKey();
-    }
-
-    /**
-     * Deletes a service account token.
-     */
-    public void deleteToken() {
-        ServiceToken hertzbeatToken = serviceTokenDao.findByName(ACCOUNT_TOKEN_NAME);
-        if (hertzbeatToken == null) {
-            log.error("Service token not found");
-            throw new RuntimeException("Service token not found");
-        }
-        serviceTokenDao.delete(hertzbeatToken);
-    }
-
-    /**
-     * Retrieves the ID of the service account.
-     *
-     * @return The ID of the service account
-     */
-    public long getAccountId() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
-            log.error("Service account not found");
-            throw new RuntimeException("Service account not found");
-        }
-        log.info("Service account: {}", hertzbeat);
-        return hertzbeat.getId();
-    }
-
-    /**
-     * Retrieves the service account.
-     *
-     * @return The service account
-     */
-    public ServiceAccount getAccount() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
-            log.error("Service account not found");
-            throw new RuntimeException("Service account not found");
-        }
-        log.info("Service account: {}", hertzbeat);
-        return hertzbeat;
-    }
-
-    /**
-     * Deletes the service account.
-     */
-    public void deleteAccount() {
-        ServiceAccount hertzbeat = serviceAccountDao.findByName(ACCOUNT_NAME);
-        if (hertzbeat == null) {
-            log.error("Service account not found");
-            throw new RuntimeException("Service account not found");
-        }
-        serviceAccountDao.delete(hertzbeat);
-    }
-
     private HttpHeaders createHeaders() {
         String auth = username + ":" + password;
         byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@hertzbeat.apache.org
For additional commands, e-mail: notifications-help@hertzbeat.apache.org