Skip to content

Commit

Permalink
WIP Next Phase...
Browse files Browse the repository at this point in the history
  • Loading branch information
vorburger committed Dec 10, 2023
1 parent d02cd5b commit 456dfbb
Show file tree
Hide file tree
Showing 25 changed files with 842 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ tab_width = 2
[*.json]
indent_size = 2

[*.jsonc]
indent_size = 2

[*.toml]
indent_size = 2

Expand Down
16 changes: 12 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,

// https://github.com/salesforce/bazel-vscode#installation
"java.import.bazel.enabled": true,
"java.import.maven.enabled": false,
"java": {
"completion.favoriteStaticMembers": ["com.google.common.truth.Truth.*"],

// https://github.com/salesforce/bazel-vscode#installation
"import.bazel.enabled": true,
"import.maven.enabled": false
// NOT! "import.gradle.enabled": false
},

// https://squidfunk.github.io/mkdocs-material/creating-your-site/#configuration
"yaml.schemas": {
Expand Down Expand Up @@ -86,5 +91,8 @@
},
"markdown.validate.ignoredLinks": ["../dev/proto/core#id"],
"java.compile.nullAnalysis.mode": "automatic",
"bazel.projectview.open": false
"bazel.projectview.open": false,
"[proto3]": {
"editor.defaultFormatter": "zxh404.vscode-proto3"
}
}
4 changes: 2 additions & 2 deletions cli/src/main/java/dev/enola/cli/CommandWithModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ protected abstract void run(EntityKindRepository ekr, EnolaServiceBlockingStub s
static class ModelOrServer {

@Option(
names = {"--model"},
names = {"--model", "-m"},
required = true,
description = "URI to EntityKinds (e.g. file:model.yaml)")
private URI model;

@Option(
names = {"--server"},
names = {"--server", "-s"},
required = true,
description = "Target of an Enola gRPC Server (e.g. localhost:7070)")
private String server;
Expand Down
4 changes: 2 additions & 2 deletions connectors/demo/src/test/java/dev/enola/demo/ServerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void bothConnectorDirectlyAndViaServer()
var credz = InsecureChannelCredentials.create();
ManagedChannel channel = Grpc.newChannelBuilder(endpoint, credz).build();
var client =
ConnectorServiceGrpc.newBlockingStub(channel).withDeadlineAfter(3, SECONDS);
ConnectorServiceGrpc.newBlockingStub(channel).withDeadlineAfter(7, SECONDS);

// Test the Demo Connector directly
checkConnectorAugment(client);
Expand All @@ -76,7 +76,7 @@ public void bothConnectorDirectlyAndViaServer()
checkEnolaGet(enola);
checkEnolaList(enola);

channel.shutdownNow().awaitTermination(3, SECONDS);
channel.shutdownNow().awaitTermination(7, SECONDS);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void list() throws ValidationException, EnolaException {
var request = ListEntitiesRequest.newBuilder().setId(schemaKindID).build();
var response = service.listEntities(request);

assertThat(response.getEntitiesList()).hasSize(38);
assertThat(response.getEntitiesList().size()).isAtLeast(38);
}

@Test
Expand Down
31 changes: 29 additions & 2 deletions core/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ load("@rules_proto_grpc//buf:defs.bzl", "buf_proto_lint_test")
load("@rules_proto_grpc//doc:defs.bzl", "doc_markdown_compile")

# https://rules-proto-grpc.com/en/latest/example.html#step-3-write-a-build-file
proto_library(
name = "ext_proto",
srcs = ["src/main/java/dev/enola/core/enola_ext.proto"],
deps = [
"@com_google_protobuf//:descriptor_proto",
],
)

proto_library(
name = "core_proto",
srcs = ["src/main/java/dev/enola/core/enola_core.proto"],
Expand All @@ -56,7 +64,11 @@ proto_library(
proto_library(
name = "meta_proto",
srcs = ["src/main/java/dev/enola/core/meta/enola_meta.proto"],
deps = [":core_proto"],
deps = [
":core_proto",
":ext_proto",
"@com_google_protobuf//:empty_proto",
],
)

proto_library(
Expand All @@ -79,6 +91,7 @@ java_proto_library(
deps = [
"connector_proto",
"core_proto",
"ext_proto",
"meta_proto",
"util_proto",
],
Expand Down Expand Up @@ -117,6 +130,7 @@ doc_markdown_compile(
protos = [
"connector_proto",
"core_proto",
"ext_proto",
"meta_proto",
"util_proto",
],
Expand All @@ -132,6 +146,7 @@ buf_proto_lint_test(
protos = [
"connector_proto",
"core_proto",
# "ext_proto",
"meta_proto",
"util_proto",
],
Expand All @@ -154,6 +169,7 @@ java_library(
deps = [
":core_java_proto",
"@maven//:com_google_guava_guava",
"@maven//:com_google_protobuf_protobuf_java",
],
)

Expand All @@ -166,13 +182,21 @@ java_library(
":core_java_proto",
":lib_java",
"@maven//:com_google_guava_guava",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:com_google_truth_truth",
"@maven//:junit_junit",
],
) for name in glob([
"src/test/java/**/*Test.java",
])]

go_proto_library(
name = "ext_go_proto",
importpath = "dev/enola/core/ext",
protos = [":ext_proto"],
visibility = [],
)

go_proto_library(
name = "core_go_proto",
importpath = "dev/enola/core",
Expand All @@ -193,7 +217,10 @@ go_proto_library(
importpath = "dev/enola/core/meta",
protos = [":meta_proto"],
visibility = [],
deps = [":core_go_proto"],
deps = [
":core_go_proto",
":ext_go_proto",
],
)

go_proto_library(
Expand Down
168 changes: 168 additions & 0 deletions core/lib/src/main/java/dev/enola/core/ByteSeq.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2023 The Enola <https://enola.dev> Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 dev.enola.core;

import com.google.protobuf.ByteString;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.UUID;

/**
* Sequence of Bytes, of variable length, and immutable; often used as an Enola Type / Entity ID. Do
* not use this for "BLOBs" (like images or so). The hashCode is cached.
*
* <p>In Enola, these IDs are intended to be unique, for a given (possibly clustered) instance.
* Federated Enola instances in theory could have duplicates, but with sufficiently long randomly
* generated bytes this is considered rare enough in practice that you can assume these are globally
* unique.
*/
// TODO Make this a (the first!) Enola "simple type", with verbs for create & asUUID!
// TODO Link to docs/**/enola.md once that's published on https://docs.enola.dev.
public final class ByteSeq implements Comparable<ByteSeq> {

public static final ByteSeq EMPTY = new ByteSeq(new byte[0]);

public static final class Builder {
private final byte[] bytes;

private Builder(int size) {
bytes = new byte[size];
}

public ByteSeq build() {
return new ByteSeq(bytes);
}

public Builder add(ByteBuffer bb) {
if (!bb.isReadOnly()) {
throw new IllegalArgumentException("ByteBuffer !isReadOnly()");
}
bb.get(bytes);
return this;
}
}

public static Builder builder(int size) {
return new Builder(size);
}

// TODO public static final ByteSeq fromMultibase(String multibase) {

/**
* Create a ByteSeq from an array of bytes. Prefer using the Builder instead of this, to avoid
* the implementation have to copy the array.
*
* @param bytes Bytes (which will be copied)
* @return the ByteSeq
*/
public static final ByteSeq from(byte[] bytes) {
if (bytes.length == 0) {
return EMPTY;
}
return new ByteSeq(Arrays.copyOf(bytes, bytes.length));
}

/**
* Create a ByteSeq from a Protocol Buffer "bytes" field.
*
* @param proto the ByteString
* @return the ByteSeq
*/
public static ByteSeq from(ByteString proto) {
return ByteSeq.builder(proto.size()).add(proto.asReadOnlyByteBuffer()).build();
}

// ? public static ByteSeq toByteSeq(Message proto) { return
// ByteSeq.copyFrom(proto.toByteArray()); }

public static ByteSeq from(UUID uuid) {
var byteBuffer = ByteBuffer.allocate(16);
byteBuffer.putLong(uuid.getMostSignificantBits());
byteBuffer.putLong(uuid.getLeastSignificantBits());
byteBuffer.position(0);

var builder = builder(16);
builder.add(byteBuffer.asReadOnlyBuffer());
return builder.build();
}

private final byte[] bytes;
private transient int hashCode;

private ByteSeq(byte[] bytes) {
this.bytes = bytes;
}

public byte[] toBytes() {
return Arrays.copyOf(bytes, bytes.length);
}

public int size() {
return bytes.length;
}

public byte get(int index) {
return bytes[index];
}

// public String toString(Base base) { return Multibase.encode(Base.Base32, id.toByteArray()); }

public ByteString toByteString() {
return ByteString.copyFrom(bytes);
}

public UUID toUUID() {
if (bytes.length != 16) {
throw new IllegalStateException(
"toUUID() is currently only supported for length == 16, not: " + bytes.length);
}
ByteBuffer bb = ByteBuffer.wrap(bytes);
long high = bb.getLong();
long low = bb.getLong();
return new UUID(high, low);
}

@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Arrays.hashCode(bytes);
}
return hashCode;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
var other = (ByteSeq) obj;
if (hashCode() != other.hashCode()) {
return false;
}
return Arrays.equals(bytes, other.bytes);
}

@Override
public int compareTo(ByteSeq other) {
return Arrays.compare(bytes, other.bytes);
}
}
35 changes: 35 additions & 0 deletions core/lib/src/main/java/dev/enola/core/enola_core.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,41 @@ option java_package = "dev.enola.core.proto";
option java_multiple_files = true;
option go_package = "dev/enola/core";

// This is (loosely) inspired by JSON-LD, and src/google/protobuf/struct.proto,
// or
// https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp,
// et al.
message LinkedDataStruct {
// TODO Proto Annotation to core.meta.Type;
// for example: [ enola.type = dev.enola.core.meta.Type ]
string type = 1;
string id = 2;
map<string, Field> fields = 3;
}

message Field {
string type = 1;
map<string, Value> meta = 2;
Value value = 3;
}

message Value {
oneof kind {
Null null = 3;
string string = 4;
List list = 5;
LinkedDataStruct struct = 6;
}
}

message List {
repeated Value entries = 1;
}

enum Null {
NULL_UNSPECIFIED = 0;
}

// TODO Replace this with //docs/concepts/uri.md!
// ID of an Entity known to Enola, fully qualified.
// Can be formatted to and parsed from several different string text forms,
Expand Down
Loading

0 comments on commit 456dfbb

Please sign in to comment.