This is an automated email from the ASF dual-hosted git repository. hutran pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-gobblin.git
The following commit(s) were added to refs/heads/master by this push: new 5b10709 [GOBBLIN-1179] Add typed config in salesforce 5b10709 is described below commit 5b1070992d906824889eda4c7041bb6d28ae549b Author: Alex Li <al...@linkedin.com> AuthorDate: Wed Jun 3 17:47:07 2020 -0700 [GOBBLIN-1179] Add typed config in salesforce Closes #2910 from arekusuri/typedconfig --- .gitignore | 2 + .../gobblin/salesforce/QueryBasedSourceConfig.java | 29 +++++ .../salesforce/SalesforceConfigurationKeys.java | 6 - .../gobblin/salesforce/SalesforceExtractor.java | 12 +- .../org/apache/gobblin/salesforce/SfConfig.java | 39 ++++++ .../java/org/apache/gobblin/typedconfig/Alias.java | 30 +++++ .../apache/gobblin/typedconfig/ConstraintUtil.java | 135 +++++++++++++++++++++ .../org/apache/gobblin/typedconfig/Default.java | 30 +++++ .../java/org/apache/gobblin/typedconfig/Key.java | 31 +++++ .../apache/gobblin/typedconfig/TypedConfig.java | 127 +++++++++++++++++++ .../typedconfig/compiletime/EnumOptions.java | 30 +++++ .../gobblin/typedconfig/compiletime/IntRange.java | 30 +++++ .../gobblin/typedconfig/compiletime/LongRange.java | 30 +++++ .../typedconfig/compiletime/StringRegex.java | 30 +++++ 14 files changed, 548 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 4135edf..a6075f2 100644 --- a/.gitignore +++ b/.gitignore @@ -80,7 +80,9 @@ FsDatasetStateStoreTest/ GobblinHelixTaskTest/ commit-sequence-store-test/ gobblin-test-harness/src/test/resources/runtime_test/state_store/ + gobblin-integration-test-work-dir/ gobblin-test-utils/src/main/gen-avro/ gobblin-test-utils/src/main/gen-proto/ + diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/QueryBasedSourceConfig.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/QueryBasedSourceConfig.java new file mode 100644 index 0000000..20c24fb --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/QueryBasedSourceConfig.java @@ -0,0 +1,29 @@ +/* + * 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.gobblin.salesforce; + +import java.util.Properties; +import org.apache.gobblin.typedconfig.TypedConfig; + + +public class QueryBasedSourceConfig extends TypedConfig { + + public QueryBasedSourceConfig(Properties prop) { + super(prop); + } +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceConfigurationKeys.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceConfigurationKeys.java index b40e0e8..a01285a 100644 --- a/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceConfigurationKeys.java +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceConfigurationKeys.java @@ -25,8 +25,6 @@ public final class SalesforceConfigurationKeys { } public static final String SOURCE_QUERYBASED_SALESFORCE_IS_SOFT_DELETES_PULL_DISABLED = "source.querybased.salesforce.is.soft.deletes.pull.disabled"; - public static final int DEFAULT_FETCH_RETRY_LIMIT = 5; - public static final String BULK_API_USE_QUERY_ALL = "salesforce.bulkApiUseQueryAll"; // bulk api retry sleep duration for avoid resource consuming peak. public static final String RETRY_EXCEED_QUOTA_INTERVAL = "salesforce.retry.exceedQuotaInterval"; @@ -39,10 +37,6 @@ public final class SalesforceConfigurationKeys { public static final String BULK_TEST_JOB_ID = "salesforce.bulk.testJobId"; public static final String BULK_TEST_BATCH_ID_LIST = "salesforce.bulk.testBatchIds"; public static final String SALESFORCE_PARTITION_TYPE = "salesforce.partitionType"; - public static final String PARTITION_PK_CHUNKING_SIZE = "salesforce.partition.pkChunkingSize"; public static final String PK_CHUNKING_JOB_ID = "__salesforce.job.id"; // don't use in ini config public static final String PK_CHUNKING_BATCH_RESULT_ID_PAIRS = "__salesforce.batch.result.id.pairs"; // don't use in ini config - public static final int MAX_PK_CHUNKING_SIZE = 250_000; // this number is from SFDC's doc - https://tinyurl.com/ycjvgwv2 - public static final int MIN_PK_CHUNKING_SIZE = 20_000; - public static final int DEFAULT_PK_CHUNKING_SIZE = 250_000; // default to max for saving request quota } diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceExtractor.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceExtractor.java index 2a5d8bc..868ed54 100644 --- a/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceExtractor.java +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SalesforceExtractor.java @@ -100,8 +100,6 @@ public class SalesforceExtractor extends RestApiExtractor { private static final String SALESFORCE_SOAP_SERVICE = "/services/Soap/u"; private static final Gson GSON = new Gson(); private static final int MAX_RETRY_INTERVAL_SECS = 600; - private static final String FETCH_RETRY_LIMIT_KEY = "salesforce.fetchRetryLimit"; - private static final boolean DEFAULT_BULK_API_USE_QUERY_ALL = false; private boolean pullStatus = true; private String nextUrl; @@ -120,20 +118,20 @@ public class SalesforceExtractor extends RestApiExtractor { private final long retryExceedQuotaInterval; private final boolean bulkApiUseQueryAll; + private SfConfig conf; public SalesforceExtractor(WorkUnitState state) { super(state); + conf = new SfConfig(state.getProperties()); this.sfConnector = (SalesforceConnector) this.connector; - this.pkChunkingSize = - Math.max(MIN_PK_CHUNKING_SIZE, - Math.min(MAX_PK_CHUNKING_SIZE, workUnitState.getPropAsInt(PARTITION_PK_CHUNKING_SIZE, DEFAULT_PK_CHUNKING_SIZE))); + this.pkChunkingSize = conf.pkChunkingSize; - this.bulkApiUseQueryAll = workUnitState.getPropAsBoolean(BULK_API_USE_QUERY_ALL, DEFAULT_BULK_API_USE_QUERY_ALL); - this.retryLimit = workUnitState.getPropAsInt(FETCH_RETRY_LIMIT_KEY, DEFAULT_FETCH_RETRY_LIMIT); this.retryInterval = workUnitState.getPropAsLong(RETRY_INTERVAL, RETRY_INTERVAL_DEFAULT); this.retryExceedQuotaInterval = workUnitState.getPropAsLong(RETRY_EXCEED_QUOTA_INTERVAL, RETRY_EXCEED_QUOTA_INTERVAL_DEFAULT); + this.bulkApiUseQueryAll = conf.bulkApiUseQueryAll; + this.retryLimit = conf.fetchRetryLimit; } @Override diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SfConfig.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SfConfig.java new file mode 100644 index 0000000..4377237 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/salesforce/SfConfig.java @@ -0,0 +1,39 @@ +/* + * 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.gobblin.salesforce; + +import java.util.Properties; +import org.apache.gobblin.typedconfig.Default; +import org.apache.gobblin.typedconfig.Key; +import org.apache.gobblin.typedconfig.compiletime.IntRange; + + +public class SfConfig extends QueryBasedSourceConfig { + public SfConfig(Properties prop) { + super(prop); + } + + @Key("salesforce.partition.pkChunkingSize")@Default("250000")@IntRange({20_000, 250_000}) + public int pkChunkingSize; + + @Key("salesforce.bulkApiUseQueryAll")@Default("false") + public boolean bulkApiUseQueryAll; + + @Key("salesforce.fetchRetryLimit")@Default("5") + public int fetchRetryLimit; +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Alias.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Alias.java new file mode 100644 index 0000000..1a0110e --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Alias.java @@ -0,0 +1,30 @@ +/* + * 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.gobblin.typedconfig; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Alias { + String value(); +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/ConstraintUtil.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/ConstraintUtil.java new file mode 100644 index 0000000..af4b57f --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/ConstraintUtil.java @@ -0,0 +1,135 @@ +/* + * 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.gobblin.typedconfig; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.apache.gobblin.typedconfig.compiletime.EnumOptions; +import org.apache.gobblin.typedconfig.compiletime.IntRange; +import org.apache.gobblin.typedconfig.compiletime.LongRange; +import org.apache.gobblin.typedconfig.compiletime.StringRegex; + + +/** + * Util class for handling constraint annotation + * supports: IntRange, LongRange, EnumOption, StringRegex + */ +@Slf4j +public class ConstraintUtil { + private ConstraintUtil() { + } + + public static Object constraint(Field field, Object value) { + Class type = field.getType(); + if (type.isEnum()) { + return getEnumValue(field, value); + } + switch (type.getName()) { + case "int": case "java.lang.Integer": + return getIntValue(field, value); + case "long": case "java.lang.Long": + return getLongValue(field, value); + case "java.lang.String": + return getStringValue(field, value); + case "boolean": case "java.lang.Boolean": + return getBooleanValue(field, value); + case "java.util.Date": + return getDateValue(field, value); + default: + throw new RuntimeException("not supported the return type: " + type.getName()); + } + } + + static private Object getIntValue(Field field, Object value) { + IntRange intRange = field.getAnnotation(IntRange.class); + if (intRange == null) { + return value; + } + int[] range = intRange.value(); + int intValue = Integer.parseInt(value.toString()); + if (range.length != 2) { + throw new RuntimeException(String.format("Field [%s]: Long range is invalid.", field.getName())); + } + if (intValue >= range[0] && intValue <= range[1]) { + return value; + } else { + throw new RuntimeException( + String.format("Field [%s]: value [%s] is out of range [%s, %s].", field.getName(), value, range[0], range[1]) + ); + } + } + static private Object getLongValue(Field field, Object value) { + LongRange longRange = field.getAnnotation(LongRange.class); + long[] range = longRange.value(); + if (range == null) { + return value; + } + long longValue = Long.parseLong(value.toString()); + if (range.length != 2) { + throw new RuntimeException(String.format("Field [%s]: Long range is invalid.", field.getName())); + } + if (longValue > range[0] && longValue < range[1]) { + return value; + } else { + throw new RuntimeException( + String.format("Field [%s]: value [%s] is out of range [%s, %s].", field.getName(), value, range[0], range[1]) + ); + } + } + + static private Object getStringValue(Field field, Object value) { + StringRegex stringRegex = field.getAnnotation(StringRegex.class); + if (stringRegex == null) { + return value; + } + String regex = stringRegex.value(); + if (regex == null) { + return value; + } + boolean isMatching = value.toString().matches(regex); + if (isMatching) { + return value; + } else { + throw new RuntimeException(String.format("[%s] is not matching pattern [%s]", value, regex)); + } + } + + static private Object getBooleanValue(Field field, Object value) { + return value; // there is no restriction for boolean value. + } + + static private Object getDateValue(Field field, Object value) { + return value; // there is no restriction for Date value. + } + + static private Object getEnumValue(Field field, Object value) { + EnumOptions enumOptions = field.getAnnotation(EnumOptions.class); + if (enumOptions == null) { + return value; + } + List<String> options = Arrays.asList(enumOptions.value()); + if (options.indexOf(value) >= 0) { + return value; + } else { + throw new RuntimeException(String.format("Enum [%s] is not allowed.", value)); + } + } +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Default.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Default.java new file mode 100644 index 0000000..cd12fdf --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Default.java @@ -0,0 +1,30 @@ +/* + * 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.gobblin.typedconfig; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Default { + String value(); +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Key.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Key.java new file mode 100644 index 0000000..cb43249 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/Key.java @@ -0,0 +1,31 @@ +/* + * 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.gobblin.typedconfig; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Key { + String value(); +} + diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/TypedConfig.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/TypedConfig.java new file mode 100644 index 0000000..cd70794 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/TypedConfig.java @@ -0,0 +1,127 @@ +/* + * 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.gobblin.typedconfig; + +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Properties; +import lombok.SneakyThrows; +import org.apache.commons.beanutils.BeanUtilsBean; +import org.apache.commons.beanutils.ConvertUtilsBean; + + +public class TypedConfig { + + public TypedConfig(Properties prop) { + if (prop != null) { + fulfillFields(this.getClass(), prop); + } + } + + @SneakyThrows + private void fulfillFields(Class<? extends TypedConfig> clazz, Properties prop) { + if (!clazz.equals(TypedConfig.class)) { + this.fulfillFields((Class<? extends TypedConfig>) clazz.getSuperclass(), prop); + } + for (Field field : clazz.getDeclaredFields()) { + if (field.getAnnotations().length == 0) { + continue; + } + Object defaultValue = pickupDefaultValue(field); // get default value which is in config class + Object configValue = pickupValueByKey(field, prop); // get ini file config value by key + if (configValue == null) { + configValue = pickupValueByAlias(field, prop); // by alias (2nd key) + } + if (configValue == null) { + configValue = defaultValue; + } + if (configValue != null) { + configValue = ConstraintUtil.constraint(field, configValue); + field.set(this, convert(configValue, field.getType())); + } + } + } + + private Object pickupDefaultValue(Field field) { + Default defaultAnn = field.getAnnotation(Default.class); + if (defaultAnn == null) { + return null; + } + return defaultAnn.value(); // the value was put in source code instead of ini file + } + + private Object pickupValueByAlias(Field field, Properties prop) { + Alias alias = field.getAnnotation(Alias.class); + if (alias == null) { + return null; + } + return prop.get(alias.value()); // get ini config value by alias(2nd key) + } + + private Object pickupValueByKey(Field field, Properties prop) { + Key key = field.getAnnotation(Key.class); + if (key == null) { + return null; + } + return prop.get(key.value()); // get ini config value by key + } + + private Object convert(Object value, Class targetClazz) { + if (value == null) { + return null; + } + BeanUtilsBean beanUtilsBean = new BeanUtilsBean(new ConvertUtilsBean() { + @SneakyThrows + @Override + public Object convert(Object value, Class clazz) { + if (clazz.isEnum()) { + return Enum.valueOf(clazz, (String) value); + } else if (clazz == Date.class) { + String dateStr = ((String) value).replaceAll("-| |:", ""); // date format: 1, 2020-01-02 03:04:59, 2, 20200102030459 + dateStr = String.format("%-14s", dateStr).replaceAll(" ", "0"); + Date date = new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr); + return date; + } else { + return super.convert(value, clazz); + } + } + }); + return beanUtilsBean.getConvertUtils().convert(value, targetClazz); + } + + /** + * convert data to property + */ + @SneakyThrows + public Properties toProp() { + Properties prop = new Properties(); + for (Field field : this.getClass().getDeclaredFields()) { + Key keyAnn = field.getAnnotation(Key.class); + if (keyAnn == null) { + continue; + } + Object configValue = field.get(this); + if (configValue == null) { + continue; + } + prop.put(keyAnn.value(), configValue.toString()); + } + return prop; + } +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/EnumOptions.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/EnumOptions.java new file mode 100644 index 0000000..925ee20 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/EnumOptions.java @@ -0,0 +1,30 @@ +/* + * 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.gobblin.typedconfig.compiletime; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface EnumOptions { + String[] value(); +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/IntRange.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/IntRange.java new file mode 100644 index 0000000..9ba6077 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/IntRange.java @@ -0,0 +1,30 @@ +/* + * 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.gobblin.typedconfig.compiletime; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface IntRange { + int[] value(); +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/LongRange.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/LongRange.java new file mode 100644 index 0000000..0362b88 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/LongRange.java @@ -0,0 +1,30 @@ +/* + * 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.gobblin.typedconfig.compiletime; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface LongRange { + long[] value(); +} diff --git a/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/StringRegex.java b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/StringRegex.java new file mode 100644 index 0000000..1a8bd97 --- /dev/null +++ b/gobblin-salesforce/src/main/java/org/apache/gobblin/typedconfig/compiletime/StringRegex.java @@ -0,0 +1,30 @@ +/* + * 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.gobblin.typedconfig.compiletime; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface StringRegex { + String value(); +}