You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/06/28 05:57:32 UTC
[19/25] incubator-atlas git commit: ATLAS-1898: initial commit of ODF
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationDeserializer.java
----------------------------------------------------------------------
diff --git a/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationDeserializer.java b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationDeserializer.java
new file mode 100755
index 0000000..6ea9c97
--- /dev/null
+++ b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationDeserializer.java
@@ -0,0 +1,165 @@
+/**
+ * Licensed 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.atlas.odf.json;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.atlas.odf.api.metadata.models.Annotation;
+import org.apache.atlas.odf.api.metadata.models.ClassificationAnnotation;
+import org.apache.atlas.odf.api.metadata.models.ProfilingAnnotation;
+import org.apache.atlas.odf.api.metadata.models.RelationshipAnnotation;
+
+/**
+ * The Jackson deserializer for Annotation objects
+ *
+ *
+ */
+public class AnnotationDeserializer extends StdDeserializer<Annotation> {
+
+ private static final long serialVersionUID = -3143233438847937374L;
+
+ Logger logger = Logger.getLogger(AnnotationDeserializer.class.getName());
+
+ public AnnotationDeserializer() {
+ super(Annotation.class);
+ }
+
+ ClassLoader getClassLoader() {
+ return this.getClass().getClassLoader();
+ }
+
+ @Override
+ public Annotation deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ ObjectMapper jpom = ((ObjectMapper) jp.getCodec());
+ ObjectNode tree = jpom.readTree(jp);
+ String jsonString = tree.toString();
+ Annotation result = null;
+
+ Class<? extends Annotation> javaClass = null;
+ JsonNode javaClassNode = tree.get("javaClass");
+ if (javaClassNode == null) {
+ throw new IOException("Can not deserialize object since the javaClass attribute is missing: " + jsonString);
+ }
+ JsonNode jsonPropertiesNode = tree.get("jsonProperties");
+ String javaClassName = javaClassNode.asText();
+ if (javaClassName.equals(ProfilingAnnotation.class.getName())) {
+ javaClass = ProfilingAnnotation.class;
+ }
+ else if (javaClassName.equals(ClassificationAnnotation.class.getName())) {
+ javaClass = ClassificationAnnotation.class;
+ }
+ else if (javaClassName.equals(RelationshipAnnotation.class.getName())) {
+ javaClass = RelationshipAnnotation.class;
+ }
+ else {
+ try {
+ javaClass = (Class<? extends Annotation>) this.getClassLoader().loadClass(javaClassName);
+ if (jsonPropertiesNode != null && !jsonPropertiesNode.isNull()) { // unfold jsonProperties in case of specific annotations
+ JsonNode jsonPropertiesNodeUnfolded = null;
+ if (jsonPropertiesNode.isTextual()) {
+ jsonPropertiesNodeUnfolded = jpom.readTree(jsonPropertiesNode.asText());
+ }
+ else {
+ jsonPropertiesNodeUnfolded = jsonPropertiesNode;
+ }
+ JsonNode newJsonPropertiesNode = (JsonNode)jp.getCodec().createObjectNode(); // initialize new jsonProperties node
+ Field classFields[] = javaClass.getDeclaredFields();
+ HashSet<String> classFieldSet = new HashSet<String>();
+ for (Field f: classFields) {
+ f.setAccessible(true);
+ String fieldName = f.getName();
+ classFieldSet.add(fieldName);
+ }
+ Iterator<Entry<String,JsonNode>> jsonPropertiesFields = jsonPropertiesNodeUnfolded.fields();
+ while (jsonPropertiesFields.hasNext()) {
+ Entry<String,JsonNode> field = jsonPropertiesFields.next();
+ String fieldName = field.getKey();
+ if (JSONUtils.annotationFields.contains(fieldName)) {
+ throw new IOException("Name conflict: Field name in jsonProperties matches predefined field [" + fieldName + "]");
+ }
+ JsonNode fieldValue = field.getValue();
+ if (classFieldSet.contains(fieldName)) {
+ tree.set(fieldName, fieldValue);
+ }
+ else {
+ ((ObjectNode)newJsonPropertiesNode).set(fieldName, field.getValue());
+ }
+ }
+ tree.put("jsonProperties", newJsonPropertiesNode.textValue());
+ }
+ } catch (ClassNotFoundException exc) {
+ String msg = MessageFormat.format("Java class ''{0}'' could not be deserialized automatically (probably because it is not on the classpath)", javaClassName);
+ logger.warning(msg);
+ logger.log(Level.FINE, msg, exc);
+ }
+ if (javaClass == null) {
+ if (tree.get("profiledObject") != null) { // class not found -> create as instance of corresponding 'unknown' types
+ javaClass = ProfilingAnnotation.class;
+ }
+ else if (tree.get("classifiedObject") != null) {
+ javaClass = ClassificationAnnotation.class;
+ }
+ else if (tree.get("relatedObjects") != null) {
+ javaClass = RelationshipAnnotation.class;
+ }
+ else { // malformed annotation
+ javaClass = Annotation.class;
+ }
+ if (jsonPropertiesNode == null) {
+ jsonPropertiesNode = (JsonNode)jp.getCodec().createObjectNode(); // initialize if not already present
+ }
+ Iterator<Entry<String,JsonNode>> fields = tree.fields();
+ ArrayList<String> fieldsToRemove = new ArrayList<String>();
+ try {
+ while (fields.hasNext()) { // move all fields not present in the predefined annotation types
+ Entry<String,JsonNode> field = fields.next(); // to the string valued jsonProperties attribute
+ String fieldName = field.getKey();
+ if (!JSONUtils.annotationFields.contains(fieldName)) {
+ ((ObjectNode)jsonPropertiesNode).set(fieldName, field.getValue());
+ fieldsToRemove.add(fieldName);
+ }
+ }
+ String jsonProperties = (jsonPropertiesNode.isTextual()) ? jsonPropertiesNode.textValue() : jsonPropertiesNode.toString();
+ tree.put("jsonProperties", jsonProperties);
+ for (String fieldToRemove:fieldsToRemove) { // remove fields not present in the predefined annotation types
+ tree.remove(fieldToRemove);
+ }
+ }
+ catch (Exception e) {
+ throw new IOException(e);
+ }
+ }
+ jsonString = tree.toString();
+ }
+ result = jpom.readValue(jsonString, javaClass);
+ logger.log(Level.FINEST, "Annotation created. Original: {0}, deserialized annotation: {1}", new Object[]{ jsonString, JSONUtils.lazyJSONSerializer(result)});
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationSerializer.java
----------------------------------------------------------------------
diff --git a/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationSerializer.java b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationSerializer.java
new file mode 100755
index 0000000..6fcc28e
--- /dev/null
+++ b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/AnnotationSerializer.java
@@ -0,0 +1,121 @@
+/**
+ * Licensed 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.atlas.odf.json;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+import org.apache.atlas.odf.api.metadata.models.Annotation;
+import org.apache.wink.json4j.JSONException;
+import org.apache.wink.json4j.JSONObject;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+/**
+ * The Jackson serializer for Annotation objects
+ *
+ *
+ */
+public class AnnotationSerializer extends StdSerializer<Annotation> {
+
+ public AnnotationSerializer() {
+ this(null);
+ }
+
+ public AnnotationSerializer(Class<Annotation> t) {
+ super(t);
+ }
+
+ Logger logger = Logger.getLogger(AnnotationSerializer.class.getName());
+
+ ClassLoader getClassLoader() {
+ return this.getClass().getClassLoader();
+ }
+
+ // In the following jsonProperties is either already pre-populated (because we are serializing an instance of ProfilingAnnotation, ....
+ // or it is created from all attributes not present in ProfilingAnnotation, or its ancestors (e.g. serializing an instance of ColumnAnalysisColumnAnntation)
+ // in the latter case jsonProperties is expected to be null
+
+ @Override
+ public void serialize(Annotation annot, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonProcessingException {
+ jg.writeStartObject();
+ Class<?> cl = annot.getClass();
+ class JSONPropField {
+ String name;
+ Object value;
+ JSONPropField(String name, Object value) {this.name = name; this.value = value;}
+ }
+ ArrayList<JSONPropField> jsonPropFields = null;
+ String jsonPropertiesValue = null;
+ while (cl != Object.class) { // process class hierarchy up to and including MetaDataObject.class
+ Field fields[] = cl.getDeclaredFields();
+ for (Field f: fields) {
+ f.setAccessible(true);
+ String fieldName = f.getName();
+ try {
+ Object fieldValue = f.get(annot);
+ if (fieldName.equals("jsonProperties")) {
+ jsonPropertiesValue = (String)fieldValue;
+ }
+ else if (JSONUtils.annotationFields.contains(fieldName)) {
+ jg.writeFieldName(fieldName);
+ jg.writeObject(fieldValue);
+ }
+ else {
+ if (jsonPropFields == null) jsonPropFields = new ArrayList<JSONPropField>();
+ jsonPropFields.add(new JSONPropField(fieldName, fieldValue));
+ }
+ }
+ catch (IllegalAccessException e) {
+ throw new IOException(e);
+ }
+ }
+ cl = cl.getSuperclass();
+ }
+ jg.writeFieldName("jsonProperties");
+ if (jsonPropFields != null) {
+ jg.writeStartObject();
+ if (jsonPropertiesValue != null) {
+ try {
+ JSONObject jo = new JSONObject(jsonPropertiesValue);
+ Iterator<String> it = jo.keys();
+ while(it.hasNext()) {
+ String key = it.next();
+ jg.writeFieldName(key);
+ jg.writeObject(jo.get(key));
+ }
+ }
+ catch (JSONException e) {
+ throw new IOException(e);
+ }
+ }
+ for (JSONPropField jpf:jsonPropFields) {
+ jg.writeFieldName(jpf.name);
+ jg.writeObject(jpf.value);
+ }
+ jg.writeEndObject();
+ }
+ else {
+ jg.writeString(jsonPropertiesValue);
+ }
+ jg.writeEndObject();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-api/src/main/java/org/apache/atlas/odf/json/DefaultODFDeserializer.java
----------------------------------------------------------------------
diff --git a/odf/odf-api/src/main/java/org/apache/atlas/odf/json/DefaultODFDeserializer.java b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/DefaultODFDeserializer.java
new file mode 100755
index 0000000..d1ae80e
--- /dev/null
+++ b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/DefaultODFDeserializer.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed 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.atlas.odf.json;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class DefaultODFDeserializer<T> extends StdDeserializer<T> {
+ private static final long serialVersionUID = 4895771352050172936L;
+
+ Logger logger = Logger.getLogger(DefaultODFDeserializer.class.getName());
+
+ Class<? extends T> defaultClass;
+
+ public DefaultODFDeserializer(Class<T> cl, Class<? extends T> defaultClass) {
+ super(cl);
+ this.defaultClass = defaultClass;
+ }
+
+ ClassLoader getClassLoader() {
+ return this.getClass().getClassLoader();
+ }
+
+ @Override
+ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ ObjectMapper jpom = ((ObjectMapper) jp.getCodec());
+ JsonNode tree = jpom.readTree(jp);
+ String jsonString = tree.toString();
+
+ Class<? extends T> javaClass = null;
+ String javaClassName = null;
+ try {
+ JsonNode javaClassNode = tree.get("javaClass");
+ javaClassName = javaClassNode.asText();
+ logger.log(Level.FINEST, "Trying to deserialize object of java class {0}", javaClassName);
+ javaClass = (Class<? extends T>) this.getClassLoader().loadClass(javaClassName);
+ if (javaClass != null) {
+ if (!javaClass.equals(this.handledType())) {
+ return jpom.readValue(jsonString, javaClass);
+ }
+ }
+ } catch (Exception exc) {
+ String msg = MessageFormat.format("Java class ''{0}'' could not be deserialized automatically (probably because it is not on the classpath)", javaClassName);
+ logger.warning(msg);
+ logger.log(Level.FINE, msg, exc);
+ }
+ return jpom.readValue(jsonString, defaultClass);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-api/src/main/java/org/apache/atlas/odf/json/JSONUtils.java
----------------------------------------------------------------------
diff --git a/odf/odf-api/src/main/java/org/apache/atlas/odf/json/JSONUtils.java b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/JSONUtils.java
new file mode 100755
index 0000000..fe9d592
--- /dev/null
+++ b/odf/odf-api/src/main/java/org/apache/atlas/odf/json/JSONUtils.java
@@ -0,0 +1,254 @@
+/**
+ * Licensed 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.atlas.odf.json;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.wink.json4j.JSONArray;
+import org.apache.wink.json4j.JSONException;
+import org.apache.wink.json4j.JSONObject;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.databind.Module;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import org.apache.atlas.odf.api.metadata.UnknownMetaDataObject;
+import org.apache.atlas.odf.api.metadata.models.Annotation;
+import org.apache.atlas.odf.api.metadata.models.ClassificationAnnotation;
+import org.apache.atlas.odf.api.metadata.models.Connection;
+import org.apache.atlas.odf.api.metadata.models.ConnectionInfo;
+import org.apache.atlas.odf.api.metadata.models.DataSet;
+import org.apache.atlas.odf.api.metadata.models.DataStore;
+import org.apache.atlas.odf.api.metadata.models.MetaDataObject;
+import org.apache.atlas.odf.api.metadata.models.ProfilingAnnotation;
+import org.apache.atlas.odf.api.metadata.models.RelationshipAnnotation;
+import org.apache.atlas.odf.api.metadata.models.UnknownDataSet;
+import org.apache.atlas.odf.api.metadata.models.UnknownConnection;
+import org.apache.atlas.odf.api.metadata.models.UnknownConnectionInfo;
+import org.apache.atlas.odf.api.metadata.models.UnknownDataStore;
+
+public class JSONUtils {
+
+ public static HashSet<String> annotationFields = new HashSet<String>();
+
+ static {
+ for (Class<?> cl: new Class<?>[]{Annotation.class, ProfilingAnnotation.class, ClassificationAnnotation.class,RelationshipAnnotation.class}) {
+ while (cl != Object.class) { // process class hierarchy up to and including MetaDataObject.class
+ Field fields[] = cl.getDeclaredFields();
+ for (Field f: fields) {
+ f.setAccessible(true);
+ annotationFields.add(f.getName());
+ }
+ cl = cl.getSuperclass();
+ }
+ }
+ }
+
+
+
+ // reuse object mapper for performance
+ private static ObjectMapper om = null;
+
+ static {
+ om = new ObjectMapper();
+ Module mod = createDefaultObjectMapperModule();
+ om.registerModule(mod);
+ }
+
+ public static ObjectMapper getGlobalObjectMapper() {
+ return om;
+ }
+
+ static Module createDefaultObjectMapperModule() {
+ SimpleModule mod = new SimpleModule("ODF Jackson module", Version.unknownVersion());
+ mod.addDeserializer(Annotation.class, new AnnotationDeserializer());
+ mod.addDeserializer(MetaDataObject.class, new DefaultODFDeserializer<MetaDataObject>(MetaDataObject.class, UnknownMetaDataObject.class));
+ mod.addDeserializer(DataSet.class, new DefaultODFDeserializer<DataSet>(DataSet.class, UnknownDataSet.class));
+ mod.addDeserializer(DataStore.class, new DefaultODFDeserializer<DataStore>(DataStore.class, UnknownDataStore.class));
+ mod.addDeserializer(Connection.class, new DefaultODFDeserializer<Connection>(Connection.class, UnknownConnection.class));
+ mod.addDeserializer(ConnectionInfo.class, new DefaultODFDeserializer<ConnectionInfo>(ConnectionInfo.class, UnknownConnectionInfo.class));
+
+ mod.addSerializer(Annotation.class, new AnnotationSerializer());
+ return mod;
+
+ }
+
+ public static JSONObject toJSONObject(Object o) throws JSONException {
+ JSONObject result;
+ try {
+ result = new JSONObject(om.writeValueAsString(o));
+ if (o instanceof Annotation) {
+ Object jsonPropsObject = result.get("jsonProperties");
+ if (jsonPropsObject instanceof JSONObject) { // the value of jsonProperties must be of type 'String'
+ result.put("jsonProperties", ((JSONObject)jsonPropsObject).toString());
+ }
+ }
+ } catch (JsonProcessingException e) {
+ throw new JSONException(e);
+ }
+ return result;
+ }
+
+ public static String toJSON(Object o) throws JSONException {
+ String result;
+ try {
+ result = om.writeValueAsString(o);
+ if (o instanceof Annotation) {
+ JSONObject json = new JSONObject(result);
+ Object jsonPropsObject = json.get("jsonProperties");
+ if (jsonPropsObject instanceof JSONObject) { // the value of jsonProperties must be of type 'String'
+ json.put("jsonProperties", ((JSONObject)jsonPropsObject).toString());
+ result = json.toString();
+ }
+ }
+ } catch (JsonProcessingException e) {
+ throw new JSONException(e);
+ }
+ return result;
+ }
+
+ public static <T> List<T> fromJSONList(String s, Class<T> cl) throws JSONException {
+ JSONArray ar = new JSONArray(s);
+ List<T> result = new ArrayList<>();
+ for (Object o : ar) {
+ JSONObject jo = (JSONObject) o;
+ T t = (T) fromJSON(jo.write(), cl);
+ result.add(t);
+ }
+ return result;
+
+ }
+
+ public static <T> List<T> fromJSONList(InputStream is, Class<T> cl) throws JSONException {
+ JSONArray ar = new JSONArray(is);
+ List<T> result = new ArrayList<>();
+ for (Object o : ar) {
+ JSONObject jo = (JSONObject) o;
+ T t = (T) fromJSON(jo.write(), cl);
+ result.add(t);
+ }
+ return result;
+ }
+
+ public static <T> T fromJSON(String s, Class<T> cl) throws JSONException {
+ T result = null;
+ try {
+ result = om.readValue(s, cl);
+ } catch (JsonProcessingException exc) {
+ // propagate JSON exception
+ throw new JSONException(exc);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ public static <T> T fromJSON(InputStream is, Class<T> cl) throws JSONException {
+ return fromJSON(getInputStreamAsString(is, "UTF-8"), cl);
+ }
+
+ public static <T> T readJSONObjectFromFileInClasspath(Class<T> cl, String pathToFile, ClassLoader classLoader) {
+ if (classLoader == null) {
+ // use current classloader if not provided
+ classLoader = JSONUtils.class.getClassLoader();
+ }
+ InputStream is = classLoader.getResourceAsStream(pathToFile);
+ T result = null;
+ try {
+ result = om.readValue(is, cl);
+ } catch (IOException e) {
+ // assume that this is a severe error since the provided JSONs should be correct
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ public static <T> T cloneJSONObject(T obj) throws JSONException {
+ // special case: use Annotation.class in case obj is an annotation subclass to ensure that the annotation deserializer is used
+ if (Annotation.class.isAssignableFrom(obj.getClass())) {
+ return (T) fromJSON(toJSON(obj), Annotation.class);
+ }
+ return fromJSON(toJSON(obj), (Class<T>) obj.getClass());
+ }
+
+
+ public static void mergeJSONObjects(JSONObject source, JSONObject target) {
+ if (source != null && target != null) {
+ target.putAll(source);
+ }
+ }
+
+ // use this method, e.g., if you want to use JSON objects in log / trace messages
+ // and want to do serialization only if tracing is on
+ public static Object lazyJSONSerializer(final Object jacksonObject) {
+ return new Object() {
+
+ @Override
+ public String toString() {
+ try {
+ return toJSON(jacksonObject);
+ } catch (JSONException e) {
+ return e.getMessage();
+ }
+ }
+
+ };
+ }
+
+ public static Object jsonObject4Log(final JSONObject obj) {
+ return new Object() {
+
+ @Override
+ public String toString() {
+ try {
+ return obj.write();
+ } catch (Exception e) {
+ return e.getMessage();
+ }
+ }
+
+ };
+ }
+
+ public static String getInputStreamAsString(InputStream is, String encoding) {
+ try {
+ final int n = 2048;
+ byte[] b = new byte[0];
+ byte[] temp = new byte[n];
+ int bytesRead;
+ while ((bytesRead = is.read(temp)) != -1) {
+ byte[] newB = new byte[b.length + bytesRead];
+ System.arraycopy(b, 0, newB, 0, b.length);
+ System.arraycopy(temp, 0, newB, b.length, bytesRead);
+ b = newB;
+ }
+ String s = new String(b, encoding);
+ return s;
+ } catch (IOException exc) {
+ throw new RuntimeException(exc);
+ }
+ }
+
+ public static <T, S> T convert(S source, Class<T> targetClass) throws JSONException {
+ return fromJSON(toJSON(source), targetClass);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-api/src/test/java/org/apache/atlas/odf/test/json/ODFJSONSerializationTest.java
----------------------------------------------------------------------
diff --git a/odf/odf-api/src/test/java/org/apache/atlas/odf/test/json/ODFJSONSerializationTest.java b/odf/odf-api/src/test/java/org/apache/atlas/odf/test/json/ODFJSONSerializationTest.java
new file mode 100755
index 0000000..da8d3af
--- /dev/null
+++ b/odf/odf-api/src/test/java/org/apache/atlas/odf/test/json/ODFJSONSerializationTest.java
@@ -0,0 +1,406 @@
+/**
+ * Licensed 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.atlas.odf.test.json;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+import org.apache.atlas.odf.api.metadata.InvalidReference;
+import org.apache.atlas.odf.api.metadata.StoredMetaDataObject;
+import org.apache.wink.json4j.JSON;
+import org.apache.wink.json4j.JSONException;
+import org.apache.wink.json4j.JSONObject;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.apache.atlas.odf.api.discoveryservice.DiscoveryServiceEndpoint;
+import org.apache.atlas.odf.api.discoveryservice.DiscoveryServiceProperties;
+import org.apache.atlas.odf.api.metadata.MetaDataObjectReference;
+import org.apache.atlas.odf.api.metadata.models.Annotation;
+import org.apache.atlas.odf.api.metadata.models.ClassificationAnnotation;
+import org.apache.atlas.odf.api.metadata.models.JDBCConnection;
+import org.apache.atlas.odf.api.metadata.models.JDBCConnectionInfo;
+import org.apache.atlas.odf.api.metadata.models.MetaDataCache;
+import org.apache.atlas.odf.api.metadata.models.MetaDataObject;
+import org.apache.atlas.odf.api.metadata.models.Column;
+import org.apache.atlas.odf.api.metadata.models.Connection;
+import org.apache.atlas.odf.api.metadata.models.ConnectionInfo;
+import org.apache.atlas.odf.api.metadata.models.DataFile;
+import org.apache.atlas.odf.api.metadata.models.DataSet;
+import org.apache.atlas.odf.api.metadata.models.DataStore;
+import org.apache.atlas.odf.api.metadata.models.Database;
+import org.apache.atlas.odf.api.metadata.models.Table;
+import org.apache.atlas.odf.api.metadata.models.ProfilingAnnotation;
+import org.apache.atlas.odf.api.metadata.models.RelationshipAnnotation;
+import org.apache.atlas.odf.api.metadata.models.UnknownDataSet;
+import org.apache.atlas.odf.json.JSONUtils;
+
+public class ODFJSONSerializationTest {
+
+ Logger logger = Logger.getLogger(ODFJSONSerializationTest.class.getName());
+
+ MetaDataObjectReference createNewRef() {
+ MetaDataObjectReference ref = new MetaDataObjectReference();
+ ref.setId(UUID.randomUUID().toString());
+ ref.setRepositoryId("odftestrepositoryid");
+ return ref;
+ }
+
+ static class NewAnnotation extends ProfilingAnnotation {
+ String newProp;
+
+ public String getNewProp() {
+ return newProp;
+ }
+
+ public void setNewProp(String newProp) {
+ this.newProp = newProp;
+ }
+
+ }
+
+ List<MetaDataObject> createTestObjects() throws JSONException, ParseException {
+ List<MetaDataObject> testObjects = new ArrayList<>();
+
+ Column col = new Column();
+ MetaDataObjectReference colref = createNewRef();
+ col.setReference(colref);
+ col.setName("col1");
+ col.setDescription("column desc");
+ col.setDataType("theDatatype");
+
+ Table t = new Table();
+ MetaDataObjectReference tableRef = createNewRef();
+ t.setReference(tableRef);
+ t.setName("Table");
+ t.setDescription("table desc");
+
+ Database db = new Database();
+ MetaDataObjectReference dbref = createNewRef();
+ db.setReference(dbref);
+ db.setName("DB");
+ db.setDescription("db description");
+
+ JDBCConnection jdbcConn = new JDBCConnection();
+ MetaDataObjectReference jdbcConnRef = createNewRef();
+ jdbcConn.setReference(jdbcConnRef);
+ jdbcConn.setName("jdbc connection");
+ jdbcConn.setUser("theUser");
+ jdbcConn.setPassword("thePassword");
+ jdbcConn.setJdbcConnectionString("jdbc:db2:localhost:50000/SAMPLE");
+ db.setConnections(Collections.singletonList(jdbcConnRef));
+
+ ProfilingAnnotation profAnnot1 = new ProfilingAnnotation();
+ MetaDataObjectReference uaRef = createNewRef();
+ profAnnot1.setReference(uaRef);
+ profAnnot1.setProfiledObject(jdbcConnRef);
+ profAnnot1.setJsonProperties("{\"a\": \"b\"}");
+
+ ProfilingAnnotation profAnnot2 = new ProfilingAnnotation();
+ MetaDataObjectReference mdoRef = createNewRef();
+ profAnnot2.setReference(mdoRef);
+ profAnnot2.setProfiledObject(jdbcConnRef);
+ profAnnot2.setJsonProperties("{\"a\": \"b\"}");
+
+ NewAnnotation newAnnot = new NewAnnotation();
+ MetaDataObjectReference newAnnotRef = createNewRef();
+ newAnnot.setReference(newAnnotRef);
+
+ // a generic DataSet
+ UnknownDataSet ds = new UnknownDataSet();
+ ds.setName("generic data set");
+ ds.setReference(createNewRef());
+
+ MetaDataObject[] mdos = new MetaDataObject[] { db, jdbcConn, t, col, profAnnot1, profAnnot2, newAnnot, ds };
+ testObjects.addAll(Arrays.asList(mdos));
+ return testObjects;
+ }
+
+ @Test
+ public void testSerialization() throws Exception {
+ List<MetaDataObject> testObjects = createTestObjects();
+
+ for (MetaDataObject testObject : testObjects) {
+ Class<?> cl = testObject.getClass();
+ logger.info("Testing serialization / deserialization of object: " + testObject + " of class: " + cl);
+
+ String json = JSONUtils.toJSON(testObject);
+ logger.info("Serialized json: " + json);
+
+ Object objStronglyTypedClass;
+ if (testObject instanceof Annotation) { // special treatment for Annotations -> 2nd arg of fromJSON() needs to be Annotation.class
+ objStronglyTypedClass = JSONUtils.fromJSON(json, Annotation.class);
+ Assert.assertEquals(cl, objStronglyTypedClass.getClass());
+ }
+ else {
+ objStronglyTypedClass = JSONUtils.fromJSON(json, cl);
+ Assert.assertEquals(cl, objStronglyTypedClass.getClass());
+ }
+ String json1 = JSONUtils.toJSON(objStronglyTypedClass);
+ Assert.assertEquals(json, json1);
+
+ Object objWithGenericClass = JSONUtils.fromJSON(json, MetaDataObject.class);
+
+ Assert.assertEquals(cl, objWithGenericClass.getClass());
+ String json2 = JSONUtils.toJSON(objWithGenericClass);
+ Assert.assertEquals(json, json2);
+
+ Class<?> intermediateClasses[] = new Class<?>[] { MetaDataObject.class, DataSet.class, DataStore.class, Connection.class };
+
+ for (Class<?> intermediateClass : intermediateClasses) {
+ logger.info("Checking intermediate class: " + intermediateClass);
+ if (intermediateClass.isAssignableFrom(cl)) {
+
+ Object intermediateObject = JSONUtils.fromJSON(json, intermediateClass);
+ logger.info("Deserialized object: " + intermediateObject);
+ logger.info("Deserialized object class: " + intermediateObject.getClass());
+
+ Assert.assertTrue(intermediateClass.isAssignableFrom(intermediateObject.getClass()));
+ Assert.assertEquals(cl, intermediateObject.getClass());
+ String json3 = JSONUtils.toJSON(intermediateObject);
+ Assert.assertEquals(json, json3);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Test serialization of an Annotation (subclass) which has both, its own fields (to be mapped to jsonProperties) and
+ * a non-empty jsonProperties attribute holding the string representation of a Json object.
+ */
+
+ @Test
+ public void testJsonPropertiesMerge() {
+ NewAnnotation annot = new NewAnnotation();
+ MetaDataObjectReference ref = new MetaDataObjectReference();
+ ref.setId("id");
+ ref.setRepositoryId("repoid");
+ ref.setUrl("http://url");
+ annot.setProfiledObject(ref);
+ annot.setNewProp("newPropValue");
+ annot.setJsonProperties("{\"oldProp\":\"oldPropValue\"}");
+ JSONObject jo = null;
+ try {
+ jo = JSONUtils.toJSONObject(annot);
+ String jsonPropertiesString = jo.getString("jsonProperties");
+ JSONObject jo2 = new JSONObject(jsonPropertiesString);
+ Assert.assertEquals("oldPropValue", jo2.get("oldProp"));
+ Assert.assertEquals("newPropValue", jo2.get("newProp"));
+ }
+ catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ final static private String MERGED_JSON = "{" +
+ "\"analysisRun\":null," +
+ "\"summary\":null," +
+ "\"reference\":null," +
+ "\"originRef\":null," +
+ "\"replicaRefs\":null," +
+ "\"javaClass\":\"org.apache.atlas.odf.json.test.ODFJSONSerializationTest$NewAnnotation\"," +
+ "\"jsonProperties\":\"{" +
+ "\\\"newProp\\\":\\\"newPropValue\\\"," +
+ "\\\"oldProp\\\":\\\"oldPropValue\\\"" +
+ "}\"," +
+ "\"name\":null," +
+ "\"annotationType\":\"NewAnnotation\"," +
+ "\"description\":null," +
+ "\"profiledObject\":{" +
+ "\"repositoryId\":\"repoid\"," +
+ "\"id\":\"id\"," +
+ "\"url\":\"http://url\"}" +
+ "}";
+
+ /**
+ * Test deserialization of a Json object which has fields in its jsonProperties that can not be mapped to native fields of
+ * the target class (= value of javaClass field). These and only these remain as fields in the text encoded Json object
+ * stored in the jsonProperties field of the result.
+ */
+
+ @Test
+ @Ignore
+ public void testJsonPropertiesUnmerge() throws Exception {
+ logger.info("Deserializing JSON: " + MERGED_JSON);
+ Annotation annot = JSONUtils.fromJSON(MERGED_JSON, Annotation.class);
+ Assert.assertTrue(annot instanceof NewAnnotation);
+ NewAnnotation newAnnot = (NewAnnotation) annot;
+ Assert.assertEquals("newPropValue", newAnnot.getNewProp());
+ JSONObject props = (JSONObject) JSON.parse(annot.getJsonProperties());
+
+ Assert.assertNotNull(props.get("oldProp"));
+ Assert.assertEquals("oldPropValue", props.get("oldProp"));
+
+ JSONObject jo = JSONUtils.toJSONObject(annot);
+ Assert.assertEquals(MERGED_JSON, jo.toString());
+ }
+
+ final private static String PROFILING_ANNOTATION_JSON = "{" +
+ "\"profiledObject\": null," +
+ "\"annotationType\": \"MySubType1\"," +
+ "\"javaClass\": \"org.apache.atlas.odf.core.integrationtest.metadata.atlas.MySubType1\"," +
+ "\"analysisRun\": \"bla\"," +
+ "\"newProp1\": 42," +
+ "\"newProp2\": \"hi\"," +
+ "\"newProp3\": \"hello\"" +
+ "}";
+
+ final private static String CLASSIFICATION_ANNOTATION_JSON = "{" +
+ "\"classifyingObject\": null," +
+ "\"classifiedObject\": null," +
+ "\"annotationType\": \"MySubType2\"," +
+ "\"javaClass\": \"org.apache.atlas.odf.core.integrationtest.metadata.atlas.MySubType2\"," +
+ "\"analysisRun\": \"bla\"," +
+ "\"newProp1\": 42," +
+ "\"newProp2\": \"hi\"," +
+ "\"newProp3\": \"hello\"" +
+ "}";
+
+ final private static String RELATIONSHIP_ANNOTATION_JSON = "{" +
+ "\"relatedObjects\": null," +
+ "\"annotationType\": \"MySubType3\"," +
+ "\"javaClass\": \"org.apache.atlas.odf.core.integrationtest.metadata.atlas.MySubType3\"," +
+ "\"analysisRun\": \"bla\"," +
+ "\"newProp1\": 42," +
+ "\"newProp2\": \"hi\"," +
+ "\"newProp3\": \"hello\"" +
+ "}";
+
+ /**
+ * Replacement for AtlasAnnotationTypeDefinitionCreatTest
+ */
+
+ @Test
+ public void testSimpleAnnotationPrototypeCreation() throws Exception {
+ logger.info("Annotation string: " + PROFILING_ANNOTATION_JSON);
+ Annotation annot = JSONUtils.fromJSON(PROFILING_ANNOTATION_JSON, Annotation.class);
+ logger.info("Annotation: " + PROFILING_ANNOTATION_JSON);
+ Assert.assertTrue(annot instanceof ProfilingAnnotation);
+
+ logger.info("Annotation string: " + CLASSIFICATION_ANNOTATION_JSON);
+ annot = JSONUtils.fromJSON(CLASSIFICATION_ANNOTATION_JSON, Annotation.class);
+ logger.info("Annotation: " + CLASSIFICATION_ANNOTATION_JSON);
+ Assert.assertTrue(annot instanceof ClassificationAnnotation);
+
+ logger.info("Annotation string: " + RELATIONSHIP_ANNOTATION_JSON);
+ annot = JSONUtils.fromJSON(RELATIONSHIP_ANNOTATION_JSON, Annotation.class);
+ logger.info("Annotation: " + RELATIONSHIP_ANNOTATION_JSON);
+ Assert.assertTrue(annot instanceof RelationshipAnnotation);
+ }
+
+ @Test
+ public void testUnretrievedReference() throws Exception {
+ String repoId = "SomeRepoId";
+ Column col = new Column();
+ col.setName("name");
+ col.setReference(InvalidReference.createInvalidReference(repoId));
+
+ String json = JSONUtils.toJSON(col);
+ Column col2 = JSONUtils.fromJSON(json, Column.class);
+ Assert.assertTrue(InvalidReference.isInvalidRef(col2.getReference()));
+
+ Database db = new Database();
+ db.setName("database");
+
+ JSONUtils.toJSON(db);
+
+ db.setConnections(InvalidReference.createInvalidReferenceList(repoId));
+
+ Database db2 = JSONUtils.fromJSON(JSONUtils.toJSON(db), Database.class);
+ Assert.assertTrue(InvalidReference.isInvalidRefList(db2.getConnections()));
+ }
+
+ @Test
+ public void testExtensibleDiscoveryServiceEndpoints() throws Exception {
+ DiscoveryServiceProperties dsprops = new DiscoveryServiceProperties();
+ dsprops.setId("theid");
+ dsprops.setName("thename");
+
+ DiscoveryServiceEndpoint ep = new DiscoveryServiceEndpoint();
+ ep.setRuntimeName("newruntime");
+ ep.set("someKey", "someValue");
+ dsprops.setEndpoint(ep);
+
+ String dspropsJSON = JSONUtils.toJSON(dsprops);
+ logger.info("Discovery service props JSON: " +dspropsJSON);
+
+ DiscoveryServiceProperties deserProps = JSONUtils.fromJSON(dspropsJSON, DiscoveryServiceProperties.class);
+ Assert.assertNotNull(deserProps);
+ Assert.assertEquals("theid", dsprops.getId());
+ Assert.assertEquals("thename", dsprops.getName());
+ Assert.assertNotNull(deserProps.getEndpoint());
+ Assert.assertTrue(deserProps.getEndpoint() instanceof DiscoveryServiceEndpoint);
+ Assert.assertTrue(deserProps.getEndpoint().getClass().equals(DiscoveryServiceEndpoint.class));
+ DiscoveryServiceEndpoint deserEP = (DiscoveryServiceEndpoint) deserProps.getEndpoint();
+ Assert.assertEquals("newruntime", deserEP.getRuntimeName());
+ Assert.assertEquals("someValue", deserEP.get().get("someKey"));
+ }
+
+ @Test
+ public void testMetaDataCache() {
+ MetaDataCache cache = new MetaDataCache();
+
+ MetaDataObjectReference ref = new MetaDataObjectReference();
+ ref.setId("id");
+ ref.setRepositoryId("repositoryId");
+ DataFile dataFile = new DataFile();
+ dataFile.setName("dataFile");
+ dataFile.setEncoding("encoding");
+ dataFile.setReference(ref);
+
+ List<MetaDataObjectReference> refList = new ArrayList<MetaDataObjectReference>();
+ refList.add(ref);
+ StoredMetaDataObject storedObject = new StoredMetaDataObject(dataFile);
+ HashMap<String, List<MetaDataObjectReference>> referenceMap = new HashMap<String, List<MetaDataObjectReference>>();
+ referenceMap.put("id", refList);
+ storedObject.setReferencesMap(referenceMap);
+ List<StoredMetaDataObject> metaDataObjects = new ArrayList<StoredMetaDataObject>();
+ metaDataObjects.add(storedObject);
+ cache.setMetaDataObjects(metaDataObjects);
+
+ Connection con = new JDBCConnection();
+ con.setName("connection");
+ JDBCConnectionInfo conInfo = new JDBCConnectionInfo();
+ conInfo.setConnections(Collections.singletonList(con));
+ conInfo.setAssetReference(ref);
+ conInfo.setTableName("tableName");
+ List<ConnectionInfo> connectionInfoObjects = new ArrayList<ConnectionInfo>();
+ connectionInfoObjects.add(conInfo);
+ cache.setConnectionInfoObjects(connectionInfoObjects);
+
+ try {
+ String serializedCache = JSONUtils.toJSON(cache);
+ logger.info("Serialized metadata cache JSON: " + serializedCache);
+ MetaDataCache deserializedCache = JSONUtils.fromJSON(serializedCache, MetaDataCache.class);
+ Assert.assertEquals("dataFile", deserializedCache.getMetaDataObjects().get(0).getMetaDataObject().getName());
+ Assert.assertEquals("encoding", ((DataFile) deserializedCache.getMetaDataObjects().get(0).getMetaDataObject()).getEncoding());
+ Assert.assertEquals("connection", deserializedCache.getConnectionInfoObjects().get(0).getConnections().get(0).getName());
+ Assert.assertEquals("tableName", ((JDBCConnectionInfo) deserializedCache.getConnectionInfoObjects().get(0)).getTableName());
+ Assert.assertEquals("repositoryId", deserializedCache.getMetaDataObjects().get(0).getReferenceMap().get("id").get(0).getRepositoryId());
+ }
+ catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/.gitignore
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/.gitignore b/odf/odf-archetype-discoveryservice/.gitignore
new file mode 100755
index 0000000..67c976b
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/.gitignore
@@ -0,0 +1,17 @@
+#
+# Licensed 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.
+#
+ .settings
+target
+.classpath
+.project
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/pom.xml
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/pom.xml b/odf/odf-archetype-discoveryservice/pom.xml
new file mode 100755
index 0000000..c9c2aed
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+~
+~ Licensed 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>odf-archetype-discoveryservice</artifactId>
+ <packaging>maven-archetype</packaging>
+
+ <description>The SDP maven archetype for discovery services</description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.archetype</groupId>
+ <artifactId>archetype-packaging</artifactId>
+ <version>2.4</version>
+ </extension>
+ </extensions>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-archetype-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/main/resources/META-INF/maven/archetype.xml
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/main/resources/META-INF/maven/archetype.xml b/odf/odf-archetype-discoveryservice/src/main/resources/META-INF/maven/archetype.xml
new file mode 100755
index 0000000..9848e46
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/main/resources/META-INF/maven/archetype.xml
@@ -0,0 +1,27 @@
+<!--
+~
+~ Licensed 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.
+-->
+<archetype>
+ <id>odf-archetype-discoveryservice-jar</id>
+ <sources>
+ <source>src/main/java/MyAnnotation.java</source>
+ <source>src/main/java/MyDiscoveryService.java</source>
+ </sources>
+ <resources>
+ <resource>src/main/resources/META-INF/odf/odf-services.json</resource>
+ </resources>
+ <testSources>
+ <source>src/test/java/MyDiscoveryServiceTest.java</source>
+ </testSources>
+</archetype>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/pom.xml
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/pom.xml b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/pom.xml
new file mode 100755
index 0000000..0ada9e8
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+~
+~ Licensed 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>${groupId}</groupId>
+ <artifactId>${artifactId}</artifactId>
+ <version>${version}</version>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-api</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyAnnotation.java
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyAnnotation.java b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyAnnotation.java
new file mode 100755
index 0000000..8ce0d2f
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyAnnotation.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed 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 ${package};
+
+import org.apache.atlas.odf.api.metadata.models.ProfilingAnnotation;
+
+public class MyAnnotation extends ProfilingAnnotation {
+
+ private String myProperty;
+
+ public String getMyProperty() {
+ return myProperty;
+ }
+
+ public void setMyProperty(String myValue) {
+ this.myProperty = myValue;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyDiscoveryService.java
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyDiscoveryService.java b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyDiscoveryService.java
new file mode 100755
index 0000000..a07ccdb
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/java/MyDiscoveryService.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed 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 ${package};
+
+import java.util.Collections;
+import java.util.Date;
+
+import org.apache.atlas.odf.api.discoveryservice.DiscoveryServiceRequest;
+import org.apache.atlas.odf.api.discoveryservice.DiscoveryServiceResponse.ResponseCode;
+import org.apache.atlas.odf.api.discoveryservice.SyncDiscoveryServiceBase;
+import org.apache.atlas.odf.api.discoveryservice.sync.DiscoveryServiceSyncResponse;
+
+/**
+ * A simple synchronous discovery service that creates one annotation for the data set it analyzes.
+ *
+ */
+public class MyDiscoveryService extends SyncDiscoveryServiceBase {
+
+ @Override
+ public DiscoveryServiceSyncResponse runAnalysis(DiscoveryServiceRequest request) {
+ // 1. create an annotation that annotates the data set object passed in the request
+ MyAnnotation annotation = new MyAnnotation();
+ annotation.setProfiledObject(request.getDataSetContainer().getDataSet().getReference());
+ // set a new property called "tutorialProperty" to some string
+ annotation.setMyProperty("My property was created on " + new Date());
+
+ // 2. create a response with our annotation created above
+ return createSyncResponse( //
+ ResponseCode.OK, // Everything works OK
+ "Everything worked", // human-readable message
+ Collections.singletonList(annotation) // new annotations
+ );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/resources/META-INF/odf/odf-services.json
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/resources/META-INF/odf/odf-services.json b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/resources/META-INF/odf/odf-services.json
new file mode 100755
index 0000000..e90ce7b
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/main/resources/META-INF/odf/odf-services.json
@@ -0,0 +1,11 @@
+[
+ {
+ "id": "${groupId}.${artifactId}.MyDiscoveryService",
+ "name": "My service",
+ "description": "My service creates my annotation for a data set",
+ "endpoint": {
+ "runtimeName": "Java",
+ "className": "${package}.MyDiscoveryService"
+ }
+ }
+]
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/test/java/MyDiscoveryServiceTest.java
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/test/java/MyDiscoveryServiceTest.java b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/test/java/MyDiscoveryServiceTest.java
new file mode 100755
index 0000000..bc585d2
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/main/resources/archetype-resources/src/test/java/MyDiscoveryServiceTest.java
@@ -0,0 +1,28 @@
+/**
+ * Licensed 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 ${package};
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test template for discovery service
+ */
+public class MyDiscoveryServiceTest {
+
+ @Test
+ public void test() throws Exception {
+ Assert.assertTrue(true);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/archetype.properties
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/archetype.properties b/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/archetype.properties
new file mode 100755
index 0000000..9fbb593
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/archetype.properties
@@ -0,0 +1,23 @@
+#
+# Licensed 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.
+#
+
+archetype.groupId=org.apache.atlas.odf
+archetype.artifactId=odf-archetype-discoveryservice-jar
+archetype.version=1.2.0-SNAPSHOT
+
+groupId=jg1
+artifactId=ja1
+version=0.1
+package=odf.j.p1.p2
+
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/goal.txt
----------------------------------------------------------------------
diff --git a/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/goal.txt b/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/goal.txt
new file mode 100755
index 0000000..3cb5141
--- /dev/null
+++ b/odf/odf-archetype-discoveryservice/src/test/resources/projects/it1/goal.txt
@@ -0,0 +1,14 @@
+#
+# Licensed 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.
+#
+clean verify
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-atlas/.gitignore
----------------------------------------------------------------------
diff --git a/odf/odf-atlas/.gitignore b/odf/odf-atlas/.gitignore
new file mode 100755
index 0000000..174a0a7
--- /dev/null
+++ b/odf/odf-atlas/.gitignore
@@ -0,0 +1,20 @@
+#
+# Licensed 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.
+#
+.settings
+target
+.classpath
+.project
+.factorypath
+.DS_Store
+derby.log
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-atlas/atlasconfig/jetty-web.xml
----------------------------------------------------------------------
diff --git a/odf/odf-atlas/atlasconfig/jetty-web.xml b/odf/odf-atlas/atlasconfig/jetty-web.xml
new file mode 100755
index 0000000..66ec730
--- /dev/null
+++ b/odf/odf-atlas/atlasconfig/jetty-web.xml
@@ -0,0 +1,24 @@
+<!--
+~
+~ Licensed 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.
+-->
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Get name="securityHandler">
+ <Set name="loginService">
+ <New class="org.eclipse.jetty.security.HashLoginService">
+ <Set name="name">ODF Realm</Set>
+ <Set name="config"><SystemProperty name="atlas.home" default="."/>/conf/realm.properties</Set>
+ </New>
+ </Set>
+ </Get>
+</Configure>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-atlas/atlasconfig/realm.properties
----------------------------------------------------------------------
diff --git a/odf/odf-atlas/atlasconfig/realm.properties b/odf/odf-atlas/atlasconfig/realm.properties
new file mode 100755
index 0000000..0d57c4a
--- /dev/null
+++ b/odf/odf-atlas/atlasconfig/realm.properties
@@ -0,0 +1,24 @@
+#
+# Licensed 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.
+#
+# Credentials for Atlas basic authentication
+#
+# Format:
+# <username>: <password>[,<rolename> ...]
+#
+# Password is stored in obfuscated format.
+# Re-generate password using the org.eclipse.jetty.util.security.Password class in the jetty lib folder.
+# Example:
+# cd jetty-distribution-<version>/lib
+# java -cp jetty-util-<version>.jar org.eclipse.jetty.util.security.Password <plain password>
+atlas: OBF:1v1p1s3m1w1s1wtw1u3019q71u2a1wui1w1q1s3g1v2p,user
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-atlas/build_atlas.xml
----------------------------------------------------------------------
diff --git a/odf/odf-atlas/build_atlas.xml b/odf/odf-atlas/build_atlas.xml
new file mode 100755
index 0000000..8b6de87
--- /dev/null
+++ b/odf/odf-atlas/build_atlas.xml
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+~ Licensed 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.
+-->
+<project name="build_atlas">
+ <dirname property="script.basedir" file="${ant.file.build_atlas}" />
+ <property name="atlas-dir" value="apache-atlas-${atlas.version}" />
+ <!-- Properties provided by pom.xml: -->
+ <!-- <property name="atlas-unpack-dir" value="" /> -->
+ <!-- <property name="atlas.version" value="" /> -->
+
+ <property name="atlas-archive" value="/tmp/${atlas-dir}-bin.zip" />
+
+ <condition property="is-windows">
+ <os family="windows">
+ </os>
+ </condition>
+
+ <condition property="is-unix">
+ <os family="unix">
+ </os>
+ </condition>
+
+ <condition property="is-mac">
+ <os family="mac">
+ </os>
+ </condition>
+
+ <condition property="atlas-zip-not-found">
+ <not>
+ <available file="${atlas-archive}">
+ </available>
+ </not>
+ </condition>
+
+ <condition property="atlas-unpacked">
+ <available file="${atlas-unpack-dir}/${atlas-dir}/bin/atlas_start.py"/>
+ </condition>
+
+ <condition property="atlas-running">
+ <available file="${atlas-unpack-dir}/${atlas-dir}/logs/atlas.pid"/>
+ </condition>
+
+ <condition property="running-build-process">
+ <equals arg1="${atlas-unpack-dir}" arg2="/tmp"/>
+ </condition>
+
+ <!-- ****************************************************************************************** -->
+
+ <target name="download-atlas" if="atlas-zip-not-found">
+ <echo message="Downloading Apache Atlas 0.7-incubating-release. Depending on your network this can last up to 20 (yes, twenty) minutes." />
+ <!-- Make sure to update text message when moving to a new Atlas release / revision -->
+ <get verbose="true" src="https://ibm.box.com/shared/static/ftwi0wlpjtyv3nnvyh354epayqfwynsn.zip" dest="${atlas-archive}" />
+ <echo message="Atlas downloaded" />
+ </target>
+
+ <target name="unzip-atlas" unless="atlas-unpacked">
+ <antcall target="download-atlas"/>
+ <echo message="Installing Atlas test instance" />
+ <echo message="Deleting ${atlas-unpack-dir}/${atlas-dir}" />
+ <delete dir="${atlas-unpack-dir}/${atlas-dir}" failonerror="false" />
+ <echo message="deleted" />
+ <chmod file="${atlas-unpack-dir}/${atlas-archive}" perm="755" os="unix,mac"/>
+ <unzip src="${atlas-archive}" dest="${atlas-unpack-dir}" />
+ </target>
+
+ <!-- ****************************************************************************************** -->
+
+ <target name="stop-atlas" if="atlas-unpacked">
+ <echo message="Stopping atlas server if it exists" />
+ <exec dir="${atlas-unpack-dir}/${atlas-dir}/bin" executable="python">
+ <env key="JAVA_HOME" value="${java.home}" />
+ <arg value="atlas_stop.py" />
+ </exec>
+ <sleep seconds="10" />
+ </target>
+
+ <target name="ensure-atlas-stopped" depends="print-info" unless="use.running.atlas">
+ <echo message="Ensure Atlas is stopped..."/>
+ <antcall target="stop-atlas"/>
+ <delete file="${atlas-unpack-dir}/${atlas-dir}/logs/atlas.pid"/>
+ <echo message="Atlas is stopped."/>
+ </target>
+
+ <target name="remove-atlas-dir" depends="ensure-atlas-stopped" if="running-build-process">
+ <echo message="Resetting atlas data"/>
+ <delete dir="/tmp/${atlas-dir}" />
+ <echo message="Atlas directory deleted"/>
+ </target>
+
+ <target name="reset-derby-data">
+ <echo message="Resetting derby DB"/>
+ <delete dir="/tmp/odf-derby" />
+ </target>
+
+ <target name="restart-atlas-on-windows" if="is-windows">
+ <antcall target="start-atlas"/>
+ <antcall target="stop-atlas"/>
+ </target>
+
+ <!-- ****************************************************************************************** -->
+
+ <target name="start-atlas">
+ <echo message="Starting atlas server" />
+ <exec dir="${atlas-unpack-dir}/${atlas-dir}/bin" executable="python">
+ <env key="JAVA_HOME" value="${java.home}/.." />
+ <arg value="atlas_start.py" />
+ </exec>
+ <echo message="Waiting for Atlas Server to start..." />
+ <waitfor maxwait="60" maxwaitunit="second">
+ <socket server="localhost" port="21443" />
+ </waitfor>
+ </target>
+
+ <target name="check-atlas-url">
+ <fail>
+ <condition>
+ <not>
+ <socket server="localhost" port="21443" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="prepare-atlas" unless="atlas-running">
+ <antcall target="unzip-atlas"/>
+ <antcall target="enable-atlas-ssl"/>
+ </target>
+
+ <!-- ****************************************************************************************** -->
+
+ <target name="import-atlas-sampledata-win" if="is-windows">
+ <echo message="Importing sample data" />
+ <exec executable="cmd">
+ <env key="JAVA_HOME" value="${java.home}" />
+ <arg value="/c" />
+ <arg value="${atlas-unpack-dir}/${atlas-dir}/bin/quick_start.py" />
+ </exec>
+
+ <echo message="Atlas test instance brought up" />
+ </target>
+
+ <target name="import-atlas-sampledata-unix" if="is-unix">
+ <echo message="Importing sample data" />
+ <exec dir="${atlas-unpack-dir}/${atlas-dir}/bin" executable="python">
+ <env key="JAVA_HOME" value="${java.home}" />
+ <arg value="quick_start.py" />
+ </exec>
+
+ <echo message="Atlas test instance brought up" />
+ </target>
+
+ <target name="import-atlas-sampledata" depends="import-atlas-sampledata-win,import-atlas-sampledata-unix">
+ </target>
+
+ <!-- ****************************************************************************************** -->
+
+ <target name="select-atlas-config-file-windows" if="is-windows">
+ <copy file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties_windows" tofile="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties" overwrite="true"/>
+ <echo message="Using atlas SSL configuration for Windows." />
+ </target>
+
+ <target name="select-atlas-config-file-mac" if="is-mac">
+ <copy file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties_mac" tofile="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties" overwrite="true"/>
+ <echo message="Using atlas SSL configuration for Mac OS." />
+ </target>
+
+ <target name="select-atlas-config-file-unix" if="is-unix">
+ <copy file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties_linux" tofile="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties" overwrite="true"/>
+ <echo message="Using atlas SSL configuration for Unix." />
+ </target>
+
+ <target name="select-atlas-config-file" depends="select-atlas-config-file-unix,select-atlas-config-file-windows,select-atlas-config-file-mac">
+ </target>
+
+ <target name="unquote-colons-in-atlas-config-file">
+ <!-- The following replacement is needed because the ant propertyfile task quotes colons and backslashed-->
+ <replace file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties">
+ <replacetoken>\:</replacetoken>
+ <replacevalue>:</replacevalue>
+ </replace>
+ <replace file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties">
+ <replacetoken>\\</replacetoken>
+ <replacevalue>\</replacevalue>
+ </replace>
+ </target>
+
+ <target name="enable-atlas-ssl">
+ <!-- For Atlas security features see: http://atlas.incubator.apache.org/Security.html -->
+ <echo message="Updating atlas-application.properties file..." />
+ <propertyfile file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties">
+ <entry key="cert.stores.credential.provider.path" value="jceks://file/${sys:atlas.home}/conf/keystore_openjdk.jceks"/>
+ <entry key="atlas.enableTLS" value="true"/>
+ <entry key="truststore.file" value="${sys:atlas.home}/conf/keystore_openjdk.jks"/>
+ <entry key="keystore.file" value="${sys:atlas.home}/conf/keystore_openjdk.jks"/>
+ <entry key="atlas.server.https.port" value="21443"/>
+ <entry key="atlas.DeleteHandler.impl" value="org.apache.atlas.repository.graph.HardDeleteHandler"/>
+ <entry key="atlas.TypeCache.impl" value="org.apache.atlas.repository.typestore.StoreBackedTypeCache"/>
+ </propertyfile>
+ <antcall target="unquote-colons-in-atlas-config-file"/>
+ <!-- Keep this version of the config file for Mac (using oracle/open jdk) -->
+ <copy file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties" tofile="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties_mac" overwrite="true"/>
+
+ <!-- Create separate version of config file for Linux (using ibm jdk) -->
+ <propertyfile file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties">
+ <entry key="cert.stores.credential.provider.path" value="jceks://file/${sys:atlas.home}/conf/keystore_ibmjdk.jceks"/>
+ <entry key="truststore.file" value="${sys:atlas.home}/conf/keystore_ibmjdk.jks"/>
+ <entry key="keystore.file" value="${sys:atlas.home}/conf/keystore_ibmjdk.jks"/>
+ </propertyfile>
+ <antcall target="unquote-colons-in-atlas-config-file"/>
+ <copy file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties" tofile="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties_linux" overwrite="true"/>
+
+ <!-- Create separate version of config file for Windows (using ibm jdk and hardcoded credential provider file (issue #94)) -->
+ <propertyfile file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties">
+ <entry key="cert.stores.credential.provider.path" value="jceks://file/C\:/tmp/${atlas-dir}/conf/keystore_ibmjdk.jceks"/>
+ </propertyfile>
+ <antcall target="unquote-colons-in-atlas-config-file"/>
+ <copy file="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties" tofile="${atlas-unpack-dir}/${atlas-dir}/conf/atlas-application.properties_windows" overwrite="true"/>
+
+ <!-- keystore.jceks file is stored in Box@IBM - Re-generate the file using Atlas command bin/cputil.sh -->
+ <!-- Note that ibm jdk uses different format than oracle/open jdk, therefore a separate version has to be generated for each jdk -->
+ <get verbose="true" src="https://ibm.box.com/shared/static/uyzqeayk5ut5f5fqnlvm8nhn9ixb642d.jceks" dest="${atlas-unpack-dir}/${atlas-dir}/conf/keystore_openjdk.jceks" />
+ <get verbose="true" src="https://ibm.box.com/shared/static/ibopoyukw7uhbt83a1zu33nwvnamht3j.jceks" dest="${atlas-unpack-dir}/${atlas-dir}/conf/keystore_ibmjdk.jceks" />
+ <!-- keystore.jks file is stored in Box@IBM - Re-generate the file using the Java keytool -->
+ <!-- command: keytool -genkey -alias myatlas -keyalg RSA -keystore /tmp/atlas-security/keystore.jks -keysize 2048 -->
+ <!-- Note that ibm jdk uses different format than oracle/open jdk, therefore a separate version has to be generated for each jdk -->
+ <get verbose="true" src="https://ibm.box.com/shared/static/odnmhqua5sdue03z43vqsv0lp509ov70.jks" dest="${atlas-unpack-dir}/${atlas-dir}/conf/keystore_openjdk.jks" />
+ <get verbose="true" src="https://ibm.box.com/shared/static/k0qgh31ynbgnjsrbg5s97hsqbssh6pd4.jks" dest="${atlas-unpack-dir}/${atlas-dir}/conf/keystore_ibmjdk.jks" />
+
+ <antcall target="select-atlas-config-file"/>
+ <echo message="Atlas SSL has been enabled." />
+ <!-- On windows, Atlas needs to be re-started again in order for the kafka queues to come up properly -->
+ <antcall target="restart-atlas-on-windows" />
+ </target>
+
+ <!-- ****************************************************************************************** -->
+ <target name="print-info" if="use.running.atlas">
+ <echo message="Don't start/stop Atlas because use.running.atlas is set" />
+ </target>
+
+ <target name="clean-atlas" depends="print-info" unless="use.running.atlas">
+ <echo message="Cleaning Atlas" />
+ <antcall target="remove-atlas-dir"/>
+ <antcall target="reset-derby-data"/>
+ </target>
+
+ <target name="ensure-atlas-running" depends="print-info" unless="use.running.atlas">
+ <echo message="Ensure that Atlas is running" />
+ <antcall target="prepare-atlas" />
+ <antcall target="start-atlas"/>
+ <antcall target="check-atlas-url"/>
+ <echo message="Atlas is running" />
+ </target>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6d19e129/odf/odf-atlas/pom.xml
----------------------------------------------------------------------
diff --git a/odf/odf-atlas/pom.xml b/odf/odf-atlas/pom.xml
new file mode 100755
index 0000000..cc714e6
--- /dev/null
+++ b/odf/odf-atlas/pom.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+~
+~ Licensed 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns:if="ant:if">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>odf-atlas</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-api</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-core</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-messaging</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-messaging</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-store</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-spark</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-core</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.atlas.odf</groupId>
+ <artifactId>odf-spark</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <version>10.12.1.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>2.19</version>
+ <configuration>
+ <systemPropertyVariables>
+ <odf.zookeeper.connect>${testZookeepeConnectionString}</odf.zookeeper.connect>
+ <odf.logspec>${odf.integrationtest.logspec}</odf.logspec>
+ <atlas.url>${atlas.url}</atlas.url>
+ <atlas.user>${atlas.user}</atlas.user>
+ <atlas.password>${atlas.password}</atlas.password>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.apache.atlas.odf:odf-core</dependency>
+ </dependenciesToScan>
+ <includes>
+ <include>**/integrationtest/**/**.java</include>
+ </includes>
+ </configuration>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <goals>
+ <goal>integration-test</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>verify</id>
+ <goals>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.19</version>
+ <configuration>
+ <systemPropertyVariables>
+ <odf.zookeeper.connect>${testZookeepeConnectionString}</odf.zookeeper.connect>
+ <odf.logspec>${odf.unittest.logspec}</odf.logspec>
+ <odf.build.project.name>${project.name}</odf.build.project.name>
+ <atlas.url>${atlas.url}</atlas.url>
+ <atlas.user>${atlas.user}</atlas.user>
+ <atlas.password>${atlas.password}</atlas.password>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <inherited>false</inherited>
+ <id>clean-atlas</id>
+ <phase>clean</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <property name="atlas-unpack-dir" value="/tmp"/>
+ <property name="atlas.version" value="${atlas.version}"/>
+ <ant antfile="build_atlas.xml" target="clean-atlas"/>
+ </target>
+ </configuration>
+ </execution>
+ <execution>
+ <id>ensure-atlas-running</id>
+ <phase>process-test-classes</phase>
+ <!-- <phase>pre-integration-test</phase> -->
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target unless="skipTests">
+ <property name="atlas-unpack-dir" value="/tmp" />
+ <property name="atlas.version" value="${atlas.version}" />
+ <ant antfile="build_atlas.xml" target="ensure-atlas-running"></ant>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>atlas</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <!-- Start Atlas even in order to have it available for the test-env when skipping the tests -->
+ <execution>
+ <id>ensure-atlas-running</id>
+ <phase>process-test-classes</phase>
+ <!-- <phase>pre-integration-test</phase> -->
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target unless="skipTests">
+ <property name="atlas-unpack-dir" value="/tmp" />
+ <property name="atlas.version" value="${atlas.version}" />
+ <ant antfile="build_atlas.xml" target="ensure-atlas-running"></ant>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>