Skip to content

WIP: ContinueOnError #73

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ For the Grabbit developers, [instructions for releasing a new version of Grabbit
* [Groovy v2.3.6](http://groovy.codehaus.org/Download)
* [Google Protocol Buffers v2.4.1](https://code.google.com/p/protobuf/downloads/list) - The compiler and runtime library is used for Serialization and De-serialization of Data
* [Spring Batch v2.2.7.RELEASE](http://docs.spring.io/spring-batch/2.2.x/downloads.html) - It is used on the server and client to read/write, marshal/unmarshall and send/receive the data to client in a controlled manner.
* [Jackalope v2.0.0](https://bintray.com/twcable/aem/jackalope/2.0.0/view) - Jackalope is used for testing
* [CQ Gradle Plugins v2.0.1](https://bintray.com/twcable/aem/cq-gradle-plugins/2.0.1/view) : They provide Gradle build support.
* [Jackalope](https://bintray.com/twcable/aem/jackalope/) - Jackalope is used for testing
* [CQ Gradle Plugins](https://bintray.com/twcable/aem/cq-gradle-plugins/) : They provide Gradle build support.
* [Gradle Protocol Buffers Plugin v0.9.1](http://search.maven.org/#artifactdetails%7Cws.antonov.gradle.plugins%7Cgradle-plugin-protobuf%7C0.9.1%7Cjar) - It provides easy integration of the ProtoBuf compiler with Gradle.

# LICENSE
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ allprojects {
// hack to allow getting to a working version of AEM 6.1 workflow-console jar
// without running afoul of licensing restrictions
flatDir { dirs rootProject.projectDir }

mavenLocal()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2015 Time Warner Cable, Inc.
*
* 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 com.twcable.grabbit.server.services

import com.twcable.grabbit.GrabbitConfiguration
import com.twcable.grabbit.client.services.ClientService
import com.twcable.grabbit.client.services.impl.DefaultClientService
import com.twcable.grabbit.jcr.AbstractJcrSpec
import com.twcable.jackalope.impl.sling.SimpleResourceResolverFactory
import com.twcable.jackalope.impl.sling.SlingRepositoryImpl
import org.apache.sling.jcr.api.SlingRepository
import org.springframework.context.ApplicationContext
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.support.ClassPathXmlApplicationContext
import org.springframework.context.support.StaticApplicationContext
import spock.lang.Subject

@Subject(ServerService)
class ClientServiceSpec extends AbstractJcrSpec {

SlingRepository slingRepository

ConfigurableApplicationContext appCtx

ClientService syncClientService


def setup() {
slingRepository = new SlingRepositoryImpl()

ApplicationContext parentAppCtx = new StaticApplicationContext()
parentAppCtx.beanFactory.registerSingleton("slingRepository", slingRepository)
parentAppCtx.beanFactory.registerSingleton("resourceResolverFactory", new SimpleResourceResolverFactory(slingRepository))
parentAppCtx.refresh()
appCtx = new ClassPathXmlApplicationContext(["META-INF/spring/client-batch-job.xml", "META-INF/spring/client-workflow-on-step.xml", "META-INF/spring/client-workflow-off-step.xml"] as String[], parentAppCtx)

syncClientService = new DefaultClientService(slingRepository: slingRepository,
applicationContext: appCtx)
}


def "Service initiate a grab and return jobs"() {
when:
def jobIds = syncClientService.initiateGrab(new GrabbitConfiguration("admin", "adminPass", "testbox", "4502", false, [new GrabbitConfiguration.PathConfiguration("/content/test", [], [], false)]), "admin")

then:
jobIds.size() == 1
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import groovy.util.logging.Slf4j
import org.springframework.batch.core.BatchStatus
import org.springframework.batch.core.JobExecution
import org.springframework.batch.core.launch.JobOperator
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.ApplicationContext

import javax.annotation.Nonnull

Expand All @@ -48,7 +48,9 @@ class ClientBatchJob {
public static final String CONTENT_AFTER_DATE = "contentAfterDate"
public static final String DELETE_BEFORE_WRITE = "deleteBeforeWrite"

@SuppressWarnings("GrFinalVariableAccess")
private final Map<String, String> jobParameters
@SuppressWarnings("GrFinalVariableAccess")
private final JobOperator jobOperator


Expand Down Expand Up @@ -80,12 +82,12 @@ class ClientBatchJob {

@CompileStatic
static class ServerBuilder {
final ConfigurableApplicationContext configAppContext
final ApplicationContext configAppContext
String host
String port


ServerBuilder(ConfigurableApplicationContext configurableApplicationContext) {
ServerBuilder(ApplicationContext configurableApplicationContext) {
this.configAppContext = configurableApplicationContext
}

Expand Down Expand Up @@ -193,16 +195,16 @@ class ClientBatchJob {

ClientBatchJob build() {
final jobParameters = [
"timestamp" : System.currentTimeMillis() as String,
"${PATH}" : pathConfiguration.path,
"${HOST}" : serverBuilder.host,
"${PORT}" : serverBuilder.port,
"${CLIENT_USERNAME}" : credentialsBuilder.clientUsername,
"${SERVER_USERNAME}" : credentialsBuilder.serverUsername,
"${SERVER_PASSWORD}" : credentialsBuilder.serverPassword,
"${EXCLUDE_PATHS}" : pathConfiguration.excludePaths.join("*"),
"${WORKFLOW_CONFIGS}" : pathConfiguration.workflowConfigIds.join("|"),
"${DELETE_BEFORE_WRITE}" : "${pathConfiguration.deleteBeforeWrite}"
timestamp : System.currentTimeMillis() as String,
(PATH) : pathConfiguration.path,
(HOST) : serverBuilder.host,
(PORT) : serverBuilder.port,
(CLIENT_USERNAME) : credentialsBuilder.clientUsername,
(SERVER_USERNAME) : credentialsBuilder.serverUsername,
(SERVER_PASSWORD) : credentialsBuilder.serverPassword,
(EXCLUDE_PATHS) : pathConfiguration.excludePaths.join("*"),
(WORKFLOW_CONFIGS) : pathConfiguration.workflowConfigIds.join("|"),
(DELETE_BEFORE_WRITE): "${pathConfiguration.deleteBeforeWrite}"
] as Map<String, String>

if (deltaContentBuilder.doDeltaContent) {
Expand All @@ -212,18 +214,15 @@ class ClientBatchJob {
if (lastSuccessFulJobExecution) {
final contentAfterDate = DateUtil.getISOStringFromDate(lastSuccessFulJobExecution.endTime)
log.info "Last Successful run for ${pathConfiguration.path} was on $contentAfterDate"
return new ClientBatchJob(
jobParameters + (["${CONTENT_AFTER_DATE}": contentAfterDate] as Map<String, String>),
serverBuilder.configAppContext.getBean("clientJobOperator", JobOperator)
)
jobParameters.put(CONTENT_AFTER_DATE, contentAfterDate)
}
else {
log.warn "There was no successful job run for $pathConfiguration.path. Defaulting to normal content grab"
}
}
return new ClientBatchJob(
jobParameters,
serverBuilder.configAppContext.getBean("clientJobOperator", JobOperator)
jobParameters,
serverBuilder.configAppContext.getBean("clientJobOperator", JobOperator)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ import com.twcable.grabbit.client.batch.ClientBatchJob
import com.twcable.grabbit.client.services.ClientService
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.felix.scr.annotations.Activate
import org.apache.felix.scr.annotations.Component
import org.apache.felix.scr.annotations.Reference
import org.apache.felix.scr.annotations.Service
import org.apache.sling.jcr.api.SlingRepository
import org.springframework.batch.core.JobExecution
import org.springframework.batch.core.JobInstance
import org.springframework.batch.core.explore.JobExplorer
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.ApplicationContext

@Slf4j
@CompileStatic
Expand All @@ -44,14 +43,8 @@ class DefaultClientService implements ClientService {
@Reference(bind = 'setSlingRepository')
SlingRepository slingRepository

@Reference(bind = 'setConfigurableApplicationContext')
ConfigurableApplicationContext configurableApplicationContext


@Activate
void activate() {
log.info "Activate\n\n"
}
@Reference(bind = 'setApplicationContext')
ApplicationContext applicationContext


@Override
Expand All @@ -67,13 +60,13 @@ class DefaultClientService implements ClientService {

for (PathConfiguration pathConfig : configuration.pathConfigurations) {
try {
final clientBatchJob = new ClientBatchJob.ServerBuilder(configurableApplicationContext)
.andServer(configuration.serverHost, configuration.serverPort)
.andCredentials(clientUsername, configuration.serverUsername, configuration.serverPassword)
.andDoDeltaContent(doDeltaContent)
.andClientJobExecutions(clientJobExecutions)
.andConfiguration(pathConfig)
.build()
final clientBatchJob = new ClientBatchJob.ServerBuilder(applicationContext)
.andServer(configuration.serverHost, configuration.serverPort)
.andCredentials(clientUsername, configuration.serverUsername, configuration.serverPassword)
.andDoDeltaContent(doDeltaContent)
.andClientJobExecutions(clientJobExecutions)
.andConfiguration(pathConfig)
.build()
final Long currentJobExecutionId = clientBatchJob.start()
jobExecutionIds << currentJobExecutionId
}
Expand All @@ -88,7 +81,7 @@ class DefaultClientService implements ClientService {


private List<JobExecution> fetchAllClientJobExecutions() {
final explorer = configurableApplicationContext.getBean("clientJobExplorer", JobExplorer)
final explorer = applicationContext.getBean("clientJobExplorer", JobExplorer)
final instances = explorer.getJobInstances("clientJob", 0, Integer.MAX_VALUE - 1) ?: [] as List<JobInstance>
final executions = instances.collect { explorer.getJobExecutions(it) }.flatten() as List<JobExecution>
executions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import org.apache.sling.api.SlingHttpServletRequest
import org.apache.sling.api.SlingHttpServletResponse
import org.apache.sling.api.servlets.SlingAllMethodsServlet
import org.springframework.batch.core.explore.JobExplorer
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.ApplicationContext

import javax.servlet.http.HttpServletResponse

Expand All @@ -40,8 +40,8 @@ import javax.servlet.http.HttpServletResponse
@SlingServlet(methods = ['GET', 'PUT'], resourceTypes = ['twcable:grabbit/job'])
class GrabbitServlet extends SlingAllMethodsServlet {

@Reference(bind = 'setConfigurableApplicationContext')
ConfigurableApplicationContext configurableApplicationContext
@Reference(bind = 'setApplicationContext')
ApplicationContext applicationContext

@Reference(bind = 'setClientService')
ClientService clientService
Expand Down Expand Up @@ -114,7 +114,7 @@ class GrabbitServlet extends SlingAllMethodsServlet {


private String getJsonString(String jobId) {
final JobExplorer jobExplorer = configurableApplicationContext.getBean("clientJobExplorer", JobExplorer)
final JobExplorer jobExplorer = applicationContext.getBean("clientJobExplorer", JobExplorer)
if (jobId.isNumber()) {
//Returns Status for A Job
final ClientJobStatus status = ClientJobStatus.get(jobExplorer, Long.valueOf(jobId))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,62 +22,59 @@ import org.springframework.batch.core.BatchStatus
import org.springframework.batch.core.JobExecution
import org.springframework.batch.core.JobParametersBuilder
import org.springframework.batch.core.launch.JobOperator
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.ApplicationContext
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Subject
import spock.lang.Unroll

@Subject(ClientBatchJob)
@SuppressWarnings("GroovyAccessibility")
class ClientBatchJobSpec extends Specification {

@Shared
def dateNow


def setupSpec() {
dateNow = new Date()
}
Date dateNow = new Date()


@Unroll
def "Make sure ClientBatch job gets configured correctly"() {
def "Job Params: #path #doDeltaContent #contentAfterDate #deleteBeforeWrite"() {
when:
final appContext = Mock(ConfigurableApplicationContext)
final appContext = Mock(ApplicationContext)
appContext.getBean(_ as String, JobOperator) >> Mock(JobOperator)
final job = new ClientBatchJob.ServerBuilder(appContext)
.andServer("host", "port")
.andCredentials("clientUser", "serverUser", "serverPass")
.andDoDeltaContent(doDeltaContent)
.andClientJobExecutions(jobExecutions)
.andConfiguration(new GrabbitConfiguration.PathConfiguration(path, [], [], deleteBeforeWrite))
.build()
.andServer("host", "port")
.andCredentials("clientUser", "serverUser", "serverPass")
.andDoDeltaContent(doDeltaContent)
.andClientJobExecutions(jobExecutions)
.andConfiguration(new GrabbitConfiguration.PathConfiguration(path, [], [], deleteBeforeWrite))
.build()

then:
job != null
job.jobParameters != null
job.jobParameters.get("${ClientBatchJob.PATH}") == path
job.jobParameters.get("${ClientBatchJob.CONTENT_AFTER_DATE}") == contentAfterDate
job.jobParameters.get("${ClientBatchJob.DELETE_BEFORE_WRITE}").toBoolean() == deleteBeforeWrite
job.jobParameters.get(ClientBatchJob.PATH) == path
job.jobParameters.get(ClientBatchJob.CONTENT_AFTER_DATE) == contentAfterDate
job.jobParameters.get(ClientBatchJob.DELETE_BEFORE_WRITE).toBoolean() == deleteBeforeWrite

where:
doDeltaContent | path | contentAfterDate | deleteBeforeWrite
true | "/path1" | DateUtil.getISOStringFromDate(dateNow) | true
false | "/path1" | null | false
true | "/path2" | null | true
false | "/path2" | null | false

path | doDeltaContent | contentAfterDate | deleteBeforeWrite
"/path1" | true | DateUtil.getISOStringFromDate(dateNow) | true
"/path1" | false | null | false
"/path2" | true | null | true
"/path2" | false | null | false
}


def getJobExecutions() {
def ex1 = new JobExecution(1, new JobParametersBuilder().addString("path", "/path1").toJobParameters())
ex1.endTime = dateNow
ex1.status = BatchStatus.COMPLETED

def ex2 = new JobExecution(2, new JobParametersBuilder().addString("path", "/path2").toJobParameters())
ex2.endTime = dateNow
ex2.status = BatchStatus.FAILED

[ex1, ex2]
}

}
Loading