diff --git a/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml b/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml index a1f14a0b4..95bb5a997 100644 --- a/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml +++ b/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml @@ -68,7 +68,22 @@ data: "secretAccessKey": "", "logLevel": "INFO" } - } + }, + "datasource": [ + { + "name": "prometheus-1", + "provider": "prometheus", + "serviceName": "prometheus-k8s", + "namespace": "openshift-monitoring", + "url": "", + "authentication": { + "type": "bearer", + "credentials": { + "tokenFilePath": "/var/run/secrets/kubernetes.io/serviceaccount/token" + } + } + } + ] } --- apiVersion: apps/v1 diff --git a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml index e3b7068c9..d4e72a157 100644 --- a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml +++ b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml @@ -134,7 +134,13 @@ data: "provider": "prometheus", "serviceName": "prometheus-k8s", "namespace": "openshift-monitoring", - "url": "" + "url": "", + "authentication": { + "type": "bearer", + "credentials": { + "tokenFilePath": "/var/run/secrets/kubernetes.io/serviceaccount/token" + } + } } ] } @@ -463,3 +469,16 @@ spec: - name: nginx-config-volume configMap: name: nginx-config +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kruize-monitoring-view +subjects: + - kind: ServiceAccount + name: kruize-sa + namespace: openshift-tuning +roleRef: + kind: ClusterRole + name: cluster-monitoring-view + apiGroup: rbac.authorization.k8s.io diff --git a/migrations/kruize_local_ddl.sql b/migrations/kruize_local_ddl.sql index 087ad1bf4..cd6453371 100644 --- a/migrations/kruize_local_ddl.sql +++ b/migrations/kruize_local_ddl.sql @@ -1,4 +1,4 @@ -create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), primary key (name)); +create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), authentication jsonb, primary key (name)); create table IF NOT EXISTS kruize_dsmetadata (id serial, version varchar(255), datasource_name varchar(255), cluster_name varchar(255), namespace varchar(255), workload_type varchar(255), workload_name varchar(255), container_name varchar(255), container_image_name varchar(255), primary key (id)); alter table kruize_experiments add column metadata_id bigint references kruize_dsmetadata(id), alter column datasource type varchar(255); create table IF NOT EXISTS kruize_metric_profiles (api_version varchar(255), kind varchar(255), metadata jsonb, name varchar(255) not null, k8s_type varchar(255), profile_version float(53) not null, slo jsonb, primary key (name)); diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index 67bb1cb8d..df608f913 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -17,7 +17,6 @@ import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.analyzer.utils.AnalyzerErrorConstants; import com.autotune.common.data.ValidationOutputData; -import com.autotune.common.data.dataSourceQueries.PromQLDataSourceQueries; import com.autotune.common.data.metrics.AggregationFunctions; import com.autotune.common.data.metrics.Metric; import com.autotune.common.data.metrics.MetricAggregationInfoResults; @@ -26,6 +25,9 @@ import com.autotune.common.data.result.IntervalResults; import com.autotune.common.data.result.NamespaceData; import com.autotune.common.datasource.DataSourceInfo; +import com.autotune.common.auth.AuthenticationConfig; +import com.autotune.common.auth.AuthenticationStrategy; +import com.autotune.common.auth.AuthenticationStrategyFactory; import com.autotune.common.exceptions.DataSourceNotExist; import com.autotune.common.k8sObjects.K8sObject; import com.autotune.common.utils.CommonUtils; @@ -1973,6 +1975,10 @@ public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, T long interval_end_time_epoc = 0; long interval_start_time_epoc = 0; SimpleDateFormat sdf = new SimpleDateFormat(KruizeConstants.DateFormats.STANDARD_JSON_DATE_FORMAT, Locale.ROOT); + AuthenticationStrategy authenticationStrategy = AuthenticationStrategyFactory.createAuthenticationStrategy( + dataSourceInfo.getAuthenticationConfig()); + // Create the client + GenericRestApiClient client = new GenericRestApiClient(authenticationStrategy); String metricProfileName = kruizeObject.getPerformanceProfile(); PerformanceProfile metricProfile = MetricProfileCollection.getInstance().getMetricProfileCollection().get(metricProfileName); @@ -2027,7 +2033,8 @@ public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, T URLEncoder.encode(queryToEncode, CHARACTER_ENCODING) ); LOGGER.info(dateMetricsUrl); - JSONObject genericJsonObject = new GenericRestApiClient(dateMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); + client.setBaseURL(dateMetricsUrl); + JSONObject genericJsonObject = client.fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); // Process fetched metrics @@ -2099,7 +2106,8 @@ public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, T interval_end_time_epoc, measurementDurationMinutesInDouble.intValue() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); LOGGER.info(podMetricsUrl); - JSONObject genericJsonObject = new GenericRestApiClient(podMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); + client.setBaseURL(podMetricsUrl); + JSONObject genericJsonObject = client.fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); // Process fetched metrics diff --git a/src/main/java/com/autotune/common/auth/APIKeyAuthenticationStrategy.java b/src/main/java/com/autotune/common/auth/APIKeyAuthenticationStrategy.java new file mode 100644 index 000000000..e65705c73 --- /dev/null +++ b/src/main/java/com/autotune/common/auth/APIKeyAuthenticationStrategy.java @@ -0,0 +1,14 @@ +package com.autotune.common.auth; + +public class APIKeyAuthenticationStrategy implements AuthenticationStrategy { + private final String apiKey; + + public APIKeyAuthenticationStrategy(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public String applyAuthentication() { + return "Api-Key " + apiKey; + } +} diff --git a/src/main/java/com/autotune/common/auth/AuthenticationConfig.java b/src/main/java/com/autotune/common/auth/AuthenticationConfig.java new file mode 100644 index 000000000..6eebdf2a5 --- /dev/null +++ b/src/main/java/com/autotune/common/auth/AuthenticationConfig.java @@ -0,0 +1,76 @@ +package com.autotune.common.auth; + +import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.utils.KruizeConstants; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AuthenticationConfig { + private String type; // "basic", "bearer", "apiKey", "oauth2" + private Credentials credentials; + private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationConfig.class); + + public AuthenticationConfig(String type, Credentials credentials) { + this.type = type; + this.credentials = credentials; + } + + public AuthenticationConfig() { + } + + public String getType() { + return type; + } + + public Credentials getCredentials() { + return credentials; + } + + public static AuthenticationConfig createAuthenticationConfigObject(JSONObject authenticationObj) { + // Parse and map authentication methods if they exist + if (authenticationObj != null) { + String type = authenticationObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TYPE); + JSONObject credentialsObj = authenticationObj.getJSONObject(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CREDENTIALS); + + Credentials credentials = new Credentials(); + switch (type.toLowerCase()) { + case KruizeConstants.AuthenticationConstants.BASIC: + credentials.setUsername(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_USERNAME)); + credentials.setPassword(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_PASSWORD)); + break; + case KruizeConstants.AuthenticationConstants.BEARER: + credentials.setTokenFilePath(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_FILE)); + break; + case KruizeConstants.AuthenticationConstants.API_KEY: + credentials.setApiKey(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_API_KEY)); + credentials.setHeaderName(credentialsObj.optString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_HEADER_NAME, "X-API-Key")); + break; + case KruizeConstants.AuthenticationConstants.OAUTH2: + credentials.setTokenEndpoint(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_TOKEN_ENDPOINT)); + credentials.setClientId(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_ID)); + credentials.setClientSecret(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_CLIENT_SECRET)); + credentials.setGrantType(credentialsObj.getString(KruizeConstants.AuthenticationConstants.AUTHENTICATION_GRANT_TYPE)); + break; + default: + LOGGER.error(KruizeConstants.AuthenticationConstants.UNKNOWN_AUTHENTICATION + "{}", type); + } + + return new AuthenticationConfig(type, credentials); + } + return noAuth(); + } + + // Static method to return a no-auth config + public static AuthenticationConfig noAuth() { + return new AuthenticationConfig(AnalyzerConstants.NONE, null); + } + + @Override + public String toString() { + return "AuthenticationConfig{" + + "type='" + type + '\'' + + ", credentials=" + credentials + + '}'; + } +} diff --git a/src/main/java/com/autotune/common/auth/AuthenticationStrategy.java b/src/main/java/com/autotune/common/auth/AuthenticationStrategy.java new file mode 100644 index 000000000..ea5b8d95e --- /dev/null +++ b/src/main/java/com/autotune/common/auth/AuthenticationStrategy.java @@ -0,0 +1,5 @@ +package com.autotune.common.auth; + +public interface AuthenticationStrategy { + String applyAuthentication(); +} diff --git a/src/main/java/com/autotune/common/auth/AuthenticationStrategyFactory.java b/src/main/java/com/autotune/common/auth/AuthenticationStrategyFactory.java new file mode 100644 index 000000000..9022aa50f --- /dev/null +++ b/src/main/java/com/autotune/common/auth/AuthenticationStrategyFactory.java @@ -0,0 +1,29 @@ +package com.autotune.common.auth; + +import com.autotune.utils.KruizeConstants; + +public class AuthenticationStrategyFactory { + + public static AuthenticationStrategy createAuthenticationStrategy(AuthenticationConfig authConfig) { + String type = authConfig.getType(); + switch (type) { + case KruizeConstants.AuthenticationConstants.BASIC: + String username = authConfig.getCredentials().getUsername(); + String password = authConfig.getCredentials().getPassword(); + return new BasicAuthenticationStrategy(username, password); + case KruizeConstants.AuthenticationConstants.BEARER: + String tokenFilePath = authConfig.getCredentials().getTokenFilePath(); + return new BearerAuthenticationStrategy(tokenFilePath); + case KruizeConstants.AuthenticationConstants.API_KEY: + String apiKey = authConfig.getCredentials().getApiKey(); + return new APIKeyAuthenticationStrategy(apiKey); + case KruizeConstants.AuthenticationConstants.OAUTH2: + String tokenEndpoint = authConfig.getCredentials().getTokenEndpoint(); + String clientId = authConfig.getCredentials().getClientId(); + String clientSecret = authConfig.getCredentials().getClientSecret(); + return new OAuth2AuthenticationStrategy(tokenEndpoint, clientId, clientSecret); + default: + throw new IllegalArgumentException(KruizeConstants.AuthenticationConstants.UNKNOWN_AUTHENTICATION+ type); + } + } +} diff --git a/src/main/java/com/autotune/common/auth/BasicAuthenticationStrategy.java b/src/main/java/com/autotune/common/auth/BasicAuthenticationStrategy.java new file mode 100644 index 000000000..8ee6fbe72 --- /dev/null +++ b/src/main/java/com/autotune/common/auth/BasicAuthenticationStrategy.java @@ -0,0 +1,19 @@ +package com.autotune.common.auth; + +import java.util.Base64; + +public class BasicAuthenticationStrategy implements AuthenticationStrategy { + private final String username; + private final String password; + + public BasicAuthenticationStrategy(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public String applyAuthentication() { + String auth = username + ":" + password; + return "Basic " + Base64.getEncoder().encodeToString(auth.getBytes()); + } +} diff --git a/src/main/java/com/autotune/common/auth/BearerAuthenticationStrategy.java b/src/main/java/com/autotune/common/auth/BearerAuthenticationStrategy.java new file mode 100644 index 000000000..28b52b46b --- /dev/null +++ b/src/main/java/com/autotune/common/auth/BearerAuthenticationStrategy.java @@ -0,0 +1,26 @@ +package com.autotune.common.auth; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class BearerAuthenticationStrategy implements AuthenticationStrategy { + private final String tokenFilePath; + + public BearerAuthenticationStrategy(String tokenFilePath) { + this.tokenFilePath = tokenFilePath; + } + + @Override + public String applyAuthentication() { + // Read token from file + try { + BufferedReader reader = new BufferedReader(new FileReader(tokenFilePath)); + String token = reader.readLine(); + reader.close(); + return "Bearer " + token; + } catch (IOException e) { + throw new RuntimeException("Failed to read Bearer token: " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/autotune/common/auth/Credentials.java b/src/main/java/com/autotune/common/auth/Credentials.java new file mode 100644 index 000000000..4638eb088 --- /dev/null +++ b/src/main/java/com/autotune/common/auth/Credentials.java @@ -0,0 +1,108 @@ +package com.autotune.common.auth; + +public class Credentials { + private String grantType; // OAuth2 + private String clientId; // OAuth2 + private String clientSecret; // OAuth2 + private String username; // Basic auth + private String password; // Basic auth + private String tokenEndpoint; // OAuth2 + private String tokenFilePath; // Bearer token + private String apiKey; // API key + private String headerName; // API key header name + + public Credentials(String username, String password) { + this.username = username; + this.password = password; + } + + public Credentials() { + } + + public String getUsername() { + return username; + } + + public String getGrantType() { + return grantType; + } + + public String getClientSecret() { + return clientSecret; + } + + public String getClientId() { + return clientId; + } + + public String getTokenEndpoint() { + return tokenEndpoint; + } + + public String getHeaderName() { + return headerName; + } + + public String getApiKey() { + return apiKey; + } + + public String getTokenFilePath() { + return tokenFilePath; + } + + public String getPassword() { + return password; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setTokenEndpoint(String tokenEndpoint) { + this.tokenEndpoint = tokenEndpoint; + } + + public void setTokenFilePath(String tokenFilePath) { + this.tokenFilePath = tokenFilePath; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public void setHeaderName(String headerName) { + this.headerName = headerName; + } + + @Override + public String toString() { + return "Credentials{" + + "grantType='" + grantType + '\'' + + ", clientId='" + clientId + '\'' + + ", clientSecret='" + clientSecret + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", tokenEndpoint='" + tokenEndpoint + '\'' + + ", tokenFilePath='" + tokenFilePath + '\'' + + ", apiKey='" + apiKey + '\'' + + ", headerName='" + headerName + '\'' + + '}'; + } +} diff --git a/src/main/java/com/autotune/common/auth/OAuth2AuthenticationStrategy.java b/src/main/java/com/autotune/common/auth/OAuth2AuthenticationStrategy.java new file mode 100644 index 000000000..2423a55c0 --- /dev/null +++ b/src/main/java/com/autotune/common/auth/OAuth2AuthenticationStrategy.java @@ -0,0 +1,64 @@ +package com.autotune.common.auth; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +public class OAuth2AuthenticationStrategy implements AuthenticationStrategy { + private final String tokenEndpoint; + private final String clientId; + private final String clientSecret; + + public OAuth2AuthenticationStrategy(String tokenEndpoint, String clientId, String clientSecret) { + this.tokenEndpoint = tokenEndpoint; + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + @Override + public String applyAuthentication() { + try { + // Fetch the OAuth2 token using client credentials + HttpClient client = HttpClient.newHttpClient(); + + // Create the request body for the OAuth2 token request + String form = "grant_type=client_credentials" + + "&client_id=" + clientId + + "&client_secret=" + clientSecret; + + // Send the POST request to fetch the token + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(tokenEndpoint)) + .header("Content-Type", "application/x-www-form-urlencoded") + .POST(HttpRequest.BodyPublishers.ofString(form)) + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + if (response.statusCode() == 200) { + // Parse the token from the response JSON (assuming GitHub returns a JSON) + String token = parseToken(response.body()); + return "Bearer " + token; // Return the token in Bearer format + } else { + throw new RuntimeException("Failed to fetch OAuth2 token: " + response.body()); + } + } catch (Exception e) { + throw new RuntimeException("Error fetching OAuth2 token", e); + } + } + + // You will need a method to parse the token from the response body + private String parseToken(String responseBody) { + // Parse the response and extract the access token. + // GitHub returns a form-encoded response, so you need to parse the "access_token" + String[] pairs = responseBody.split("&"); + for (String pair : pairs) { + String[] keyValue = pair.split("="); + if (keyValue[0].equals("access_token")) { + return keyValue[1]; + } + } + throw new RuntimeException("No access token found in response"); + } +} diff --git a/src/main/java/com/autotune/common/datasource/DataSourceCollection.java b/src/main/java/com/autotune/common/datasource/DataSourceCollection.java index 3e4737200..858ec6dc2 100644 --- a/src/main/java/com/autotune/common/datasource/DataSourceCollection.java +++ b/src/main/java/com/autotune/common/datasource/DataSourceCollection.java @@ -15,6 +15,7 @@ *******************************************************************************/ package com.autotune.common.datasource; +import com.autotune.common.auth.AuthenticationConfig; import com.autotune.common.exceptions.datasource.*; import com.autotune.common.data.ValidationOutputData; import com.autotune.common.utils.CommonUtils; @@ -83,7 +84,6 @@ public HashMap getDataSourcesCollection() { public void addDataSource(DataSourceInfo datasource) { final String name = datasource.getName(); final String provider = datasource.getProvider(); - final String url = datasource.getUrl().toString(); ValidationOutputData addedToDB = null; LOGGER.info(KruizeConstants.DataSourceConstants.DataSourceInfoMsgs.ADDING_DATASOURCE + name); @@ -96,7 +96,7 @@ public void addDataSource(DataSourceInfo datasource) { if (provider.equalsIgnoreCase(KruizeConstants.SupportedDatasources.PROMETHEUS)) { LOGGER.info(KruizeConstants.DataSourceConstants.DataSourceInfoMsgs.VERIFYING_DATASOURCE_REACHABILITY + name); DataSourceOperatorImpl op = DataSourceOperatorImpl.getInstance().getOperator(KruizeConstants.SupportedDatasources.PROMETHEUS); - if (op.isServiceable(url) == CommonUtils.DatasourceReachabilityStatus.REACHABLE) { + if (op.isServiceable(datasource) == CommonUtils.DatasourceReachabilityStatus.REACHABLE) { LOGGER.info(KruizeConstants.DataSourceConstants.DataSourceSuccessMsgs.DATASOURCE_SERVICEABLE); // add the data source to DB addedToDB = new ExperimentDBService().addDataSourceToDB(datasource); @@ -153,7 +153,11 @@ public void addDataSourcesFromConfigFile(String configFileName) { String serviceName = dataSourceObject.getString(KruizeConstants.DataSourceConstants.DATASOURCE_SERVICE_NAME); String namespace = dataSourceObject.getString(KruizeConstants.DataSourceConstants.DATASOURCE_SERVICE_NAMESPACE); String dataSourceURL = dataSourceObject.getString(KruizeConstants.DataSourceConstants.DATASOURCE_URL); + JSONObject authenticationObj = dataSourceObject.optJSONObject(KruizeConstants.AuthenticationConstants.AUTHENTICATION); + // create the corresponding authentication object + AuthenticationConfig authConfig = AuthenticationConfig.createAuthenticationConfigObject(authenticationObj); DataSourceInfo datasource = null; + // Validate input if (!validateInput(name, provider, serviceName, dataSourceURL, namespace)) { continue; } @@ -162,6 +166,8 @@ public void addDataSourcesFromConfigFile(String configFileName) { } else { datasource = new DataSourceInfo(name, provider, serviceName, namespace, new URL(dataSourceURL)); } + // set the authentication config + datasource.setAuthenticationConfig(authConfig); addDataSource(datasource); } } catch (IOException e) { diff --git a/src/main/java/com/autotune/common/datasource/DataSourceInfo.java b/src/main/java/com/autotune/common/datasource/DataSourceInfo.java index 60fe3d7fb..e3b81f29e 100644 --- a/src/main/java/com/autotune/common/datasource/DataSourceInfo.java +++ b/src/main/java/com/autotune/common/datasource/DataSourceInfo.java @@ -19,6 +19,7 @@ import java.net.URL; import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.common.auth.AuthenticationConfig; import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.utils.KruizeConstants; import org.slf4j.LoggerFactory; @@ -39,6 +40,7 @@ public class DataSourceInfo { private final String serviceName; private final String namespace; private final URL url; + private AuthenticationConfig authenticationConfig; private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DataSourceInfo.class); @@ -117,6 +119,14 @@ private URL getDNSBasedUrlForService(String serviceName, String namespace, Strin return dnsUrl; } + public AuthenticationConfig getAuthenticationConfig() { + return authenticationConfig; + } + + public void setAuthenticationConfig(AuthenticationConfig authenticationConfig) { + this.authenticationConfig = authenticationConfig; + } + @Override public String toString() { return "DataSourceInfo{" + diff --git a/src/main/java/com/autotune/common/datasource/DataSourceMetadataOperator.java b/src/main/java/com/autotune/common/datasource/DataSourceMetadataOperator.java index 3fed859c4..d1079564b 100644 --- a/src/main/java/com/autotune/common/datasource/DataSourceMetadataOperator.java +++ b/src/main/java/com/autotune/common/datasource/DataSourceMetadataOperator.java @@ -129,8 +129,7 @@ public DataSourceMetadataInfo processQueriesAndPopulateDataSourceMetadataInfo(Da */ try { String dataSourceName = dataSourceInfo.getName(); - String dataSourceUrl = dataSourceInfo.getUrl().toString(); - JsonArray namespacesDataResultArray = op.getResultArrayForQuery(dataSourceUrl, PromQLDataSourceQueries.NAMESPACE_QUERY); + JsonArray namespacesDataResultArray = op.getResultArrayForQuery(dataSourceInfo, PromQLDataSourceQueries.NAMESPACE_QUERY); if (false == op.validateResultArray(namespacesDataResultArray)){ dataSourceMetadataInfo = dataSourceDetailsHelper.createDataSourceMetadataInfoObject(dataSourceName, null); throw new Exception(KruizeConstants.DataSourceConstants.DataSourceMetadataErrorMsgs.NAMESPACE_QUERY_VALIDATION_FAILED); @@ -153,7 +152,7 @@ public DataSourceMetadataInfo processQueriesAndPopulateDataSourceMetadataInfo(Da * TODO - get workload metadata for a given namespace */ HashMap> datasourceWorkloads = new HashMap<>(); - JsonArray workloadDataResultArray = op.getResultArrayForQuery(dataSourceUrl, + JsonArray workloadDataResultArray = op.getResultArrayForQuery(dataSourceInfo, PromQLDataSourceQueries.WORKLOAD_QUERY); if (op.validateResultArray(workloadDataResultArray)) { @@ -172,7 +171,7 @@ public DataSourceMetadataInfo processQueriesAndPopulateDataSourceMetadataInfo(Da * TODO - get container metadata for a given workload */ HashMap> datasourceContainers = new HashMap<>(); - JsonArray containerDataResultArray = op.getResultArrayForQuery(dataSourceUrl, + JsonArray containerDataResultArray = op.getResultArrayForQuery(dataSourceInfo, PromQLDataSourceQueries.CONTAINER_QUERY); if (op.validateResultArray(containerDataResultArray)) { diff --git a/src/main/java/com/autotune/common/datasource/DataSourceOperator.java b/src/main/java/com/autotune/common/datasource/DataSourceOperator.java index 91f79a320..f4fa77f86 100644 --- a/src/main/java/com/autotune/common/datasource/DataSourceOperator.java +++ b/src/main/java/com/autotune/common/datasource/DataSourceOperator.java @@ -47,34 +47,38 @@ public interface DataSourceOperator { /** * Check if a datasource is reachable, implementation of this function * should check and return the reachability status (REACHABLE, NOT_REACHABLE) - * @param dataSourceUrl String containing the url for the datasource + * + * @param dataSource DatasourceInfo object containing the datasource details * @return DatasourceReachabilityStatus */ - CommonUtils.DatasourceReachabilityStatus isServiceable(String dataSourceUrl); + CommonUtils.DatasourceReachabilityStatus isServiceable(DataSourceInfo dataSource); /** * executes specified query on datasource and returns the result value - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return Object containing the result value for the specified query */ - Object getValueForQuery(String url, String query); + Object getValueForQuery(DataSourceInfo dataSource, String query); /** * executes specified query on datasource and returns the JSON Object - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return JSONObject for the specified query */ - JSONObject getJsonObjectForQuery(String url, String query); + JSONObject getJsonObjectForQuery(DataSourceInfo dataSource, String query); /** * executes specified query on datasource and returns the result array - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return JsonArray containing the result array for the specified query */ - public JsonArray getResultArrayForQuery(String url, String query); + public JsonArray getResultArrayForQuery(DataSourceInfo dataSource, String query); /** * Validates a JSON array to ensure it is not null, not a JSON null, and has at least one element. diff --git a/src/main/java/com/autotune/common/datasource/DataSourceOperatorImpl.java b/src/main/java/com/autotune/common/datasource/DataSourceOperatorImpl.java index 358ba5ca1..5e102d98b 100644 --- a/src/main/java/com/autotune/common/datasource/DataSourceOperatorImpl.java +++ b/src/main/java/com/autotune/common/datasource/DataSourceOperatorImpl.java @@ -3,6 +3,9 @@ import com.autotune.analyzer.exceptions.MonitoringAgentNotFoundException; import com.autotune.analyzer.exceptions.TooManyRecursiveCallsException; import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.common.auth.AuthenticationConfig; +import com.autotune.common.auth.AuthenticationStrategy; +import com.autotune.common.auth.AuthenticationStrategyFactory; import com.autotune.common.datasource.prometheus.PrometheusDataOperatorImpl; import com.autotune.common.exceptions.datasource.ServiceNotFound; import com.autotune.common.target.kubernetes.service.KubernetesServices; @@ -12,7 +15,6 @@ import com.autotune.utils.GenericRestApiClient; import com.autotune.utils.KruizeConstants; import com.google.gson.JsonArray; -import com.autotune.utils.authModels.BearerAccessToken; import io.fabric8.kubernetes.api.model.Service; import org.json.JSONArray; import org.json.JSONObject; @@ -71,22 +73,24 @@ public String getDefaultServicePortForProvider() { /** * Check if a datasource is reachable, implementation of this function * should check and return the reachability status (REACHABLE, NOT_REACHABLE) - * @param dataSourceUrl String containing the url for the datasource + * + * @param dataSource DatasourceInfo object containing the datasource details * @return DatasourceReachabilityStatus */ @Override - public CommonUtils.DatasourceReachabilityStatus isServiceable(String dataSourceUrl) { + public CommonUtils.DatasourceReachabilityStatus isServiceable(DataSourceInfo dataSource) { return null; } /** * executes specified query on datasource and returns the result value - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return Object containing the result value for the specified query */ @Override - public Object getValueForQuery(String url, String query) { + public Object getValueForQuery(DataSourceInfo dataSource, String query) { return null; } @@ -100,23 +104,25 @@ public String getQueryEndpoint() { } /** * executes specified query on datasource and returns the JSON Object - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return JSONObject for the specified query */ @Override - public JSONObject getJsonObjectForQuery(String url, String query) { + public JSONObject getJsonObjectForQuery(DataSourceInfo dataSource, String query) { return null; } /** * executes specified query on datasource and returns the result array - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return JsonArray containing the result array for the specified query */ @Override - public JsonArray getResultArrayForQuery(String url, String query) { + public JsonArray getResultArrayForQuery(DataSourceInfo dataSource, String query) { return null; } @@ -159,10 +165,11 @@ public ArrayList getAppsForLayer(DataSourceInfo dataSource, String query String queryURL = dataSourceURL + queryEndpoint + query; LOGGER.debug("Query URL is: {}", queryURL); try { - GenericRestApiClient genericRestApiClient = new GenericRestApiClient( - dataSourceURL + queryEndpoint, - new BearerAccessToken(this.getToken()) - ); + AuthenticationStrategy authenticationStrategy = AuthenticationStrategyFactory.createAuthenticationStrategy( + dataSource.getAuthenticationConfig()); + // Create the client + GenericRestApiClient genericRestApiClient = new GenericRestApiClient(authenticationStrategy); + genericRestApiClient.setBaseURL(dataSourceURL + queryEndpoint); JSONObject responseJson = genericRestApiClient.fetchMetricsJson("GET", query); int level = 0; try { diff --git a/src/main/java/com/autotune/common/datasource/prometheus/PrometheusDataOperatorImpl.java b/src/main/java/com/autotune/common/datasource/prometheus/PrometheusDataOperatorImpl.java index ac1d66239..362ca06fd 100644 --- a/src/main/java/com/autotune/common/datasource/prometheus/PrometheusDataOperatorImpl.java +++ b/src/main/java/com/autotune/common/datasource/prometheus/PrometheusDataOperatorImpl.java @@ -16,6 +16,9 @@ package com.autotune.common.datasource.prometheus; import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.common.auth.AuthenticationStrategy; +import com.autotune.common.auth.AuthenticationStrategyFactory; +import com.autotune.common.datasource.DataSourceInfo; import com.autotune.common.datasource.DataSourceOperatorImpl; import com.autotune.common.utils.CommonUtils; import com.autotune.operator.KruizeDeploymentInfo; @@ -71,18 +74,19 @@ public String getDefaultServicePortForProvider() { /** * Check if a datasource is reachable, implementation of this function * should check and return the reachability status (REACHABLE, NOT_REACHABLE) - * @param dataSourceURL String containing the url for the datasource + * + * @param dataSource The DataSourceInfo object containing information about the data source * @return DatasourceReachabilityStatus */ @Override - public CommonUtils.DatasourceReachabilityStatus isServiceable(String dataSourceURL) { + public CommonUtils.DatasourceReachabilityStatus isServiceable(DataSourceInfo dataSource) { String dataSourceStatus; Object queryResult; String query = KruizeConstants.DataSourceConstants.PROMETHEUS_REACHABILITY_QUERY; CommonUtils.DatasourceReachabilityStatus reachabilityStatus; - queryResult = this.getValueForQuery(dataSourceURL, query); + queryResult = this.getValueForQuery(dataSource, query); if (queryResult != null){ dataSourceStatus = queryResult.toString(); @@ -100,14 +104,15 @@ public CommonUtils.DatasourceReachabilityStatus isServiceable(String dataSourceU /** * executes specified query on datasource and returns the result value - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource The DataSourceInfo object containing information about the data source + * @param query String containing the query to be executed * @return Object containing the result value for the specified query */ @Override - public Object getValueForQuery(String url, String query) { + public Object getValueForQuery(DataSourceInfo dataSource, String query) { try { - JSONObject jsonObject = getJsonObjectForQuery(url, query); + JSONObject jsonObject = getJsonObjectForQuery(dataSource, query); if (null == jsonObject) { return null; @@ -131,18 +136,21 @@ public Object getValueForQuery(String url, String query) { /** * executes specified query on datasource and returns the JSON Object - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource The DataSourceInfo object containing information about the data source + * @param query String containing the query to be executed * @return JSONObject for the specified query */ @Override - public JSONObject getJsonObjectForQuery(String url, String query) { - GenericRestApiClient apiClient = new GenericRestApiClient( - CommonUtils.getBaseDataSourceUrl( - url, - KruizeConstants.SupportedDatasources.PROMETHEUS - ) - ); + public JSONObject getJsonObjectForQuery(DataSourceInfo dataSource, String query) { + AuthenticationStrategy authenticationStrategy = AuthenticationStrategyFactory.createAuthenticationStrategy( + dataSource.getAuthenticationConfig()); + // Create the client + GenericRestApiClient apiClient = new GenericRestApiClient(authenticationStrategy); + apiClient.setBaseURL(CommonUtils.getBaseDataSourceUrl( + dataSource, + KruizeConstants.SupportedDatasources.PROMETHEUS + )); if (null == apiClient) { return null; @@ -190,8 +198,9 @@ public String getQueryEndpoint() { /** * executes specified query on datasource and returns the result array - * @param url String containing the url for the datasource - * @param query String containing the query to be executed + * + * @param dataSource DatasourceInfo object containing the datasource details + * @param query String containing the query to be executed * @return JsonArray containing the result array for the specified query * * Example output JsonArray - @@ -206,9 +215,9 @@ public String getQueryEndpoint() { */ @Override - public JsonArray getResultArrayForQuery(String url, String query) { + public JsonArray getResultArrayForQuery(DataSourceInfo dataSource, String query) { try { - JSONObject jsonObject = getJsonObjectForQuery(url, query); + JSONObject jsonObject = getJsonObjectForQuery(dataSource, query); if (null == jsonObject) { return null; diff --git a/src/main/java/com/autotune/common/utils/CommonUtils.java b/src/main/java/com/autotune/common/utils/CommonUtils.java index 58eba2810..1f0efa344 100644 --- a/src/main/java/com/autotune/common/utils/CommonUtils.java +++ b/src/main/java/com/autotune/common/utils/CommonUtils.java @@ -16,6 +16,7 @@ package com.autotune.common.utils; +import com.autotune.common.datasource.DataSourceInfo; import com.autotune.utils.KruizeConstants; import java.sql.Timestamp; @@ -247,14 +248,14 @@ public static boolean checkTimeMatch(String timeStrOne, String timeStrTwo) { /** * Get the base datasource URL for running query - * @param url + * @param dataSourceInfo * @param datasource * @return */ - public static String getBaseDataSourceUrl(String url, String datasource) { + public static String getBaseDataSourceUrl(DataSourceInfo dataSourceInfo, String datasource) { if (datasource.equalsIgnoreCase(KruizeConstants.SupportedDatasources.PROMETHEUS)) { return (new StringBuilder()) - .append(url) + .append(dataSourceInfo.getUrl().toString()) .append("/api/v1/query?query=") .toString(); } diff --git a/src/main/java/com/autotune/experimentManager/handler/MetricCollectionHandler.java b/src/main/java/com/autotune/experimentManager/handler/MetricCollectionHandler.java index f078d9845..0aa8c41d7 100644 --- a/src/main/java/com/autotune/experimentManager/handler/MetricCollectionHandler.java +++ b/src/main/java/com/autotune/experimentManager/handler/MetricCollectionHandler.java @@ -122,8 +122,7 @@ public void execute(ExperimentTrial experimentTrial, TrialDetails trialDetails, // TODO: Return an error saying unsupported datasource } String queryResult = (String) ado.getValueForQuery(experimentTrial.getDatasourceInfoHashMap() - .get(podMetric.getDatasource()) - .getUrl().toString(), updatedPodQuery); + .get(podMetric.getDatasource()), updatedPodQuery); if (null != queryResult && !queryResult.isEmpty() && !queryResult.isBlank()) { try { queryResult = queryResult.trim(); @@ -161,8 +160,7 @@ public void execute(ExperimentTrial experimentTrial, TrialDetails trialDetails, if (null != updatedContainerQuery) { LOGGER.debug("Updated Query - " + updatedContainerQuery); String queryResult = (String) ado.getValueForQuery(experimentTrial.getDatasourceInfoHashMap() - .get(containerMetric.getDatasource()) - .getUrl().toString(), updatedContainerQuery); + .get(containerMetric.getDatasource()), updatedContainerQuery); if (null != queryResult && !queryResult.isEmpty() && !queryResult.isBlank()) { try { queryResult = queryResult.trim(); diff --git a/src/main/java/com/autotune/utils/GenericRestApiClient.java b/src/main/java/com/autotune/utils/GenericRestApiClient.java index 2626ba7ff..30de160ec 100644 --- a/src/main/java/com/autotune/utils/GenericRestApiClient.java +++ b/src/main/java/com/autotune/utils/GenericRestApiClient.java @@ -15,10 +15,10 @@ *******************************************************************************/ package com.autotune.utils; +import com.autotune.common.auth.AuthenticationStrategy; import com.autotune.utils.authModels.APIKeysAuthentication; import com.autotune.utils.authModels.BasicAuthentication; import com.autotune.utils.authModels.BearerAccessToken; -import com.autotune.utils.authModels.OAuth2Config; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; @@ -35,8 +35,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.SSLContext; -import java.io.BufferedReader; -import java.io.FileReader; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -52,113 +50,46 @@ public class GenericRestApiClient { private static final long serialVersionUID = 1L; private static final Logger LOGGER = LoggerFactory.getLogger(GenericRestApiClient.class); - private final String baseURL; + private String baseURL; private BasicAuthentication basicAuthentication; private BearerAccessToken bearerAccessToken; private APIKeysAuthentication apiKeysAuthentication; - private OAuth2Config oAuth2Config; //Yet to implement - private String authHeaderString; + private AuthenticationStrategy authenticationStrategy; /** * Initializes a new instance just by passing baseURL which does not need any authentication. - * @param baseURL + * @param authenticationStrategy */ - public GenericRestApiClient(String baseURL) { - String tokenFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/token"; - String token = null; - try { - // Read the token from the file - BufferedReader reader = new BufferedReader(new FileReader(tokenFilePath)); - token = reader.readLine(); - reader.close(); - this.bearerAccessToken = new BearerAccessToken(token); - this.setAuthHeaderString(this.bearerAccessToken.getAuthHeader()); - // Print the service account token - } catch (Exception e) { - LOGGER.error("Error reading service account token: " + e.getMessage()); - } - - this.baseURL = baseURL; - } - - /** - * Use this constructor to initializes a new instance if RESTAPI need Basic authentication. - * @param baseURL - * @param basicAuthentication - */ - public GenericRestApiClient(String baseURL, BasicAuthentication basicAuthentication) { - this.baseURL = baseURL; - this.basicAuthentication = basicAuthentication; - this.setAuthHeaderString(this.basicAuthentication.getAuthHeader()); + public GenericRestApiClient(AuthenticationStrategy authenticationStrategy) { + this.authenticationStrategy = authenticationStrategy; } /** - * Use this constructor to initializes a new instance if RESTAPI need Bearer authentication. - * @param baseURL - * @param bearerAccessToken - */ - public GenericRestApiClient(String baseURL, BearerAccessToken bearerAccessToken) { - this.baseURL = baseURL; - this.bearerAccessToken = bearerAccessToken; - this.setAuthHeaderString(this.bearerAccessToken.getAuthHeader()); - } - - /** - * Use this constructor to initializes a new instance if RESTAPI need APIKeys authentication. - * @param baseURL - * @param apiKeysAuthentication - */ - public GenericRestApiClient(String baseURL, APIKeysAuthentication apiKeysAuthentication) { - this.baseURL = baseURL; - this.apiKeysAuthentication = apiKeysAuthentication; - this.setAuthHeaderString(this.apiKeysAuthentication.getAuthHeader()); - } - - /** - * Use this constructor to initializes a new instance if RESTAPI need OAuth2 authentication. - * @param baseURL - * @param oAuth2Config - */ - public GenericRestApiClient(String baseURL, OAuth2Config oAuth2Config) { - this.baseURL = baseURL; - this.oAuth2Config = oAuth2Config; - } - - public String getAuthHeaderString() { - return authHeaderString; - } - - public void setAuthHeaderString(String authHeaderString) { - this.authHeaderString = authHeaderString; - } - - /** - * This methode appends aueryString with baseURL and returns response in JSON using specified authentication. + * This method appends aueryString with baseURL and returns response in JSON using specified authentication. * @param methodType Http methods like GET,POST,PATCH etc * @param queryString * @return Json object which contains API response. * @throws IOException */ public JSONObject fetchMetricsJson(String methodType, String queryString) throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { - java.lang.System.setProperty("https.protocols", "TLSv1.2"); + System.setProperty("https.protocols", "TLSv1.2"); String jsonOutputInString = ""; - SSLContext sslContext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true).build(); //overriding the standard certificate verification process and trust all certificate chains regardless of their validity + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true).build(); // Trust all certificates SSLConnectionSocketFactory sslConnectionSocketFactory = - new SSLConnectionSocketFactory(sslContext, new String[] - {"TLSv1.2" }, null, - NoopHostnameVerifier.INSTANCE); + new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE); try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build()) { - HttpRequestBase httpRequestBase = null; + HttpRequestBase httpRequestBase; if (methodType.equalsIgnoreCase("GET")) { - httpRequestBase = new HttpGet(this.baseURL - + URLEncoder.encode(queryString, StandardCharsets.UTF_8) - ); + httpRequestBase = new HttpGet(baseURL + URLEncoder.encode(queryString, StandardCharsets.UTF_8)); + } else { + throw new UnsupportedOperationException("Unsupported method type: " + methodType); } - // Checks if auth string is null and then checks if it's not empty - if (null != this.authHeaderString && !this.authHeaderString.isEmpty()) { - httpRequestBase.setHeader("Authorization", this.authHeaderString); + // Apply authentication + if (authenticationStrategy != null) { + String authHeader = authenticationStrategy.applyAuthentication(); + httpRequestBase.setHeader(KruizeConstants.AuthenticationConstants.AUTHORIZATION, authHeader); } - LOGGER.debug("Executing request " + httpRequestBase.getRequestLine()); + LOGGER.info("Executing request: {}", httpRequestBase.getRequestLine()); jsonOutputInString = httpclient.execute(httpRequestBase, new StringResponseHandler()); } @@ -180,5 +111,7 @@ public String handleResponse(HttpResponse response) throws IOException { } - + public void setBaseURL(String baseURL) { + this.baseURL = baseURL; + } } diff --git a/src/main/java/com/autotune/utils/HttpUtils.java b/src/main/java/com/autotune/utils/HttpUtils.java index e7129ddfc..16858ff2a 100644 --- a/src/main/java/com/autotune/utils/HttpUtils.java +++ b/src/main/java/com/autotune/utils/HttpUtils.java @@ -56,7 +56,7 @@ public static String getDataFromURL(URL url, String bearerToken) { connection = (HttpURLConnection) url.openConnection(); } - connection.setRequestProperty("Authorization", bearerToken); + connection.setRequestProperty(KruizeConstants.AuthenticationConstants.AUTHORIZATION, bearerToken); if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) { result = getDataFromConnection(connection); diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 506917536..c27cfe9e0 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -723,4 +723,26 @@ public static final class KRUIZE_RECOMMENDATION_METRICS { public static final String notification_format_for_METRICS = "%s|%s|%s"; //termname,modelname,type } + + public static final class AuthenticationConstants { + public static final String AUTHENTICATION = "authentication"; + public static final String AUTHENTICATION_TYPE = "type"; + public static final String AUTHENTICATION_CREDENTIALS = "credentials"; + public static final String AUTHENTICATION_USERNAME = "username"; + public static final String AUTHENTICATION_PASSWORD = "password"; + public static final String AUTHENTICATION_TOKEN_FILE = "tokenFilePath"; + public static final String AUTHENTICATION_API_KEY = "apiKey"; + public static final String AUTHENTICATION_HEADER_NAME = "header"; + public static final String AUTHENTICATION_TOKEN_ENDPOINT = "tokenEndpoint"; + public static final String AUTHENTICATION_CLIENT_ID = "clientId"; + public static final String AUTHENTICATION_CLIENT_SECRET = "clientSecret"; + public static final String AUTHENTICATION_GRANT_TYPE = "grantType"; + public static final String BASIC = "basic"; + public static final String BEARER = "bearer"; + public static final String API_KEY = "apikey"; + public static final String OAUTH2 = "oauth2"; + public static final String UNKNOWN_AUTHENTICATION = "Unknown authentication type: "; + public static final String AUTHORIZATION = "Authorization"; + + } }