Camel catalog - Add api to validate endpoint uri
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/13ebce9b
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/13ebce9b
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/13ebce9b
Branch: refs/heads/camel-2.16.x
Commit: 13ebce9b3b9bb4456e8688f8c95d0ae71cee29cc
Parents: 43775d0
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Sat Dec 19 14:49:43 2015 +0100
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Mon Dec 21 13:42:01 2015 +0100
----------------------------------------------------------------------
.../org/apache/camel/catalog/CamelCatalog.java | 11 ++
.../camel/catalog/DefaultCamelCatalog.java | 117 +++++++++++++++++++
.../apache/camel/catalog/JSonSchemaHelper.java | 78 +++++++++++++
.../apache/camel/catalog/CamelCatalogTest.java | 45 ++++++-
4 files changed, 250 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/13ebce9b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
index 7dc67a0..dc1a3ca 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
@@ -170,6 +170,17 @@ public interface CamelCatalog {
Map<String, String> endpointProperties(String uri) throws URISyntaxException;
/**
+ * Parses and validates the endpoint uri and constructs a key/value properties of each
option
+ *
+ * @param uri the endpoint uri
+ * @return invalid properties as key/value properties of each invalid option, returns
an empty map if no validation errors
+ */
+ Map<String, String> validateProperties(String uri) throws URISyntaxException;
+
+ // TODO: json with error instead of map
+ // with description of the error, index, etc
+
+ /**
* Returns the component name from the given endpoint uri
*
* @param uri the endpoint uri
http://git-wip-us.apache.org/repos/asf/camel/blob/13ebce9b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
index 870bc0f..13b3052 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
@@ -42,8 +42,14 @@ import org.w3c.dom.Document;
import static org.apache.camel.catalog.CatalogHelper.after;
import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyDefaultValue;
+import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyEnum;
+import static org.apache.camel.catalog.JSonSchemaHelper.getRow;
+import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyBoolean;
+import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyInteger;
+import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyNumber;
import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyRequired;
import static org.apache.camel.catalog.URISupport.createQueryString;
+import static org.apache.camel.catalog.URISupport.isEmpty;
import static org.apache.camel.catalog.URISupport.normalizeUri;
import static org.apache.camel.catalog.URISupport.stripQuery;
@@ -72,9 +78,17 @@ public class DefaultCamelCatalog implements CamelCatalog {
private boolean caching;
+ /**
+ * Creates the {@link CamelCatalog} without caching enabled.
+ */
public DefaultCamelCatalog() {
}
+ /**
+ * Creates the {@link CamelCatalog}
+ *
+ * @param caching whether to use cache
+ */
public DefaultCamelCatalog(boolean caching) {
this.caching = caching;
}
@@ -632,6 +646,109 @@ public class DefaultCamelCatalog implements CamelCatalog {
}
@Override
+ public Map<String, String> validateProperties(String uri) throws URISyntaxException
{
+ Map<String, String> answer = new LinkedHashMap<String, String>();
+
+ // parse the uri
+ URI u = normalizeUri(uri);
+ String scheme = u.getScheme();
+ String json = componentJSonSchema(scheme);
+ List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("properties",
json, true);
+
+ // parse into a map of properties of the uri, and look for options that are invalid
+ Map<String, String> properties = endpointProperties(uri);
+ for (Map.Entry<String, String> property : properties.entrySet()) {
+ String name = property.getKey();
+ String value = property.getValue();
+ boolean placeholder = value.startsWith("{{") || value.startsWith("${") || value.startsWith("$simple{");
+
+ Map<String, String> row = getRow(rows, name);
+ // unknown option
+ if (row == null) {
+ answer.put(name, property.getValue());
+ } else {
+ // invalid value/type
+
+ // is required but the value is empty
+ boolean required = isPropertyRequired(rows, name);
+ if (required && isEmpty(value)) {
+ answer.put(name, value);
+ }
+
+ // is enum but the value is not within the enum range
+ // but we can only check if the value is not a placeholder
+ String enums = getPropertyEnum(rows, name);
+ if (!placeholder && enums != null) {
+ boolean found = false;
+ for (String s : enums.split(",")) {
+ if (value.equalsIgnoreCase(s)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ answer.put(name, value);
+ }
+ }
+
+ // is boolean
+ if (!placeholder && isPropertyBoolean(rows, name)) {
+ // value must be a boolean
+ boolean bool = "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value);
+ if (!bool) {
+ answer.put(name, value);
+ }
+ }
+
+ // is integer
+ if (!placeholder && isPropertyInteger(rows, name)) {
+ // value must be an integer
+ boolean valid = false;
+ try {
+ valid = Integer.valueOf(value) != null;
+ } catch (Exception e) {
+ // ignore
+ }
+ if (!valid) {
+ answer.put(name, value);
+ }
+ }
+
+ // is number
+ if (!placeholder && isPropertyNumber(rows, name)) {
+ // value must be an number
+ boolean valid = false;
+ try {
+ valid = Double.valueOf(value).isNaN() == false || Float.valueOf(value).isNaN()
== false;
+ } catch (Exception e) {
+ // ignore
+ }
+ if (!valid) {
+ answer.put(name, value);
+ }
+ }
+ }
+ }
+
+ // now check if all required values are there, and that a default value does not
exists
+ for (Map<String, String> row : rows) {
+ String name = row.get("name");
+ boolean required = isPropertyRequired(rows, name);
+ if (required) {
+ String value = properties.get(name);
+ if (isEmpty(value)) {
+ value = getPropertyDefaultValue(rows, name);
+ }
+ if (isEmpty(value)) {
+ answer.put(name, value);
+ }
+ }
+ }
+
+ return answer;
+ }
+
+ @Override
public Map<String, String> endpointProperties(String uri) throws URISyntaxException
{
// NOTICE: This logic is similar to org.apache.camel.util.EndpointHelper#endpointProperties
// as the catalog also offers similar functionality (without having camel-core on
classpath)
http://git-wip-us.apache.org/repos/asf/camel/blob/13ebce9b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java
b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java
index 17e0f85..e3e4beb 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java
@@ -129,6 +129,57 @@ public final class JSonSchemaHelper {
return false;
}
+ public static boolean isPropertyBoolean(List<Map<String, String>> rows, String
name) {
+ for (Map<String, String> row : rows) {
+ String type = null;
+ boolean found = false;
+ if (row.containsKey("name")) {
+ found = name.equals(row.get("name"));
+ }
+ if (row.containsKey("type")) {
+ type = row.get("type");
+ }
+ if (found) {
+ return "boolean".equals(type);
+ }
+ }
+ return false;
+ }
+
+ public static boolean isPropertyInteger(List<Map<String, String>> rows, String
name) {
+ for (Map<String, String> row : rows) {
+ String type = null;
+ boolean found = false;
+ if (row.containsKey("name")) {
+ found = name.equals(row.get("name"));
+ }
+ if (row.containsKey("type")) {
+ type = row.get("type");
+ }
+ if (found) {
+ return "integer".equals(type);
+ }
+ }
+ return false;
+ }
+
+ public static boolean isPropertyNumber(List<Map<String, String>> rows, String
name) {
+ for (Map<String, String> row : rows) {
+ String type = null;
+ boolean found = false;
+ if (row.containsKey("name")) {
+ found = name.equals(row.get("name"));
+ }
+ if (row.containsKey("type")) {
+ type = row.get("type");
+ }
+ if (found) {
+ return "number".equals(type);
+ }
+ }
+ return false;
+ }
+
public static String getPropertyDefaultValue(List<Map<String, String>> rows,
String name) {
for (Map<String, String> row : rows) {
String defaultValue = null;
@@ -146,4 +197,31 @@ public final class JSonSchemaHelper {
return null;
}
+ public static String getPropertyEnum(List<Map<String, String>> rows, String
name) {
+ for (Map<String, String> row : rows) {
+ String enums = null;
+ String defaultValue = null;
+ boolean found = false;
+ if (row.containsKey("name")) {
+ found = name.equals(row.get("name"));
+ }
+ if (row.containsKey("enum")) {
+ enums = row.get("enum");
+ }
+ if (found) {
+ return enums;
+ }
+ }
+ return null;
+ }
+
+ public static Map<String, String> getRow(List<Map<String, String>>
rows, String key) {
+ for (Map<String, String> row : rows) {
+ if (key.equals(row.get("name"))) {
+ return row;
+ }
+ }
+ return null;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/camel/blob/13ebce9b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index 324362f..4c020da 100644
--- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -22,7 +22,6 @@ import java.util.Map;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -388,6 +387,50 @@ public class CamelCatalogTest {
}
@Test
+ public void validateProperties() throws Exception {
+ // valid
+ Map<String, String> map = catalog.validateProperties("log:mylog");
+ assertNotNull(map);
+ assertEquals(0, map.size());
+
+ // unknown
+ map = catalog.validateProperties("log:mylog?level=WARN&foo=bar");
+ assertNotNull(map);
+ assertEquals(1, map.size());
+ assertEquals("bar", map.get("foo"));
+
+ // enum
+ map = catalog.validateProperties("jms:unknown:myqueue");
+ assertNotNull(map);
+ assertEquals(1, map.size());
+
+ // okay
+ map = catalog.validateProperties("yammer:MESSAGES?accessToken=aaa&consumerKey=bbb&consumerSecret=ccc&useJson=true&initialDelay=500");
+ assertNotNull(map);
+ assertEquals(0, map.size());
+
+ // required / boolean / integer
+ map = catalog.validateProperties("yammer:MESSAGES?accessToken=aaa&consumerKey=&useJson=no&initialDelay=five");
+ assertNotNull(map);
+ assertEquals(4, map.size());
+ assertEquals(null, map.get("consumerKey"));
+ assertEquals(null, map.get("consumerSecret"));
+ assertEquals("no", map.get("useJson"));
+ assertEquals("five", map.get("initialDelay"));
+
+ // okay
+ map = catalog.validateProperties("mqtt:myqtt?reconnectBackOffMultiplier=2.5");
+ assertNotNull(map);
+ assertEquals(0, map.size());
+
+ // number
+ map = catalog.validateProperties("mqtt:myqtt?reconnectBackOffMultiplier=five");
+ assertNotNull(map);
+ assertEquals(1, map.size());
+ assertEquals("five", map.get("reconnectBackOffMultiplier"));
+ }
+
+ @Test
public void testEndpointComponentName() throws Exception {
String name = catalog.endpointComponentName("jms:queue:foo");
assertEquals("jms", name);
|