org.neo4j.driver.internal.util.MetadataExtractor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of neo4j-java-driver Show documentation
Show all versions of neo4j-java-driver Show documentation
Access to the Neo4j graph database through Java
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* 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.neo4j.driver.internal.util;
import static org.neo4j.driver.internal.summary.InternalDatabaseInfo.DEFAULT_DATABASE_INFO;
import static org.neo4j.driver.internal.types.InternalTypeSystem.TYPE_SYSTEM;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.neo4j.driver.Bookmark;
import org.neo4j.driver.Query;
import org.neo4j.driver.Value;
import org.neo4j.driver.exceptions.ProtocolException;
import org.neo4j.driver.exceptions.UntrustedServerException;
import org.neo4j.driver.internal.InternalBookmark;
import org.neo4j.driver.internal.spi.Connection;
import org.neo4j.driver.internal.summary.InternalDatabaseInfo;
import org.neo4j.driver.internal.summary.InternalNotification;
import org.neo4j.driver.internal.summary.InternalPlan;
import org.neo4j.driver.internal.summary.InternalProfiledPlan;
import org.neo4j.driver.internal.summary.InternalResultSummary;
import org.neo4j.driver.internal.summary.InternalServerInfo;
import org.neo4j.driver.internal.summary.InternalSummaryCounters;
import org.neo4j.driver.summary.DatabaseInfo;
import org.neo4j.driver.summary.Notification;
import org.neo4j.driver.summary.Plan;
import org.neo4j.driver.summary.ProfiledPlan;
import org.neo4j.driver.summary.QueryType;
import org.neo4j.driver.summary.ResultSummary;
import org.neo4j.driver.summary.ServerInfo;
public class MetadataExtractor {
public static final int ABSENT_QUERY_ID = -1;
private static final String UNEXPECTED_TYPE_MSG_FMT = "Unexpected query type '%s', consider updating the driver";
private static final Function UNEXPECTED_TYPE_EXCEPTION_SUPPLIER =
(type) -> new ProtocolException(String.format(UNEXPECTED_TYPE_MSG_FMT, type));
private final String resultAvailableAfterMetadataKey;
private final String resultConsumedAfterMetadataKey;
public MetadataExtractor(String resultAvailableAfterMetadataKey, String resultConsumedAfterMetadataKey) {
this.resultAvailableAfterMetadataKey = resultAvailableAfterMetadataKey;
this.resultConsumedAfterMetadataKey = resultConsumedAfterMetadataKey;
}
public QueryKeys extractQueryKeys(Map metadata) {
Value keysValue = metadata.get("fields");
if (keysValue != null) {
if (!keysValue.isEmpty()) {
QueryKeys keys = new QueryKeys(keysValue.size());
for (Value value : keysValue.values()) {
keys.add(value.asString());
}
return keys;
}
}
return QueryKeys.empty();
}
public long extractQueryId(Map metadata) {
Value queryId = metadata.get("qid");
if (queryId != null) {
return queryId.asLong();
}
return ABSENT_QUERY_ID;
}
public long extractResultAvailableAfter(Map metadata) {
Value resultAvailableAfterValue = metadata.get(resultAvailableAfterMetadataKey);
if (resultAvailableAfterValue != null) {
return resultAvailableAfterValue.asLong();
}
return -1;
}
public ResultSummary extractSummary(
Query query, Connection connection, long resultAvailableAfter, Map metadata) {
ServerInfo serverInfo = new InternalServerInfo(
connection.serverAgent(),
connection.serverAddress(),
connection.serverVersion(),
connection.protocol().version());
DatabaseInfo dbInfo = extractDatabaseInfo(metadata);
return new InternalResultSummary(
query,
serverInfo,
dbInfo,
extractQueryType(metadata),
extractCounters(metadata),
extractPlan(metadata),
extractProfiledPlan(metadata),
extractNotifications(metadata),
resultAvailableAfter,
extractResultConsumedAfter(metadata, resultConsumedAfterMetadataKey));
}
public static DatabaseInfo extractDatabaseInfo(Map metadata) {
Value dbValue = metadata.get("db");
if (dbValue == null || dbValue.isNull()) {
return DEFAULT_DATABASE_INFO;
} else {
return new InternalDatabaseInfo(dbValue.asString());
}
}
public static Bookmark extractBookmarks(Map metadata) {
Value bookmarkValue = metadata.get("bookmark");
if (bookmarkValue != null && !bookmarkValue.isNull() && bookmarkValue.hasType(TYPE_SYSTEM.STRING())) {
return InternalBookmark.parse(bookmarkValue.asString());
}
return InternalBookmark.empty();
}
public static ServerVersion extractNeo4jServerVersion(Map metadata) {
Value serverValue = extractServer(metadata);
ServerVersion server = ServerVersion.version(serverValue.asString());
if (ServerVersion.NEO4J_PRODUCT.equalsIgnoreCase(server.product())) {
return server;
} else {
throw new UntrustedServerException(
"Server does not identify as a genuine Neo4j instance: '" + server.product() + "'");
}
}
public static Value extractServer(Map metadata) {
Value versionValue = metadata.get("server");
if (versionValue == null || versionValue.isNull()) {
throw new UntrustedServerException("Server provides no product identifier");
}
return versionValue;
}
private static QueryType extractQueryType(Map metadata) {
Value typeValue = metadata.get("type");
if (typeValue != null) {
return QueryType.fromCode(typeValue.asString(), UNEXPECTED_TYPE_EXCEPTION_SUPPLIER);
}
return null;
}
private static InternalSummaryCounters extractCounters(Map metadata) {
Value countersValue = metadata.get("stats");
if (countersValue != null) {
return new InternalSummaryCounters(
counterValue(countersValue, "nodes-created"),
counterValue(countersValue, "nodes-deleted"),
counterValue(countersValue, "relationships-created"),
counterValue(countersValue, "relationships-deleted"),
counterValue(countersValue, "properties-set"),
counterValue(countersValue, "labels-added"),
counterValue(countersValue, "labels-removed"),
counterValue(countersValue, "indexes-added"),
counterValue(countersValue, "indexes-removed"),
counterValue(countersValue, "constraints-added"),
counterValue(countersValue, "constraints-removed"),
counterValue(countersValue, "system-updates"));
}
return null;
}
private static int counterValue(Value countersValue, String name) {
Value value = countersValue.get(name);
return value.isNull() ? 0 : value.asInt();
}
private static Plan extractPlan(Map metadata) {
Value planValue = metadata.get("plan");
if (planValue != null) {
return InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply(planValue);
}
return null;
}
private static ProfiledPlan extractProfiledPlan(Map metadata) {
Value profiledPlanValue = metadata.get("profile");
if (profiledPlanValue != null) {
return InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply(profiledPlanValue);
}
return null;
}
private static List extractNotifications(Map metadata) {
Value notificationsValue = metadata.get("notifications");
if (notificationsValue != null) {
return notificationsValue.asList(InternalNotification.VALUE_TO_NOTIFICATION);
}
return Collections.emptyList();
}
private static long extractResultConsumedAfter(Map metadata, String key) {
Value resultConsumedAfterValue = metadata.get(key);
if (resultConsumedAfterValue != null) {
return resultConsumedAfterValue.asLong();
}
return -1;
}
public static Set extractBoltPatches(Map metadata) {
Value boltPatch = metadata.get("patch_bolt");
if (boltPatch != null && !boltPatch.isNull()) {
return new HashSet<>(boltPatch.asList(Value::asString));
} else {
return Collections.emptySet();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy