From 5ca85dd9020f90695ac88c7e307bd9098d1bccdd Mon Sep 17 00:00:00 2001 From: brunovg Date: Thu, 3 Aug 2023 10:36:36 +0000 Subject: [PATCH 1/2] Create draft PR for #31 From 3600042c1da969122cf163c2245a83b9dabc4773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Gon=C3=A7alves?= Date: Thu, 3 Aug 2023 12:03:38 +0100 Subject: [PATCH 2/2] replicate changes on oauth2 / googledrive components --- googledrive/pom.xml | 9 ++- .../googledrive/GoogleDriveClientFactory.java | 5 +- .../googledrive/GoogleDriveConfiguration.java | 16 ++-- .../googledrive/GoogleDriveConsumer.java | 73 +++++++++-------- .../googledrive/GoogleDriveEndpoint.java | 4 +- .../googledrive/GoogleDriveProducer.java | 4 +- .../component/mail/MailConfiguration.java | 19 +---- .../oauth2token/OAuth2TokenProcessor.java | 9 ++- .../oauth2token/service/TokenService.java | 35 ++++++-- .../TenantVariablesProcessor.java | 4 + .../tenantvariables/mongo/MongoDao.java | 80 +++++++++++++------ 11 files changed, 160 insertions(+), 98 deletions(-) diff --git a/googledrive/pom.xml b/googledrive/pom.xml index 960bc5c9..04a0d873 100644 --- a/googledrive/pom.xml +++ b/googledrive/pom.xml @@ -41,7 +41,14 @@ google-oauth-client-jetty ${google.oauth.version} - + + + ${project.groupId} + tenantvariables + ${project.version} + provided + + diff --git a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveClientFactory.java b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveClientFactory.java index ca7bad65..e84def16 100644 --- a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveClientFactory.java +++ b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveClientFactory.java @@ -26,16 +26,13 @@ public GoogleDriveClientFactory() { this.jsonFactory = new JacksonFactory(); } - public Drive makeClient(String clientId, String clientSecret, String applicationName, String refreshToken, String accessToken) { + public Drive makeClient(String clientId, String clientSecret, String applicationName, String accessToken) { if (clientId == null || clientSecret == null) { throw new IllegalArgumentException("clientId and clientSecret are required to create Google Drive client."); } try { Credential credential = authorize(clientId, clientSecret); - if (refreshToken != null && !"".equals(refreshToken)) { - credential.setRefreshToken(refreshToken); - } if (accessToken != null && !"".equals(accessToken)) { credential.setAccessToken(accessToken); } diff --git a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConfiguration.java b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConfiguration.java index 86ffd628..80e04677 100644 --- a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConfiguration.java +++ b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConfiguration.java @@ -2,6 +2,7 @@ import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriParam; +import org.assimbly.tenantvariables.mongo.MongoDao; public class GoogleDriveConfiguration { @@ -15,7 +16,8 @@ public GoogleDriveConfiguration() { protected String accessToken; @UriParam - protected String refreshToken; + @Metadata(required = true) + protected String tenant; @UriParam protected String directoryId; @@ -70,6 +72,10 @@ public void setInitialDelay(String initialDelay) { } public String getAccessToken() { + return MongoDao.interpolatePossibleTenantVariable(accessToken, getTenant()); + } + + public String getAccessTokenNoInterporlation() { return accessToken; } @@ -77,12 +83,12 @@ public void setAccessToken(String accessToken) { this.accessToken = accessToken; } - public String getRefreshToken() { - return refreshToken; + public String getTenant() { + return tenant; } - public void setRefreshToken(String refreshToken) { - this.refreshToken = refreshToken; + public void setTenant(String tenant) { + this.tenant = tenant; } public String getFilterFiles() { diff --git a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConsumer.java b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConsumer.java index 59697c1c..fa62d027 100644 --- a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConsumer.java +++ b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveConsumer.java @@ -1,5 +1,6 @@ package org.assimbly.googledrive; +import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.services.drive.Drive; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.FileList; @@ -43,7 +44,7 @@ public class GoogleDriveConsumer extends ScheduledPollConsumer implements Consum @Override protected void doStart() throws Exception { super.doStart(); - service = this.endpoint.getClient(); + service = this.endpoint.getClient(false); if (configuration.getFilterFiles() != null) filterPattern = Pattern.compile(configuration.getFilterFiles()); @@ -51,45 +52,51 @@ protected void doStart() throws Exception { @Override protected int poll() throws Exception { - if(configuration.getDirectoryId() == null) - configuration.setDirectoryId("root"); - - findOrCreateMoveToDirectory(); - - List filesToProcess = new ArrayList<>(); - String pageToken = null; - - do { - FileList result = service.files().list() - .setQ( "'" + configuration.getDirectoryId() + "' in parents" + - " and mimeType != 'application/vnd.google-apps.folder'" + - " and trashed = false") - .setSpaces("drive") - .setFields("nextPageToken, files(id, name, mimeType)") - .setPageToken(pageToken) - .execute(); - - for (File file : result.getFiles()) { - if (isGSuiteFile(file) && configuration.getGSuiteFiles().equals("Ignore")) - continue; - - if (filterPattern == null || filterPattern.matcher(file.getName()).matches()) - filesToProcess.add(file); - } - pageToken = result.getNextPageToken(); + try { + if(configuration.getDirectoryId() == null) + configuration.setDirectoryId("root"); + + findOrCreateMoveToDirectory(); + + List filesToProcess = new ArrayList<>(); + String pageToken = null; + + do { + FileList result = service.files().list() + .setQ( "'" + configuration.getDirectoryId() + "' in parents" + + " and mimeType != 'application/vnd.google-apps.folder'" + + " and trashed = false") + .setSpaces("drive") + .setFields("nextPageToken, files(id, name, mimeType)") + .setPageToken(pageToken) + .execute(); - } while (pageToken != null); + for (File file : result.getFiles()) { + if (isGSuiteFile(file) && configuration.getGSuiteFiles().equals("Ignore")) + continue; - for(File fileModel : filesToProcess) { + if (filterPattern == null || filterPattern.matcher(file.getName()).matches()) + filesToProcess.add(file); + } - java.io.File file = downloadFile(fileModel); + pageToken = result.getNextPageToken(); - Exchange exchange = endpoint.createExchange(file, fileModel); + } while (pageToken != null); - this.getProcessor().process(exchange); + for(File fileModel : filesToProcess) { - postProcess(fileModel, file); + java.io.File file = downloadFile(fileModel); + + Exchange exchange = endpoint.createExchange(file, fileModel); + + this.getProcessor().process(exchange); + + postProcess(fileModel, file); + } + } catch (GoogleJsonResponseException e) { + LOG.error("Google Drive Consume error:", e); + service = this.endpoint.getClient(true); } return 0; diff --git a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveEndpoint.java b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveEndpoint.java index 6a924dec..22dde640 100644 --- a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveEndpoint.java +++ b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveEndpoint.java @@ -71,10 +71,10 @@ public boolean isSingleton() { return false; } - Drive getClient() { + Drive getClient(boolean forceFlag) { if (client == null) { client = getClientFactory().makeClient(CLIENT_ID, CLIENT_SECRET, APPLICATION_NAME, - configuration.getRefreshToken(), configuration.getAccessToken()); + configuration.getAccessToken()); } return client; diff --git a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveProducer.java b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveProducer.java index 72281057..76c40f2e 100644 --- a/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveProducer.java +++ b/googledrive/src/main/java/org/assimbly/googledrive/GoogleDriveProducer.java @@ -5,6 +5,7 @@ import org.apache.camel.Exchange; import org.apache.camel.component.file.GenericFile; import org.apache.camel.support.DefaultProducer; +import org.assimbly.tenantvariables.mongo.MongoDao; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +46,8 @@ public void process(Exchange exchange) throws Exception { } private void prepareGoogleDriveClient() { - this.service = ((GoogleDriveEndpoint) getEndpoint()).getClient(); + boolean forceClient = MongoDao.isTenantVar(configuration.getAccessTokenNoInterporlation()); + this.service = ((GoogleDriveEndpoint) getEndpoint()).getClient(forceClient); } private GenericFile prepareCamelFile(Exchange exchange) throws IOException { diff --git a/mail/src/main/java/org/assimbly/mail/component/mail/MailConfiguration.java b/mail/src/main/java/org/assimbly/mail/component/mail/MailConfiguration.java index 428bf41f..a5f0951d 100644 --- a/mail/src/main/java/org/assimbly/mail/component/mail/MailConfiguration.java +++ b/mail/src/main/java/org/assimbly/mail/component/mail/MailConfiguration.java @@ -463,24 +463,7 @@ public void setAuthenticationType(String authenticationType) { * The accessToken for login */ public String getAccessToken() { - - StringBuffer accessTokenBuf = new StringBuffer(); - - Pattern pattern = Pattern.compile(TENANT_VARIABLE_EXP); - Matcher matcher = pattern.matcher(accessToken); - - while(matcher.find()){ - String accessTokenVarName = matcher.group(1); - - TenantVariable accessTokenGlobVar = MongoDao.findTenantVariableByName(accessTokenVarName, getTenant()); - String accessTokenValue = accessTokenGlobVar.find(getEnvironment()).get().getValue(); - - matcher.appendReplacement(accessTokenBuf, Matcher.quoteReplacement(accessTokenValue)); - } - matcher.appendTail(accessTokenBuf); - - return accessTokenBuf.toString(); - + return MongoDao.interpolatePossibleTenantVariable(accessToken, getTenant()); } public void setAccessToken(String accessToken) { diff --git a/oauth2token/src/main/java/org/assimbly/oauth2token/OAuth2TokenProcessor.java b/oauth2token/src/main/java/org/assimbly/oauth2token/OAuth2TokenProcessor.java index 924eb9d9..2708047c 100644 --- a/oauth2token/src/main/java/org/assimbly/oauth2token/OAuth2TokenProcessor.java +++ b/oauth2token/src/main/java/org/assimbly/oauth2token/OAuth2TokenProcessor.java @@ -2,6 +2,7 @@ import org.apache.camel.Exchange; import org.apache.camel.Processor; +import org.apache.commons.lang3.StringUtils; import org.assimbly.tenantvariables.mongo.MongoDao; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,7 +42,7 @@ public void process(Exchange exchange) { String expireDate = MongoDao.getTenantVariableValue(expireDateVarName, tenant, environment); String accessToken = MongoDao.getTenantVariableValue(accessTokenVarName, tenant, environment); String refreshFlag = MongoDao.getTenantVariableValue(refreshFlagVarName, tenant, environment); - String tokenGlobVarValue = MongoDao.getTenantVariableValue(tokenName, tenant, environment); + String tokenTenantVarValue = MongoDao.getTenantVariableValue(tokenName, tenant, environment); Calendar expireCal = Calendar.getInstance(); Calendar expireDelayCal = Calendar.getInstance(); @@ -56,21 +57,21 @@ public void process(Exchange exchange) { try { expiryDelayInt = - Integer.parseInt(expiryDelay); } catch (Exception e) { - logger.error("ERROR to parse expiryDelay value. Default value is "+expiryDelayInt); + logger.warn("Failed to parse expiryDelay value. Default value is "+expiryDelayInt); } expireDelayCal.add(Calendar.SECOND, expiryDelayInt); } catch (Exception e) { logger.error("ERROR to calculate/set expire date vars", e); } - if(tokenGlobVarValue == null || + if(StringUtils.isEmpty(tokenTenantVarValue) || nowCal.after(expireCal) || ( nowCal.before(expireCal) && nowCal.after(expireDelayCal) && refreshFlag.equals("0")) ) { // get new access token from service String accessTokenOld = accessToken; accessToken = TokenService.refreshTokenInfo(id, environment, tenant); - if(accessToken!=null && (!accessToken.equals(accessTokenOld) || tokenGlobVarValue==null)) { + if(accessToken!=null && (!accessToken.equals(accessTokenOld) || StringUtils.isEmpty(tokenTenantVarValue))) { // add token to tenant variable MongoDao.saveTenantVariable(tokenName, accessToken, tenant, environment); } diff --git a/oauth2token/src/main/java/org/assimbly/oauth2token/service/TokenService.java b/oauth2token/src/main/java/org/assimbly/oauth2token/service/TokenService.java index 822f9e16..2a3cb64e 100644 --- a/oauth2token/src/main/java/org/assimbly/oauth2token/service/TokenService.java +++ b/oauth2token/src/main/java/org/assimbly/oauth2token/service/TokenService.java @@ -1,5 +1,6 @@ package org.assimbly.oauth2token.service; +import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.assimbly.tenantvariables.mongo.MongoDao; import org.assimbly.util.exception.OAuth2TokenException; @@ -12,6 +13,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.util.*; +import java.util.stream.Collectors; @Path("/") @Secured @@ -29,6 +31,8 @@ public class TokenService { public static String OAUTH2_REFRESH_TOKEN_SUFFIX = "_refresh_token"; public static String OAUTH2_REFRESH_FLAG_SUFFIX = "_refresh_flag"; public static String OAUTH2_REDIRECT_URI_SUFFIX = "_redirect_uri"; + public static String OAUTH2_CREDENTIALS_TYPE_URI_SUFFIX = "_credentials_type"; + public static String OAUTH2_TOKEN_TENANT_VAR_SUFFIX = "_token_global_var"; private static String SERVICE_PARAM_EXPIRES_IN = "expires_in"; private static String SERVICE_PARAM_ACCESS_TOKEN = "access_token"; @@ -36,6 +40,10 @@ public class TokenService { private static String SERVICE_PARAM_ERROR = "error"; private static String SERVICE_PARAM_ERROR_DESCRIPTION = "error_description"; + private static final String GOOGLE_CLIENT_ID = System.getenv("GOOGLE_CLIENT_ID"); + private static final String GOOGLE_CLIENT_SECRET = System.getenv("GOOGLE_CLIENT_SECRET"); + private static final String CREDENTIALS_TYPE_CUSTOM = "custom"; + // call service to get token information @GET @Consumes("application/json") @@ -61,6 +69,8 @@ public Map tokenInfo( String refreshTokenVarName = OAUTH2_PREFIX + id + OAUTH2_REFRESH_TOKEN_SUFFIX; String refreshFlagVarName = OAUTH2_PREFIX + id + OAUTH2_REFRESH_FLAG_SUFFIX; String redirectUriVarName = OAUTH2_PREFIX + id + OAUTH2_REDIRECT_URI_SUFFIX; + String credentialsTypeVarName = OAUTH2_PREFIX + id + OAUTH2_CREDENTIALS_TYPE_URI_SUFFIX; + String tokenTenantVarName = OAUTH2_PREFIX + id + OAUTH2_TOKEN_TENANT_VAR_SUFFIX; // check if there's a tenant variable inside tenantVar, and return real value String scope = MongoDao.getTenantVariableValue(scopeVarName, tenant, environment); @@ -68,13 +78,18 @@ public Map tokenInfo( String clientSecret = MongoDao.getTenantVariableValue(clientSecretVarName, tenant, environment); String redirectUri = MongoDao.getTenantVariableValue(redirectUriVarName, tenant, environment); String uriToken = MongoDao.getTenantVariableValue(uriTokenVarName, tenant, environment); + String credentialsType = MongoDao.getTenantVariableValue(credentialsTypeVarName, tenant, environment); + String tokenTenantVar = MongoDao.getTenantVariableValue(tokenTenantVarName, tenant, environment); + + boolean customCredentialsType = StringUtils.isEmpty(credentialsType) || + credentialsType.equals(CREDENTIALS_TYPE_CUSTOM); // prepare data to send - String urlParameters = "client_id="+clientId+ + String urlParameters = "client_id="+(customCredentialsType ? clientId : GOOGLE_CLIENT_ID)+ (scope!=null && !scope.trim().equals("") ? "&scope="+scope : "")+ "&redirect_uri="+redirectUri+ "&grant_type=authorization_code"+ - "&client_secret="+clientSecret+ + "&client_secret="+(customCredentialsType ? clientSecret : GOOGLE_CLIENT_SECRET)+ "&code="+code; // call service @@ -88,6 +103,7 @@ public Map tokenInfo( String accessToken = tokenInfoMap.get(SERVICE_PARAM_ACCESS_TOKEN); if(accessToken!=null && !accessToken.isEmpty()) { MongoDao.saveTenantVariable(accessTokenVarName, accessToken, tenant, environment); + MongoDao.saveTenantVariable(tokenTenantVar, accessToken, tenant, environment); } String refreshToken = tokenInfoMap.get(SERVICE_PARAM_REFRESH_TOKEN); if(refreshToken!=null && !refreshToken.isEmpty()) { @@ -116,6 +132,7 @@ public static String refreshTokenInfo(String id, String environment, String tena String refreshTokenVarName = OAUTH2_PREFIX + id + OAUTH2_REFRESH_TOKEN_SUFFIX; String refreshFlagVarName = OAUTH2_PREFIX + id + OAUTH2_REFRESH_FLAG_SUFFIX; String redirectUriVarName = OAUTH2_PREFIX + id + OAUTH2_REDIRECT_URI_SUFFIX; + String credentialsTypeVarName = OAUTH2_PREFIX + id + OAUTH2_CREDENTIALS_TYPE_URI_SUFFIX; try { // set refresh flag to active @@ -128,13 +145,17 @@ public static String refreshTokenInfo(String id, String environment, String tena String redirectUri = MongoDao.getTenantVariableValue(redirectUriVarName, tenant, environment); String refreshToken = MongoDao.getTenantVariableValue(refreshTokenVarName, tenant, environment); String uriToken = MongoDao.getTenantVariableValue(uriTokenVarName, tenant, environment); + String credentialsType = MongoDao.getTenantVariableValue(credentialsTypeVarName, tenant, environment); + + boolean customCredentialsType = StringUtils.isEmpty(credentialsType) || + credentialsType.equals(CREDENTIALS_TYPE_CUSTOM); // prepare data to send - String urlParameters = "client_id="+clientId+ + String urlParameters = "client_id="+(customCredentialsType ? clientId : GOOGLE_CLIENT_ID)+ (scope!=null && !scope.trim().equals("") ? "&scope="+scope : "")+ "&redirect_uri="+redirectUri+ "&grant_type=refresh_token"+ - "&client_secret="+clientSecret+ + "&client_secret="+(customCredentialsType ? clientSecret : GOOGLE_CLIENT_SECRET)+ "&refresh_token="+refreshToken; // call service @@ -201,8 +222,8 @@ private static void callService( stream = con.getErrorStream(); } - BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"), 8); - tokenInfoResp = reader.readLine(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + tokenInfoResp = reader.lines().collect(Collectors.joining(System.lineSeparator())); if (tokenInfoResp != null) { JSONObject tokenInfoJson = new JSONObject(tokenInfoResp); @@ -224,7 +245,7 @@ private static void callService( // access_token String accessToken = tokenInfoJson.getString(SERVICE_PARAM_ACCESS_TOKEN); // refresh_token - String refreshToken = tokenInfoJson.getString(SERVICE_PARAM_REFRESH_TOKEN); + String refreshToken = tokenInfoJson.optString(SERVICE_PARAM_REFRESH_TOKEN); // add token info into hashmap tokenInfoMap.put(SERVICE_PARAM_EXPIRES_IN, String.valueOf(nowCal.getTimeInMillis())); tokenInfoMap.put(SERVICE_PARAM_ACCESS_TOKEN, accessToken); diff --git a/tenantvariables/src/main/java/org/assimbly/tenantvariables/TenantVariablesProcessor.java b/tenantvariables/src/main/java/org/assimbly/tenantvariables/TenantVariablesProcessor.java index 2ae3204d..ca55867e 100644 --- a/tenantvariables/src/main/java/org/assimbly/tenantvariables/TenantVariablesProcessor.java +++ b/tenantvariables/src/main/java/org/assimbly/tenantvariables/TenantVariablesProcessor.java @@ -71,6 +71,10 @@ public String encrypt(String value) { return encryptedValue; } + public String getValueByEnvironmentValue(EnvironmentValue environmentVar) { + return (environmentVar.isEncrypted() ? decrypt(environmentVar.getValue()) : environmentVar.getValue()); + } + private void getTenantVariable(Exchange exchange) { String name = endpoint.getConfiguration().getName(); String tenant = (endpoint.getConfiguration().getTenant()!=null ? endpoint.getConfiguration().getTenant() : TENANT_DEFAULT); diff --git a/tenantvariables/src/main/java/org/assimbly/tenantvariables/mongo/MongoDao.java b/tenantvariables/src/main/java/org/assimbly/tenantvariables/mongo/MongoDao.java index f6f9fbec..6beb6e08 100644 --- a/tenantvariables/src/main/java/org/assimbly/tenantvariables/mongo/MongoDao.java +++ b/tenantvariables/src/main/java/org/assimbly/tenantvariables/mongo/MongoDao.java @@ -2,6 +2,7 @@ import dev.morphia.Datastore; import dev.morphia.query.Query; +import org.assimbly.tenantvariables.TenantVariablesProcessor; import org.assimbly.tenantvariables.domain.EnvironmentValue; import org.assimbly.tenantvariables.domain.TenantVariable; import org.assimbly.tenantvariables.exception.EnvironmentValueNotFoundException; @@ -26,17 +27,17 @@ public class MongoDao { private static final String TENANT_VARIABLE_EXPRESSION = "@\\{(.*?)}"; - static public TenantVariable findTenantVariableByName(String variableName, String tenant) { + public static TenantVariable findTenantVariableByName(String variableName, String tenant) { Datastore datastore = MongoClientProvider.getInstance().getDatastore(tenant); return datastore.find(TenantVariable.class).field(NAME_FIELD).equal(variableName).get(); } - static public List findAll(String tenant) { + public static List findAll(String tenant) { Datastore datastore = MongoClientProvider.getInstance().getDatastore(tenant); return datastore.createQuery(TenantVariable.class).asList(); } - static public String getTenantVariableValue(String tenantVarName, String tenant, String environment) { + public static String getTenantVariableValue(String tenantVarName, String tenant, String environment) { TenantVariable tenantVar = MongoDao.findTenantVariableByName(tenantVarName, tenant); if(tenantVar==null) { @@ -49,31 +50,64 @@ static public String getTenantVariableValue(String tenantVarName, String tenant, .orElseThrow(() -> new EnvironmentValueNotFoundException("Tenant variable (" + tenantVarName + ") value not found for environment: " + environment)) .getValue(); - Pattern pattern = Pattern.compile(TENANT_VARIABLE_EXPRESSION); - Matcher matcher = pattern.matcher(tenantVariableValue); - - while(matcher.find()) { - String internalTenantVarName = matcher.group(1); - - TenantVariable internalTenantVar = findTenantVariableByName(internalTenantVarName, tenant); - if(internalTenantVar != null) { - Optional optionalEnvironmentValue = internalTenantVar.find(environment); - if(optionalEnvironmentValue.isPresent()) { - internalTenantVarName = optionalEnvironmentValue.get().getValue(); + if(tenantVariableValue!=null) { + Pattern pattern = Pattern.compile(TENANT_VARIABLE_EXPRESSION); + Matcher matcher = pattern.matcher(tenantVariableValue); + + while(matcher.find()) { + String internalTenantVarName = matcher.group(1); + + TenantVariable internalTenantVar = findTenantVariableByName(internalTenantVarName, tenant); + if(internalTenantVar != null) { + Optional optionalEnvironmentValue = internalTenantVar.find(environment); + if(optionalEnvironmentValue.isPresent()) { + internalTenantVarName = optionalEnvironmentValue.get().getValue(); + } else { + internalTenantVarName = ""; + } } else { internalTenantVarName = ""; } - } else { - internalTenantVarName = ""; - } - matcher.appendReplacement(output, Matcher.quoteReplacement(internalTenantVarName)); + matcher.appendReplacement(output, Matcher.quoteReplacement(internalTenantVarName)); + } + matcher.appendTail(output); } - matcher.appendTail(output); + return output.toString(); } - static public void saveTenantVariable( + public static String interpolatePossibleTenantVariable(String value, String tenant) { + StringBuffer valueBuf = new StringBuffer(); + String environment = TenantVariablesProcessor.getEnvironment(); + Pattern pattern = Pattern.compile(TENANT_VARIABLE_EXPRESSION); + Matcher matcher = pattern.matcher(value); + + while(matcher.find()){ + String varName = matcher.group(1); + TenantVariablesProcessor tenantVarProcessor = new TenantVariablesProcessor(); + String environmentVarValue = ""; + + TenantVariable tenantVar = MongoDao.findTenantVariableByName(varName, tenant); + Optional environmentVar = tenantVar.find(environment); + if(environmentVar.isPresent()) { + environmentVarValue = tenantVarProcessor.getValueByEnvironmentValue(environmentVar.get()); + } + + matcher.appendReplacement(valueBuf, Matcher.quoteReplacement(environmentVarValue)); + } + matcher.appendTail(valueBuf); + + return valueBuf.toString(); + } + + public static boolean isTenantVar(String value) { + Pattern pattern = Pattern.compile(TENANT_VARIABLE_EXPRESSION); + Matcher matcher = pattern.matcher(value); + return matcher.find(); + } + + public static void saveTenantVariable( String tenantVarName, String tenantVarValue, String tenant, String environment ) { TenantVariable tenantVariable = findTenantVariableByName(tenantVarName, tenant); @@ -97,17 +131,17 @@ static public void saveTenantVariable( updateTenantVariable(tenantVariable, tenant); } - static public void updateTenantVariable(TenantVariable tenantVariable, String tenant){ + public static void updateTenantVariable(TenantVariable tenantVariable, String tenant){ Datastore datastore = MongoClientProvider.getInstance().getDatastore(tenant); datastore.save(tenantVariable); } - static public void deleteTenantVariable(TenantVariable tenantVariable, String tenant) { + public static void deleteTenantVariable(TenantVariable tenantVariable, String tenant) { Datastore datastore = MongoClientProvider.getInstance().getDatastore(tenant); datastore.delete(tenantVariable); } - static public void deleteTenantVariablesByName(String tenantVarName, String tenant) { + public static void deleteTenantVariablesByName(String tenantVarName, String tenant) { Datastore datastore = MongoClientProvider.getInstance().getDatastore(tenant); Query query = datastore.createQuery(TenantVariable.class) .field("name")