Merge branch 'gerrit/trinity' into 'master'
Change-Id: I31d1dd61195b4f03cc983c21e309cfd9adb02f6c
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
index b5abdf0..25d43b2 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
@@ -40,6 +40,7 @@
import org.apache.asterix.metadata.api.IAsterixStateProxy;
import org.apache.asterix.metadata.api.IExtensionMetadataEntity;
import org.apache.asterix.metadata.api.IExtensionMetadataSearchKey;
+import org.apache.asterix.metadata.api.IMetadataIndex;
import org.apache.asterix.metadata.api.IMetadataManager;
import org.apache.asterix.metadata.api.IMetadataNode;
import org.apache.asterix.metadata.entities.CompactionPolicy;
@@ -66,6 +67,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Strings;
/**
@@ -1323,6 +1325,16 @@
}
@Override
+ public JsonNode getEntitiesAsJson(MetadataTransactionContext mdTxnCtx, IMetadataIndex metadataIndex,
+ int payloadPosition) throws AlgebricksException {
+ try {
+ return metadataNode.getEntitiesAsJson(mdTxnCtx.getTxnId(), metadataIndex, payloadPosition);
+ } catch (RemoteException e) {
+ throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
+ }
+ }
+
+ @Override
public void rebindMetadataNode() {
rebindMetadataNode = true;
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
index 03d4bb8..0eb1111 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
@@ -57,6 +57,7 @@
import static org.apache.asterix.common.exceptions.ErrorCode.UNKNOWN_TYPE;
import static org.apache.asterix.common.utils.IdentifierUtil.dataset;
+import java.io.PrintStream;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -87,6 +88,7 @@
import org.apache.asterix.common.transactions.TxnId;
import org.apache.asterix.common.utils.StoragePathUtil;
import org.apache.asterix.external.indexing.ExternalFile;
+import org.apache.asterix.formats.nontagged.CleanJSONPrinterFactoryProvider;
import org.apache.asterix.formats.nontagged.NullIntrospector;
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.formats.nontagged.TypeTraitProvider;
@@ -162,12 +164,15 @@
import org.apache.asterix.transaction.management.opcallbacks.UpsertOperationCallback;
import org.apache.asterix.transaction.management.service.transaction.DatasetIdFactory;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.data.IPrinter;
+import org.apache.hyracks.algebricks.data.IPrinterFactory;
import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
import org.apache.hyracks.api.exceptions.ErrorCode;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.api.util.HyracksConstants;
+import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleReference;
import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -186,9 +191,12 @@
import org.apache.hyracks.storage.common.IModificationOperationCallback;
import org.apache.hyracks.storage.common.MultiComparator;
import org.apache.hyracks.util.ExitUtil;
+import org.apache.hyracks.util.JSONUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.base.Strings;
public class MetadataNode implements IMetadataNode {
@@ -378,6 +386,16 @@
return getEntities(txnId, searchKey.getSearchKey(mdIndexesProvider), tupleTranslator, index);
}
+ @Override
+ public JsonNode getEntitiesAsJson(TxnId txnId, IMetadataIndex metadataIndex, int payloadPosition)
+ throws AlgebricksException, RemoteException {
+ try {
+ return getJsonNodes(txnId, metadataIndex, payloadPosition);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
private <T extends IExtensionMetadataEntity> ExtensionMetadataDataset<T> getExtensionMetadataDataset(
ExtensionMetadataDatasetId datasetId) throws AlgebricksException {
ExtensionMetadataDataset<T> index = (ExtensionMetadataDataset<T>) extensionDatasets.get(datasetId);
@@ -3059,4 +3077,44 @@
return MetadataBuiltinEntities.DEFAULT_DATABASE;
}
}
+
+ private ArrayNode getJsonNodes(TxnId txnId, IMetadataIndex mdIndex, int payloadPosition)
+ throws AlgebricksException, HyracksDataException {
+ IValueExtractor<JsonNode> valueExtractor = createValueExtractor(mdIndex, payloadPosition);
+ List<JsonNode> results = new ArrayList<>();
+ searchIndex(txnId, mdIndex, null, valueExtractor, results);
+ ArrayNode array = JSONUtil.createArray();
+ results.forEach(array::add);
+ return array;
+ }
+
+ private static IValueExtractor<JsonNode> createValueExtractor(IMetadataIndex mdIndex, int payloadFieldIndex) {
+ return new IValueExtractor<>() {
+
+ final ARecordType payloadRecordType = mdIndex.getPayloadRecordType();
+ final IPrinterFactory printerFactory =
+ CleanJSONPrinterFactoryProvider.INSTANCE.getPrinterFactory(payloadRecordType);
+ final IPrinter printer = printerFactory.createPrinter();
+ final ByteArrayAccessibleOutputStream outputStream = new ByteArrayAccessibleOutputStream();
+ final PrintStream printStream = new PrintStream(outputStream);
+
+ @Override
+ public JsonNode getValue(TxnId txnId, ITupleReference tuple) {
+ try {
+ byte[] serRecord = tuple.getFieldData(payloadFieldIndex);
+ int recordStartOffset = tuple.getFieldStart(payloadFieldIndex);
+ int recordLength = tuple.getFieldLength(payloadFieldIndex);
+
+ printer.init();
+ outputStream.reset();
+
+ printer.print(serRecord, recordStartOffset, recordLength, printStream);
+ printStream.flush();
+ return JSONUtil.readTree(outputStream.getByteArray(), 0, outputStream.getLength());
+ } catch (Throwable th) {
+ return JSONUtil.createObject();
+ }
+ }
+ };
+ }
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java
index d5e0157..fdd36de 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java
@@ -47,6 +47,8 @@
import org.apache.asterix.metadata.entities.Synonym;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import com.fasterxml.jackson.databind.JsonNode;
+
/**
* A metadata manager provides user access to Asterix metadata (e.g., types,
* datasets, indexes, etc.). A metadata manager satisfies requests by contacting
@@ -883,6 +885,20 @@
IExtensionMetadataSearchKey searchKey) throws AlgebricksException;
/**
+ * Gets all the records of a metadata dataset as JSON.
+ *
+ * @param mdTxnCtx metadata transaction context
+ * @param metadataIndex the metadata dataset
+ * @param payloadPosition the position of the record in the tuple
+ *
+ * @return the metadata records as JSON
+ *
+ * @throws AlgebricksException AlgebricksException
+ */
+ JsonNode getEntitiesAsJson(MetadataTransactionContext mdTxnCtx, IMetadataIndex metadataIndex, int payloadPosition)
+ throws AlgebricksException;
+
+ /**
* Indicate when the metadata node has left or rejoined the cluster, and the
* MetadataManager should rebind it
*/
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java
index 0d753d8..ee4a2c9 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java
@@ -48,6 +48,8 @@
import org.apache.asterix.transaction.management.opcallbacks.AbstractIndexModificationOperationCallback;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import com.fasterxml.jackson.databind.JsonNode;
+
/**
* A metadata node stores metadata in its local storage structures (currently
* BTrees). A metadata node services requests on behalf of the (possibly remote)
@@ -990,6 +992,21 @@
<T extends IExtensionMetadataEntity> List<T> getEntities(TxnId txnId, IExtensionMetadataSearchKey searchKey)
throws AlgebricksException, RemoteException;
+ /**
+ * Gets all the records of a metadata dataset as JSON.
+ *
+ * @param txnId transaction id
+ * @param metadataIndex the metadata dataset
+ * @param payloadPosition the position of the record in the tuple
+ *
+ * @return the metadata records as JSON
+ *
+ * @throws AlgebricksException AlgebricksException
+ * @throws RemoteException RemoteException
+ */
+ JsonNode getEntitiesAsJson(TxnId txnId, IMetadataIndex metadataIndex, int payloadPosition)
+ throws AlgebricksException, RemoteException;
+
void addFeedConnection(TxnId txnId, FeedConnection feedConnection) throws AlgebricksException, RemoteException;
FeedConnection getFeedConnection(TxnId txnId, String database, DataverseName dataverseName, String feedName,
diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
index f937e97..191df1f 100644
--- a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
@@ -50,6 +50,10 @@
SORTED_MAPPER.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
}
+ public static JsonNode readTree(byte[] bytes, int start, int size) throws IOException {
+ return OBJECT_MAPPER.readTree(bytes, start, size);
+ }
+
public static String convertNode(final JsonNode node) throws JsonProcessingException {
return SORTED_MAPPER.writeValueAsString(SORTED_MAPPER.treeToValue(node, Object.class));
}