This is an automated email from the ASF dual-hosted git repository. xiaokang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/incubator-graphar.git
The following commit(s) were added to refs/heads/main by this push: new ae20a93a feat(java,info): refactor GraphInfoLoader provide API, hide yaml dependencies, replace prefix to uri (#745) ae20a93a is described below commit ae20a93a6eb6bdb980e575448fd09de98a99d00f Author: Xiaokang Yang <81174897+yang...@users.noreply.github.com> AuthorDate: Mon Sep 8 14:33:23 2025 +0800 feat(java,info): refactor GraphInfoLoader provide API, hide yaml dependencies, replace prefix to uri (#745) * refactor load graphInfo method * refactor save graphInfo method * format * update * Provide uris directly * resolve uri by path * format * update * reset saver * fix graph prefix * format * change prefix from string to uri * add loader impl and test * add uri parser test * add builder test --- maven-projects/info/pom.xml | 28 +++- .../java/org/apache/graphar/info/AdjacentList.java | 22 +-- .../java/org/apache/graphar/info/EdgeInfo.java | 177 +++++++++------------ .../java/org/apache/graphar/info/GraphInfo.java | 111 +++---------- .../org/apache/graphar/info/PropertyGroup.java | 27 ++-- .../java/org/apache/graphar/info/VertexInfo.java | 104 +++--------- .../graphar/info/loader/BaseGraphInfoLoader.java | 101 ++++++++++++ .../graphar/info/loader/GraphInfoLoader.java | 35 ++++ .../graphar/info/loader/LocalYamlGraphLoader.java | 89 ----------- .../graphar/info/loader/ReaderGraphInfoLoader.java | 62 ++++++++ .../graphar/info/loader/StreamGraphInfoLoader.java | 63 ++++++++ .../graphar/info/loader/StringGraphInfoLoader.java | 61 +++++++ .../impl/LocalFileSystemReaderGraphInfoLoader.java | 36 +++++ .../impl/LocalFileSystemStreamGraphInfoLoader.java | 37 +++++ .../impl/LocalFileSystemStringGraphInfoLoader.java | 41 +++++ .../org/apache/graphar/info/yaml/EdgeYaml.java | 19 --- .../graphar/info/yaml/PropertyGroupYaml.java | 2 +- .../org/apache/graphar/info/yaml/VertexYaml.java | 11 -- .../java/org/apache/graphar/util/PathUtil.java | 48 ------ .../java/org/apache/graphar/info/EdgeInfoTest.java | 74 ++++++++- .../apache/graphar/info/GraphInfoLoaderTest.java | 92 +++++++++++ .../org/apache/graphar/info/GraphInfoTest.java | 96 ++++++----- .../org/apache/graphar/info/GraphInfoUriTest.java | 101 ++++++++++++ .../org/apache/graphar/info/GraphLoaderTest.java | 61 ------- .../java/org/apache/graphar/info/TestUtil.java | 119 +++++++++++++- 25 files changed, 1047 insertions(+), 570 deletions(-) diff --git a/maven-projects/info/pom.xml b/maven-projects/info/pom.xml index 52c85867..475aca61 100644 --- a/maven-projects/info/pom.xml +++ b/maven-projects/info/pom.xml @@ -57,15 +57,33 @@ <version>2.0</version> <scope>compile</scope> </dependency> - <dependency> - <groupId>org.apache.hadoop</groupId> - <artifactId>hadoop-common</artifactId> - <version>3.4.0</version> - </dependency> </dependencies> <build> <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.5.0</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <relocations> + <relocation> + <pattern>org.yaml.snakeyaml</pattern> + <shadedPattern>org.apache.graphar.shaded.snakeyaml</shadedPattern> + </relocation> + </relocations> + <createDependencyReducedPom>true</createDependencyReducedPom> + <minimizeJar>false</minimizeJar> + </configuration> + </execution> + </executions> + </plugin> <plugin> <groupId>com.diffplug.spotless</groupId> <artifactId>spotless-maven-plugin</artifactId> diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/AdjacentList.java b/maven-projects/info/src/main/java/org/apache/graphar/info/AdjacentList.java index ddf285de..bfe20cd1 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/AdjacentList.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/AdjacentList.java @@ -19,27 +19,23 @@ package org.apache.graphar.info; +import java.net.URI; import org.apache.graphar.info.type.AdjListType; import org.apache.graphar.info.type.FileType; -import org.apache.graphar.info.yaml.AdjacentListYaml; public class AdjacentList { private final AdjListType type; private final FileType fileType; - private final String prefix; + private final URI baseUri; - public AdjacentList(AdjListType type, FileType fileType, String prefix) { + public AdjacentList(AdjListType type, FileType fileType, URI baseUri) { this.type = type; this.fileType = fileType; - this.prefix = prefix; + this.baseUri = baseUri; } - AdjacentList(AdjacentListYaml yamlParser) { - this.type = - AdjListType.fromOrderedAndAlignedBy( - yamlParser.isOrdered(), yamlParser.getAligned_by()); - this.fileType = FileType.fromString(yamlParser.getFile_type()); - this.prefix = yamlParser.getPrefix(); + public AdjacentList(AdjListType type, FileType fileType, String prefix) { + this(type, fileType, URI.create(prefix)); } public AdjListType getType() { @@ -51,6 +47,10 @@ public class AdjacentList { } public String getPrefix() { - return prefix; + return baseUri.toString(); + } + + public URI getBaseUri() { + return baseUri; } } diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java b/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java index 31588c6a..3df5a0c4 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/EdgeInfo.java @@ -19,7 +19,7 @@ package org.apache.graphar.info; -import java.io.IOException; +import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -33,14 +33,7 @@ import org.apache.graphar.info.type.DataType; import org.apache.graphar.info.yaml.EdgeYaml; import org.apache.graphar.info.yaml.GraphYaml; import org.apache.graphar.util.GeneralParams; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.FSDataInputStream; -import org.apache.hadoop.fs.FSDataOutputStream; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.Path; -import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; public class EdgeInfo { private final EdgeTriplet edgeTriplet; @@ -48,7 +41,7 @@ public class EdgeInfo { private final long srcChunkSize; private final long dstChunkSize; private final boolean directed; - private final String prefix; + private final URI baseUri; private final Map<AdjListType, AdjacentList> adjacentLists; private final PropertyGroups propertyGroups; private final VersionInfo version; @@ -63,6 +56,7 @@ public class EdgeInfo { private long srcChunkSize; private long dstChunkSize; private boolean directed; + private URI baseUri; private String prefix; private Map<AdjListType, AdjacentList> adjacentLists; private PropertyGroups propertyGroups; @@ -122,6 +116,11 @@ public class EdgeInfo { return this; } + public EdgeInfoBuilder baseUri(URI baseUri) { + this.baseUri = baseUri; + return this; + } + public EdgeInfoBuilder prefix(String prefix) { this.prefix = prefix; return this; @@ -216,6 +215,22 @@ public class EdgeInfo { throw new IllegalArgumentException("AdjacentLists is empty"); } + if (baseUri == null && prefix == null) { + throw new IllegalArgumentException("baseUri and prefix cannot be both null"); + } + + if (baseUri != null && prefix != null && !URI.create(prefix).equals(baseUri)) { + throw new IllegalArgumentException( + "baseUri and prefix conflict: baseUri=" + + baseUri.toString() + + " prefix=" + + prefix); + } + + if (baseUri == null) { + baseUri = URI.create(prefix); + } + return new EdgeInfo(this); } } @@ -226,7 +241,7 @@ public class EdgeInfo { this.srcChunkSize = builder.srcChunkSize; this.dstChunkSize = builder.dstChunkSize; this.directed = builder.directed; - this.prefix = builder.prefix; + this.baseUri = builder.baseUri; this.adjacentLists = builder.adjacentLists; this.propertyGroups = builder.propertyGroups; this.version = builder.version; @@ -240,7 +255,7 @@ public class EdgeInfo { long srcChunkSize, long dstChunkSize, boolean directed, - String prefix, + URI baseUri, String version, List<AdjacentList> adjacentListsAsList, List<PropertyGroup> propertyGroupsAsList) { @@ -252,7 +267,7 @@ public class EdgeInfo { srcChunkSize, dstChunkSize, directed, - prefix, + baseUri, VersionParser.getVersion(version), adjacentListsAsList, propertyGroupsAsList); @@ -267,6 +282,32 @@ public class EdgeInfo { long dstChunkSize, boolean directed, String prefix, + String version, + List<AdjacentList> adjacentListsAsList, + List<PropertyGroup> propertyGroupsAsList) { + this( + srcType, + edgeType, + dstType, + chunkSize, + srcChunkSize, + dstChunkSize, + directed, + URI.create(prefix), + version, + adjacentListsAsList, + propertyGroupsAsList); + } + + public EdgeInfo( + String srcType, + String edgeType, + String dstType, + long chunkSize, + long srcChunkSize, + long dstChunkSize, + boolean directed, + URI baseUri, VersionInfo version, List<AdjacentList> adjacentListsAsList, List<PropertyGroup> propertyGroupsAsList) { @@ -275,7 +316,7 @@ public class EdgeInfo { this.srcChunkSize = srcChunkSize; this.dstChunkSize = dstChunkSize; this.directed = directed; - this.prefix = prefix; + this.baseUri = baseUri; this.adjacentLists = adjacentListsAsList.stream() .collect( @@ -285,32 +326,13 @@ public class EdgeInfo { this.version = version; } - private EdgeInfo(EdgeYaml yamlParser) { - this( - yamlParser.getSrc_type(), - yamlParser.getEdge_type(), - yamlParser.getDst_type(), - yamlParser.getChunk_size(), - yamlParser.getSrc_chunk_size(), - yamlParser.getDst_chunk_size(), - yamlParser.isDirected(), - yamlParser.getPrefix(), - yamlParser.getVersion(), - yamlParser.getAdj_lists().stream() - .map(AdjacentList::new) - .collect(Collectors.toUnmodifiableList()), - yamlParser.getProperty_groups().stream() - .map(PropertyGroup::new) - .collect(Collectors.toUnmodifiableList())); - } - private EdgeInfo( EdgeTriplet edgeTriplet, long chunkSize, long srcChunkSize, long dstChunkSize, boolean directed, - String prefix, + URI baseUri, String version, Map<AdjListType, AdjacentList> adjacentLists, PropertyGroups propertyGroups) { @@ -320,7 +342,7 @@ public class EdgeInfo { srcChunkSize, dstChunkSize, directed, - prefix, + baseUri, VersionParser.getVersion(version), adjacentLists, propertyGroups); @@ -332,7 +354,7 @@ public class EdgeInfo { long srcChunkSize, long dstChunkSize, boolean directed, - String prefix, + URI baseUri, VersionInfo version, Map<AdjListType, AdjacentList> adjacentLists, PropertyGroups propertyGroups) { @@ -341,33 +363,12 @@ public class EdgeInfo { this.srcChunkSize = srcChunkSize; this.dstChunkSize = dstChunkSize; this.directed = directed; - this.prefix = prefix; + this.baseUri = baseUri; this.adjacentLists = adjacentLists; this.propertyGroups = propertyGroups; this.version = version; } - public static EdgeInfo load(String edgeInfoPath) throws IOException { - return load(edgeInfoPath, new Configuration()); - } - - public static EdgeInfo load(String edgeInfoPath, Configuration conf) throws IOException { - if (conf == null) { - throw new IllegalArgumentException("Configuration is null"); - } - return load(edgeInfoPath, FileSystem.get(conf)); - } - - public static EdgeInfo load(String edgeInfoPath, FileSystem fileSystem) throws IOException { - if (fileSystem == null) { - throw new IllegalArgumentException("FileSystem is null"); - } - FSDataInputStream inputStream = fileSystem.open(new Path(edgeInfoPath)); - Yaml edgeInfoYamlLoader = new Yaml(new Constructor(EdgeYaml.class, new LoaderOptions())); - EdgeYaml edgeInfoYaml = edgeInfoYamlLoader.load(inputStream); - return new EdgeInfo(edgeInfoYaml); - } - public static String concat(String srcLabel, String edgeLabel, String dstLabel) { return srcLabel + GeneralParams.regularSeparator @@ -394,7 +395,7 @@ public class EdgeInfo { srcChunkSize, dstChunkSize, directed, - prefix, + baseUri, version, newAdjacentLists, propertyGroups)); @@ -411,7 +412,7 @@ public class EdgeInfo { srcChunkSize, dstChunkSize, directed, - prefix, + baseUri, version, adjacentLists, newPropertyGroups)); @@ -445,38 +446,38 @@ public class EdgeInfo { return propertyGroups.getPropertyGroup(property); } - public String getPropertyGroupPrefix(PropertyGroup propertyGroup) { + public URI getPropertyGroupPrefix(PropertyGroup propertyGroup) { checkPropertyGroupExist(propertyGroup); - return getPrefix() + propertyGroup.getPrefix(); + return getBaseUri().resolve(propertyGroup.getBaseUri()); } - public String getPropertyGroupChunkPath(PropertyGroup propertyGroup, long chunkIndex) { + public URI getPropertyGroupChunkPath(PropertyGroup propertyGroup, long chunkIndex) { // PropertyGroup will be checked in getPropertyGroupPrefix - return getPropertyGroupPrefix(propertyGroup) + "chunk" + chunkIndex; + return getPropertyGroupPrefix(propertyGroup).resolve("chunk" + chunkIndex); } - public String getAdjacentListPrefix(AdjListType adjListType) { - return getPrefix() + getAdjacentList(adjListType).getPrefix() + "adj_list/"; + public URI getAdjacentListPrefix(AdjListType adjListType) { + return getBaseUri().resolve(getAdjacentList(adjListType).getBaseUri()).resolve("adj_list/"); } - public String getAdjacentListChunkPath(AdjListType adjListType, long vertexChunkIndex) { - return getAdjacentListPrefix(adjListType) + "chunk" + vertexChunkIndex; + public URI getAdjacentListChunkPath(AdjListType adjListType, long vertexChunkIndex) { + return getAdjacentListPrefix(adjListType).resolve("chunk" + vertexChunkIndex); } - public String getOffsetPrefix(AdjListType adjListType) { - return getAdjacentListPrefix(adjListType) + "offset/"; + public URI getOffsetPrefix(AdjListType adjListType) { + return getAdjacentListPrefix(adjListType).resolve("offset/"); } - public String getOffsetChunkPath(AdjListType adjListType, long vertexChunkIndex) { - return getOffsetPrefix(adjListType) + "chunk" + vertexChunkIndex; + public URI getOffsetChunkPath(AdjListType adjListType, long vertexChunkIndex) { + return getOffsetPrefix(adjListType).resolve("chunk" + vertexChunkIndex); } - public String getVerticesNumFilePath(AdjListType adjListType) { - return getAdjacentListPrefix(adjListType) + "vertex_count"; + public URI getVerticesNumFilePath(AdjListType adjListType) { + return getAdjacentListPrefix(adjListType).resolve("vertex_count"); } - public String getEdgesNumFilePath(AdjListType adjListType, long vertexChunkIndex) { - return getAdjacentListPrefix(adjListType) + "edge_count" + vertexChunkIndex; + public URI getEdgesNumFilePath(AdjListType adjListType, long vertexChunkIndex) { + return getAdjacentListPrefix(adjListType).resolve("edge_count" + vertexChunkIndex); } public DataType getPropertyType(String propertyName) { @@ -491,26 +492,6 @@ public class EdgeInfo { return propertyGroups.isNullableKey(propertyName); } - public void save(String filePath) throws IOException { - save(filePath, new Configuration()); - } - - public void save(String filePath, Configuration conf) throws IOException { - if (conf == null) { - throw new IllegalArgumentException("Configuration is null"); - } - save(filePath, FileSystem.get(conf)); - } - - public void save(String fileName, FileSystem fileSystem) throws IOException { - if (fileSystem == null) { - throw new IllegalArgumentException("FileSystem is null"); - } - FSDataOutputStream outputStream = fileSystem.create(new Path(fileName)); - outputStream.writeBytes(dump()); - outputStream.close(); - } - public String dump() { Yaml yaml = new Yaml(GraphYaml.getRepresenter(), GraphYaml.getDumperOptions()); EdgeYaml edgeYaml = new EdgeYaml(this); @@ -550,11 +531,11 @@ public class EdgeInfo { } public String getPrefix() { - return prefix; + return baseUri.toString(); } - public String getEdgePath() { - return getPrefix() + getConcat() + ".edge.yaml"; + public URI getBaseUri() { + return baseUri; } public VersionInfo getVersion() { diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java b/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java index ddad1a88..7ba3ee59 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/GraphInfo.java @@ -19,8 +19,7 @@ package org.apache.graphar.info; -import java.io.IOException; -import java.util.ArrayList; +import java.net.URI; import java.util.List; import java.util.Map; import java.util.Optional; @@ -28,20 +27,13 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.graphar.info.yaml.GraphYaml; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.FSDataInputStream; -import org.apache.hadoop.fs.FSDataOutputStream; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.Path; -import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; public class GraphInfo { private final String name; private final List<VertexInfo> vertexInfos; private final List<EdgeInfo> edgeInfos; - private final String prefix; + private final URI baseUri; private final Map<String, VertexInfo> vertexType2VertexInfo; private final Map<String, EdgeInfo> edgeConcat2EdgeInfo; private final VersionInfo version; @@ -52,10 +44,19 @@ public class GraphInfo { List<EdgeInfo> edgeInfos, String prefix, String version) { + this(name, vertexInfos, edgeInfos, URI.create(prefix), version); + } + + public GraphInfo( + String name, + List<VertexInfo> vertexInfos, + List<EdgeInfo> edgeInfos, + URI baseUri, + String version) { this.name = name; this.vertexInfos = List.copyOf(vertexInfos); this.edgeInfos = List.copyOf(edgeInfos); - this.prefix = prefix; + this.baseUri = baseUri; this.version = VersionParser.getVersion(version); this.vertexType2VertexInfo = vertexInfos.stream() @@ -69,20 +70,11 @@ public class GraphInfo { EdgeInfo::getConcat, Function.identity())); } - private GraphInfo(GraphYaml graphYaml, Configuration conf) throws IOException { - this( - graphYaml.getName(), - vertexFileNames2VertexInfos(graphYaml.getVertices(), conf), - edgeFileNames2EdgeInfos(graphYaml.getEdges(), conf), - graphYaml.getPrefix(), - graphYaml.getVersion()); - } - private GraphInfo( String name, List<VertexInfo> vertexInfos, List<EdgeInfo> edgeInfos, - String prefix, + URI baseUri, String version, Map<String, VertexInfo> vertexType2VertexInfo, Map<String, EdgeInfo> edgeConcat2EdgeInfo) { @@ -90,7 +82,7 @@ public class GraphInfo { name, vertexInfos, edgeInfos, - prefix, + baseUri, VersionParser.getVersion(version), vertexType2VertexInfo, edgeConcat2EdgeInfo); @@ -100,62 +92,19 @@ public class GraphInfo { String name, List<VertexInfo> vertexInfos, List<EdgeInfo> edgeInfos, - String prefix, + URI baseUri, VersionInfo version, Map<String, VertexInfo> vertexType2VertexInfo, Map<String, EdgeInfo> edgeConcat2EdgeInfo) { this.name = name; this.vertexInfos = vertexInfos; this.edgeInfos = edgeInfos; - this.prefix = prefix; + this.baseUri = baseUri; this.version = version; this.vertexType2VertexInfo = vertexType2VertexInfo; this.edgeConcat2EdgeInfo = edgeConcat2EdgeInfo; } - public static GraphInfo load(String graphPath) throws IOException { - return load(graphPath, new Configuration()); - } - - public static GraphInfo load(String graphPath, FileSystem fileSystem) throws IOException { - if (fileSystem == null) { - throw new IllegalArgumentException("FileSystem is null"); - } - return load(graphPath, fileSystem.getConf()); - } - - public static GraphInfo load(String graphPath, Configuration conf) throws IOException { - if (conf == null) { - throw new IllegalArgumentException("Configuration is null"); - } - Path path = new Path(graphPath); - FileSystem fileSystem = path.getFileSystem(conf); - FSDataInputStream inputStream = fileSystem.open(path); - Yaml graphYamlLoader = new Yaml(new Constructor(GraphYaml.class, new LoaderOptions())); - GraphYaml graphYaml = graphYamlLoader.load(inputStream); - return new GraphInfo(graphYaml, conf); - } - - public void save(String filePath) throws IOException { - save(filePath, new Configuration()); - } - - public void save(String filePath, Configuration conf) throws IOException { - if (conf == null) { - throw new IllegalArgumentException("Configuration is null"); - } - save(filePath, FileSystem.get(conf)); - } - - public void save(String fileName, FileSystem fileSystem) throws IOException { - if (fileSystem == null) { - throw new IllegalArgumentException("FileSystem is null"); - } - FSDataOutputStream outputStream = fileSystem.create(new Path(fileName)); - outputStream.writeBytes(dump()); - outputStream.close(); - } - public String dump() { Yaml yaml = new Yaml(GraphYaml.getRepresenter(), GraphYaml.getDumperOptions()); GraphYaml graphYaml = new GraphYaml(this); @@ -181,7 +130,7 @@ public class GraphInfo { name, newVertexInfos, edgeInfos, - prefix, + baseUri, version, newVertexType2VertexInfo, edgeConcat2EdgeInfo)); @@ -207,7 +156,7 @@ public class GraphInfo { name, vertexInfos, newEdgeInfos, - prefix, + baseUri, version, vertexType2VertexInfo, newEdgeConcat2EdgeInfo)); @@ -252,29 +201,15 @@ public class GraphInfo { } public String getPrefix() { - return prefix; + return baseUri.toString(); } - public VersionInfo getVersion() { - return version; + public URI getBaseUri() { + return baseUri; } - private static List<VertexInfo> vertexFileNames2VertexInfos( - List<String> vertexFileNames, Configuration conf) throws IOException { - ArrayList<VertexInfo> tempVertices = new ArrayList<>(vertexFileNames.size()); - for (String vertexFileName : vertexFileNames) { - tempVertices.add(VertexInfo.load(vertexFileName, conf)); - } - return List.copyOf(tempVertices); - } - - private static List<EdgeInfo> edgeFileNames2EdgeInfos( - List<String> edgeFileNames, Configuration conf) throws IOException { - ArrayList<EdgeInfo> tempEdges = new ArrayList<>(edgeFileNames.size()); - for (String edgeFileName : edgeFileNames) { - tempEdges.add(EdgeInfo.load(edgeFileName, conf)); - } - return List.copyOf(tempEdges); + public VersionInfo getVersion() { + return version; } private void checkVertexExist(String type) { diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/PropertyGroup.java b/maven-projects/info/src/main/java/org/apache/graphar/info/PropertyGroup.java index c00ce3f5..b1c94a69 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/PropertyGroup.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/PropertyGroup.java @@ -19,6 +19,7 @@ package org.apache.graphar.info; +import java.net.URI; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -29,16 +30,19 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.graphar.info.type.DataType; import org.apache.graphar.info.type.FileType; -import org.apache.graphar.info.yaml.PropertyGroupYaml; import org.apache.graphar.util.GeneralParams; public class PropertyGroup implements Iterable<Property> { private final List<Property> propertyList; private final Map<String, Property> propertyMap; private final FileType fileType; - private final String prefix; + private final URI baseUri; public PropertyGroup(List<Property> propertyMap, FileType fileType, String prefix) { + this(propertyMap, fileType, URI.create(prefix)); + } + + public PropertyGroup(List<Property> propertyMap, FileType fileType, URI baseUri) { this.propertyList = List.copyOf(propertyMap); this.propertyMap = propertyMap.stream() @@ -46,16 +50,7 @@ public class PropertyGroup implements Iterable<Property> { Collectors.toUnmodifiableMap( Property::getName, Function.identity())); this.fileType = fileType; - this.prefix = prefix; - } - - PropertyGroup(PropertyGroupYaml yamlParser) { - this( - yamlParser.getProperties().stream() - .map(Property::new) - .collect(Collectors.toUnmodifiableList()), - FileType.fromString(yamlParser.getFile_type()), - yamlParser.getPrefix()); + this.baseUri = baseUri; } public Optional<PropertyGroup> addPropertyAsNew(Property property) { @@ -65,7 +60,7 @@ public class PropertyGroup implements Iterable<Property> { List<Property> newPropertyMap = Stream.concat(propertyMap.values().stream(), Stream.of(property)) .collect(Collectors.toUnmodifiableList()); - return Optional.of(new PropertyGroup(newPropertyMap, fileType, prefix)); + return Optional.of(new PropertyGroup(newPropertyMap, fileType, baseUri)); } @Override @@ -97,7 +92,11 @@ public class PropertyGroup implements Iterable<Property> { } public String getPrefix() { - return prefix; + return baseUri.toString(); + } + + public URI getBaseUri() { + return baseUri; } } diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java b/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java index 45eb4f04..711315c1 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java @@ -19,27 +19,19 @@ package org.apache.graphar.info; -import java.io.IOException; +import java.net.URI; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import org.apache.graphar.info.type.DataType; import org.apache.graphar.info.yaml.GraphYaml; import org.apache.graphar.info.yaml.VertexYaml; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.FSDataInputStream; -import org.apache.hadoop.fs.FSDataOutputStream; -import org.apache.hadoop.fs.FileSystem; -import org.apache.hadoop.fs.Path; -import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; public class VertexInfo { private final String type; private final long chunkSize; private final PropertyGroups propertyGroups; - private final String prefix; + private final URI baseUri; private final VersionInfo version; public VertexInfo( @@ -48,55 +40,31 @@ public class VertexInfo { List<PropertyGroup> propertyGroups, String prefix, String version) { - this(type, chunkSize, propertyGroups, prefix, VersionParser.getVersion(version)); + this(type, chunkSize, propertyGroups, URI.create(prefix), version); } public VertexInfo( String type, long chunkSize, List<PropertyGroup> propertyGroups, - String prefix, + URI baseUri, + String version) { + this(type, chunkSize, propertyGroups, baseUri, VersionParser.getVersion(version)); + } + + public VertexInfo( + String type, + long chunkSize, + List<PropertyGroup> propertyGroups, + URI baseUri, VersionInfo version) { this.type = type; this.chunkSize = chunkSize; this.propertyGroups = new PropertyGroups(propertyGroups); - this.prefix = prefix; + this.baseUri = baseUri; this.version = version; } - private VertexInfo(VertexYaml parser) { - this( - parser.getType(), - parser.getChunk_size(), - parser.getProperty_groups().stream() - .map(PropertyGroup::new) - .collect(Collectors.toUnmodifiableList()), - parser.getPrefix(), - parser.getVersion()); - } - - public static VertexInfo load(String vertexInfoPath) throws IOException { - return load(vertexInfoPath, new Configuration()); - } - - public static VertexInfo load(String vertexInfoPath, Configuration conf) throws IOException { - if (conf == null) { - throw new IllegalArgumentException("Configuration is null"); - } - return load(vertexInfoPath, FileSystem.get(conf)); - } - - public static VertexInfo load(String vertexInfoPath, FileSystem fileSystem) throws IOException { - if (fileSystem == null) { - throw new IllegalArgumentException("FileSystem is null"); - } - FSDataInputStream inputStream = fileSystem.open(new Path(vertexInfoPath)); - Yaml vertexInfoYamlLoader = - new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); - VertexYaml vertexInfoYaml = vertexInfoYamlLoader.load(inputStream); - return new VertexInfo(vertexInfoYaml); - } - public Optional<VertexInfo> addPropertyGroupAsNew(PropertyGroup propertyGroup) { return propertyGroups .addPropertyGroupAsNew(propertyGroup) @@ -104,7 +72,7 @@ public class VertexInfo { .map( newPropertyGroups -> new VertexInfo( - type, chunkSize, newPropertyGroups, prefix, version)); + type, chunkSize, newPropertyGroups, baseUri, version)); } public int propertyGroupNum() { @@ -131,38 +99,18 @@ public class VertexInfo { return propertyGroups.hasPropertyGroup(propertyGroup); } - public String getPropertyGroupPrefix(PropertyGroup propertyGroup) { + public URI getPropertyGroupPrefix(PropertyGroup propertyGroup) { checkPropertyGroupExist(propertyGroup); - return getPrefix() + propertyGroup.getPrefix(); + return getBaseUri().resolve(propertyGroup.getBaseUri()); } - public String getPropertyGroupChunkPath(PropertyGroup propertyGroup, long chunkIndex) { + public URI getPropertyGroupChunkPath(PropertyGroup propertyGroup, long chunkIndex) { // PropertyGroup will be checked in getPropertyGroupPrefix - return getPropertyGroupPrefix(propertyGroup) + "chunk" + chunkIndex; - } - - public String getVerticesNumFilePath() { - return getPrefix() + "vertex_count"; - } - - public void save(String filePath) throws IOException { - save(filePath, new Configuration()); + return getPropertyGroupPrefix(propertyGroup).resolve("chunk" + chunkIndex); } - public void save(String filePath, Configuration conf) throws IOException { - if (conf == null) { - throw new IllegalArgumentException("Configuration is null"); - } - save(filePath, FileSystem.get(conf)); - } - - public void save(String fileName, FileSystem fileSystem) throws IOException { - if (fileSystem == null) { - throw new IllegalArgumentException("FileSystem is null"); - } - FSDataOutputStream outputStream = fileSystem.create(new Path(fileName)); - outputStream.writeBytes(dump()); - outputStream.close(); + public URI getVerticesNumFilePath() { + return getBaseUri().resolve("vertex_count"); } public String dump() { @@ -184,15 +132,15 @@ public class VertexInfo { } public String getPrefix() { - return prefix; + return baseUri.toString(); } - public VersionInfo getVersion() { - return version; + public URI getBaseUri() { + return baseUri; } - public String getVertexPath() { - return getPrefix() + getType() + ".vertex.yaml"; + public VersionInfo getVersion() { + return version; } private void checkPropertyGroupExist(PropertyGroup propertyGroup) { diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java new file mode 100644 index 00000000..77b74f8b --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.graphar.info.EdgeInfo; +import org.apache.graphar.info.GraphInfo; +import org.apache.graphar.info.VertexInfo; +import org.apache.graphar.info.yaml.AdjacentListYaml; +import org.apache.graphar.info.yaml.EdgeYaml; +import org.apache.graphar.info.yaml.GraphYaml; +import org.apache.graphar.info.yaml.PropertyGroupYaml; +import org.apache.graphar.info.yaml.VertexYaml; + +public abstract class BaseGraphInfoLoader implements GraphInfoLoader { + + public abstract GraphInfo loadGraphInfo(URI graphYamlUri) throws IOException; + + public abstract VertexInfo loadVertexInfo(URI vertexYamlUri) throws IOException; + + public abstract EdgeInfo loadEdgeInfo(URI edgeYamlUri) throws IOException; + + public GraphInfo buildGraphInfoFromGraphYaml(URI baseUri, GraphYaml graphYaml) + throws IOException { + + URI defaultBaseUri = baseUri.resolve("."); + if (graphYaml.getPrefix() != null && !graphYaml.getPrefix().isEmpty()) { + defaultBaseUri = baseUri.resolve(graphYaml.getPrefix()); + } + + // load vertices + List<VertexInfo> vertexInfos = new ArrayList<>(graphYaml.getVertices().size()); + for (String vertexYamlPath : graphYaml.getVertices()) { + URI vertexInfoUri = baseUri.resolve(vertexYamlPath); + vertexInfos.add(loadVertexInfo(vertexInfoUri)); + } + // load edges + List<EdgeInfo> edgeInfos = new ArrayList<>(graphYaml.getEdges().size()); + for (String edgeYamlPath : graphYaml.getEdges()) { + URI edgeInfoUri = baseUri.resolve(edgeYamlPath); + edgeInfos.add(loadEdgeInfo(edgeInfoUri)); + } + return new GraphInfo( + graphYaml.getName(), + vertexInfos, + edgeInfos, + defaultBaseUri, + graphYaml.getVersion()); + } + + public VertexInfo buildVertexInfoFromGraphYaml(VertexYaml vertexYaml) { + return new VertexInfo( + vertexYaml.getType(), + vertexYaml.getChunk_size(), + vertexYaml.getProperty_groups().stream() + .map(PropertyGroupYaml::toPropertyGroup) + .collect(Collectors.toList()), + vertexYaml.getPrefix(), + vertexYaml.getVersion()); + } + + public EdgeInfo buildEdgeInfoFromGraphYaml(EdgeYaml edgeYaml) { + return new EdgeInfo( + edgeYaml.getSrc_type(), + edgeYaml.getEdge_type(), + edgeYaml.getDst_type(), + edgeYaml.getChunk_size(), + edgeYaml.getSrc_chunk_size(), + edgeYaml.getDst_chunk_size(), + edgeYaml.isDirected(), + edgeYaml.getPrefix(), + edgeYaml.getVersion(), + edgeYaml.getAdj_lists().stream() + .map(AdjacentListYaml::toAdjacentList) + .collect(Collectors.toUnmodifiableList()), + edgeYaml.getProperty_groups().stream() + .map(PropertyGroupYaml::toPropertyGroup) + .collect(Collectors.toList())); + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/GraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/GraphInfoLoader.java new file mode 100644 index 00000000..0c5e6d14 --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/GraphInfoLoader.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader; + +import java.io.IOException; +import java.net.URI; +import org.apache.graphar.info.EdgeInfo; +import org.apache.graphar.info.GraphInfo; +import org.apache.graphar.info.VertexInfo; + +public interface GraphInfoLoader { + + GraphInfo loadGraphInfo(URI graphYamlUri) throws IOException; + + VertexInfo loadVertexInfo(URI vertexYamlUri) throws IOException; + + EdgeInfo loadEdgeInfo(URI edgeYamlUri) throws IOException; +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/LocalYamlGraphLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/LocalYamlGraphLoader.java deleted file mode 100644 index 936fa9ed..00000000 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/LocalYamlGraphLoader.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.graphar.info.loader; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import org.apache.graphar.info.EdgeInfo; -import org.apache.graphar.info.GraphInfo; -import org.apache.graphar.info.VertexInfo; -import org.apache.graphar.info.yaml.EdgeYaml; -import org.apache.graphar.info.yaml.GraphYaml; -import org.apache.graphar.info.yaml.VertexYaml; -import org.apache.graphar.util.PathUtil; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; - -public class LocalYamlGraphLoader implements GraphLoader { - public LocalYamlGraphLoader() {} - - @Override - public GraphInfo load(String graphYamlPath) throws IOException { - final Path path = FileSystems.getDefault().getPath(graphYamlPath); - // load graph itself - final BufferedReader reader = Files.newBufferedReader(path); - final Yaml yamlLoader = new Yaml(new Constructor(GraphYaml.class, new LoaderOptions())); - final GraphYaml graphYaml = yamlLoader.load(reader); - reader.close(); - String defaultPrefix = PathUtil.pathToDirectory(graphYamlPath); - String prefix = defaultPrefix; - if (graphYaml.getPrefix() != null && !graphYaml.getPrefix().isEmpty()) { - prefix = graphYaml.getPrefix(); - } - - // load vertices - final String ABSOLUTE_PREFIX = path.getParent().toString(); - List<VertexInfo> vertexInfos = new ArrayList<>(graphYaml.getVertices().size()); - for (String vertexYamlName : graphYaml.getVertices()) { - vertexInfos.add(loadVertex(ABSOLUTE_PREFIX + "/" + vertexYamlName)); - } - // load edges - List<EdgeInfo> edgeInfos = new ArrayList<>(graphYaml.getEdges().size()); - for (String edgeYamlName : graphYaml.getEdges()) { - edgeInfos.add(loadEdge(ABSOLUTE_PREFIX + "/" + edgeYamlName)); - } - return new GraphInfo( - graphYaml.getName(), vertexInfos, edgeInfos, prefix, graphYaml.getVersion()); - } - - private VertexInfo loadVertex(String path) throws IOException { - final Path vertexPath = FileSystems.getDefault().getPath(path); - final BufferedReader reader = Files.newBufferedReader(vertexPath); - Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); - VertexYaml vertexYaml = vertexYamlLoader.load(reader); - reader.close(); - return vertexYaml.toVertexInfo(); - } - - private EdgeInfo loadEdge(String path) throws IOException { - final Path edgePath = FileSystems.getDefault().getPath(path); - final BufferedReader reader = Files.newBufferedReader(edgePath); - Yaml edgeYamlLoader = new Yaml(new Constructor(EdgeYaml.class, new LoaderOptions())); - EdgeYaml edgeYaml = edgeYamlLoader.load(reader); - reader.close(); - return edgeYaml.toEdgeInfo(); - } -} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/ReaderGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/ReaderGraphInfoLoader.java new file mode 100644 index 00000000..f83b826b --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/ReaderGraphInfoLoader.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader; + +import java.io.IOException; +import java.io.Reader; +import java.net.URI; +import org.apache.graphar.info.EdgeInfo; +import org.apache.graphar.info.GraphInfo; +import org.apache.graphar.info.VertexInfo; +import org.apache.graphar.info.yaml.EdgeYaml; +import org.apache.graphar.info.yaml.GraphYaml; +import org.apache.graphar.info.yaml.VertexYaml; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +public abstract class ReaderGraphInfoLoader extends BaseGraphInfoLoader { + + public abstract Reader readYaml(URI uri) throws IOException; + + @Override + public GraphInfo loadGraphInfo(URI graphYamlUri) throws IOException { + Reader yaml = readYaml(graphYamlUri); + Yaml GraphYamlLoader = new Yaml(new Constructor(GraphYaml.class, new LoaderOptions())); + GraphYaml graphYaml = GraphYamlLoader.load(yaml); + return buildGraphInfoFromGraphYaml(graphYamlUri, graphYaml); + } + + @Override + public VertexInfo loadVertexInfo(URI vertexYamlUri) throws IOException { + Reader yaml = readYaml(vertexYamlUri); + Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml vertexYaml = vertexYamlLoader.load(yaml); + return buildVertexInfoFromGraphYaml(vertexYaml); + } + + @Override + public EdgeInfo loadEdgeInfo(URI edgeYamlUri) throws IOException { + Reader yaml = readYaml(edgeYamlUri); + Yaml edgeYamlLoader = new Yaml(new Constructor(EdgeYaml.class, new LoaderOptions())); + EdgeYaml edgeYaml = edgeYamlLoader.load(yaml); + return buildEdgeInfoFromGraphYaml(edgeYaml); + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/StreamGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/StreamGraphInfoLoader.java new file mode 100644 index 00000000..5292c622 --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/StreamGraphInfoLoader.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import org.apache.graphar.info.EdgeInfo; +import org.apache.graphar.info.GraphInfo; +import org.apache.graphar.info.VertexInfo; +import org.apache.graphar.info.yaml.EdgeYaml; +import org.apache.graphar.info.yaml.GraphYaml; +import org.apache.graphar.info.yaml.VertexYaml; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +public abstract class StreamGraphInfoLoader extends BaseGraphInfoLoader { + + public abstract InputStream readYaml(URI uri) throws IOException; + + @Override + public GraphInfo loadGraphInfo(URI graphYamluri) throws IOException { + // load graph itself + InputStream yaml = readYaml(graphYamluri); + Yaml GraphYamlLoader = new Yaml(new Constructor(GraphYaml.class, new LoaderOptions())); + GraphYaml graphYaml = GraphYamlLoader.load(yaml); + return buildGraphInfoFromGraphYaml(graphYamluri, graphYaml); + } + + @Override + public VertexInfo loadVertexInfo(URI vertexYamlUri) throws IOException { + InputStream yaml = readYaml(vertexYamlUri); + Yaml edgeYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml edgeYaml = edgeYamlLoader.load(yaml); + return buildVertexInfoFromGraphYaml(edgeYaml); + } + + @Override + public EdgeInfo loadEdgeInfo(URI edgeYamlUri) throws IOException { + InputStream yaml = readYaml(edgeYamlUri); + Yaml edgeYamlLoader = new Yaml(new Constructor(EdgeYaml.class, new LoaderOptions())); + EdgeYaml edgeYaml = edgeYamlLoader.load(yaml); + return buildEdgeInfoFromGraphYaml(edgeYaml); + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/StringGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/StringGraphInfoLoader.java new file mode 100644 index 00000000..cc82ab69 --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/StringGraphInfoLoader.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader; + +import java.io.IOException; +import java.net.URI; +import org.apache.graphar.info.EdgeInfo; +import org.apache.graphar.info.GraphInfo; +import org.apache.graphar.info.VertexInfo; +import org.apache.graphar.info.yaml.EdgeYaml; +import org.apache.graphar.info.yaml.GraphYaml; +import org.apache.graphar.info.yaml.VertexYaml; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +public abstract class StringGraphInfoLoader extends BaseGraphInfoLoader { + + public abstract String readYaml(URI uri) throws IOException; + + @Override + public GraphInfo loadGraphInfo(URI graphYamlUri) throws IOException { + String yaml = readYaml(graphYamlUri); + Yaml GraphYamlLoader = new Yaml(new Constructor(GraphYaml.class, new LoaderOptions())); + GraphYaml graphYaml = GraphYamlLoader.load(yaml); + return buildGraphInfoFromGraphYaml(graphYamlUri, graphYaml); + } + + @Override + public VertexInfo loadVertexInfo(URI vertexYamlUri) throws IOException { + String yaml = readYaml(vertexYamlUri); + Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml vertexYaml = vertexYamlLoader.load(yaml); + return buildVertexInfoFromGraphYaml(vertexYaml); + } + + @Override + public EdgeInfo loadEdgeInfo(URI edgeYamlUri) throws IOException { + String yaml = readYaml(edgeYamlUri); + Yaml edgeYamlLoader = new Yaml(new Constructor(EdgeYaml.class, new LoaderOptions())); + EdgeYaml edgeYaml = edgeYamlLoader.load(yaml); + return buildEdgeInfoFromGraphYaml(edgeYaml); + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemReaderGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemReaderGraphInfoLoader.java new file mode 100644 index 00000000..b1580c06 --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemReaderGraphInfoLoader.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader.impl; + +import java.io.IOException; +import java.io.Reader; +import java.net.URI; +import org.apache.graphar.info.loader.ReaderGraphInfoLoader; + +public class LocalFileSystemReaderGraphInfoLoader extends ReaderGraphInfoLoader { + @Override + public Reader readYaml(URI uri) throws IOException { + if (uri.getScheme() != null && !"file".equals(uri.getScheme())) { + throw new RuntimeException("Only file:// scheme is supported in Local File System"); + } + String path = uri.getPath(); + return java.nio.file.Files.newBufferedReader(java.nio.file.Paths.get(path)); + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemStreamGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemStreamGraphInfoLoader.java new file mode 100644 index 00000000..5a4d35ef --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemStreamGraphInfoLoader.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader.impl; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import org.apache.graphar.info.loader.StreamGraphInfoLoader; + +public class LocalFileSystemStreamGraphInfoLoader extends StreamGraphInfoLoader { + @Override + public InputStream readYaml(URI uri) throws IOException { + if (uri.getScheme() != null && !"file".equals(uri.getScheme())) { + throw new RuntimeException("Only file:// scheme is supported in Local File System"); + } + String path = uri.getPath(); + return new FileInputStream(path); + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemStringGraphInfoLoader.java b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemStringGraphInfoLoader.java new file mode 100644 index 00000000..24b3d078 --- /dev/null +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/impl/LocalFileSystemStringGraphInfoLoader.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info.loader.impl; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URI; +import org.apache.graphar.info.loader.StringGraphInfoLoader; + +public class LocalFileSystemStringGraphInfoLoader extends StringGraphInfoLoader { + @Override + public String readYaml(URI uri) throws IOException { + if (uri.getScheme() != null && !"file".equals(uri.getScheme())) { + throw new IllegalArgumentException( + "Only file:// scheme is supported in Local File System"); + } + String path = uri.getPath(); + try (FileInputStream fis = new FileInputStream(path)) { + byte[] data = new byte[fis.available()]; + fis.read(data); + return new String(data); + } + } +} diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/EdgeYaml.java b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/EdgeYaml.java index 5ef06d33..141802f0 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/EdgeYaml.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/EdgeYaml.java @@ -77,25 +77,6 @@ public class EdgeYaml { .collect(Collectors.toList()); } - public EdgeInfo toEdgeInfo() { - return new EdgeInfo( - src_type, - edge_type, - dst_type, - chunk_size, - src_chunk_size, - dst_chunk_size, - directed, - prefix, - version, - adj_lists.stream() - .map(AdjacentListYaml::toAdjacentList) - .collect(Collectors.toUnmodifiableList()), - property_groups.stream() - .map(PropertyGroupYaml::toPropertyGroup) - .collect(Collectors.toList())); - } - public String getSrc_type() { return src_type; } diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/PropertyGroupYaml.java b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/PropertyGroupYaml.java index 457d4175..72393218 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/PropertyGroupYaml.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/PropertyGroupYaml.java @@ -45,7 +45,7 @@ public class PropertyGroupYaml { this.prefix = propertyGroup.getPrefix(); } - PropertyGroup toPropertyGroup() { + public PropertyGroup toPropertyGroup() { return new PropertyGroup( properties.stream().map(PropertyYaml::toProperty).collect(Collectors.toList()), FileType.fromString(file_type), diff --git a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java index 512d8e8c..345e0369 100644 --- a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java +++ b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java @@ -56,17 +56,6 @@ public class VertexYaml { .orElse(null); } - public VertexInfo toVertexInfo() { - return new VertexInfo( - type, - chunk_size, - property_groups.stream() - .map(PropertyGroupYaml::toPropertyGroup) - .collect(Collectors.toList()), - prefix, - version); - } - public String getType() { return type; } diff --git a/maven-projects/info/src/main/java/org/apache/graphar/util/PathUtil.java b/maven-projects/info/src/main/java/org/apache/graphar/util/PathUtil.java deleted file mode 100644 index 7b68c543..00000000 --- a/maven-projects/info/src/main/java/org/apache/graphar/util/PathUtil.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.graphar.util; - -public class PathUtil { - public static String pathToDirectory(String path) { - if (path.startsWith("s3://")) { - int t = path.indexOf('?'); - if (t != -1) { - String prefix = path.substring(0, t); - String suffix = path.substring(t); - int lastSlashIdx = prefix.lastIndexOf('/'); - if (lastSlashIdx != -1) { - return prefix.substring(0, lastSlashIdx + 1) + suffix; - } - } else { - int lastSlashIdx = path.lastIndexOf('/'); - if (lastSlashIdx != -1) { - return path.substring(0, lastSlashIdx + 1); - } - return path; - } - } else { - int lastSlashIdx = path.lastIndexOf('/'); - if (lastSlashIdx != -1) { - return path.substring(0, lastSlashIdx + 1); - } - } - return path; - } -} diff --git a/maven-projects/info/src/test/java/org/apache/graphar/info/EdgeInfoTest.java b/maven-projects/info/src/test/java/org/apache/graphar/info/EdgeInfoTest.java index 10e6125b..caf25bb5 100644 --- a/maven-projects/info/src/test/java/org/apache/graphar/info/EdgeInfoTest.java +++ b/maven-projects/info/src/test/java/org/apache/graphar/info/EdgeInfoTest.java @@ -19,13 +19,14 @@ package org.apache.graphar.info; +import java.net.URI; import java.util.List; import org.junit.Assert; import org.junit.Test; public class EdgeInfoTest { - private EdgeInfo.EdgeInfoBuilder e = + private final EdgeInfo.EdgeInfoBuilder e = EdgeInfo.builder() .srcType("person") .edgeType("knows") @@ -33,9 +34,72 @@ public class EdgeInfoTest { .srcChunkSize(100) .dstChunkSize(100) .directed(false) - .prefix("edge/person_knows_person/") + .baseUri(URI.create("edge/person_knows_person/")) .version("gar/v1"); + @Test + public void testBuildWithPrefix() { + EdgeInfo edgeInfo = + EdgeInfo.builder() + .srcType("person") + .edgeType("knows") + .dstType("person") + .propertyGroups(new PropertyGroups(List.of(TestUtil.pg3))) + .adjacentLists(List.of(TestUtil.orderedBySource)) + .chunkSize(1024) + .srcChunkSize(100) + .dstChunkSize(100) + .directed(false) + .prefix("edge/person_knows_person/") + .version("gar/v1") + .build(); + Assert.assertEquals(URI.create("edge/person_knows_person/"), edgeInfo.getBaseUri()); + } + + @Test + public void testUriAndPrefixConflict() { + try { + EdgeInfo.builder() + .srcType("person") + .edgeType("knows") + .dstType("person") + .propertyGroups(new PropertyGroups(List.of(TestUtil.pg3))) + .adjacentLists(List.of(TestUtil.orderedBySource)) + .chunkSize(1024) + .srcChunkSize(100) + .dstChunkSize(100) + .directed(false) + .prefix("edge/person_knows_person/") + .baseUri(URI.create("/person_knows_person/")) + .version("gar/v1") + .build(); + } catch (IllegalArgumentException e) { + Assert.assertEquals( + "baseUri and prefix conflict: baseUri=/person_knows_person/ prefix=edge/person_knows_person/", + e.getMessage()); + } + } + + @Test + public void testMissingUriAndPrefix() { + try { + EdgeInfo.builder() + .srcType("person") + .edgeType("knows") + .dstType("person") + .propertyGroups(new PropertyGroups(List.of(TestUtil.pg3))) + .adjacentLists(List.of(TestUtil.orderedBySource)) + .chunkSize(1024) + .srcChunkSize(100) + .dstChunkSize(100) + .directed(false) + .version("gar/v1") + .build(); + } catch (IllegalArgumentException e) { + Assert.assertEquals("baseUri and prefix cannot be both null", e.getMessage()); + } + } + @Test public void erroneousTripletEdgeBuilderTest() { try { @@ -43,7 +107,7 @@ public class EdgeInfoTest { .addPropertyGroups(List.of(TestUtil.pg3)) .build(); } catch (IllegalArgumentException e) { - System.err.println(e.getMessage()); + Assert.assertEquals("Edge triplet is null", e.getMessage()); } } @@ -52,7 +116,7 @@ public class EdgeInfoTest { try { e.dstType("person").addPropertyGroups(List.of(TestUtil.pg3)).build(); } catch (IllegalArgumentException e) { - System.err.println(e.getMessage()); + Assert.assertEquals("AdjacentLists is empty", e.getMessage()); } } @@ -63,7 +127,7 @@ public class EdgeInfoTest { .dstType("person") .build(); } catch (IllegalArgumentException e) { - System.err.println(e.getMessage()); + Assert.assertEquals("PropertyGroups is empty", e.getMessage()); } } diff --git a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoLoaderTest.java b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoLoaderTest.java new file mode 100644 index 00000000..6ae1398f --- /dev/null +++ b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoLoaderTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info; + +import java.io.IOException; +import java.net.URI; +import org.apache.graphar.info.loader.GraphInfoLoader; +import org.apache.graphar.info.loader.impl.LocalFileSystemReaderGraphInfoLoader; +import org.apache.graphar.info.loader.impl.LocalFileSystemStreamGraphInfoLoader; +import org.apache.graphar.info.loader.impl.LocalFileSystemStringGraphInfoLoader; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class GraphInfoLoaderTest { + + @BeforeClass + public static void init() { + TestUtil.checkTestData(); + } + + @AfterClass + public static void clean() {} + + @Test + public void testStringLoader() { + final URI GRAPH_PATH_URI = TestUtil.getLdbcSampleGraphURI(); + GraphInfoLoader loader = new LocalFileSystemStringGraphInfoLoader(); + try { + final GraphInfo graphInfo = loader.loadGraphInfo(GRAPH_PATH_URI); + testGraphInfo(graphInfo); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + public void testStreamLoader() { + final URI GRAPH_PATH_URI = TestUtil.getLdbcSampleGraphURI(); + GraphInfoLoader loader = new LocalFileSystemStreamGraphInfoLoader(); + try { + final GraphInfo graphInfo = loader.loadGraphInfo(GRAPH_PATH_URI); + testGraphInfo(graphInfo); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + public void testReaderLoader() { + final URI GRAPH_PATH_URI = TestUtil.getLdbcSampleGraphURI(); + GraphInfoLoader loader = new LocalFileSystemReaderGraphInfoLoader(); + try { + final GraphInfo graphInfo = loader.loadGraphInfo(GRAPH_PATH_URI); + testGraphInfo(graphInfo); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void testGraphInfo(GraphInfo graphInfo) { + Assert.assertNotNull(graphInfo); + Assert.assertNotNull(graphInfo.getEdgeInfos()); + Assert.assertEquals(1, graphInfo.getEdgeInfos().size()); + for (EdgeInfo edgeInfo : graphInfo.getEdgeInfos()) { + Assert.assertNotNull(edgeInfo.getConcat()); + } + Assert.assertNotNull(graphInfo.getVertexInfos()); + Assert.assertEquals(1, graphInfo.getVertexInfos().size()); + for (VertexInfo vertexInfo : graphInfo.getVertexInfos()) { + Assert.assertNotNull(vertexInfo.getType()); + } + } +} diff --git a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java index 20cae797..afb0da71 100644 --- a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java +++ b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java @@ -20,14 +20,14 @@ package org.apache.graphar.info; import java.io.IOException; +import java.net.URI; import java.util.ArrayList; import java.util.List; -import org.apache.graphar.info.loader.GraphLoader; -import org.apache.graphar.info.loader.LocalYamlGraphLoader; +import org.apache.graphar.info.loader.GraphInfoLoader; +import org.apache.graphar.info.loader.impl.LocalFileSystemStreamGraphInfoLoader; import org.apache.graphar.info.type.AdjListType; import org.apache.graphar.info.type.DataType; import org.apache.graphar.info.type.FileType; -import org.apache.graphar.util.PathUtil; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -38,15 +38,15 @@ public class GraphInfoTest { private static GraphInfo graphInfo; private static VertexInfo personVertexInfo; private static EdgeInfo knowsEdgeInfo; - private static String GRAPH_PATH; + private static URI GRAPH_PATH_URI; @BeforeClass public static void setUp() { TestUtil.checkTestData(); - GRAPH_PATH = TestUtil.getLdbcSampleGraphPath(); - final GraphLoader graphLoader = new LocalYamlGraphLoader(); + GRAPH_PATH_URI = TestUtil.getLdbcSampleGraphURI(); + GraphInfoLoader loader = new LocalFileSystemStreamGraphInfoLoader(); try { - graphInfo = graphLoader.load(GRAPH_PATH); + graphInfo = loader.loadGraphInfo(GRAPH_PATH_URI); } catch (IOException e) { throw new RuntimeException(e); } @@ -57,11 +57,22 @@ public class GraphInfoTest { @AfterClass public static void clean() {} + @Test + public void test() { + System.out.println( + graphInfo + .getBaseUri() + .resolve( + knowsEdgeInfo.getAdjacentListPrefix( + AdjListType.ordered_by_source))); + } + @Test public void testGraphInfoBasics() { Assert.assertNotNull(graphInfo); Assert.assertEquals("ldbc_sample", graphInfo.getName()); - Assert.assertEquals(PathUtil.pathToDirectory(GRAPH_PATH), graphInfo.getPrefix()); + Assert.assertEquals(GRAPH_PATH_URI.resolve(".").toString(), graphInfo.getPrefix()); + Assert.assertEquals(GRAPH_PATH_URI.resolve("."), graphInfo.getBaseUri()); Assert.assertNotNull(graphInfo.getEdgeInfos()); Assert.assertEquals(1, graphInfo.getEdgeInfos().size()); Assert.assertNotNull(graphInfo.getVertexInfos()); @@ -76,9 +87,7 @@ public class GraphInfoTest { Assert.assertEquals("person", personVertexInfo.getType()); Assert.assertEquals(100, personVertexInfo.getChunkSize()); Assert.assertEquals("vertex/person/", personVertexInfo.getPrefix()); - Assert.assertEquals( - "vertex/person/vertex_count", personVertexInfo.getVerticesNumFilePath()); - Assert.assertEquals("vertex/person/person.vertex.yaml", personVertexInfo.getVertexPath()); + Assert.assertEquals(URI.create("vertex/person/"), personVertexInfo.getBaseUri()); Assert.assertNotNull(personVertexInfo.getPropertyGroups()); Assert.assertEquals(2, personVertexInfo.getPropertyGroups().size()); Assert.assertEquals(1, personVertexInfo.getVersion().getVersion()); @@ -89,14 +98,16 @@ public class GraphInfoTest { // group1 id PropertyGroup idPropertyGroup = personVertexInfo.getPropertyGroups().get(0); Assert.assertEquals("id/", idPropertyGroup.getPrefix()); + Assert.assertEquals(URI.create("id/"), idPropertyGroup.getBaseUri()); Assert.assertEquals(FileType.CSV, idPropertyGroup.getFileType()); Assert.assertEquals( - "vertex/person/id/", personVertexInfo.getPropertyGroupPrefix(idPropertyGroup)); + URI.create("vertex/person/id/"), + personVertexInfo.getPropertyGroupPrefix(idPropertyGroup)); Assert.assertEquals( - "vertex/person/id/chunk0", + URI.create("vertex/person/id/chunk0"), personVertexInfo.getPropertyGroupChunkPath(idPropertyGroup, 0)); Assert.assertEquals( - "vertex/person/id/chunk4", + URI.create("vertex/person/id/chunk4"), personVertexInfo.getPropertyGroupChunkPath(idPropertyGroup, 4)); Assert.assertNotNull(idPropertyGroup.getPropertyList()); Assert.assertEquals(1, idPropertyGroup.getPropertyList().size()); @@ -109,15 +120,17 @@ public class GraphInfoTest { // group2 firstName_lastName_gender PropertyGroup firstName_lastName_gender = personVertexInfo.getPropertyGroups().get(1); Assert.assertEquals("firstName_lastName_gender/", firstName_lastName_gender.getPrefix()); + Assert.assertEquals( + URI.create("firstName_lastName_gender/"), firstName_lastName_gender.getBaseUri()); Assert.assertEquals(FileType.CSV, firstName_lastName_gender.getFileType()); Assert.assertEquals( - "vertex/person/firstName_lastName_gender/", + URI.create("vertex/person/firstName_lastName_gender/"), personVertexInfo.getPropertyGroupPrefix(firstName_lastName_gender)); Assert.assertEquals( - "vertex/person/firstName_lastName_gender/chunk0", + URI.create("vertex/person/firstName_lastName_gender/chunk0"), personVertexInfo.getPropertyGroupChunkPath(firstName_lastName_gender, 0)); Assert.assertEquals( - "vertex/person/firstName_lastName_gender/chunk4", + URI.create("vertex/person/firstName_lastName_gender/chunk4"), personVertexInfo.getPropertyGroupChunkPath(firstName_lastName_gender, 4)); Assert.assertNotNull(firstName_lastName_gender.getPropertyList()); Assert.assertEquals(3, firstName_lastName_gender.getPropertyList().size()); @@ -152,9 +165,7 @@ public class GraphInfoTest { Assert.assertFalse(knowsEdgeInfo.isDirected()); Assert.assertEquals("person_knows_person", knowsEdgeInfo.getConcat()); Assert.assertEquals("edge/person_knows_person/", knowsEdgeInfo.getPrefix()); - Assert.assertEquals( - "edge/person_knows_person/person_knows_person.edge.yaml", - knowsEdgeInfo.getEdgePath()); + Assert.assertEquals(URI.create("edge/person_knows_person/"), knowsEdgeInfo.getBaseUri()); Assert.assertEquals(1, knowsEdgeInfo.getVersion().getVersion()); } @@ -167,32 +178,33 @@ public class GraphInfoTest { Assert.assertEquals(FileType.CSV, adjOrderBySource.getFileType()); Assert.assertEquals(AdjListType.ordered_by_source, adjOrderBySource.getType()); Assert.assertEquals("ordered_by_source/", adjOrderBySource.getPrefix()); + Assert.assertEquals(URI.create("ordered_by_source/"), adjOrderBySource.getBaseUri()); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/vertex_count", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/vertex_count"), knowsEdgeInfo.getVerticesNumFilePath(AdjListType.ordered_by_source)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/edge_count0", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/edge_count0"), knowsEdgeInfo.getEdgesNumFilePath(AdjListType.ordered_by_source, 0)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/edge_count4", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/edge_count4"), knowsEdgeInfo.getEdgesNumFilePath(AdjListType.ordered_by_source, 4)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/"), knowsEdgeInfo.getAdjacentListPrefix(AdjListType.ordered_by_source)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/chunk0", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/chunk0"), knowsEdgeInfo.getAdjacentListChunkPath(AdjListType.ordered_by_source, 0)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/chunk4", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/chunk4"), knowsEdgeInfo.getAdjacentListChunkPath(AdjListType.ordered_by_source, 4)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/offset/", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/offset/"), knowsEdgeInfo.getOffsetPrefix(AdjListType.ordered_by_source)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/offset/chunk0", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/offset/chunk0"), knowsEdgeInfo.getOffsetChunkPath(AdjListType.ordered_by_source, 0)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_source/adj_list/offset/chunk4", + URI.create("edge/person_knows_person/ordered_by_source/adj_list/offset/chunk4"), knowsEdgeInfo.getOffsetChunkPath(AdjListType.ordered_by_source, 4)); // test ordered by destination adjacency list @@ -201,32 +213,33 @@ public class GraphInfoTest { Assert.assertEquals(FileType.CSV, adjOrderByDestination.getFileType()); Assert.assertEquals(AdjListType.ordered_by_dest, adjOrderByDestination.getType()); Assert.assertEquals("ordered_by_dest/", adjOrderByDestination.getPrefix()); + Assert.assertEquals(URI.create("ordered_by_dest/"), adjOrderByDestination.getBaseUri()); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/vertex_count", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/vertex_count"), knowsEdgeInfo.getVerticesNumFilePath(AdjListType.ordered_by_dest)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/edge_count0", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/edge_count0"), knowsEdgeInfo.getEdgesNumFilePath(AdjListType.ordered_by_dest, 0)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/edge_count4", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/edge_count4"), knowsEdgeInfo.getEdgesNumFilePath(AdjListType.ordered_by_dest, 4)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/"), knowsEdgeInfo.getAdjacentListPrefix(AdjListType.ordered_by_dest)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/chunk0", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/chunk0"), knowsEdgeInfo.getAdjacentListChunkPath(AdjListType.ordered_by_dest, 0)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/chunk4", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/chunk4"), knowsEdgeInfo.getAdjacentListChunkPath(AdjListType.ordered_by_dest, 4)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/offset/", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/offset/"), knowsEdgeInfo.getOffsetPrefix(AdjListType.ordered_by_dest)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/offset/chunk0", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/offset/chunk0"), knowsEdgeInfo.getOffsetChunkPath(AdjListType.ordered_by_dest, 0)); Assert.assertEquals( - "edge/person_knows_person/ordered_by_dest/adj_list/offset/chunk4", + URI.create("edge/person_knows_person/ordered_by_dest/adj_list/offset/chunk4"), knowsEdgeInfo.getOffsetChunkPath(AdjListType.ordered_by_dest, 4)); } @@ -236,15 +249,16 @@ public class GraphInfoTest { // edge properties group 1 PropertyGroup propertyGroup = knowsEdgeInfo.getPropertyGroups().get(0); Assert.assertEquals("creationDate/", propertyGroup.getPrefix()); + Assert.assertEquals(URI.create("creationDate/"), propertyGroup.getBaseUri()); Assert.assertEquals(FileType.CSV, propertyGroup.getFileType()); Assert.assertEquals( - "edge/person_knows_person/creationDate/", + URI.create("edge/person_knows_person/creationDate/"), knowsEdgeInfo.getPropertyGroupPrefix(propertyGroup)); Assert.assertEquals( - "edge/person_knows_person/creationDate/chunk0", + URI.create("edge/person_knows_person/creationDate/chunk0"), knowsEdgeInfo.getPropertyGroupChunkPath(propertyGroup, 0)); Assert.assertEquals( - "edge/person_knows_person/creationDate/chunk4", + URI.create("edge/person_knows_person/creationDate/chunk4"), knowsEdgeInfo.getPropertyGroupChunkPath(propertyGroup, 4)); // edge properties in group 1 Assert.assertNotNull(propertyGroup.getPropertyList()); diff --git a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoUriTest.java b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoUriTest.java new file mode 100644 index 00000000..dc3cc83b --- /dev/null +++ b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoUriTest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.graphar.info; + +import java.net.URI; +import org.apache.graphar.info.loader.BaseGraphInfoLoader; +import org.apache.graphar.info.loader.impl.LocalFileSystemStringGraphInfoLoader; +import org.apache.graphar.info.yaml.VertexYaml; +import org.junit.Assert; +import org.junit.Test; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +public class GraphInfoUriTest { + + @Test + public void testBaseGraphInfo() { + Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml vertexYaml = vertexYamlLoader.load(TestUtil.getBaseGraphInfoYaml()); + BaseGraphInfoLoader baseGraphInfoLoader = new LocalFileSystemStringGraphInfoLoader(); + VertexInfo vertexInfo = baseGraphInfoLoader.buildVertexInfoFromGraphYaml(vertexYaml); + Assert.assertEquals(URI.create("vertex/person/"), vertexInfo.getBaseUri()); + // absolute paths + Assert.assertEquals( + URI.create("vertex/person/id/"), + vertexInfo.getPropertyGroupPrefix(vertexInfo.getPropertyGroups().get(0))); + // relative paths + Assert.assertEquals( + URI.create("/tmp/vertex/person/firstName_lastName_gender/chunk0"), + vertexInfo.getPropertyGroupChunkPath(vertexInfo.getPropertyGroups().get(1), 0)); + } + + @Test + public void testS3GraphInfo() { + Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml vertexYaml = vertexYamlLoader.load(TestUtil.getS3GraphInfoYaml()); + BaseGraphInfoLoader baseGraphInfoLoader = new LocalFileSystemStringGraphInfoLoader(); + VertexInfo vertexInfo = baseGraphInfoLoader.buildVertexInfoFromGraphYaml(vertexYaml); + Assert.assertEquals(URI.create("s3://graphar/vertex/person/"), vertexInfo.getBaseUri()); + // absolute paths + Assert.assertEquals( + URI.create("s3://graphar/vertex/person/id/"), + vertexInfo.getPropertyGroupPrefix(vertexInfo.getPropertyGroups().get(0))); + // relative paths + Assert.assertEquals( + URI.create("s3://tmp/vertex/person/firstName_lastName_gender/chunk0"), + vertexInfo.getPropertyGroupChunkPath(vertexInfo.getPropertyGroups().get(1), 0)); + } + + @Test + public void testHdfsGraphInfo() { + Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml vertexYaml = vertexYamlLoader.load(TestUtil.getHdfsGraphInfoYaml()); + BaseGraphInfoLoader baseGraphInfoLoader = new LocalFileSystemStringGraphInfoLoader(); + VertexInfo vertexInfo = baseGraphInfoLoader.buildVertexInfoFromGraphYaml(vertexYaml); + Assert.assertEquals(URI.create("hdfs://graphar/vertex/person/"), vertexInfo.getBaseUri()); + // absolute paths + Assert.assertEquals( + URI.create("hdfs://graphar/vertex/person/id/"), + vertexInfo.getPropertyGroupPrefix(vertexInfo.getPropertyGroups().get(0))); + // relative paths + Assert.assertEquals( + URI.create("hdfs://tmp/vertex/person/firstName_lastName_gender/chunk0"), + vertexInfo.getPropertyGroupChunkPath(vertexInfo.getPropertyGroups().get(1), 0)); + } + + @Test + public void testFileGraphInfo() { + Yaml vertexYamlLoader = new Yaml(new Constructor(VertexYaml.class, new LoaderOptions())); + VertexYaml vertexYaml = vertexYamlLoader.load(TestUtil.getFileGraphInfoYaml()); + BaseGraphInfoLoader baseGraphInfoLoader = new LocalFileSystemStringGraphInfoLoader(); + VertexInfo vertexInfo = baseGraphInfoLoader.buildVertexInfoFromGraphYaml(vertexYaml); + Assert.assertEquals(URI.create("file:///graphar/vertex/person/"), vertexInfo.getBaseUri()); + // absolute paths + Assert.assertEquals( + URI.create("file:///graphar/vertex/person/id/"), + vertexInfo.getPropertyGroupPrefix(vertexInfo.getPropertyGroups().get(0))); + // relative paths + Assert.assertEquals( + URI.create("file:///tmp/vertex/person/firstName_lastName_gender/chunk0"), + vertexInfo.getPropertyGroupChunkPath(vertexInfo.getPropertyGroups().get(1), 0)); + } +} diff --git a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphLoaderTest.java b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphLoaderTest.java deleted file mode 100644 index 00272042..00000000 --- a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphLoaderTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.graphar.info; - -import java.io.IOException; -import org.apache.graphar.info.loader.GraphLoader; -import org.apache.graphar.info.loader.LocalYamlGraphLoader; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -public class GraphLoaderTest { - - @BeforeClass - public static void init() { - TestUtil.checkTestData(); - } - - @AfterClass - public static void clean() {} - - @Test - public void testLoad() { - final GraphLoader graphLoader = new LocalYamlGraphLoader(); - final String GRAPH_PATH = TestUtil.getLdbcSampleGraphPath(); - try { - final GraphInfo graphInfo = graphLoader.load(GRAPH_PATH); - Assert.assertNotNull(graphInfo); - Assert.assertNotNull(graphInfo.getEdgeInfos()); - Assert.assertEquals(1, graphInfo.getEdgeInfos().size()); - for (EdgeInfo edgeInfo : graphInfo.getEdgeInfos()) { - Assert.assertNotNull(edgeInfo.getConcat()); - } - Assert.assertNotNull(graphInfo.getVertexInfos()); - Assert.assertEquals(1, graphInfo.getVertexInfos().size()); - for (VertexInfo vertexInfo : graphInfo.getVertexInfos()) { - Assert.assertNotNull(vertexInfo.getType()); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/maven-projects/info/src/test/java/org/apache/graphar/info/TestUtil.java b/maven-projects/info/src/test/java/org/apache/graphar/info/TestUtil.java index ab56dc1c..c8c84900 100644 --- a/maven-projects/info/src/test/java/org/apache/graphar/info/TestUtil.java +++ b/maven-projects/info/src/test/java/org/apache/graphar/info/TestUtil.java @@ -19,6 +19,7 @@ package org.apache.graphar.info; +import java.net.URI; import java.util.List; import org.apache.graphar.info.type.AdjListType; import org.apache.graphar.info.type.DataType; @@ -40,6 +41,10 @@ public class TestUtil { return getTestData() + "/" + LDBC_SAMPLE_GRAPH_PATH; } + public static URI getLdbcSampleGraphURI() { + return URI.create(getLdbcSampleGraphPath()); + } + public static final AdjacentList orderedBySource = new AdjacentList(AdjListType.ordered_by_source, FileType.CSV, "ordered_by_source/"); public static final AdjacentList orderedByDest = @@ -123,7 +128,7 @@ public class TestUtil { .srcChunkSize(100) .dstChunkSize(100) .directed(false) - .prefix("edge/person_knows_person/") + .baseUri(URI.create("edge/person_knows_person/")) .version("gar/v1") .adjacentLists(List.of(orderedBySource, orderedByDest)) .addPropertyGroups(List.of(pg3)) @@ -145,4 +150,116 @@ public class TestUtil { } Assume.assumeTrue("GAR_TEST_DATA is not set", GAR_TEST_DATA != null); } + + public static String getBaseGraphInfoYaml() { + return "type: person\n" + + "chunk_size: 100\n" + + "prefix: vertex/person/\n" + + "property_groups:\n" + + " - properties:\n" + + " - name: id\n" + + " data_type: int64\n" + + " is_primary: true\n" + + " is_nullable: false\n" + + " prefix: id/\n" + + " file_type: csv\n" + + " - properties:\n" + + " - name: firstName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: lastName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: gender\n" + + " data_type: string\n" + + " is_primary: false\n" + + " is_nullable: true\n" + + " prefix: /tmp/vertex/person/firstName_lastName_gender/\n" + + " file_type: csv\n" + + "version: gar/v1\n"; + } + + public static String getS3GraphInfoYaml() { + return "type: person\n" + + "chunk_size: 100\n" + + "prefix: s3://graphar/vertex/person/\n" + + "property_groups:\n" + + " - properties:\n" + + " - name: id\n" + + " data_type: int64\n" + + " is_primary: true\n" + + " is_nullable: false\n" + + " prefix: id/\n" + + " file_type: csv\n" + + " - properties:\n" + + " - name: firstName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: lastName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: gender\n" + + " data_type: string\n" + + " is_primary: false\n" + + " is_nullable: true\n" + + " prefix: s3://tmp/vertex/person/firstName_lastName_gender/\n" + + " file_type: csv\n" + + "version: gar/v1\n"; + } + + public static String getHdfsGraphInfoYaml() { + return "type: person\n" + + "chunk_size: 100\n" + + "prefix: hdfs://graphar/vertex/person/\n" + + "property_groups:\n" + + " - properties:\n" + + " - name: id\n" + + " data_type: int64\n" + + " is_primary: true\n" + + " is_nullable: false\n" + + " prefix: id/\n" + + " file_type: csv\n" + + " - properties:\n" + + " - name: firstName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: lastName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: gender\n" + + " data_type: string\n" + + " is_primary: false\n" + + " is_nullable: true\n" + + " prefix: hdfs://tmp/vertex/person/firstName_lastName_gender/\n" + + " file_type: csv\n" + + "version: gar/v1\n"; + } + + public static String getFileGraphInfoYaml() { + return "type: person\n" + + "chunk_size: 100\n" + + "prefix: file:///graphar/vertex/person/\n" + + "property_groups:\n" + + " - properties:\n" + + " - name: id\n" + + " data_type: int64\n" + + " is_primary: true\n" + + " is_nullable: false\n" + + " prefix: id/\n" + + " file_type: csv\n" + + " - properties:\n" + + " - name: firstName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: lastName\n" + + " data_type: string\n" + + " is_primary: false\n" + + " - name: gender\n" + + " data_type: string\n" + + " is_primary: false\n" + + " is_nullable: true\n" + + " prefix: file:///tmp/vertex/person/firstName_lastName_gender/\n" + + " file_type: csv\n" + + "version: gar/v1\n"; + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@graphar.apache.org For additional commands, e-mail: commits-h...@graphar.apache.org