Skip to content

Commit

Permalink
cloudwatch activity support
Browse files Browse the repository at this point in the history
this begins to introduce *Ref dependencies for buckets allowing a s3:///prefix url to ref a bucket component and include the bucket name

this gets around breaking json syntax for substitutions, and allows the cloudwatch activity to introduce new resource permissions directly on the Bucket object
  • Loading branch information
cwensel committed Dec 5, 2023
1 parent bf54620 commit a05dfa7
Show file tree
Hide file tree
Showing 31 changed files with 255 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ else
repositories {
mavenCentral()

// mavenLocal()
// maven {
// url = uri("https://maven.pkg.github.com/heretical/*")
//
Expand Down Expand Up @@ -98,7 +99,7 @@ dependencies {
constraints {
// manage dependency versions here

val commons = "0.9"
val commons = "0.10"
implementationAndTestFixture("io.clusterless:clusterless-commons-core:$commons")
implementationAndTestFixture("io.clusterless:clusterless-commons-aws:$commons")

Expand Down
50 changes: 44 additions & 6 deletions clusterless-common/src/main/java/clusterless/cls/util/URIs.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public static String asKeyPath(URI uri) {
* Returns the path part of the uri without the leading slash, for use in S3 request.
*
* @param uri
* @return
* @return null if the path is empty
*/
public static String asKey(URI uri) {
if (uri == null) {
Expand All @@ -145,19 +145,57 @@ public static String asKey(URI uri) {

String normalize = uri.normalize().getPath();

if (normalize.isEmpty()) {
return asKey(normalize);
}

/**
* Returns the path part of the uri without the leading slash, for use in S3 request.
*
* @param path
* @return null if the path is empty
*/
public static String asKey(String path) {
if (path == null || path.isEmpty()) {
return null;
}

if (normalize.charAt(0) == '/') {
if (normalize.length() == 1) {
if (path.charAt(0) == '/') {
if (path.length() == 1) {
return null;
}

return normalize.substring(1);
return path.substring(1);
}

return path;
}

public static String asKeyPrefix(URI path) {
if (path == null) {
return null;
}

return normalize;
return asKeyPrefix(path.getPath());
}

/**
* Removes the first slash and trailing slash, if any.
*
* @param path the path to remove the first and trailing slash from
* @return the path without the first and trailing slash
*/
public static String asKeyPrefix(String path) {
path = asKey(path);

if (path == null || path.isEmpty()) {
return null;
}

if (path.charAt(path.length() - 1) == '/') {
return path.substring(0, path.length() - 1);
}

return path;
}

public static URI fromTo(URI fromBase, URI from, URI toBase) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ void asKey() {
Assertions.assertEquals("foo/", URIs.asKey(URI.create("s3://bucket/foo//")));
Assertions.assertEquals("foo/", URIs.asKey(URI.create("s3://bucket//foo//")));
Assertions.assertNull(URIs.asKey(URI.create("/")));
Assertions.assertNull(URIs.asKey(URI.create("/")));
Assertions.assertNull(URIs.asKey(URI.create("s3://bucket")));
Assertions.assertNull(URIs.asKey(URI.create("s3://bucket/")));
}
Expand All @@ -93,11 +92,19 @@ void asPath() {
Assertions.assertEquals("foo/", URIs.asKeyPath(URI.create("s3://bucket/foo//")));
Assertions.assertEquals("foo/", URIs.asKeyPath(URI.create("s3://bucket//foo//")));
Assertions.assertNull(URIs.asKeyPath(URI.create("/")));
Assertions.assertNull(URIs.asKeyPath(URI.create("/")));
Assertions.assertNull(URIs.asKeyPath(URI.create("s3://bucket")));
Assertions.assertNull(URIs.asKeyPath(URI.create("s3://bucket/")));
}

@Test
void asKeyPrefix() {
Assertions.assertEquals("foo", URIs.asKeyPrefix(URI.create("s3://bucket/foo")));
Assertions.assertEquals("foo", URIs.asKeyPrefix(URI.create("s3://bucket/foo/")));
Assertions.assertEquals("foo", URIs.asKeyPrefix("/foo"));
Assertions.assertEquals("foo", URIs.asKeyPrefix("/foo/"));
Assertions.assertNull(URIs.asKeyPrefix("/"));
}

public static Stream<Arguments> copyAppend() {
return Stream.of(
Arguments.arguments("s3://from/1", "s3://from/", new String[]{"1"}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
*
*/
public interface Component {
String name();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package clusterless.cls.model.deploy;

import clusterless.cls.json.ExtensibleResolver;
import clusterless.cls.json.JsonRequiredProperty;
import clusterless.cls.json.Views;
import clusterless.cls.model.Model;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
Expand All @@ -30,6 +31,8 @@ public abstract class Extensible extends Model {
// can't use @JsonRequiredProperty here
@JsonView(Views.Required.class)
String type;
@JsonRequiredProperty
String name;
boolean exclude = false;

public Extensible() {
Expand Down Expand Up @@ -60,6 +63,10 @@ public String type() {
return type;
}

public String name() {
return name;
}

/**
* @return true if this object should be excluded when creating constructs
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Response createExportLogGroupTask(String taskName, String logGroupName, S
.from(from.toEpochMilli())
.to(to.toEpochMilli())
.destination(destination.getHost())
.destinationPrefix(URIs.asKey(destination))
.destinationPrefix(URIs.asKeyPrefix(destination))
.logStreamNamePrefix(logStreamPrefix)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
/**
*
*/
public class ActivityConstruct<M extends Activity> extends ModelConstruct<M> implements ActivityComponent {
public ActivityConstruct(@NotNull ManagedComponentContext context, @NotNull M model, @NotNull String id) {
super(context, model, id);
public class ActivityConstruct<M extends Activity> extends ExtensibleConstruct<M> implements ActivityComponent {
public ActivityConstruct(@NotNull ManagedComponentContext context, @NotNull M model) {
super(context, model);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
/**
*
*/
public abstract class ArcConstruct<M extends Arc<?>> extends ModelConstruct<M> implements ArcComponent {
public abstract class ArcConstruct<M extends Arc<?>> extends ExtensibleConstruct<M> implements ArcComponent {

private final Lazy<IBucket> manifestBucket = Lazy.of(() -> BootstrapStores.manifestBucket(this));

public ArcConstruct(@NotNull ManagedComponentContext context, @NotNull M model) {
super(context, model, model.name());
super(context, model);
}

protected void grantManifestAndDatasetPermissionsTo(IGrantable grantable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
/**
*
*/
public class EgressBoundaryConstruct<M extends EgressBoundary> extends ModelConstruct<M> implements BoundaryComponent {
public abstract class EgressBoundaryConstruct<M extends EgressBoundary> extends ExtensibleConstruct<M> implements BoundaryComponent {
public EgressBoundaryConstruct(@NotNull ManagedComponentContext context, @NotNull M model) {
super(context, model, model.name());
super(context, model);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

package clusterless.cls.substrate.aws.construct;

import clusterless.cls.model.Model;
import clusterless.cls.model.deploy.Extensible;
import clusterless.cls.substrate.aws.managed.ManagedComponentContext;
import clusterless.cls.substrate.aws.managed.ManagedConstruct;
Expand All @@ -31,28 +30,38 @@
/**
*
*/
public class ModelConstruct<M extends Model> extends ManagedConstruct {
private static final Logger LOG = LogManager.getLogger(ModelConstruct.class);
public class ExtensibleConstruct<E extends Extensible> extends ManagedConstruct {
private static final Logger LOG = LogManager.getLogger(ExtensibleConstruct.class);

private final Map<String, IBucket> buckets = new HashMap<>(); // cache the construct to prevent collisions
private final Map<String, ITable> tables = new HashMap<>(); // cache the construct to prevent collisions
private final M model;
private final E model;

public ModelConstruct(@NotNull ManagedComponentContext context, @NotNull M model, @NotNull String id) {
super(context, uniqueId(model, id));
public ExtensibleConstruct(@NotNull ManagedComponentContext context, @NotNull E model) {
super(context, uniqueId(model, Label.of(model.name())));
this.model = model;
}

private static Label uniqueId(@NotNull Model model, @NotNull String id) {
public ExtensibleConstruct(@NotNull ManagedComponentContext context, @NotNull E model, @NotNull Label discriminator) {
super(context, uniqueId(model, discriminator));
this.model = model;
}

private static Label uniqueId(@NotNull Extensible model, @NotNull Label discriminator) {
return model
.label()
.with(id);
.with(discriminator);
}

public M model() {
@NotNull
public E model() {
return model;
}

public String name() {
return model().name();
}

protected String id(String value) {
return model()
.label()
Expand All @@ -61,8 +70,8 @@ protected String id(String value) {
}

protected <R extends IConstruct> R constructWithinHandler(Supplier<R> supplier) {
if (model() instanceof Extensible) {
return ErrorsUtil.construct(((Extensible) model()).type(), supplier, LOG);
if (model() != null) {
return ErrorsUtil.construct(model().type(), supplier, LOG);
}

return ErrorsUtil.construct(null, supplier, LOG);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,8 @@
/**
*
*/
public class IngressBoundaryConstruct<M extends IngressBoundary> extends ModelConstruct<M> implements BoundaryComponent {
public abstract class IngressBoundaryConstruct<M extends IngressBoundary> extends ExtensibleConstruct<M> implements BoundaryComponent {
public IngressBoundaryConstruct(@NotNull ManagedComponentContext context, @NotNull M model) {
super(context, model, model.name());
}

public IngressBoundaryConstruct(@NotNull ManagedComponentContext context, @NotNull M model, @NotNull String id) {
super(context, model, id);
super(context, model);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
import clusterless.cls.managed.component.ResourceComponent;
import clusterless.cls.model.deploy.Resource;
import clusterless.cls.substrate.aws.managed.ManagedComponentContext;
import clusterless.commons.naming.Label;
import org.jetbrains.annotations.NotNull;

/**
*
*/
public class ResourceConstruct<M extends Resource> extends ModelConstruct<M> implements ResourceComponent {
public ResourceConstruct(@NotNull ManagedComponentContext context, @NotNull M model, @NotNull String id) {
super(context, model, id);
public class ResourceConstruct<M extends Resource> extends ExtensibleConstruct<M> implements ResourceComponent {
public ResourceConstruct(@NotNull ManagedComponentContext context, @NotNull M model, @NotNull Label discriminator) {
super(context, model, discriminator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import clusterless.commons.naming.Stage;
import clusterless.commons.naming.Version;
import clusterless.commons.substrate.aws.cdk.scoped.ScopedApp;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import software.amazon.awscdk.AppProps;
import software.amazon.awscdk.TagProps;
import software.constructs.Construct;
Expand All @@ -26,6 +28,7 @@
*
*/
public class ManagedApp extends ScopedApp implements Managed {
private final Multimap<Class<? extends Construct>, Construct> constructs = LinkedListMultimap.create();
private final List<Deployable> deployableModel;
private final List<ManagedStack> stacks = new LinkedList<>();

Expand All @@ -51,11 +54,14 @@ public ManagedApp(String name, String version, String stage, List<Deployable> de
applyTags();
}

public Multimap<Class<? extends Construct>, Construct> constructs() {
return constructs;
}

public List<Deployable> projectModels() {
return deployableModel;
}


public List<ManagedStack> stacks() {
return stacks;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public DatasetResolver resolver() {
return resolver;
}

public ManagedApp managedProject() {
public ManagedApp managedApp() {
return managedApp;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,32 +46,30 @@ protected Placement placement() {
.build();
}

protected void addIdRefFor(Resource resource, Construct construct, String value, String description) {
protected void exportIdRefFor(Resource resource, Construct construct, String value, String description) {
Ref ref = Ref.ref()
.withResourceNs(resource.resourceNs())
.withResourceType(resource.resourceType())
.withResourceName(resource.name());

addIdRefFor(ref, construct, value, description);
exportIdRefFor(ref, construct, value, description);
}

protected void addArnRefFor(Resource resource, Construct construct, String value, String description) {
protected void exportArnRefFor(Resource resource, Construct construct, String value, String description) {
Ref ref = Ref.ref()
.withResourceNs(resource.resourceNs())
.withResourceType(resource.resourceType())
.withResourceName(resource.name());

addArnRefFor(ref, construct, value, description);
exportArnRefFor(ref, construct, value, description);
}

protected void addNameRefFor(Resource resource, Construct construct, String value, String description) {
protected void exportNameRefFor(Resource resource, Construct construct, String value, String description) {
Ref ref = Ref.ref()
.withResourceNs(resource.resourceNs())
.withResourceType(resource.resourceType())
.withResourceName(resource.name());

addNameRefFor(ref, construct, value, description);
exportNameRefFor(ref, construct, value, description);
}


}
Loading

0 comments on commit a05dfa7

Please sign in to comment.