Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
28 changes: 28 additions & 0 deletions src/main/java/com/dtsx/astra/cli/core/models/DbRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.*;

import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Function;

Expand All @@ -15,10 +16,17 @@
@EqualsAndHashCode
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class DbRef implements Highlightable {
private static final int UUID_LENGTH = 36;

private final Either<UUID, String> ref;

public static Either<String, DbRef> parse(@NonNull String ref) {
return ModelUtils.trimAndValidateBasics("Database name/id", ref).flatMap((trimmed) -> {
val maybeIdFromEndpoint = tryParseEndpointUrl(trimmed);
if (maybeIdFromEndpoint.isPresent()) {
return Either.pure(new DbRef(Either.left(maybeIdFromEndpoint.get())));
}

try {
return Either.pure(new DbRef(Either.left(UUID.fromString(trimmed))));
} catch (IllegalArgumentException e) {
Expand All @@ -27,6 +35,26 @@ public static Either<String, DbRef> parse(@NonNull String ref) {
});
}

private static Optional<UUID> tryParseEndpointUrl(String input) {
if (!input.startsWith("https://") && !input.startsWith("http://")) {
return Optional.empty();
}

val hostStart = input.indexOf("://") + 3;
val afterScheme = input.substring(hostStart);
val host = afterScheme.contains("/") ? afterScheme.substring(0, afterScheme.indexOf('/')) : afterScheme;

if (host.length() <= UUID_LENGTH || host.charAt(UUID_LENGTH) != '-') {
return Optional.empty();
}

try {
return Optional.of(UUID.fromString(host.substring(0, UUID_LENGTH)));
} catch (IllegalArgumentException e) {
return Optional.empty();
}
}

public static DbRef fromNameUnsafe(@NonNull String name) {
return new DbRef(Either.pure(name));
}
Expand Down
88 changes: 88 additions & 0 deletions src/test/java/com/dtsx/astra/cli/unit/core/models/DbRefTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.dtsx.astra.cli.unit.core.models;

import com.dtsx.astra.cli.core.models.DbRef;
import com.dtsx.astra.cli.unit.BaseParseableTest;
import lombok.val;
import net.jqwik.api.Example;
import net.jqwik.api.Group;

import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

public class DbRefTest extends BaseParseableTest.WithTrimAndBasicValidation {
private static final UUID SAMPLE_ID = UUID.fromString("822b0fff-6a73-4322-a8ec-09832b075287");

public DbRefTest() {
super("Database name/id", DbRef::parse);
}

@Group
public class from_name {
@Example
public void parses_plain_name_as_name_ref() {
val result = DbRef.parse("my-database");
assertThat(result.getRight().isName()).isTrue();
assertThat(result.getRight().toString()).isEqualTo("my-database");
}
}

@Group
public class from_uuid {
@Example
public void parses_uuid_as_id_ref() {
val result = DbRef.parse(SAMPLE_ID.toString());
assertThat(result.getRight().isId()).isTrue();
assertThat(result.getRight().toString()).isEqualTo(SAMPLE_ID.toString());
}
}

@Group
public class from_endpoint_url {
@Example
public void parses_prod_api_endpoint() {
val url = "https://" + SAMPLE_ID + "-us-east1.apps.astra.datastax.com";
val result = DbRef.parse(url);
assertThat(result.getRight().isId()).isTrue();
assertThat(result.getRight().toString()).isEqualTo(SAMPLE_ID.toString());
}

@Example
public void parses_dev_api_endpoint() {
val url = "https://" + SAMPLE_ID + "-ap-south-1.apps.astra-dev.datastax.com";
val result = DbRef.parse(url);
assertThat(result.getRight().isId()).isTrue();
assertThat(result.getRight().toString()).isEqualTo(SAMPLE_ID.toString());
}

@Example
public void parses_endpoint_with_path() {
val url = "https://" + SAMPLE_ID + "-us-east1.apps.astra.datastax.com/api/json/v1";
val result = DbRef.parse(url);
assertThat(result.getRight().isId()).isTrue();
assertThat(result.getRight().toString()).isEqualTo(SAMPLE_ID.toString());
}

@Example
public void parses_swagger_endpoint() {
val url = "https://" + SAMPLE_ID + "-ap-south-1.apps.astra-dev.datastax.com/api/json/swagger-ui";
val result = DbRef.parse(url);
assertThat(result.getRight().isId()).isTrue();
assertThat(result.getRight().toString()).isEqualTo(SAMPLE_ID.toString());
}

@Example
public void falls_back_to_name_for_non_astra_url() {
val url = "https://some-other-host.example.com/path";
val result = DbRef.parse(url);
assertThat(result.getRight().isName()).isTrue();
}

@Example
public void falls_back_to_name_when_url_has_no_uuid_prefix() {
val url = "https://not-a-uuid-at-all.apps.astra.datastax.com";
val result = DbRef.parse(url);
assertThat(result.getRight().isName()).isTrue();
}
}
}