Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<version>3.14.0</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
Expand All @@ -146,6 +146,8 @@
<!-- Silence warning "No processor claimed any of these annotations". One of the
annotations that would trigger it is org.junit.jupiter.api.Test -->
<arg>-Xlint:-processing</arg>
<!-- Silence warnning "source value 8 is obsolete and will be removed in a future release" -->
<arg>-Xlint:-options</arg>
</compilerArgs>
</configuration>
</plugin>
Expand Down
5 changes: 5 additions & 0 deletions scheme/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>tech.ydb.test</groupId>
<artifactId>ydb-junit4-support</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@
*/
public class DescribePathResult {
private final SchemeOperationProtos.Entry self;
private final Entry entry;

protected DescribePathResult(SchemeOperationProtos.Entry self) {
this.self = self;
this.entry = new Entry(self);
}

public DescribePathResult(SchemeOperationProtos.DescribePathResult result) {
this(result.getSelf());
}

@Deprecated
public SchemeOperationProtos.Entry getSelf() {
return self;
}

public Entry getEntry() {
return this.entry;
}
}
85 changes: 85 additions & 0 deletions scheme/src/main/java/tech/ydb/scheme/description/Entry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package tech.ydb.scheme.description;

import java.util.Objects;

import tech.ydb.proto.scheme.SchemeOperationProtos;

/**
*
* @author Aleksandr Gorshenin
*/
public class Entry {
private final String name;
private final String owner;
private final EntryType type;
private final long sizeBytes;

public Entry(SchemeOperationProtos.Entry pb) {
this.name = pb.getName();
this.owner = pb.getOwner();
this.type = EntryType.fromCode(pb.getTypeValue());
this.sizeBytes = pb.getSizeBytes();
}

/**
* @return Name of scheme entry (dir2 of /dir1/dir2)
*/
public String getName() {
return this.name;
}

/**
* @return SID (Security ID) of user or group
*/
public String getOwner() {
return this.owner;
}

/**
* Size of entry in bytes. Currently filled for:
* <ul>
* <li> TABLE </li>
* <li> DATABASE </li>
* </ul>
* Empty (zero) in other cases.
*
* @return Size of entry in bytes
*/
public long getSizeBytes() {
return this.sizeBytes;
}

public EntryType getType() {
return this.type;
}

@Override
public int hashCode() {
return Objects.hash(name, owner, type, sizeBytes);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || obj.getClass() != Entry.class) {
return false;
}
Entry o = (Entry) obj;
return Objects.equals(name, o.name)
&& Objects.equals(owner, o.owner)
&& type == o.type
&& sizeBytes == o.sizeBytes;
}

@Override
public String toString() {
return "Entry{name='" + name + "'"
+ (owner == null || owner.isEmpty() ? "" : ", owner='" + owner + "'")
+ ", type=" + type
+ (sizeBytes == 0 ? "" : ", size=" + Long.toUnsignedString(sizeBytes))
+ "}";
}
}

44 changes: 44 additions & 0 deletions scheme/src/main/java/tech/ydb/scheme/description/EntryType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package tech.ydb.scheme.description;

/**
*
* @author Aleksandr Gorshenin
*/
public enum EntryType {
UNSPECIFIED(0),

DIRECTORY(1),
TABLE(2),
PERS_QUEUE_GROUP(3),
DATABASE(4),
RTMR_VOLUME(5),
BLOCK_STORE_VOLUME(6),
COORDINATION_NODE(7),
COLUMN_STORE(12),
COLUMN_TABLE(13),
SEQUENCE(15),
REPLICATION(16),
TOPIC(17),
EXTERNAL_TABLE(18),
EXTERNAL_DATA_SOURCE(19),
VIEW(20);

private final int code;

EntryType(int code) {
this.code = code;
}

public int getCode() {
return code;
}

public static EntryType fromCode(int code) {
for (EntryType type: EntryType.values()) {
if (code == type.code) {
return type;
}
}
return UNSPECIFIED;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tech.ydb.scheme.description;

import java.util.List;
import java.util.stream.Collectors;

import tech.ydb.proto.scheme.SchemeOperationProtos;

Expand All @@ -10,13 +11,20 @@
public class ListDirectoryResult extends DescribePathResult {

private final List<SchemeOperationProtos.Entry> children;
private final List<Entry> entryChildren;

public ListDirectoryResult(SchemeOperationProtos.ListDirectoryResult result) {
super(result.getSelf());
this.children = result.getChildrenList();
this.entryChildren = result.getChildrenList().stream().map(Entry::new).collect(Collectors.toList());
}

@Deprecated
public List<SchemeOperationProtos.Entry> getChildren() {
return children;
}

public List<Entry> getEntryChildren() {
return entryChildren;
}
}
117 changes: 117 additions & 0 deletions scheme/src/test/java/tech/ydb/scheme/BaseIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package tech.ydb.scheme;

import java.util.Optional;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;

import tech.ydb.core.Result;
import tech.ydb.core.Status;
import tech.ydb.core.StatusCode;
import tech.ydb.scheme.description.DescribePathResult;
import tech.ydb.scheme.description.Entry;
import tech.ydb.scheme.description.EntryType;
import tech.ydb.scheme.description.ListDirectoryResult;
import tech.ydb.test.junit4.GrpcTransportRule;

/**
*
* @author Aleksandr Gorshenin
*/
public class BaseIntegrationTest {
@ClassRule
public final static GrpcTransportRule transport = new GrpcTransportRule();

private final static SchemeClient client = SchemeClient.newClient(transport).build();

@AfterClass
public static void close() {
client.close();
}

@Test
public void rootPathTest() {
Result<DescribePathResult> describeRoot = client.describePath("/").join();
Assert.assertTrue(describeRoot.isSuccess());
DescribePathResult root = describeRoot.getValue();
Assert.assertEquals("/", root.getEntry().getName());
Assert.assertEquals("", root.getEntry().getOwner());

Result<ListDirectoryResult> listRoot = client.listDirectory("/").join();
Assert.assertTrue(listRoot.isSuccess());
ListDirectoryResult listResult = listRoot.getValue();
Assert.assertEquals("/", listResult.getEntry().getName());
Assert.assertEquals("", listResult.getEntry().getOwner());
Assert.assertEquals("/", listResult.getEntry().getName());
Assert.assertEquals(0l, listResult.getEntry().getSizeBytes());
Assert.assertEquals(EntryType.DIRECTORY, listResult.getEntry().getType());
Assert.assertEquals("Entry{name='/', type=DIRECTORY}", listResult.getEntry().toString());


Assert.assertEquals(1, listResult.getEntryChildren().size());
listResult.getEntryChildren().get(0);
Entry firstChild = listResult.getEntryChildren().get(0);
Assert.assertTrue(transport.getDatabase().startsWith("/" + firstChild.getName()));
Assert.assertEquals(EntryType.DIRECTORY, firstChild.getType());
}

@Test
public void invalidPathTest() {
Result<DescribePathResult> describeInvalid = client.describePath("/invalid-path").join();
Assert.assertFalse(describeInvalid.isSuccess());
Assert.assertEquals(StatusCode.SCHEME_ERROR, describeInvalid.getStatus().getCode());
Assert.assertEquals(
"Status{code = SCHEME_ERROR(code=400070), issues = [Root not found (S_ERROR)]}",
describeInvalid.getStatus().toString()
);

Result<ListDirectoryResult> listInvalid = client.listDirectory("/invalid-path").join();
Assert.assertFalse(listInvalid.isSuccess());
Assert.assertEquals(StatusCode.SCHEME_ERROR, listInvalid.getStatus().getCode());
Assert.assertEquals(
"Status{code = SCHEME_ERROR(code=400070), issues = [Root not found (S_ERROR)]}",
listInvalid.getStatus().toString()
);

Status makeDirectory= client.makeDirectory("/invalid-path").join();
Assert.assertFalse(makeDirectory.isSuccess());
Assert.assertEquals(StatusCode.BAD_REQUEST, makeDirectory.getCode());

Status removeDirectory= client.removeDirectory("/invalid-path").join();
Assert.assertFalse(removeDirectory.isSuccess());
Assert.assertEquals(StatusCode.SCHEME_ERROR, removeDirectory.getCode());
Assert.assertEquals(
"Status{code = SCHEME_ERROR(code=400070), issues = [#200200 Path does not exist (S_ERROR)]}",
removeDirectory.toString()
);
}

@Test
public void createAndDeleteTest() {
String basePath = transport.getDatabase();
String dirName = "test_dir";

Status dirCreate1 = client.makeDirectory(basePath + "/" + dirName).join();
Assert.assertTrue(dirCreate1.isSuccess());

// Directory creating is idempotent
Status dirCreate2 = client.makeDirectory(basePath + "/" + dirName).join();
Assert.assertTrue(dirCreate2.isSuccess());

Result<DescribePathResult> dirEntry = client.describePath(basePath + "/" + dirName).join();
Assert.assertTrue(dirEntry.isSuccess());
Assert.assertEquals(dirName, dirEntry.getValue().getEntry().getName());

Result<ListDirectoryResult> rootList = client.listDirectory(basePath).join();
Assert.assertTrue(rootList.isSuccess());
Optional<Entry> child = rootList.getValue().getEntryChildren().stream()
.filter(e -> dirName.equals(e.getName())).findFirst();
Assert.assertTrue(child.isPresent());
Assert.assertEquals(child.get(), dirEntry.getValue().getEntry());

Status dirDelete = client.removeDirectory(basePath + "/" + dirName).join();
Assert.assertTrue(dirDelete.isSuccess());
}
}
26 changes: 26 additions & 0 deletions scheme/src/test/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%level] %d{HH:mm:ss.SSS} [%t] %logger{36} - %msg%n"/>
</Console>
</Appenders>

<Loggers>
<Logger name="io.grpc" level="warn" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="tech.ydb.core.grpc" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>

<!-- https://www.testcontainers.org/supported_docker_environment/logging_config/ -->
<Logger name="org.testcontainers" level="warn" />
<Logger name="com.github.dockerjava" level="warn"/>
<Logger name="com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.wire" level="off"/>

<Root level="debug" >
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Loading