Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move automations linkrel types to separate namespace #293

Merged
merged 3 commits into from
Nov 25, 2024
Merged
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.contentgrid.spring.automations;


import lombok.experimental.UtilityClass;
import org.springframework.hateoas.LinkRelation;
import org.springframework.hateoas.UriTemplate;
import org.springframework.hateoas.mediatype.hal.HalLinkRelation;

@UtilityClass
public class AutomationLinkRelations {
static final String CURIE = "automation";
static final UriTemplate TEMPLATE = UriTemplate.of("https://contentgrid.cloud/rels/automation/{rel}");

public static final LinkRelation ANNOTATION = HalLinkRelation.curied(CURIE, "annotation");
public static final String ANNOTATION_STRING = CURIE+":annotation";
public static final LinkRelation TARGET_ENTITY = HalLinkRelation.curied(CURIE, "target-entity");
public static final LinkRelation REGISTRATIONS = HalLinkRelation.curied(CURIE, "registrations");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this just be automations:automations? Because it's not like you can register at that endpoint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, those objects are the automations themselves, are they?
They are registrations for automations; containing automation annotations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's right that you cannot add registrations here, but you can list the registrations that already there.


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.contentgrid.spring.automations;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import com.contentgrid.spring.automations.rest.AutomationAnnotationRepresentationModelAssembler;
import com.contentgrid.spring.automations.rest.AutomationRepresentationModelAssembler;
import com.contentgrid.spring.automations.rest.AutomationsRestController;
import com.contentgrid.spring.data.rest.hal.CurieProviderCustomizer;
import com.contentgrid.thunx.spring.data.context.AbacContextSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.rest.webmvc.RepositoryLinksResource;
import org.springframework.hateoas.server.RepresentationModelProcessor;

@Import({
AutomationRepresentationModelAssembler.class,
AutomationAnnotationRepresentationModelAssembler.class
})
@Configuration(proxyBeanMethods = false)
public class ContentGridAutomationsConfiguration {

private static final String AUTOMATIONS_RESOURCE = "classpath:automation/automations.json";

@Bean
AutomationsRestController automationsRestController(
ResourceLoader resourceLoader,
AutomationRepresentationModelAssembler assembler,
AbacContextSupplier abacContextSupplier
) {
return new AutomationsRestController(
resourceLoader.getResource(AUTOMATIONS_RESOURCE),
assembler,
abacContextSupplier
);
}

@Bean
CurieProviderCustomizer automationCurieProvider() {
return CurieProviderCustomizer.register(AutomationLinkRelations.CURIE, AutomationLinkRelations.TEMPLATE);
}

@Bean
RepresentationModelProcessor<RepositoryLinksResource> automationRepositoryLinksRepresentationModelProcessor() {
// This must be a class instead of a lambda so the generic parameter can be determined by spring-hateoas
return new RepresentationModelProcessor<RepositoryLinksResource>() {
@Override
public RepositoryLinksResource process(RepositoryLinksResource model) {
return model.add(
linkTo(methodOn(AutomationsRestController.class).getAutomations())
.withRel(AutomationLinkRelations.REGISTRATIONS)
);
}
};
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import com.contentgrid.spring.automations.AutomationLinkRelations;
import java.util.Map;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand All @@ -14,7 +15,7 @@
@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(callSuper = true)
@Relation(collectionRelation = "cg:automation-annotation")
@Relation(collectionRelation = AutomationLinkRelations.ANNOTATION_STRING)
public class AutomationAnnotationRepresentationModel extends
RepresentationModel<AutomationAnnotationRepresentationModel> {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.contentgrid.spring.automations.rest;

import com.contentgrid.spring.automations.AutomationLinkRelations;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationAnnotationModel;
import lombok.RequiredArgsConstructor;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.core.mapping.ResourceMappings;
import org.springframework.data.rest.webmvc.ProfileController;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.RepresentationModelAssembler;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class AutomationAnnotationRepresentationModelAssembler implements
RepresentationModelAssembler<AutomationAnnotationModel, AutomationAnnotationRepresentationModel> {

private final RepositoryRestConfiguration repositoryRestConfiguration;
private final ResourceMappings mappings;

@Override
public AutomationAnnotationRepresentationModel toModel(AutomationAnnotationModel annotation) {
return AutomationAnnotationRepresentationModel.from(annotation)
.add(getTargetEntityLink(annotation));
}

private Link getTargetEntityLink(AutomationAnnotationModel annotation) {
var profileUrl = ProfileController.getPath(repositoryRestConfiguration,
mappings.getMetadataFor(annotation.getEntityClass()));

return Link.of(profileUrl, AutomationLinkRelations.TARGET_ENTITY);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.thunx.predicates.model.FunctionExpression;
import com.contentgrid.thunx.predicates.model.Scalar;
import com.contentgrid.thunx.predicates.model.SymbolicReference;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.hateoas.CollectionModel;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import java.util.List;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.thunx.spring.data.context.AbacContextSupplier;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

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

import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.thunx.predicates.model.Comparison;
import com.contentgrid.thunx.predicates.model.LogicalOperation;
import com.contentgrid.thunx.predicates.model.Scalar;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

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

import com.contentgrid.automations.rest.AutomationsModel.AutomationAnnotationModel;
import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationAnnotationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.test.fixture.invoicing.model.Customer;
import java.util.List;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.contentgrid.automations.rest;
package com.contentgrid.spring.automations.rest;

import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.contentgrid.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationModel;
import com.contentgrid.spring.boot.autoconfigure.integration.EventsAutoConfiguration;
import com.contentgrid.automations.rest.AutomationsModel.AutomationAnnotationModel;
import com.contentgrid.spring.automations.rest.AutomationsModel.AutomationAnnotationModel;
import com.contentgrid.spring.test.fixture.invoicing.InvoicingApplication;
import com.contentgrid.spring.test.fixture.invoicing.model.Customer;
import com.contentgrid.spring.test.security.WithMockJwt;
Expand All @@ -27,6 +27,7 @@
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;

Expand Down Expand Up @@ -116,6 +117,23 @@ void setup() {
.build());
}

@Test
void getRoot_containsLink() throws Exception {
mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)
.header("X-ABAC-Context", headerEncode(DEFAULT_POLICY))
)
.andExpect(status().isOk())
.andExpect(content().json("""
{
_links: {
"automation:registrations": {
href: "http://localhost/.contentgrid/automations"
}
}
}
"""));
}

@Test
void getAutomations_http200() throws Exception {
mockMvc.perform(get("/.contentgrid/automations")
Expand Down Expand Up @@ -192,7 +210,7 @@ void getAutomation_http200() throws Exception {
foo: "bar"
},
_embedded: {
"cg:automation-annotation": [ {
"automation:annotation": [ {
id: "${ENTITY_ANNOTATION_ID}",
subject: {
type: "entity",
Expand All @@ -202,12 +220,8 @@ void getAutomation_http200() throws Exception {
color: "blue"
},
_links: {
"cg:entity-profile": {
"automation:target-entity": {
href: "http://localhost/profile/customers"
},
"cg:entity": {
href: "http://localhost/customers{?page,size,sort*}",
templated: true
}
}
},
Expand All @@ -222,12 +236,8 @@ void getAutomation_http200() throws Exception {
type: "input"
},
_links: {
"cg:entity-profile": {
"automation:target-entity": {
href: "http://localhost/profile/customers"
},
"cg:entity": {
href: "http://localhost/customers{?page,size,sort*}",
templated: true
}
}
} ]
Expand Down Expand Up @@ -256,4 +266,4 @@ void getAutomation_noAccess_http404() throws Exception {
.andExpect(status().isNotFound());
}

}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
package com.contentgrid.spring.boot.autoconfigure.automation;

import com.contentgrid.automations.rest.AutomationAnnotationRepresentationModelAssembler;
import com.contentgrid.automations.rest.AutomationRepresentationModelAssembler;
import com.contentgrid.automations.rest.AutomationsRestController;
import com.contentgrid.spring.automations.ContentGridAutomationsConfiguration;
import com.contentgrid.spring.boot.autoconfigure.data.web.ContentGridSpringDataRestAutoConfiguration;
import com.contentgrid.thunx.predicates.model.ThunkExpression;
import com.contentgrid.thunx.spring.data.context.AbacContextSupplier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

@AutoConfiguration
@AutoConfiguration(
after = ContentGridSpringDataRestAutoConfiguration.class
)
@ConditionalOnWebApplication
@ConditionalOnClass({ AutomationsRestController.class, AbacContextSupplier.class, ThunkExpression.class })
vierbergenlars marked this conversation as resolved.
Show resolved Hide resolved
@Import({
AutomationRepresentationModelAssembler.class,
AutomationAnnotationRepresentationModelAssembler.class
})
@ConditionalOnClass({ContentGridAutomationsConfiguration.class, AbacContextSupplier.class, ThunkExpression.class})
@Import(ContentGridAutomationsConfiguration.class)
public class ContentGridAutomationAutoConfiguration {

@Autowired
private ApplicationContext applicationContext;

@Bean
AutomationsRestController automationsRestController(AutomationRepresentationModelAssembler assembler,
AbacContextSupplier abacContextSupplier) {
return new AutomationsRestController(applicationContext.getResource("classpath:automation/automations.json"),
assembler, abacContextSupplier);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,5 @@ public class ContentGridLinkRelations {
public static final LinkRelation ENTITY = HalLinkRelation.curied(CURIE, "entity");
public static final LinkRelation RELATION = HalLinkRelation.curied(CURIE, "relation");
public static final LinkRelation CONTENT = HalLinkRelation.curied(CURIE, "content");
public static final LinkRelation AUTOMATION_ANNOTATION = HalLinkRelation.curied(CURIE, "automation-annotation");
public static final LinkRelation ENTITY_PROFILE = HalLinkRelation.curied(CURIE, "entity-profile");

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ public class ChangeEventPublicationIntegrationTest {
{
name: "cg",
templated: true
},
{
name: "automation",
templated: true
}
]
}
Expand Down