Skip to content

Commit

Permalink
Support nested resources (#195)
Browse files Browse the repository at this point in the history
- Adds support for one resource descriptor to expose dependencies on other resources.
- Removes unnecessary methods on `ResourceDescriptor`.
- Ensure all resource interfaces derive from `ResourceDescriptor`.
  • Loading branch information
big-andy-coates authored Jan 12, 2024
1 parent 0c445c9 commit 3858f81
Show file tree
Hide file tree
Showing 19 changed files with 491 additions and 184 deletions.
6 changes: 0 additions & 6 deletions config/spotbugs/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,4 @@
<!-- Exclude generated sources -->
<Source name="~.*[\\/]build[\\/]generated[\\/]source.*" />
</Match>

<Match>
<!-- Disable this check as it leads to longer names and harder to read code -->
<!-- Discussion: https://github.com/spotbugs/spotbugs/issues/2627 -->
<Bug pattern="PI_DO_NOT_REUSE_PUBLIC_IDENTIFIERS_CLASS_NAMES"/>
</Match>
</FindBugsFilter>
17 changes: 7 additions & 10 deletions metadata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,19 @@ Authors of Creek based services will build implementations of both aggregate and

The inputs of a component define any external resources the component consumes/reads.

All input resources implement the [`ComponentInput`](src/main/java/org/creekservice/api/platform/metadata/ComponentInput.java)
marker interface.
All input resources implement the [`ComponentInput`](src/main/java/org/creekservice/api/platform/metadata/ComponentInput.java) interface.

### Internals

The internals of a component define any external resources the component uses internally to perform its function.

All internal resources implement the [`ComponentInternal`](src/main/java/org/creekservice/api/platform/metadata/ComponentInternal.java)
marker interface.
All internal resources implement the [`ComponentInternal`](src/main/java/org/creekservice/api/platform/metadata/ComponentInternal.java) interface.

### Outputs

The outputs of a component define any external resources the component produces/writes.

All output resources implement the [`ComponentOutput`](src/main/java/org/creekservice/api/platform/metadata/ComponentOutput.java)
marker interface.
All output resources implement the [`ComponentOutput`](src/main/java/org/creekservice/api/platform/metadata/ComponentOutput.java) interface.

### Service descriptors

Expand All @@ -55,10 +52,10 @@ to define their public [inputs](#inputs) and [outputs](#outputs).
## Resource Descriptors

Resource descriptors define the resources a component uses in its [inputs](#inputs), [internals](#internals) and [outputs](#outputs).
There are corresponding `ComponentInput`, `ComponentInternal` and `ComponentOutput` marker interfaces, respectively.
There are corresponding `ComponentInput`, `ComponentInternal` and `ComponentOutput` interfaces, respectively.

Authors of creek services are not expected to implement the above marker interfaces. Creek extensions,
(such as [creek-kafka][1]), expose their own interfaces, which extend these marker interfaces, and which can be used to
Authors of creek services are not expected to implement the above interfaces. Creek extensions,
(such as [creek-kafka][1]), expose their own interfaces, which extend these interfaces, and which can be used to
define a resource the component uses, e.g. a Kafka Topic.

> ### NOTE
Expand Down Expand Up @@ -128,7 +125,7 @@ input, internal or output.

##### Unmanaged Resources

Any resource descriptor that does not implement one of the resource initialization marker interfaces are deemed not
Any resource descriptor that does not implement one of the resource initialization interfaces are deemed not
to be initialized by Creek. Such resources must be initialized some other way.

#### Resource deployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
* <li>both of the above
* </ul>
*/
public interface ComponentDescriptor {
public interface ComponentDescriptor extends ResourceCollection {

/**
* @return the unique name of the component within the platform. Can not be {@code null}, blank
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@

package org.creekservice.api.platform.metadata;

/** Marker interface of component inputs. */
/** Base type for component inputs. */
public interface ComponentInput extends ResourceDescriptor {}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@

package org.creekservice.api.platform.metadata;

/** Marker interface of component internals. */
/** Base type for component internals. */
public interface ComponentInternal extends ResourceDescriptor {}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@

package org.creekservice.api.platform.metadata;

/** Marker interface of component outputs. */
/** Base type for component outputs. */
public interface ComponentOutput extends ResourceDescriptor {}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@

package org.creekservice.api.platform.metadata;

/** Marker interface to indicate a resource is {@link ResourceDescriptor#isCreatable creatable}. */
interface CreatableResource {}
/**
* Base type for creatable resources.
*
* <p>Extensions should not implement this directly. Instead, implement one of this interface's
* subtypes, e.g. {@link OwnedResource} or {@link SharedResource}.
*/
public interface CreatableResource extends ResourceDescriptor {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.creekservice.api.platform.metadata;

/**
* Marker interface of an owned resources.
* Base type for an owned resources.
*
* <p>A resource can conceptually be either:
*
Expand All @@ -30,7 +30,7 @@
*
* <p>Resources should inherit <b>at most</b> one of the above interfaces.
*
* <p>For more information on resource initialization, see
* https://github.com/creek-service/creek-platform/tree/main/metadata#resource-initialization.
* <p>For more information on resource initialization, see <a
* href="https://github.com/creek-service/creek-platform/tree/main/metadata#resource-initialization">resource-initialization</a>.
*/
public interface OwnedResource extends CreatableResource {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2023 Creek Contributors (https://github.com/creek-service)
*
* 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
*
* 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.creekservice.api.platform.metadata;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;

/** A collection of resources. */
public interface ResourceCollection {

/**
* The stream of the resources in the collection.
*
* <p>In general, callers should call {@link #collectResources(ResourceCollection)}, rather than
* directly calling this method.
*
* @return the resources in the collection.
*/
Stream<? extends ResourceDescriptor> resources();

/**
* Utility method to collect all resources from a collection, including any resources referenced
* by any resources encountered.
*
* <p>Child resources are returned earlier in the stream than parents.
*
* @param collection the resource collection to retrieve all resources from.
* @return complete stream of resources.
*/
static Stream<ResourceDescriptor> collectResources(final ResourceCollection collection) {
final Set<ResourceCollection> visited = new HashSet<>();
visited.add(collection);
return collection.resources().flatMap(child -> collectResources(child, visited));
}

/**
* Utility method to collect all resources referenced by a {@code ResourceDescriptor}, including
* any resources referenced by any resources encountered.
*
* <p>Child resources are returned earlier in the stream than parents.
*
* <p>In general, callers should call {@link #collectResources(ResourceCollection)}, rather than
* directly calling this method.
*
* @param resource the resource descriptor to retrieve all resources from.
* @param visited the set of resource containers already visited.
* @return complete stream of resources.
*/
static Stream<ResourceDescriptor> collectResources(
final ResourceDescriptor resource, final Set<ResourceCollection> visited) {
if (!visited.add(resource)) {
// Already processed:
return Stream.empty();
}

return Stream.concat(
resource.resources().flatMap(child -> collectResources(child, visited)),
Stream.of(resource));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
package org.creekservice.api.platform.metadata;

import java.net.URI;
import java.util.stream.Stream;

/** Marker interface of resource descriptors. */
public interface ResourceDescriptor {
/** Base type for describing resource. */
public interface ResourceDescriptor extends ResourceCollection {

/**
* A unique identifier for this resource.
Expand All @@ -42,50 +43,19 @@ public interface ResourceDescriptor {
URI id();

/**
* Determine if a resource descriptor is creatable.
* Additional resources this resource requires.
*
* @param r the resource descriptor to check.
* @return {@code true} if creatable, {@code false} otherwise.
* @return stream of resources this resource depends on.
*/
static boolean isCreatable(final ResourceDescriptor r) {
return r instanceof CreatableResource;
}

/**
* Determine if a resource descriptor is marked owned.
*
* @param r the resource descriptor to check.
* @return {@code true} if creatable, {@code false} otherwise.
*/
static boolean isOwned(final ResourceDescriptor r) {
return r instanceof OwnedResource;
}

/**
* Determine if a resource descriptor is unowned.
*
* @param r the resource descriptor to check.
* @return {@code true} if creatable, {@code false} otherwise.
*/
static boolean isUnowned(final ResourceDescriptor r) {
return r instanceof UnownedResource;
}

/**
* Determine if a resource descriptor is shared.
*
* @param r the resource descriptor to check.
* @return {@code true} if creatable, {@code false} otherwise.
*/
static boolean isShared(final ResourceDescriptor r) {
return r instanceof SharedResource;
default Stream<? extends ResourceDescriptor> resources() {
return Stream.of();
}

/**
* Determine if a resource descriptor is unmanaged.
*
* @param r the r descriptor to check.
* @return {@code true} if creatable, {@code false} otherwise.
* @return {@code true} if unmanaged, {@code false} otherwise.
*/
static boolean isUnmanaged(final ResourceDescriptor r) {
return !(r instanceof SharedResource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.creekservice.api.platform.metadata;

/**
* Marker interface of an owned resources.
* Base type for shared resources.
*
* <p>A resource can conceptually be either:
*
Expand All @@ -30,7 +30,7 @@
*
* <p>Resources should inherit <b>at most</b> one of the above interfaces.
*
* <p>For more information on resource initialization, see
* https://github.com/creek-service/creek-platform/tree/main/metadata#resource-initialization.
* <p>For more information on resource initialization, see <a
* href="https://github.com/creek-service/creek-platform/tree/main/metadata#resource-initialization">resource-initialization</a>.
*/
public interface SharedResource extends CreatableResource {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.creekservice.api.platform.metadata;

/**
* Marker interface of an unowned resources.
* Base type for unowned resources.
*
* <p>A resource can conceptually be either:
*
Expand All @@ -30,7 +30,7 @@
*
* <p>Resources should inherit <b>at most</b> one of the above interfaces.
*
* <p>For more information on resource initialization, see
* https://github.com/creek-service/creek-platform/tree/main/metadata#resource-initialization.
* <p>For more information on resource initialization, see <a
* href="https://github.com/creek-service/creek-platform/tree/main/metadata#resource-initialization">resource-initialization</a>
*/
public interface UnownedResource {}
public interface UnownedResource extends ResourceDescriptor {}
Loading

0 comments on commit 3858f81

Please sign in to comment.