Code Monkey home page Code Monkey logo

grabbit's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grabbit's Issues

Grabbit not working in localhost

I have newly started working on AEM 6.01 SP2 and found grabbit to copy data from different server to localhost but could not make it work in my localhost. Below is the error trace. Please help me to identify what went wrong and what changes are required to make it work. Appreciate your help!

  • Trying ::1...
  • Connected to localhost (::1) port 4502 (#0)
  • Server auth using Basic with user 'admin'

    PUT /grabbit/job HTTP/1.1
    Authorization: Basic YWRtaW46YWRtaW4=
    User-Agent: curl/7.30.0
    Host: localhost:4502
    Accept: /
    Content-Type: application/json
    Content-Length: 1154
    Expect: 100-continue

    < HTTP/1.1 100 Continue
    } [data not shown]
    < HTTP/1.1 500 Server Error
    < Date: Thu, 21 May 2015 20:26:25 GMT
    < X-Content-Type-Options: nosniff
    < Set-Cookie: cq-authoring-mode=CLASSIC;Path=/
    < Expires: Thu, 01 Jan 1970 00:00:00 GMT
    < Content-Type: text/html;charset=utf-8
    < Transfer-Encoding: chunked
  • Server Jetty(8.1.14.v20131031) is not blacklisted
    < Server: Jetty(8.1.14.v20131031)
  • HTTP error before end of send, stop sending

Grabbit Server goes Out Of Memory for large content paths

Paths with large amounts of content (often seen in /content/dam ) tend run out of memory.

The problem has been observed to be alleviated by increasing the heap size (from 2GB to 4GB)

NOTE: Try out server using the raw methods on protobuf's CodedOutputStream ... rather than the node API.
Reference : MessageLite : https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/MessageLite
CodedOutputStream : https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/CodedOutputStream

Consistent stack track on copy, "Invalid last path element for adding node event[2] relative to node"

We get the following error on copy every single time. The error was located in the batch-client.log file. The job stops and does not continue.

16.06.2015 19:04:34.723 [clientJobLauncherTaskExecutor-9] com.twc.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter ERROR Exception writing JCR Nodes to current JCR Session : session-admin-6306766. javax.jcr.RepositoryException: Invalid last path element for adding node event[2] relative to node /content/(OBFUSCATED_PATH)/jcr:content
at org.apache.jackrabbit.core.session.AddNodeOperation.perform(AddNodeOperation.java:72)
at org.apache.jackrabbit.core.session.AddNodeOperation.perform(AddNodeOperation.java:37)
at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91)
at org.apache.jackrabbit.core.NodeImpl.addNodeWithUuid(NodeImpl.java:1814)
at org.apache.jackrabbit.core.NodeImpl.addNode(NodeImpl.java:1774)
at org.apache.jackrabbit.commons.JcrUtils.getOrCreateByPath(JcrUtils.java:1136)
at org.apache.jackrabbit.commons.JcrUtils.getOrCreateByPath(JcrUtils.java:1016)
at org.apache.jackrabbit.commons.JcrUtils.getOrCreateByPath(JcrUtils.java:909)
at com.twc.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter.writeToJcr(JcrNodesWriter.groovy:95)
at com.twc.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter.write(JcrNodesWriter.groovy:57)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:151)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:274)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:199)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:141)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:151)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:130)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

Double check the Workflow Task done by Grabbit

Grabbit currently manages workflow launcher configs for paths that include DAM content. It turns off the asked workflow launcher configs before writing DAM content to the client and turns them back on at the end.
Adobe (http://docs.adobe.com/docs/en/cq/current/dam/managing_digitalassets.html#PackagingAssets) and other resources online resources (http://aemtips.blogspot.com/2013/05/how-to-migrate-huge-number-of-assets.html) recommend to ONLY turn off a couple of WorkflowLauncher bundles before writing DAM content.
Investigate if this is all we need and fix the Grabbit job correspondingly.

Protected user/group properties

Running against /home complains about mandatory property "rep:principalName" being missing.

Users/groups are being stored in Authorizable nodes. Even though both sides are running as "admin", theSession().save() in JcrNodesWriter gives errors like: javax.jcr.nodetype.ConstraintViolationException: OakConstraint0021: /home/groups/b[[rep:Group]]: Mandatory property rep:principalName not found in a new node

The issue is that this is a protected property in CRX 2.4 / JCR so the JCR API can not be used. (c.f. Interaction With Protected Properties, Repository Model - Protected.)

Before writing we need to check if the node type to be written is a user/group and use Jackrabbit's UserManager API to create the node.
(see com.twcable.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter in Grabbit.)

Add HATEOAS-style to the REST API

If you go to /grabbit/ and all "legal" subpaths you should always get a response. If it's not specific data, it should at least give HTML/JSON on legal calls from there. (i.e., self-documenting)

Introduce a "deleteBeforeWrite" flag in Grabbit Configs

This flag will be per path in a grabbit configuration. If this flag is enabled for a particular path, then that path will be deleted from the client before writing.

The configuration can look something like this :

{
    "path" : "/content/someContent",
    "workflowConfigIds" :
        [
            "/etc/workflow/launcher/config/update_asset_mod",
            "/etc/workflow/launcher/config/update_asset_create",
            "/etc/workflow/launcher/config/dam_xmp_nested_writeback",
            "/etc/workflow/launcher/config/dam_xmp_writeback"
        ],
     "deleteBeforeWrite" : true
}

cc: @jazeren1 @jdigger

Refactor the Gradle build setup to be more like a single module project

Currently, the Grabbit build setup has more of a multi-module project flavor to it. For example, there is a top level grabbit project and then there is a subproject again with the name grabbit.

There is a lot of potential for re-work of the setup to make it much simpler; both to understand and maintain.

Issue while building grabbit - Authentication required when getting bundle info

I am trying to install grabbit on my development environment, but it fails when trying to run the ':grabbit:checkBundleStatus' task.

Running gradlew with the --debug flag, I can see that the issue is related to the installer not being able to query http://localhost:4502/system/console/bundles.json for the bundle list.

Log reads as follows:

10:06:33.165 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: GET /system/console/bundles.json HTTP/1.1
10:06:33.165 [DEBUG] [org.apache.http.headers] >> GET /system/console/bundles.json HTTP/1.1
10:06:33.165 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YWRtaW46YWRtaW4
10:06:33.165 [DEBUG] [org.apache.http.headers] >> Accept: application/json
10:06:33.165 [DEBUG] [org.apache.http.headers] >> Host: localhost:4502
10:06:33.165 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
10:06:33.165 [DEBUG] [org.apache.http.headers] >> User-Agent: Apache-HttpClient/4.1.2 (java 1.5)
10:06:33.167 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 401 Unauthorized
10:06:33.167 [DEBUG] [org.apache.http.headers] << HTTP/1.1 401 Unauthorized
10:06:33.167 [DEBUG] [org.apache.http.headers] << Connection: Keep-Alive
10:06:33.167 [DEBUG] [org.apache.http.headers] << Server: Day-Servlet-Engine/4.1.52 
10:06:33.167 [DEBUG] [org.apache.http.headers] << Content-Length: 0
10:06:33.167 [DEBUG] [org.apache.http.headers] << Date: Thu, 30 Apr 2015 15:06:33 GMT
10:06:33.167 [DEBUG] [org.apache.http.headers] << WWW-Authenticate: Basic realm="OSGi Management Console"
10:06:33.167 [DEBUG] [org.apache.http.client.protocol.ResponseAuthCache] Caching 'basic' auth scheme for http://localhost:4502
10:06:33.167 [DEBUG] [org.apache.http.impl.client.DefaultHttpClient] Connection can be kept alive indefinitely
10:06:33.167 [DEBUG] [org.apache.http.impl.client.DefaultHttpClient] Target requested authentication
10:06:33.167 [DEBUG] [org.apache.http.impl.client.DefaultHttpClient] Authorization challenge processed
10:06:33.167 [DEBUG] [org.apache.http.impl.client.DefaultHttpClient] Authentication scope: BASIC 'OSGi Management Console'@localhost:4502
10:06:33.167 [DEBUG] [org.apache.http.impl.client.DefaultHttpClient] Authentication failed

It seems that the installer is trying to get the bundle list but it can't because it needs authentication.

I grepped around in the source code but didn't find any reference to the task, to be able to change it and add the proper credentials.

I wonder if this is a real bug/enhancement, or if it is just an issue I am having. In any case, I hope you can help me out.

I can hand over additional environment info if need be.

Ricardo

Parallelize presync steps as advisable

We should be able to use batch:split/batch:flow to parallelize presync steps such as deleteBeforeWrite, and namespaceSync. Parallelizing clientWorkflowOff may not be safe, as the client could have workflows around deletion of nodes; and we may run into a situation where nodes are deleted, and workflows are started, before the workflows are turned off.

Error activating bundle: "Error creating bean with name 'clientJobLauncher'"

We are consistently getting this error on our production servers. I have tried restarting the Adobe instances, but the error is the same. We are not getting the error in lower environments, only production. I'm working to see if there are any differences between the environments, but so far I haven't found any. Here is the error.

20.07.2015 12:58:26.843 -0400 ERROR [SpringOsgiExtenderThread-6] org.springframework.osgi.extender.internal.activator.ContextLoaderListener Application context refresh failed (OsgiBundleXmlApplicationContext(bundle=com.twcable.grabbit, config=osgibundle:/META-INF/spring/*.xml)) org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientJobLauncher' defined in URL [bundle://629.0:0/META-INF/spring/client-batch-job-context.xml]: Cannot resolve reference to bean 'clientJobRepository' while setting bean property 'jobRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientJobRepository' defined in URL [bundle://629.0:0/META-INF/spring/client-batch-job-context.xml]: Instantiation of bean failed; nested exception is java.lang.VerifyError: Stack map does not match the one at exception handler 54
Exception Details:
Location:
com/twcable/grabbit/spring/batch/repository/JcrJobRepositoryFactoryBean.getJobExecutionDao()Lorg/springframework/batch/core/repository/dao/JobExecutionDao; @54: dup
Reason:
Type top (current frame, locals[0]) is not assignable to 'com/twcable/grabbit/spring/batch/repository/JcrJobRepositoryFactoryBean' (stack map, locals[0])
Current Frame:
bci: @52
flags: { }
locals: { }
stack: { 'java/lang/Throwable' }
Stackmap Frame:
bci: @54
flags: { }
locals: { 'com/twcable/grabbit/spring/batch/repository/JcrJobRepositoryFactoryBean', '[Ljava/lang/Object;', 'java/lang/Object' }
stack: { 'java/lang/Throwable' }
Bytecode:
0000000: 03bd 0043 4c13 0172 1301 732a 12ea 1301
0000010: 742b b801 7a4d 2ab4 0062 014e 593a 0413
0000020: 0172 1301 732a 12ea 1301 742b 2c2d 1904
0000030: b801 7eb0 00bf 593a 0501 3a06 1301 7213
0000040: 0173 2a12 ea13 0174 2b2c 1905 1906 b801
0000050: 7ebf
Exception Handler Table:
bci [22, 54] => handler: 54
Stackmap Table:
full_frame(@52,{},{Object[#100]})
full_frame(@54,{Object[#2],Object[#384],Object[#67]},{Object[#100]})

    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:329)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)

Split Up build.gradle

The build.gradle file is gaining in size and has the potential to get overwhelming. It can be broken up in to smaller files to keep contents organized.

Handle errors/exceptions from Server gracefully

Whenever we run a Grabbit job and if server fails to send the path requested (various reasons; like The requested path was not found, Could not access the requested path, Some other error during sending the requested path.), we do not transmit that information from Server to Client in order to inform the client that something failed.

This can be handled more gracefully. For example; if a path is not found; we can send a 404 from Server back to the Client with a proper message about what happened. This way; we can also further enhance the Client Grabbit Job Status API to include such messages in case of job failures.

Implement Server-Push Sync

A client-server pull sync like what is implemented now usually suffices for a manual developer machine sync from a data warehouse or higher environment; However, the common need of syncing a set of environments with content from a single environment (such as DWH to clustered betas, or CI) would benefit from a server to client push sync in a one-to-many fashion. The alternative is synching each, one at a time, which can be time consuming; Especially for large data sets.

This would also give infrastructure to support future enhancements, such as a "transparent content sync from a DWH to subscribing developer machines on a network.", which would arguably help to alleviate content discrepancy issues in a CD implemented AEM project.

Implement a push mode that sends sync data on a network to subscribing "server group members." Consider placing protoc on top one of a number of IP multicast protocols (PGM, RUDP, UDT) that would support this need. JGroups is a popular reliable multicast API for Java.

Should we now remove the "jackrabbit-sessionImpl.log" file (At least for 3.x.x and 4.x.x releases)?

jackrabbit-sessionImpl.log was created to mitigate confusing WARNING messages when writing content for Grabbit Client.

As the comments in the XML now suggest, the issue was supposedly fixed in AEM 6+. And I also confirmed that these WARNING messages are infact not an issue anymore at least in AEM 6. If that's the case for AEM 6.1 also, should we get rid of this logger for 3.x.x and 4.x.x releases?

Make the client error-out cleanly when the server is not installed

The sheer volume of errors generated by the server not being ready to accept messages from the client makes it very easy to be confused what the problem really is. See #28.

When the client first tries to make the connection to the server it should cleanly "notice" that the server isn't there (i.e., that Grabbit is not installed on the server, as opposed to the server not being up or a network problem or the like). It should then give a clear error as to the cause ("Grabbit does not seem to be installed on xxxxxxxx") and stop.

Should this (at least the verification) be done synchronously with the PUT done to the client so that the caller can receive the error right away? Or should it be async with when the client actually tries to communicate with the server?

Some paths jobs randomly seem to fail on "TruncatedChunkException"

02.02.2015 21:30:13.471 *ERROR* [clientJobLauncherTaskExecutor-1] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientJcrNodes in job clientJob org.apache.http.TruncatedChunkException: Truncated chunk ( expected size: 32768; actual size: 16488)
    at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:182)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)

.. happening on the client.

Add better context to error logging

For example, currently an error message looks like this:

01.09.2015 21:39:59.542 *ERROR* [10.143.18.200 [1441143599540] GET /grabbit/job HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught Throwable javax.jcr.PathNotFoundException: /content/dam/VirtualAssistant
    at org.apache.jackrabbit.core.ItemManager.getNode(ItemManager.java:577)
    at org.apache.jackrabbit.core.session.SessionItemOperation$6.perform(SessionItemOperation.java:129)

The problem is, there's no (reasonable) way to know what job caused that, especially when there's lots of jobs and multiple clients.

We should try / catch to add better context information such as the job id, possibly the IP of the client, etc.

Protocol message end-group tag did not match expected tag.

Hi my name is Nicola I am an engineer at Infield Design working on OPS tasks involved with AEM. I'm currently trying to setup your Grabbit tool but I've stumbled on an error that I can't seem to resolve. I am trying to sync up content between a dev server and a local instance. Any help would very appreciated. Here is what I get in my error.log when I execute grabbit:

01.05.2015 08:16:31.381 WARN [0:0:0:0:0:0:0:1 [1430493391379] PUT /grabbit/job HTTP/1.1] com.twcable.grabbit.resources.GrabbitResourceProvider Unable to find resource for path: /grabbit.
01.05.2015 08:16:31.381 WARN [0:0:0:0:0:0:0:1 [1430493391379] PUT /grabbit/job HTTP/1.1] com.twcable.grabbit.GrabbitConfiguration Input doesn't contain deltaContent for a boolean value. Will default to false
01.05.2015 08:16:31.381 INFO [0:0:0:0:0:0:0:1 [1430493391379] PUT /grabbit/job HTTP/1.1] org.springframework.batch.core.launch.support.SimpleJobOperator Checking status of job with name=clientJob
01.05.2015 08:16:31.672 INFO [0:0:0:0:0:0:0:1 [1430493391379] PUT /grabbit/job HTTP/1.1] org.springframework.batch.core.launch.support.SimpleJobOperator Attempting to launch job with name=clientJob and parameters=timestamp=1430493391381,path=/content/someone/en_us,host=IPForServer,port=4502,username=usernameForServer,password=passwordForServer,workflowConfigIds=
01.05.2015 08:16:31.741 INFO [0:0:0:0:0:0:0:1 [1430493391379] PUT /grabbit/job HTTP/1.1] com.twcable.grabbit.servlets.GrabbitServlet Jobs started : [7697877024238993081]
01.05.2015 08:16:31.741 INFO [clientJobLauncherTaskExecutor-6] org.springframework.batch.core.launch.support.SimpleJobLauncher Job: [FlowJob: [name=clientJob]] launched with the following parameters: [{workflowConfigIds=, port=4502, password=passwordForServer, host=IPForServer, timestamp=1430493391381, path=/content/someone/en_us, username=usernameForServer}]
01.05.2015 08:16:33.564 INFO [clientJobLauncherTaskExecutor-6] org.springframework.batch.core.job.SimpleStepHandler Executing step: [clientPreprocessor]
01.05.2015 08:16:33.577 ERROR [clientJobLauncherTaskExecutor-6] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientPreprocessor in job clientJob
com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag.
at com.google.protobuf.InvalidProtocolBufferException.invalidEndTag(InvalidProtocolBufferException.java:73)
at com.google.protobuf.CodedInputStream.checkLastTagWas(CodedInputStream.java:124)
at com.google.protobuf.AbstractMessageLite$Builder.mergeFrom(AbstractMessageLite.java:213)
at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:746)
at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:238)
at com.google.protobuf.AbstractMessageLite$Builder.mergeDelimitedFrom(AbstractMessageLite.java:282)
at com.google.protobuf.AbstractMessage$Builder.mergeDelimitedFrom(AbstractMessage.java:760)
at com.google.protobuf.AbstractMessageLite$Builder.mergeDelimitedFrom(AbstractMessageLite.java:288)
at com.google.protobuf.AbstractMessage$Builder.mergeDelimitedFrom(AbstractMessage.java:752)
at com.twcable.grabbit.proto.PreProcessorProtos$Preprocessors.parseDelimitedFrom(PreProcessorProtos.java:149)
at com.twcable.grabbit.client.batch.steps.preprocessor.PreprocessTasklet.execute(PreprocessTasklet.groovy:53)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:141)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:151)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:130)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
01.05.2015 08:16:33.617 INFO [clientJobLauncherTaskExecutor-6] org.springframework.batch.core.launch.support.SimpleJobLauncher Job: [FlowJob: [name=clientJob]] completed with the following parameters: [{workflowConfigIds=, port=4502, password=passwordForServer, host=IPForServer, timestamp=1430493391381, path=/content/someone/en_us, username=usernameForServer}] and the following status: [FAILED]

Try to remove need for Adobe JARs

Since Adobe's public repo does not have functional 6.1 jars, can we either remove the need to use the workflow jar altogether or potentially compile against an older version so that CI works again?

Nodes failing with NPE or IllegalStateException

Nodes are failing with a NullPointerException or IllegalStateException on latest 6.1 branch recently merged with master.

Example node (author) on DWH server:
/content/dam/residential/specials-ola

Start of stack trace for NPE:
16.07.2015 18:16:17.044 ERROR [clientJobLauncherTaskExecutor-1] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientWorkflowOff in job clientJob
java.lang.NullPointerException: null
at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager.processConfig(DefaultWorkFlowManager.groovy:122)
at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager.access$0(DefaultWorkFlowManager.groovy)
at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager$_turnOff_closure1.doCall(DefaultWorkFlowManager.groovy:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)

Stacktrace for IllegalStateException:

16.07.2015 19:01:54.886 ERROR [clientJobLauncherTaskExecutor-3] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientWorkflowOn in job clientJob
java.lang.IllegalStateException: launcherConfig Map value for /etc/workflow/launcher/config/dam_xmp_writeback cannot be null
at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager$_turnOn_closure2.doCall(DefaultWorkFlowManager.groovy:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
at groovy.lang.Closure.call(Closure.java:423)
at groovy.lang.Closure.call(Closure.java:439)

Remove Client UI

The Client UI has since been broken and needs to be redesigned. It should be pulled out of the codebase until it can be properly redeveloped.

Be able to specify "continue on error"

Grabbit is currently -- by design -- quite fragile. If there's any bad data, incomplete transmission of data, etc. it is blatantly obvious that something went wrong with no possibility of "silent" errors. Better to fail fast and spectacularly than to let issues hide.

That said, sometimes "99%" is good enough, especially when dealing with development systems and/or unreliable networks. There should be a way to say for a particular job that it should log any errors it gets, but otherwise just keep going.

Restart Required After Install

After installing the Grabbit project onto CQ instances by running the gradle command:
"gradlew install"
The CQ instances that were installed to leave the Spring Batch Infrastructure bundle in the "Installed" state. Because Spring Batch is required to run Grabbit, Grabbit is unusable at this point.
The current work around is simply to restart the CQ instances and Spring Batch starts up correctly. However, this is not a long term solution and needs to be addressed.

Delta content syncs

The feature is "implemented" but it never got properly tested.

https://github.com/TWCable/grabbit/search?utf8=%E2%9C%93&q=deltaContent

It's based on last successful jobexecution "endTime" for a path on the client.

if(afterDateString) { log.info "Path : $decodedPath, Exclude Paths: $decodedExcludePaths, AfterDate String : $afterDateString. Will send only delta content" }

if (deltaContentBuilder.doDeltaContent) {
final lastSuccessFulJobExecution = jobExecutionsBuilder.jobExecutions?.find {
it.jobParameters.getString(PATH) == pathConfiguration.path && (it.status == BatchStatus.COMPLETED)
}
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)
)
}
else {
log.warn "There was no successful job run for $pathConfiguration.path. Defaulting to normal content grab"
}
}

Needs cleanup, testing and documentation.

If "clientJcrNodes" step fails, the workflow configs are not cleaned up

If clientJcrNodes step fails for some reason, the step after it workflowOnTasklet does not get executed and leaves the workflow configs in an inconsistent state.
We should either :

  1. Make sure workflowOnTasklet ALWAYS gets executed
  2. Catch when an exception happens in clientJcrNodes and manually call the {{workflowOnTasklet}'s execute() method (seems hacky)
    --A better option would be to NOT have "workflowOffTasklet" and "workflowOnTasklet" as separate steps, but rather have them as "things to do" inside the clientJcrNodesStep

NPE in DefaultWorkFlowManager.processConfig

Running v4.0.0

*ERROR* [SimpleAsyncTaskExecutor-43] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientWorkflowOff in job clientJob
java.lang.NullPointerException: null
    at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager.processConfig(DefaultWorkFlowManager.groovy:122)
    at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager.access$0(DefaultWorkFlowManager.groovy)
    at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager$_turnOff_closure1.doCall(DefaultWorkFlowManager.groovy:77)

Improved handling of conflicting jcr:primaryType

Between AEM 5.6.1 and 6.1, there was a change in the jcr:primaryType (cq:Tag to nt:folder) for the node /etc/tags/forums. If you try to copy this node, the job will fail and you'll get the following error:

*ERROR* [clientJobLauncherTaskExecutor-6] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientJcrNodes in job clientJob
javax.jcr.nodetype.ConstraintViolationException: No matching property definition: jcr:description =
        at org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate.setProperty(NodeDelegate.java:522)

In this case, the situation seems fairly innocuous, and just a warning that the server jcr:PrimaryType does not match the existing client and either doing a no op or doing the conversion for that node would seem to work. This would allow you to avoid having to work around the node.

If this isn't possible, or desired, just a clearer error message indicating the primaryType doesn't match may be helpful to a user of Grabbit.

Server should be able to provide pre-defined "job sets"

Right now each client has to maintain its own JSON file(s) for defining the copy jobs, which is error-prone -- especially as authors change the "shape" of the JCR tree.

The server should be able to provide centrally managed configuration sets. For example, "Full", "Base" (enough to get a developer environment up and running quickly), sets for each major content area, etc.

org.springframework.batch.infrastructure failed to start after package installed

Error in log:
27.03.2015 13:45:05.521 ERROR [0:0:0:0:0:0:0:1 [1427463905517] POST /system/console/bundles/354 HTTP/1.1] cqse-httpservice %bundles.pluginTitle: Cannot start (org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve bundle revision org.springframework.batch.infrastructure [354.0] because it exports package 'org.springframework.batch.repeat' and is also exposed to it from bundle revision org.springframework.batch.infrastructure [327.0] via the following dependency chain:

org.springframework.batch.infrastructure [354.0]
import: (&(osgi.wiring.package=org.springframework.batch.core)(version>=2.0.0)(!(version>=3.0.0)))
|
export: osgi.wiring.package=org.springframework.batch.core; uses:=org.springframework.batch.repeat
org.springframework.batch.core [353.0]
import: (&(osgi.wiring.package=org.springframework.batch.repeat)(version>=2.2.0)(!(version>=3.0.0)))
|
export: osgi.wiring.package=org.springframework.batch.repeat
org.springframework.batch.infrastructure [327.0]) org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve bundle revision org.springframework.batch.infrastructure [354.0] because it exports package 'org.springframework.batch.repeat' and is also exposed to it from bundle revision org.springframework.batch.infrastructure [327.0] via the following dependency chain:

org.springframework.batch.infrastructure [354.0]
import: (&(osgi.wiring.package=org.springframework.batch.core)(version>=2.0.0)(!(version>=3.0.0)))
|
export: osgi.wiring.package=org.springframework.batch.core; uses:=org.springframework.batch.repeat
org.springframework.batch.core [353.0]
import: (&(osgi.wiring.package=org.springframework.batch.repeat)(version>=2.2.0)(!(version>=3.0.0)))
|
export: osgi.wiring.package=org.springframework.batch.repeat
org.springframework.batch.infrastructure [327.0]
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3968)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2025)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:942)
at org.apache.felix.webconsole.internal.core.BundlesServlet.doPost(BundlesServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.felix.webconsole.internal.servlet.OsgiManager.service(OsgiManager.java:526)
at org.apache.felix.webconsole.internal.servlet.OsgiManager.service(OsgiManager.java:450)
at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:96)
at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:79)
at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:42)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:49)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:127)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:55)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:179)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:263)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75)
at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:88)
at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:76)
at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:47)
at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:33)
at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:48)
at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:39)
at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at com.day.j2ee.servletengine.ServletRuntimeEnvironment.service(ServletRuntimeEnvironment.java:250)
at com.day.j2ee.servletengine.RequestDispatcherImpl.doFilter(RequestDispatcherImpl.java:321)
at com.day.j2ee.servletengine.RequestDispatcherImpl.service(RequestDispatcherImpl.java:340)
at com.day.j2ee.servletengine.RequestDispatcherImpl.service(RequestDispatcherImpl.java:383)
at com.day.j2ee.servletengine.ServletHandlerImpl.process(ServletHandlerImpl.java:335)
at com.day.j2ee.servletengine.HttpListener$Worker.run(HttpListener.java:644)
at java.lang.Thread.run(Thread.java:745)

Grabbit fails to push content when using workflowConfigs for nodes without workflow

When using workflowConfigIds with AEM 6.1, it appears the data transfer will fail if the node does not actually have workflow tied to it (typically a publish instance), with the error:

24.06.2015 12:34:23.999 ERROR [clientJobLauncherTaskExecutor-7] org.springframework.batch.core.step.AbstractStep Encountered an error executing step clientWorkflowOn in job clientJob
java.lang.IllegalStateException: launcherConfig Map value for /etc/workflow/launcher/config/dam_xmp_writeback cannot be null
at com.twcable.grabbit.client.batch.workflows.impl.DefaultWorkFlowManager$_turnOn_closure2.doCall(DefaultWorkFlowManager.groovy:90)

Example config:

    {
            "path" : "/content/dam/VirtualAssistant",
            "workflowConfigIds" :
            [
                    "/etc/workflow/launcher/config/update_asset_mod",
                    "/etc/workflow/launcher/config/update_asset_create",
                    "/etc/workflow/launcher/config/dam_xmp_nested_writeback",
                    "/etc/workflow/launcher/config/dam_xmp_writeback"
            ]
    },

Add "excludePaths" per path

Something like

{
    "path" : "/content/someContent",
    "excludePaths" :
        [
            "subPath1",
            "subPath2/xyz"
        ],
}

To keep things clear/simple, the excludePaths should only allow relative paths to the path for that block. For example the following would be illegal:

{
    "path" : "/content/someContent",
    "excludePaths" :
        [
            "/content/otherContent",
            "/content/someContent/apath"
        ],
}

An open question: Should "." be legal?

Add YAML support

Some of the configuration options would get cleaner if YAML were supported. (e.g., comments, reference support, reduced verbosity, etc.) Fortunately JSON is a subset of YAML, so existing configs would still work.

Handle mix:versionable properly

Encountered exception is as follows (on the client)

02.02.2015 22:08:07.101 [clientJobLauncherTaskExecutor-3] com.twcable.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter *INFO* Encountered invalid mixin type while unmarshalling for Proto values : value {
  stringValue: "mix:versionable"
}

02.02.2015 22:08:07.102 [clientJobLauncherTaskExecutor-3] com.twcable.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter *INFO* Encountered invalid mixin type while unmarshalling for Proto values : value {
  stringValue: "mix:lockable"
}

02.02.2015 22:08:07.103 [clientJobLauncherTaskExecutor-3] com.twcable.grabbit.client.batch.steps.jcrnodes.JcrNodesWriter *ERROR* Exception writing JCR Nodes to current JCR Session : session-admin-334713.  javax.jcr.version.VersionException: Unable to perform operation. Node is checked-in.
    at org.apache.jackrabbit.core.ItemValidator.checkCondition(ItemValidator.java:284)
    at org.apache.jackrabbit.core.ItemValidator.checkModify(ItemValidator.java:248)

For starters, may be look at how filevault does it : https://github.com/apache/jackrabbit-filevault/blob/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/ImportInfoImpl.java#L228-L234 (using node.checkIn() )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.