Skip to content

Commit cf354ce

Browse files
committed
Updated GrabbitCleanJobRepositoryServlet to act on /grabbit/jobrepository/clean accepting a 'hours' parameter
1 parent fc6d9fc commit cf354ce

9 files changed

Lines changed: 175 additions & 33 deletions

File tree

grabbit/src/main/groovy/com/twcable/grabbit/client/servlets/GrabbitCleanJobRepositoryServlet.groovy

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.twcable.grabbit.resources
2+
3+
import groovy.transform.CompileStatic
4+
import org.apache.sling.api.resource.ResourceResolver
5+
import org.apache.sling.api.resource.SyntheticResource
6+
7+
import javax.annotation.Nonnull
8+
9+
/*
10+
* Copyright 2015 Time Warner Cable, Inc.
11+
*
12+
* Licensed under the Apache License, Version 2.0 (the "License");
13+
* you may not use this file except in compliance with the License.
14+
* You may obtain a copy of the License at
15+
*
16+
* http://www.apache.org/licenses/LICENSE-2.0
17+
*
18+
* Unless required by applicable law or agreed to in writing, software
19+
* distributed under the License is distributed on an "AS IS" BASIS,
20+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21+
* See the License for the specific language governing permissions and
22+
* limitations under the License.
23+
*/
24+
25+
/**
26+
* A resource representing what needs to be deleted from Grabbit's JobRepository.
27+
* provided by {@link GrabbitResourceProvider}.
28+
* Queried from {@link com.twcable.grabbit.spring.batch.repository.servlets.GrabbitCleanJobRepositoryServlet}.
29+
*/
30+
@CompileStatic
31+
class CleanJobRepositoryResource extends SyntheticResource {
32+
33+
public static final String CLEAN_JOBREPOSITORY_RESOURCE_TYPE = "twcable:grabbit/jobrepository/clean"
34+
35+
CleanJobRepositoryResource(@Nonnull final ResourceResolver resourceResolver, @Nonnull final String resolutionPath) {
36+
super(resourceResolver, resolutionPath, CLEAN_JOBREPOSITORY_RESOURCE_TYPE)
37+
}
38+
39+
40+
@Override
41+
String getResourceType() {
42+
return CLEAN_JOBREPOSITORY_RESOURCE_TYPE
43+
}
44+
}

grabbit/src/main/groovy/com/twcable/grabbit/resources/GrabbitResourceProvider.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class GrabbitResourceProvider implements ResourceProvider {
7979
case ~/^\/grabbit\/content(\/)?$/:
8080
log.debug "Resolving ${path} to ContentResource"
8181
return new ContentResource(resolver, path)
82+
case ~/^\/grabbit\/jobrepository\/clean(\/)?$/:
83+
log.debug "Resolving ${path} to CleanJobRepositoryResource"
84+
return new CleanJobRepositoryResource(resolver, path)
8285
default:
8386
//Should provide a root resource for /grabbit, along with HATEOS style for this link, and other links. https://github.com/TWCable/grabbit/issues/22
8487
return null

grabbit/src/main/groovy/com/twcable/grabbit/spring/batch/repository/JcrGrabbitJobExecutionDao.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class JcrGrabbitJobExecutionDao extends AbstractJcrDao implements GrabbitJobExec
392392
.toList()
393393
.collect { it.path }
394394
.unique() as List<String>
395-
log.info "JobExecutions: $jobExecutions, size: ${jobExecutions.size()}"
395+
log.debug "JobExecutions: $jobExecutions, size: ${jobExecutions.size()}"
396396
return jobExecutions
397397
}
398398

@@ -415,7 +415,7 @@ class JcrGrabbitJobExecutionDao extends AbstractJcrDao implements GrabbitJobExec
415415
Date endTimeDate = DateUtil.getDateFromISOString(dateInIsoString)
416416
olderThanHours.time.compareTo(endTimeDate) > 0
417417
} as List<String>
418-
log.info "JobExecutionsOlder than ${hours} hours: $olderResourcePaths , length: ${olderResourcePaths.size()}"
418+
log.debug "JobExecutionsOlder than ${hours} hours: $olderResourcePaths , length: ${olderResourcePaths.size()}"
419419
return olderResourcePaths
420420

421421
}

grabbit/src/main/groovy/com/twcable/grabbit/spring/batch/repository/services/CleanJobRepository.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ interface CleanJobRepository {
2121
/**
2222
* This API is used to clean Grabbit's JCR Job Repository. It removes all job executions and all associated
2323
* job instances etc. that are @param hours older than NOW (time when this API is called)
24+
* @return list of JobExecutionIds that were removed
2425
*/
25-
public void cleanJobRepository(int hours)
26+
public List<String> cleanJobRepository(int hours)
2627

2728
}

grabbit/src/main/groovy/com/twcable/grabbit/spring/batch/repository/services/impl/DefaultCleanJobRepository.groovy

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ class DefaultCleanJobRepository implements CleanJobRepository {
5151
}
5252

5353
@Override
54-
void cleanJobRepository(int hours) {
54+
List<String> cleanJobRepository(int hours) {
5555
JcrJobRepositoryFactoryBean jobRepositoryFactoryBean = configurableApplicationContext.getBean(JcrJobRepositoryFactoryBean)
5656

5757
if(!jobRepositoryFactoryBean) {
5858
log.error "Cannot get an instance of JcrJobRepositoryFactoryBean. Will not clean up Grabbit Jcr Job Repository"
59-
return
59+
return []
6060
}
6161

6262
List<String> jobExecutionPaths = jobRepositoryFactoryBean.jobExecutionDao.getJobExecutions([BatchStatus.FAILED, BatchStatus.COMPLETED])
@@ -69,6 +69,7 @@ class DefaultCleanJobRepository implements CleanJobRepository {
6969
JcrUtil.manageResourceResolver(resourceResolverFactory) { ResourceResolver resolver ->
7070

7171
log.debug "jobInstancesToRemove: $jobInstancesToRemove, size: ${jobInstancesToRemove.size()}"
72+
log.debug "jobExecutionsToRemove: $olderThanHoursJobExecutions, size: ${olderThanHoursJobExecutions.size()}"
7273
log.debug "stepExecutionsToRemove: $stepExecutionsToRemove, size: ${stepExecutionsToRemove.size()}"
7374
log.debug "jobExecutionContextsToRemove: $jobExecutionContextsToRemove, size: ${jobExecutionContextsToRemove.size()}"
7475
log.debug "stepExecutionContextsToResource: $stepExecutionContextsToRemove, size: ${stepExecutionContextsToRemove.size()}"
@@ -84,6 +85,9 @@ class DefaultCleanJobRepository implements CleanJobRepository {
8485
log.info "Removing ${stepExecutionContextsToRemove.size()} StepExecutionContexts"
8586
removeResources(stepExecutionContextsToRemove, resolver)
8687
}
88+
89+
List<String> removedJobExecutionIds = olderThanHoursJobExecutions.collect { it.split("/").last() }
90+
return removedJobExecutionIds
8791
}
8892

8993
private void removeResources(List<String> resourcePathsToRemove, ResourceResolver resolver) {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2015 Time Warner Cable, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.twcable.grabbit.spring.batch.repository.servlets
18+
19+
import com.twcable.grabbit.spring.batch.repository.services.CleanJobRepository
20+
import groovy.transform.CompileStatic
21+
import groovy.util.logging.Slf4j
22+
import org.apache.felix.scr.annotations.Reference
23+
import org.apache.felix.scr.annotations.sling.SlingServlet
24+
import org.apache.sling.api.SlingHttpServletRequest
25+
import org.apache.sling.api.SlingHttpServletResponse
26+
import org.apache.sling.api.servlets.SlingAllMethodsServlet
27+
import org.apache.sling.api.servlets.SlingSafeMethodsServlet
28+
29+
import javax.annotation.Nonnull
30+
import javax.servlet.http.HttpServletResponse
31+
32+
@Slf4j
33+
@CompileStatic
34+
@SlingServlet(methods = ['POST'], resourceTypes = ['twcable:grabbit/jobrepository/clean'])
35+
class GrabbitCleanJobRepositoryServlet extends SlingAllMethodsServlet {
36+
37+
@Reference
38+
CleanJobRepository cleanJobRepository
39+
40+
@Override
41+
protected void doPost( @Nonnull SlingHttpServletRequest request, @Nonnull SlingHttpServletResponse response) {
42+
String hoursParam = request.getParameter("hours") ?: ""
43+
if(!hoursParam.isInteger()) {
44+
log.warn "Parameter 'hours' must be an integer"
45+
response.status = HttpServletResponse.SC_BAD_REQUEST
46+
response.writer.write("Parameter 'hours' must be an integer")
47+
return
48+
}
49+
int hours = hoursParam.toInteger()
50+
List<String> removedJobExecutions = cleanJobRepository.cleanJobRepository(hours)
51+
response.status = HttpServletResponse.SC_OK
52+
response.writer.write ("JobExecutions and the corresponding JobInstances, StepExecutions and ExecutionContexts " +
53+
"were removed. JobExecutionsIds that were removed: ${removedJobExecutions}")
54+
}
55+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2015 Time Warner Cable, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.twcable.grabbit.spring.batch.repository.servlets
18+
19+
import com.twcable.grabbit.spring.batch.repository.services.CleanJobRepository
20+
import org.apache.sling.api.SlingHttpServletRequest
21+
import org.apache.sling.api.SlingHttpServletResponse
22+
import spock.lang.Specification
23+
import spock.lang.Subject
24+
25+
@Subject(GrabbitCleanJobRepositoryServlet)
26+
class GrabbitCleanJobRepositoryServletSpec extends Specification {
27+
28+
def "Servlet handles the case when hours parameter is not passed"() {
29+
given:
30+
def servlet = new GrabbitCleanJobRepositoryServlet(cleanJobRepository: Mock(CleanJobRepository))
31+
def request = Mock(SlingHttpServletRequest)
32+
request.getParameter("hours") >> null
33+
def response = Mock(SlingHttpServletResponse)
34+
def writer = new StringWriter()
35+
response.getWriter() >> new PrintWriter(writer)
36+
when:
37+
servlet.doPost(request, response)
38+
39+
then:
40+
writer != null
41+
writer.toString() == "Parameter 'hours' must be an integer"
42+
}
43+
44+
def "Servlet handles the case when hours parameter is correctly passed"() {
45+
given:
46+
def clientJobRepository = Mock(CleanJobRepository)
47+
clientJobRepository.cleanJobRepository(_) >> (["id1","id2","id3"] as List<String>)
48+
def servlet = new GrabbitCleanJobRepositoryServlet(cleanJobRepository: clientJobRepository)
49+
def request = Mock(SlingHttpServletRequest)
50+
request.getParameter("hours") >> 5
51+
def response = Mock(SlingHttpServletResponse)
52+
def writer = new StringWriter()
53+
response.getWriter() >> new PrintWriter(writer)
54+
when:
55+
servlet.doPost(request, response)
56+
57+
then:
58+
writer != null
59+
writer.toString().contains("JobExecutionsIds that were removed")
60+
writer.toString().contains("[id1, id2, id3]")
61+
}
62+
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+CMSPe
55
bundleInstallRoot = /apps/grabbit/install
66

77
group = com.twcable.grabbit
8-
version = 5.0.3
8+
version = 5.0.1
99

1010
# Please keep alphabetical
1111
cglib_nodep_version = 2.2.2

0 commit comments

Comments
 (0)