Skip to content

Commit cbe3c64

Browse files
authored
Merge pull request #2 from mcanoy/last-update-refresh
refresh engagements. last update
2 parents 90bdcbb + e4cad31 commit cbe3c64

File tree

9 files changed

+99
-72
lines changed

9 files changed

+99
-72
lines changed

src/main/java/com/redhat/labs/lodestar/resource/EngagementResource.java

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import com.redhat.labs.lodestar.service.ConfigService;
4747
import com.redhat.labs.lodestar.service.EngagementService;
4848
import com.redhat.labs.lodestar.util.JWTUtils;
49+
import org.slf4j.Logger;
50+
import org.slf4j.LoggerFactory;
4951

5052
@RequestScoped
5153
@Path("/engagements")
@@ -54,6 +56,7 @@
5456
@SecurityScheme(securitySchemeName = "jwt", type = SecuritySchemeType.HTTP, scheme = "bearer", bearerFormat = "JWT")
5557
@Tag(name = "Engagements", description = "Base engagement apis")
5658
public class EngagementResource {
59+
private static final Logger LOGGER = LoggerFactory.getLogger(EngagementResource.class);
5760

5861
private static final String ACCEPT_VERSION_1 = "v1";
5962

@@ -92,7 +95,6 @@ public Response getAll(@Context UriInfo uriInfo, @BeanParam ListFilterOptions fi
9295
// create one page with many results for v1
9396
setDefaultPagingFilterOptions(filterOptions);
9497

95-
// TODO not implement yet - kinda important
9698
return engagementService.getEngagementsPaged(filterOptions);
9799
}
98100

@@ -139,6 +141,7 @@ public Response findCustomers(@Context UriInfo uriInfo,
139141
*/
140142

141143
//TODO remove this access
144+
@Deprecated
142145
@GET
143146
@SecurityRequirement(name = "jwt")
144147
@Path("/customers/{customerName}/projects/{projectName}")
@@ -149,13 +152,15 @@ public Response findCustomers(@Context UriInfo uriInfo,
149152
public Response get(@PathParam("customerName") String customerName, @PathParam("projectName") String projectName,
150153
@BeanParam FilterOptions filterOptions) {
151154

155+
LOGGER.warn("Deprecated get method used /customers/{}/projects/{}", customerName, projectName);
156+
152157
Engagement engagement = engagementService.getByCustomerAndProjectName(customerName, projectName);
153158

154159
boolean writer = jwtUtils.isAllowedToWriteEngagement(jwt, configService.getPermission(engagement.getType()));
155160
engagement.setWriteable(writer);
156161

157162
return Response.ok(engagement).header(LAST_UPDATE_HEADER, engagement.getLastUpdate())
158-
.header(ACCESS_CONTROL_EXPOSE_HEADER, LAST_UPDATE_HEADER).build();
163+
.header(ACCESS_CONTROL_EXPOSE_HEADER, LAST_UPDATE_HEADER).header("deprecated", "use get by uuid").build();
159164

160165
}
161166

@@ -187,6 +192,7 @@ public Response get(@PathParam("id") String uuid, @BeanParam FilterOptions filte
187192
* GET - Queries
188193
*/
189194

195+
// Not sure if this one is being used currently
190196
@GET
191197
@Path("/state/{state}")
192198
@SecurityRequirement(name = "jwt")
@@ -253,8 +259,6 @@ public Response getUserSummary(@QueryParam("search") String search) {
253259
* HEAD
254260
*/
255261

256-
257-
//TODO ensure last update is valid here
258262
@HEAD
259263
@SecurityRequirement(name = "jwt")
260264
@Path("/{id}")
@@ -263,7 +267,7 @@ public Response getUserSummary(@QueryParam("search") String search) {
263267
@APIResponse(responseCode = "200", description = "Engagement resource found and metadata returned in headers") })
264268
@Operation(summary = "Returns metadata regarding the engagement resource for the given customer and project names.")
265269
public Response head(@PathParam("id") String uuid) {
266-
return activityService.getActivityHead(uuid);
270+
return engagementService.getEngagementHead(uuid);
267271
}
268272

269273
@HEAD
@@ -330,6 +334,8 @@ public Response post(@Valid Engagement engagement, @Context UriInfo uriInfo) {
330334
@Operation(deprecated = true, summary = "Updates the engagement resource in the database.")
331335
public Response put(@PathParam("customerName") String customerName, @PathParam("projectName") String projectName,
332336
@Valid Engagement engagement) {
337+
338+
LOGGER.warn("Deprecated put method used /customers/{}/projects/{}", customerName, projectName);
333339

334340
boolean writer = jwtUtils.isAllowedToWriteEngagement(jwt, configService.getPermission(engagement.getType()));
335341
if(!writer) {
@@ -354,6 +360,7 @@ public Response put(@PathParam("customerName") String customerName, @PathParam("
354360
@Operation(summary = "Updates the engagement resource in the database.")
355361
public Response put(@PathParam("id") String uuid, @Valid Engagement engagement) {
356362

363+
357364
boolean writer = jwtUtils.isAllowedToWriteEngagement(jwt, configService.getPermission(engagement.getType()));
358365
if(!writer) {
359366
return forbiddenResponse(engagement.getType());
@@ -367,7 +374,7 @@ public Response put(@PathParam("id") String uuid, @Valid Engagement engagement)
367374

368375
}
369376

370-
//TODO this method should be /launch/{uuid} with no body
377+
//TODO this method should be /launch/{uuid} with no body. fix after v2 rollout
371378
@PUT
372379
@Path("/launch")
373380
@SecurityRequirement(name = "jwt")
@@ -429,17 +436,9 @@ private void setDefaultPagingFilterOptions(ListFilterOptions options) {
429436

430437
boolean isV1 = null == options.getApiVersion() || ACCEPT_VERSION_1.equals(options.getApiVersion());
431438

432-
options.setPage(getPage(options.getPage()));
433-
options.setPerPage(getPerPage(options.getPerPage(), isV1));
434-
435-
}
436-
437-
private Integer getPage(Optional<Integer> page) {
438-
return page.orElse(1);
439-
}
439+
options.setPage(options.getPage().orElse(1));
440+
options.setPerPage(options.getPerPage().orElse(isV1 ? 500 : 20));
440441

441-
private Integer getPerPage(Optional<Integer> perPage, boolean isV1) {
442-
return perPage.orElse(isV1 ? 500 : 20);
443442
}
444443

445444
}

src/main/java/com/redhat/labs/lodestar/resource/RefreshResource.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import javax.ws.rs.*;
1818
import javax.ws.rs.core.MediaType;
1919
import javax.ws.rs.core.Response;
20+
import java.util.Set;
2021

2122
@RequestScoped
2223
@Path("/engagements/refresh")
@@ -38,10 +39,10 @@ public class RefreshResource {
3839
@APIResponse(responseCode = "400", description = "No refresh data set selected. Options are engagements, artifacts, participants and activity. You can mix and match"),
3940
@APIResponse(responseCode = "404", description = "UUID provided, but no engagement found in database."),
4041
@APIResponse(responseCode = "202", description = "The request was accepted and will be processed.") })
41-
@Operation(summary = "Refreshes database with data in git, purging first if the query paramater set to true.")
42+
@Operation(summary = "Refreshes database with data in git. If uuids are set then only those will be refreshed (engagements only support for that). Engagement Service first")
4243
public Response refresh(
4344
@Parameter(description = "When set deletes engagements first.") @QueryParam("purgeFirst") Boolean purgeFirst,
44-
@Parameter(description = "Refresh engagement with uuid") @QueryParam("uuid") String uuid,
45+
@Parameter(description = "Refresh engagement with uuid") @QueryParam("uuid") Set<String> uuids,
4546
@Parameter(description = "Refresh engagement with project id") @QueryParam("projectId") String projectId,
4647
@Parameter(description = "Refresh artifacts") @QueryParam("artifacts") boolean refreshArtifacts,
4748
@Parameter(description = "Refresh participants") @QueryParam("participants") boolean refreshParticipants,
@@ -51,6 +52,12 @@ public Response refresh(
5152

5253
boolean didPickSomething = false;
5354

55+
if (refreshEngagements) { //Engagements done first since all others are predicated on this content.
56+
//Engagements will be synchronous
57+
engagementService.refresh(uuids);
58+
didPickSomething = true;
59+
}
60+
5461
if (refreshActivity) {
5562
eventBus.publish(EventType.RELOAD_ACTIVITY_EVENT_ADDRESS, EventType.RELOAD_ACTIVITY_EVENT_ADDRESS);
5663
didPickSomething = true;
@@ -72,12 +79,6 @@ public Response refresh(
7279
didPickSomething = true;
7380
}
7481

75-
if (refreshEngagements) {
76-
//TODO
77-
//engagementService.syncGitToDatabase(Boolean.TRUE.equals(purgeFirst), uuid, projectId);
78-
didPickSomething = true;
79-
}
80-
8182
if (didPickSomething) {
8283
return Response.accepted().build();
8384
}

src/main/java/com/redhat/labs/lodestar/rest/client/EngagementApiClient.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,17 @@ public interface EngagementApiClient {
5454
@PUT
5555
Response updateEngagement(Engagement engagement);
5656

57+
@PUT
58+
@Path("{uuid}/lastUpdate")
59+
Response registerUpdate(@PathParam("uuid") String uuid);
60+
5761
@PUT
5862
@Path("{uuid}/launch")
5963
Response launch(@PathParam("uuid") String uuid, @QueryParam("author") String author, @QueryParam("authorEmail") String authorEmail);
6064

61-
@PUT Response refresh();
65+
@PUT
66+
@Path("refresh")
67+
Response refresh(@QueryParam("uuids") Set<String> uuids);
6268

6369
@GET
6470
@Path("suggest")

src/main/java/com/redhat/labs/lodestar/service/EngagementService.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,12 @@ public Engagement getEngagement(String uuid) {
9797
engagement.setCategories(categories);
9898
engagement.setCommits(activity);
9999

100-
if(!engagement.getCommits().isEmpty()) {
101-
engagement.setLastUpdate(activity.get(0).getCommitDate());
102-
}
103-
104100
EngagementState state = engagement.getEngagementCurrentState(Instant.now());
105101
if(state.equals(EngagementState.ACTIVE) || state.equals(EngagementState.TERMINATING)) {
106102
engagement.setStatus(getStatus(uuid));
107103
}
108104

105+
LOGGER.trace("got uuid {} with last update {}", uuid, engagement.getLastUpdate());
109106
return engagement;
110107
}
111108

@@ -150,22 +147,24 @@ public Engagement create(Engagement engagement) {
150147
* @return
151148
*/
152149
public Engagement update(Engagement engagement) {
150+
boolean somethingChanged = false;
153151

154152
String author = engagement.getLastUpdateByName();
155153
String authorEmail = engagement.getLastUpdateByEmail();
156154
String engagementUuid = engagement.getUuid();
157155

158-
// Validate activity is sync'd to prevent overwrites
159-
// This is legacy behavior. We should support last update per service
160-
validateLastUpdateIsLatest(engagementUuid, engagement.getLastUpdate());
161-
162156
//Will return a 404 with a message saying the uuid is not valid
163157
Engagement current = engagementApiClient.getEngagement(engagement.getUuid());
164158

159+
// Validate activity is sync'd to prevent overwrites
160+
// This is legacy behavior. We should support last update per service
161+
validateLastUpdateIsLatest(engagement.getLastUpdate(), current.getLastUpdate(), engagementUuid);
162+
165163
Diff diff = javers.compare(current, engagement);
166164
if(diff.hasChanges()) {
167165
LOGGER.debug("Engagement changes {}", diff);
168166
engagementApiClient.updateEngagement(engagement);
167+
//somethingChanged not needed as it will occur during engagement update
169168
}
170169

171170
nullToEmpty(engagement);
@@ -176,13 +175,15 @@ public Engagement update(Engagement engagement) {
176175
LOGGER.debug("Hosting Environment changes {}", diff);
177176
hostingEnvironmentService.updateAndReload(engagementUuid, engagement.getHostingEnvironments(),
178177
Author.builder().email(authorEmail).name(author).build());
178+
somethingChanged = true;
179179
}
180180

181181
List<Artifact> artifacts = artifactService.getArtifacts(engagement.getUuid());
182182
diff = javers.compareCollections(artifacts, engagement.getArtifacts(), Artifact.class);
183183
if(diff.hasChanges()) {
184184
LOGGER.debug("Artifacts has changes {}", diff);
185185
artifactService.update(engagement, author, authorEmail);
186+
somethingChanged = true;
186187
}
187188

188189
List<EngagementUser> participants = participantService.getParticipantsForEngagement(engagement.getUuid());
@@ -192,7 +193,7 @@ public Engagement update(Engagement engagement) {
192193
participants = participantService.updateParticipantsAndReload(engagementUuid, author, authorEmail,
193194
engagement.getEngagementUsers());
194195
LOGGER.debug("Updated {}", participants);
195-
196+
somethingChanged = true;
196197
}
197198

198199
List<Category> categories = categoryApiClient.getCategories(engagement.getUuid());
@@ -202,23 +203,26 @@ public Engagement update(Engagement engagement) {
202203
Set<String> catString = new TreeSet<>();
203204
engagement.getCategories().forEach(c -> catString.add(c.getName()));
204205
categoryApiClient.updateCategories(engagementUuid, author, authorEmail, catString);
206+
somethingChanged = true;
205207
}
206208

207209
//TODO update cache
210+
if(somethingChanged) {
211+
engagementApiClient.registerUpdate(engagementUuid);
212+
}
208213
return getEngagement(engagementUuid);
209214
}
210215

211216
/**
212217
* Will throw a 409 error if invalid
213-
* @param engagementUuid the engagement
214-
* @param requesterLastUpdate incoming last known update
215218
*/
216-
private void validateLastUpdateIsLatest(String engagementUuid, String requesterLastUpdate) {
217-
Instant lastUpdateFromRequester = Instant.parse(requesterLastUpdate);
218-
Instant lastUpdateFromSystem = activityService.getLatestActivity(engagementUuid);
219+
private void validateLastUpdateIsLatest(String requestValue, String persistedValue, String engagementUuid) {
220+
Instant lastUpdateFromRequester = Instant.parse(requestValue);
221+
Instant lastUpdateFromSystem = Instant.parse(persistedValue);
219222

220-
if(lastUpdateFromSystem.compareTo(lastUpdateFromRequester) != 0) {
221-
LOGGER.info("Last update is out of sync with the activity. Caller needs refresh for {}", engagementUuid);
223+
if(!lastUpdateFromSystem.equals(lastUpdateFromRequester)) {
224+
LOGGER.info("Last update is out of sync with the engagement db. Caller needs refresh for {} ui ({}) db ({})",
225+
engagementUuid, requestValue, persistedValue);
222226
throw new WebApplicationException(409);
223227
}
224228
}
@@ -412,7 +416,11 @@ public Response getUseCases(ListFilterOptions filterOptions) {
412416
public Engagement launch(String uuid, String author, String authorEmail) {
413417

414418
engagementApiClient.launch(uuid, author, authorEmail);
415-
return getEngagement(uuid); //TODO This method should happen via UUID not full engagement
419+
return getEngagement(uuid);
420+
}
421+
422+
public void refresh(Set<String> uuids) {
423+
engagementApiClient.refresh(uuids);
416424
}
417425

418426
}

src/main/resources/application.properties

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ quarkus.cache.caffeine.rbac-cache.expire-after-write=600S
4949
# Quarkus build properties
5050
quarkus.package.type=uber-jar
5151

52-
lodestar.git.api/mp-rest/url=${LODESTAR_GITLAB_API_URL:http://lodestar-git-api:8080}
53-
lodestar.status.api/mp-rest/url=${LODESTAR_STATUS_API_URL:http://lodestar-status:8080}
54-
lodestar.config.api/mp-rest/url=${LODESTAR_CONFIG_API_URL:http://lodestar-config:8080}
55-
lodestar.activity.api/mp-rest/url=${LODESTAR_ACTIVITY_API_URL:http://lodestar-activity:8080}
56-
lodestar.artifacts.api/mp-rest/url=${LODESTAR_ARTIFACTS_API_URL:http://lodestar-artifacts:8080}
57-
lodestar.participants.api/mp-rest/url=${LODESTAR_PARTICIPANTS_API_URL:http://lodestar-participants:8080}
58-
lodestar.engagement.status.api/mp-rest/url=${LODESTAR_ENGAGEMENT_STATUS_API_URL:http://lodestar-engagement-status:8080}
59-
lodestar.engagements.api/mp-rest/url=${LODESTAR_ENGAGEMENTS_API_URL:http://lodestar-engagements:8080}
60-
lodestar.hosting.api/mp-rest/url=${LODESTAR_HOSTING_ENV_API_URL:http://lodestar-hosting:8080}
52+
lodestar.git.api/mp-rest/url=${GITLAB_API_URL:http://lodestar-git-api:8080}
53+
lodestar.status.api/mp-rest/url=${STATUS_API_URL:http://lodestar-status:8080}
54+
lodestar.config.api/mp-rest/url=${CONFIG_API_URL:http://lodestar-config:8080}
55+
lodestar.activity.api/mp-rest/url=${ACTIVITY_API_URL:http://lodestar-activity:8080}
56+
lodestar.artifacts.api/mp-rest/url=${ARTIFACTS_API_URL:http://lodestar-artifacts:8080}
57+
lodestar.participants.api/mp-rest/url=${PARTICIPANTS_API_URL:http://lodestar-participants:8080}
58+
lodestar.engagement.status.api/mp-rest/url=${ENGAGEMENT_STATUS_API_URL:http://lodestar-engagement-status:8080}
59+
lodestar.engagements.api/mp-rest/url=${ENGAGEMENT_API_URL:http://lodestar-engagements:8080}
60+
lodestar.hosting.api/mp-rest/url=${HOSTING_ENV_API_URL:http://lodestar-hosting:8080}
6161

6262
webhook.token=${WEBHOOK_TOKEN:t}
6363
cleanup.token=${CLEANUP_TOKEN:OFF}

src/test/java/com/redhat/labs/lodestar/resource/ConfigResourceTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import javax.ws.rs.core.Response;
77

88
import com.redhat.labs.lodestar.rest.client.ConfigApiClient;
9+
import io.quarkus.test.common.http.TestHTTPEndpoint;
910
import io.quarkus.test.junit.mockito.InjectMock;
1011
import org.eclipse.microprofile.rest.client.inject.RestClient;
1112
import org.junit.jupiter.api.Tag;
@@ -17,6 +18,7 @@
1718
import io.quarkus.test.junit.QuarkusTest;
1819

1920
@QuarkusTest
21+
@TestHTTPEndpoint(ConfigResource.class)
2022
@Tag("nested")
2123
class ConfigResourceTest {
2224

@@ -33,7 +35,7 @@ void testGetConfigTokenHasWrongRole() {
3335
.when()
3436
.auth()
3537
.oauth2(token)
36-
.get("/config")
38+
.get()
3739
.then()
3840
.statusCode(403);
3941

@@ -52,7 +54,7 @@ void testGetConfigWithoutType() {
5254
.when()
5355
.auth()
5456
.oauth2(token)
55-
.get("/config")
57+
.get()
5658
.then()
5759
.statusCode(200)
5860
.body(is(body))
@@ -75,11 +77,18 @@ void testGetConfigWithType() {
7577
.when()
7678
.auth()
7779
.oauth2(token)
78-
.get("/config")
80+
.get()
7981
.then()
8082
.statusCode(200)
8183
.body(is(body));
8284

8385
}
8486

87+
@Test
88+
void testVoidCache() {
89+
String token = TokenUtils.generateTokenString("/JwtClaimsReader.json");
90+
91+
given().when().auth().oauth2(token).put("/rbac/cache").then().statusCode(200);
92+
}
93+
8594
}

0 commit comments

Comments
 (0)