Giter VIP home page Giter VIP logo

gerrit-events's People

Contributors

apetres avatar chgeo avatar christoffer-cortes avatar defer avatar dependabot[bot] avatar dpursehouse avatar gluck avatar glundh avatar howardlyliao avatar hugares avatar jakohbae avatar jeblair avatar jimilian avatar jyrkiput avatar kukido avatar mathieu-wang avatar mattlud avatar mawinter69 avatar mobangjack avatar olamy avatar orgads avatar rinrinne avatar rsandell avatar seware avatar slawekjaranowski avatar ssbarnea avatar sselberg avatar tkawachi avatar twestling avatar zaro0508 avatar

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

Watchers

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

gerrit-events's Issues

Objects in package com.sonymobile.tools.gerrit.gerritevents.dto.events should have a Constructor with JSONObject as parameter

[2017-07-12 13:31:51 DEBUG] [Gerrit Worker EventThread_1] {com.sonymobile.tools.gerrit.gerritevents.GerritJsonEventFactory:73}-Constructor with JSONObject as parameter missing, trying default constructor.
java.lang.NoSuchMethodException: com.sonymobile.tools.gerrit.gerritevents.dto.events.CommentAdded.(net.sf.json.JSONObject)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at com.sonymobile.tools.gerrit.gerritevents.GerritJsonEventFactory.getEvent(GerritJsonEventFactory.java:69)
at com.sonymobile.tools.gerrit.gerritevents.workers.AbstractJsonObjectWork.perform(AbstractJsonObjectWork.java:69)
at com.sonymobile.tools.gerrit.gerritevents.workers.StreamEventsStringWork.perform(StreamEventsStringWork.java:67)
at com.sonymobile.tools.gerrit.gerritevents.workers.EventThread.run(EventThread.java:66)

As you can see,because of the missing of Constructor with JSONObject as parameter,it will throw a lot of java.lang.NoSuchMethodException.

I am not sure the listener will work correctly in this case.But it make us confuse.

I hope someone can fix this.Of course,if I have time,I will try to do it as well.

e.....I hope that my poor english will not confuse you.I am a chinese.

Found starting '{' but missing '}' at the end.

I use Gerrit-2.14.1, plugin events-log is also in the same version.
What I receive on jenkins:

INFO: Gerrit Plugin events-log is installed
Jun 28, 2017 7:56:24 AM com.sonymobile.tools.gerrit.gerritevents.GerritJsonEventFactory getJsonObjectIfInterestingAndUsable
WARNING: Unanticipated error when examining JSON String
net.sf.json.JSONException: Found starting '{' but missing '}' at the end. at character 0 of null
at net.sf.json.util.JSONTokener.syntaxError(JSONTokener.java:499)
at net.sf.json.util.JSONTokener.(JSONTokener.java:85)
at net.sf.json.JSONObject._fromString(JSONObject.java:1145)
at net.sf.json.JSONObject.fromObject(JSONObject.java:162)
at net.sf.json.JSONSerializer.toJSON(JSONSerializer.java:139)
at net.sf.json.JSONSerializer.toJSON(JSONSerializer.java:103)
at net.sf.json.JSONSerializer.toJSON(JSONSerializer.java:84)
at com.sonymobile.tools.gerrit.gerritevents.GerritJsonEventFactory.getJsonObjectIfInterestingAndUsable(GerritJsonEventFactory.java:126)
at com.sonyericsson.hudson.plugins.gerrit.trigger.playback.GerritMissedEventsPlaybackManager.createEventsFromString(GerritMissedEventsPlaybackManager.java:327)
at com.sonyericsson.hudson.plugins.gerrit.trigger.playback.GerritMissedEventsPlaybackManager.getEventsFromDateRange(GerritMissedEventsPlaybackManager.java:311)
at com.sonyericsson.hudson.plugins.gerrit.trigger.playback.GerritMissedEventsPlaybackManager.connectionEstablished(GerritMissedEventsPlaybackManager.java:197)
at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.notifyListeners(GerritConnection.java:699)
at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.notifyConnectionEstablished(GerritConnection.java:726)
at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.run(GerritConnection.java:399)

Proposition of architecture.

I congratulate that you separate gerrit-events from jenkins plugins.
I know that this library mainly support gerrit events, but if you separate it, maybe you are interested to add some new feature.

My proposition is - create a few modules in gerrit-events project.

  • gerrit-objects - contains all gerrit JSON objects transformed to plain java object
  • gerrit-connections - interface for connection config, factory
  • gerrit-commands - gerrit abstract command impementation and command interface
  • gerrit-ssh - implementation of connections config, factory, commands and other which is connected with ssh protocol
  • gerrit-rest - implementation of connections config, factory, commands and other which is connected with rest/http protocol
  • gerrit-events - gerrit events implementation

Dependency in project should be:

  • gerrit-commands - depends on gerrit-connections, gerrit-objects
  • gerrit-shh - depends on gerrit-connections, gerrit-command, gerrit-objects
  • gerrit-rest - depends on gerrit-connections, gerrit-command, gerrit-objects
  • gerrit-events - depends on gerrit-connections, gerrit-objects, gerrit-ssh

Requirements:

  • method from commands and events return plain java object from gerrit-objects
  • connection factory can be extendable
  • modules depend on a minimum number of external libraries

Advantages:

  • minimum number of external dependency in other projects
  • using plain java object is simpler than using JSON object
  • commands are not dependent on protocol ssh / rest we have the same interface so we can easy change protocol in project

I can write:

GerritQuery query = new GerritSshQuery(new SSHConnectio(...))

in this case my project depends only on gerrit-ssh and some ssh implementation

I can also write:

GerritQuery query = new GerritRestQuery(new RestConnectio(...))

and in this case my project depends on gerrit-rest and some http connection library

Disadvantages:

  • there may be differences in the amount of commands for ssh and rest
  • there may be differences in the amount of returning data for ssh and rest

Deadlock when shutting down while establishing connection

I've noticed a deadlock when calling the GerritConnection.shutdown(true) method while establishing the connection in GerritConnection.run().

The deadlock sequence is like this:

Thread 1: calls GerritConnection.run() -> calls into connect() -> SshConnectionFactory.getConnection()
Thread 2: calls GerritConnection.shutdown(true), sshConnection is null at this point, doesn't call sshConnection.disconnect(), calls join()
Thread 1: returns from connect() call, sets sshConnection, continues up to read() and blocks
Thread 2: join() never returns as read() in Thread 1 blocks (sshConnection.disconnect() is not called before)

Below are the callstacks of the two threads (Thread 2 initiates the connection shutdown by executing a Jenkins script "io.jenkins.plugins.casc.ConfigurationAsCode.get().configure()", JCasC removes all Gerrit severs and adds them again).

Id=106 Group=main TIMED_WAITING on com.jcraft.jsch.Channel$MyPipedInputStream@686f0414
	at [email protected]/java.lang.Object.wait(Native Method)
	-  waiting on com.jcraft.jsch.Channel$MyPipedInputStream@686f0414
	at [email protected]/java.io.PipedInputStream.read(PipedInputStream.java:326)
	at [email protected]/java.io.PipedInputStream.read(PipedInputStream.java:377)
	at [email protected]/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
	at [email protected]/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
	at [email protected]/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
	-  locked java.io.InputStreamReader@450eb826
	at [email protected]/java.io.InputStreamReader.read(InputStreamReader.java:181)
	at [email protected]/java.io.Reader.read(Reader.java:189)
	at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.run(GerritConnection.java:434)

"Handling POST /scriptText from 172.17.0.4 : Jetty (winstone)-35" Id=35 Group=main WAITING on com.sonymobile.tools.gerrit.gerritevents.GerritConnection@28a5ee8e
	at [email protected]/java.lang.Object.wait(Native Method)
	-  waiting on com.sonymobile.tools.gerrit.gerritevents.GerritConnection@28a5ee8e
	at [email protected]/java.lang.Thread.join(Thread.java:1300)
	at [email protected]/java.lang.Thread.join(Thread.java:1375)
	at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.shutdown(GerritConnection.java:710)
	at com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer.stopConnection(GerritServer.java:617)
	-  locked com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer@29949ddb
	at com.sonyericsson.hudson.plugins.gerrit.trigger.config.GerritJcascConfigurator.configure(GerritJcascConfigurator.java:95)
	at com.sonyericsson.hudson.plugins.gerrit.trigger.config.GerritJcascConfigurator.configure(GerritJcascConfigurator.java:57)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:277)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:360)
	at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:283)
	at io.jenkins.plugins.casc.ConfigurationAsCode.lambda$configureWith$7(ConfigurationAsCode.java:823)
	at io.jenkins.plugins.casc.ConfigurationAsCode$$Lambda$561/0x0000000800ca8c40.apply(Unknown Source)
	at io.jenkins.plugins.casc.ConfigurationAsCode.invokeWith(ConfigurationAsCode.java:773)
	at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:823)
	at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:695)
	at io.jenkins.plugins.casc.ConfigurationAsCode.configure(ConfigurationAsCode.java:352)
	at io.jenkins.plugins.casc.ConfigurationAsCode$configure$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
	at Script1.run(Script1.groovy:1)
	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:574)
	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:612)
	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:583)
	at hudson.util.RemotingDiagnostics$Script.call(RemotingDiagnostics.java:149)
	at hudson.util.RemotingDiagnostics$Script.call(RemotingDiagnostics.java:118)
	at hudson.remoting.LocalChannel.call(LocalChannel.java:47)
	at hudson.util.RemotingDiagnostics.executeGroovy(RemotingDiagnostics.java:115)
	at jenkins.model.Jenkins._doScript(Jenkins.java:4869)
	at jenkins.model.Jenkins.doScriptText(Jenkins.java:4847)
	at [email protected]/java.lang.invoke.LambdaForm$DMH/0x00000008001ff440.invokeVirtual(LambdaForm$DMH)
	at [email protected]/java.lang.invoke.LambdaForm$MH/0x0000000800422040.invoke(LambdaForm$MH)
	at [email protected]/java.lang.invoke.LambdaForm$MH/0x00000008003f1440.invoke(LambdaForm$MH)
	at [email protected]/java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder)
	at [email protected]/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
	at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:397)
	at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:409)
	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:207)
	at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:140)
	at org.kohsuke.stapler.MetaClass$11.doDispatch(MetaClass.java:558)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:59)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:770)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:900)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:698)
	at org.kohsuke.stapler.Stapler.service(Stapler.java:248)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:163)
	at hudson.security.HudsonPrivateSecurityRealm$2.doFilter(HudsonPrivateSecurityRealm.java:1022)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at org.jenkinsci.plugins.ssegateway.Endpoint$SSEListenChannelFilter.doFilter(Endpoint.java:248)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at hudson.plugins.locale.LocaleFilter.doFilter(LocaleFilter.java:39)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at io.jenkins.blueocean.ResourceCacheControl.doFilter(ResourceCacheControl.java:134)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at io.jenkins.blueocean.auth.jwt.impl.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:60)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at jenkins.util.HttpServletFilter$1.doFilter(HttpServletFilter.java:76)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:166)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at jenkins.ErrorAttributeFilter.doFilter(ErrorAttributeFilter.java:29)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at jenkins.security.ApiCrumbExclusion.process(ApiCrumbExclusion.java:48)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:128)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:94)
	at jenkins.security.AcegiSecurityExceptionFilter.doFilter(AcegiSecurityExceptionFilter.java:52)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:54)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:110)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at jenkins.security.BasicHeaderProcessor.success(BasicHeaderProcessor.java:139)
	at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:86)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:117)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
	at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:63)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:111)
	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:172)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:53)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:86)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:38)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:569)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.Server.handle(Server.java:563)
	at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
	at [email protected]/java.lang.Thread.run(Thread.java:829)

[Refactor] Use data binding library

Now event data formatted by JSON is binded to event model by fromJSON(). It means that each event models have binding logic.

If we use data binding library like Jackson, we can get more simple event models like beans or pojo. It would allow us to follow the latest gerrit event model easily.

I created a study project. Please check the below if interested.
https://github.com/rinrinne/bind-event-sample

Add the ability to read the output and if interactive shells are disabled on Gerrit

The SshConnection successfully opens a connection to Gerrit, executes the command, and then on its first readLine() call, the stream returns null. The GerritConnection object then keeps connecting and disconnecting every second without actually showing any errors to the outside world (minus the connect and disconnect events). It would be nice to receive an error message when some servers return the following output:

  ssh -p 29418 sshusername@hostname

    ****    Welcome to Gerrit Code Review    ****

    Hi John Doe, you have successfully connected over SSH.

    Unfortunately, interactive shells are disabled.
    To clone a hosted Git repository, use:

    git clone ssh://sshusername@hostname:29418/REPOSITORY_NAME.git

  Connection to hostname closed.

How to detect if gerrit connection is alive?

I just wanted to know that after I make connection to the gerrit server, how can i find if the connection has really established or not. Sometimes when I run my program, if Gerrit has not started, I am not able to find that. Is there a way to do that after I try to establish a connection.

Using the default value of timeout=0 when creating SSH connections might lead to threads stuck forever

Hi, this is a follow-up of my investigation related to an incident me and my team was hit yesterday after our Gerrit instance outage.

I described the whole story in Jenkins' bug tracker as it was Jenkins' Gerrit Trigger plugin which was affected by the issue. See JENKINS-33959 and my comment specifically.

I believe the root cause of the above issue comes from this library.

Long story short, when the timeout parameter is not specified the library uses the default value of 0 when creating SSH connections. This blocked the calling thread, potentially forever (it's still blocked 1 day after we noticed it).

As I mentioned in the Jenkins ticket:

As a general thought setting timeouts to 0 is almost always a bad practice, unless you really want to wait forever. In practical applications it's usually better to let it timeout and simply retry.

Test fails in some time.

One test

WatchTimeExceptionDataTest.testIsExceptionAtThisTimeMinutes 

fails in time 0:00 to 0:15

Handling both SSH & HTTP?

Hello!

We want to add a functionality where gerrit events plugin retrieves data both through ssh and http.

We have 2 possible solutions for this:

  1. Transform fromJson function in GerritJsonDTO into fromJsonSSH and fromJsonHTTP
    Modify Account, Approval, Change, Comment, PatchSet, Provider, RefUpdate classes accordingly
    Transform GerritQueryHandler class to GerritQueryHandlerSSH and add GerritQueryHandlerHTTP class (with a
    common QueryHandler interface)
    Adapt the remaining necessary changes

  2. Leave gerrit events as it is and make a converter for http json to ssh json (the json returned
    by the rest api is very different in structure to the one returned by ssh)

    Here is an example of a json returned by ssh

   {  
   "project":"project",
   "branch":"master",
   "id":"123123123123",
   "number":123,
   "subject":"Subject",
   "owner":{  
      "name":"name",
      "email":"email",
      "username":"username"
   },
   "url":"url",
   "commitMessage":"commitMessage",
   "createdOn":1537137142,
   "lastUpdated":1535770916,
   "open":true,
   "status":"NEW",
   "trackingIds":[  
      {  
         "system":"system",
         "id":"id"
      }
   ],
   "currentPatchSet":{  
      "number":11,
      "revision":"revision",
      "parents":[  
         "parents"
      ],
      "ref":"refs",
      "uploader":{  
         "name":"uploader",
         "username":"username"
      },
      "createdOn":1537137142,
      "author":{  
         "name":"name",
         "email":"email",
         "username":"username"
      },
      "kind":"kind",
      "approvals":[  
         {  
            "type":"Validated",
            "description":"Validated",
            "value":"1",
            "grantedOn":1885459715,
            "by":{  
               "name":"name",
               "username":"username"
            }
         },
         {  
            "type":"Code-Review",
            "description":"Code-Review",
            "value":"1",
            "grantedOn":1888644041,
            "by":{  
               "name":"name",
               "username":"username"
            }
         }
      ],
      "sizeInsertions":sizeInsertions,
      "sizeDeletions":-sizeDeletions
        }
    }
    ```

    And here is an example of a json containing the same information, returned by http 

    ```
    {
    "id": "id",
    "project": "project",
    "branch": "master",
    "hashtags": [],
    "change_id": "change_id",
    "subject": "Subject",
    "status": "NEW",
    "created": "2017-04-06 10:05:42.574000000",
    "updated": "2019-02-14 08:21:56.634000000",
    "submit_type": "submit_type",
    "mergeable": true,
    "insertions": insertions,
    "deletions": deletions,
    "unresolved_comment_count": 0,
    "has_review_started": true,
    "_number": number,
    "owner": {
      "_account_id": _account_id,
      "name": "name",
      "email": "email",
      "username": "username"
    },
    "labels": {
      "Verified": {
        "all": [
          {
            "value": 0,
            "permitted_voting_range": {
              "min": -1,
              "max": 2
            },
            "_account_id": _account_id,
            "name": "name",
            "username": "username"
          },
          {
            "value": 0,
            "permitted_voting_range": {
              "min": -1,
              "max": 2
            },
            "_account_id": _account_id,
            "name": "name",
            "email": "email",
            "username": "username"
          }
        ],
        "values": {
          "-1": "Fails",
          " 0": "No score",
          "+1": "Formatting is ok",
          "+2": "Build pass with associated unit tests"
        },
        "default_value": 0
      },
      "Code-Review": {
        "all": [
          {
            "value": 0,
            "permitted_voting_range": {
              "min": -2,
              "max": 2
            },
            "_account_id": _account_id,
            "name": "name",
            "username": "username"
          },
          {
            "value": 0,
            "permitted_voting_range": {
              "min": -2,
              "max": 1
            },
            "_account_id": _account_id,
            "name": "name",
            "email": "email",
            "username": "username"
          }
        ],
        "values": {
          "-2": "This shall not be merged",
          "-1": "I would prefer this is not merged as is",
          " 0": "No score",
          "+1": "Looks good to me, but someone else must approve",
          "+2": "Looks good to me, approved"
        },
        "default_value": 0
      },
      "Validated": {
        "all": [
          {
            "value": 0,
            "date": "2017-04-14 08:21:56.634000000",
            "permitted_voting_range": {
              "min": -2,
              "max": 2
            },
            "_account_id": _account_id,
            "name": "name",
            "username": "username"
          },
          {
            "value": 0,
            "permitted_voting_range": {
              "min": -2,
              "max": 1
            },
            "_account_id": _account_id,
            "name": "name",
            "email": "email",
            "username": "username"
          }
        ],
        "values": {
          "-2": "Failed to validate",
          "-1": "Failed to validate tests",
          " 0": "No score",
          "+1": "Passed validation",
          "+2": "Passed validation tests"
        },
        "default_value": 0
      },
      "Priority": {
        "all": [
          {
            "value": 0,
            "permitted_voting_range": {
              "min": -2,
              "max": 1
            },
            "_account_id": _account_id,
            "name": "name",
            "username": "username"
          },
          {
            "value": 0,
            "date": "2017-08-06 10:05:42.574000000",
            "permitted_voting_range": {
              "min": -2,
              "max": 1
            },
            "_account_id": _account_id,
            "name": "name",
            "email": "email",
            "username": "username"
          }
        ],
        "values": {
          "-2": "Blocker",
          "-1": "Critical",
          " 0": "No Priority",
          "+1": "Minor"
        },
        "default_value": 0,
        "optional": true
      }
    },
    "permitted_labels": {
      "Verified": [
        "-1",
        " 0",
        "+1",
        "+2"
      ],
      "Code-Review": [
        "-2",
        "-1",
        " 0",
        "+1",
        "+2"
      ],
      "Validated": [
        "-2",
        "-1",
        " 0",
        "+1",
        "+2"
      ],
      "Priority": [
        "-2",
        "-1",
        " 0",
        "+1"
      ]
    },
    "removable_reviewers": [
      {
        "_account_id": _account_id,
        "name": "name",
        "username": "username"
      },
      {
        "_account_id": _account_id,
        "name": "name",
        "email": "email",
        "username": "username"
      }
    ],
    "reviewers": {
      "REVIEWER": [
        {
          "_account_id": _account_id,
          "name": "name",
          "email": "email",
          "username": "username"
        },
        {
          "_account_id": _account_id,
          "name": "name",
          "username": "username"
        }
      ]
    },
    "pending_reviewers": {},
    "current_revision": "current_revision",
    "revisions": {
      "revisions": {
        "kind": "NO_CODE_CHANGE",
        "_number": 7,
        "created": "2017-04-08 13:14:33.349000000",
        "uploader": {
          "_account_id": _account_id,
          "name": "name",
          "username": "username"
        },
        "ref": "refs",
        "fetch": {
          "ssh": {
            "url": "ssh://url",
            "ref": "refs"
          },
          "anonymous http": {
            "url": "url",
            "ref": "ref"
          },
          "http": {
            "url": "url",
            "ref": "ref"
          }
        },
        "description": "Edit commit message"
      }
    }
}

Let us know what is your feedback on this idea, and which one is more likely to get merged into the repo :)

PS: I saw the issue w/r/t the new architecture proposal, but we don't want to do something that big yet (#10)

How to use this library from other maven projects

This library still have not been deployed to any remote repositories. So we need to install own built package to local repository.

Do you have plan to deploy library package to remote maven repository?

Topic Changed Event does not propagate patch set

Hello,

When a topic changed event is triggered the event does not contain a patchset:

Aug 09 15:29:29 nc jenkins[886]: 2022-08-09 13:29:29.872+0000 [id=332]        INFO        c.s.h.p.g.t.g.ToGerritRunListener#onTriggered: Project [VersionBumpJenkins] triggered by Gerrit: [com.sonymobile.tools.gerrit.gerritevents.dto.events.TopicChanged@45c6eec8]
Aug 09 15:29:29 nc jenkins[886]: 2022-08-09 13:29:29.873+0000 [id=332]        INFO        c.s.h.p.g.t.h.EventListener#schedule: Project VersionBumpJenkins Build Scheduled: true By event: 542081
Aug 09 15:29:37 nc jenkins[886]: 2022-08-09 13:29:37.244+0000 [id=22014]        INFO        c.s.h.p.g.t.g.ToGerritRunListener#onStarted: Gerrit build [VersionBumpJenkins #11] Started for cause: [GerritCause: com.sonymobile.tools.gerrit.gerritevents.dto.events.TopicChanged@45c6eec8 silent: false].
Aug 09 15:29:37 nc jenkins[886]: 2022-08-09 13:29:37.244+0000 [id=22014]        INFO        c.s.h.p.g.t.g.ToGerritRunListener#onStarted: MemoryStatus:
Aug 09 15:29:37 nc jenkins[886]:   Project/Build: [VersionBumpJenkins]: [#11: null] Completed: false
Aug 09 15:29:38 nc jenkins[886]: 2022-08-09 13:29:38.640+0000 [id=19668]        SEVERE        c.s.t.g.g.w.c.AbstractSendCommandJob#sendCommand: Could not run command gerrit review 542081,<PATCHSET> --message 'Build Started http://192.168.178.22:8080/job/VersionBumpJenkins/11/ ' --verified 0 --code-review 0 --tag autogenerated:jenkins-gerrit-trigger
Aug 09 15:29:38 nc jenkins[886]: com.sonymobile.tools.gerrit.gerritevents.ssh.SshException: fatal: "542081,<PATCHSET>" is not a valid patch set (1)

This causes the our jenkins to being unable to send messages to gerrit changes where the topic was changed.

Gerrit Events not causing a trigger

We don't see the issue in #70 any longer, and we're not sure why, perhaps networking changes we are unaware of...
We have downgraded to Gerrit Trigger 2.23.3
But Events are still not triggering a Jenkins pipeline job consistently, the trigger typically stops during the night and we are having to restart the Jenkins server the next morning to get triggers working again.

We captured a heap dump this morning just before we did a Jenkins restart to get the triggers happening again on this same server. After the restart, triggers began to happen again.
Please analyze and let us know how we can help further.

I see this potential thread as suspect ???

"Connect thread gerrit.ericsson.se session" prio=5 tid=91 TIMED_WAITING
	at java.lang.Object.wait(Native Method)
	at java.io.PipedInputStream.awaitSpace(PipedInputStream.java:273)
	at java.io.PipedInputStream.receive(PipedInputStream.java:231)
	at java.io.PipedOutputStream.write(PipedOutputStream.java:149)
	at com.jcraft.jsch.Channel$PassiveOutputStream.write(Channel.java:660)
	at com.jcraft.jsch.IO.put(IO.java:64)
	   Local Variable: com.jcraft.jsch.IO#1
	at com.jcraft.jsch.Channel.write(Channel.java:438)
	at com.jcraft.jsch.Session.run(Session.java:1448)
	   Local Variable: int[]#9794
	   Local Variable: com.jcraft.jsch.Buffer#2
	   Local Variable: com.jcraft.jsch.Packet#2
	   Local Variable: int[]#9793
	   Local Variable: byte[]#32460
	   Local Variable: com.jcraft.jsch.Session#1
	at java.lang.Thread.run(Thread.java:745)

Heap Dump:
https://drive.google.com/file/d/0B533WzlrxWraWTZaOElXSGN5M1U/view?usp=sharing

fast events create invalid JSON data

When the events are coming very fast, so that there are 2 newlines in the CharBuffer the getLine method is not properly splitting and creates corrupted data.
This is a simple missing break in the getLine.

No support for ED25519 keys (replace JSCH library)

gerrit-events does not support ED25519 keys:

	com.sonymobile.tools.gerrit.gerritevents.ssh.SshException: com.jcraft.jsch.JSchException: invalid privatekey: [B@5e887fa3
		at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionImpl.connect(SshConnectionImpl.java:200)
		at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionFactory.getConnection(SshConnectionFactory.java:140)
		at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionFactory.getConnection(SshConnectionFactory.java:117)
		at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.connect(GerritConnection.java:498)
		at com.sonymobile.tools.gerrit.gerritevents.GerritConnection.run(GerritConnection.java:404)
	Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [B@5e887fa3
		at com.jcraft.jsch.KeyPair.load(KeyPair.java:664)
		at com.jcraft.jsch.KeyPair.load(KeyPair.java:561)
		at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
		at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
		at com.jcraft.jsch.JSch.addIdentity(JSch.java:387)
		at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionImpl.connect(SshConnectionImpl.java:168)
		... 4 more

This is because the JSCH library does not.

Since JSCH seems not to be maintained anymore, it should be considered to switch to an alternative SSH library, e.g. Apache MINA.

Connections possibly left unclosed

Hi Team

We are using this library in one of the Jira PlugIns to connect to the Gerrit server to gather the reviwes information.

It looks like that in our environment library leaves some unclosed leftover connections which then affecting PlugIn functionality as server denies connection because of conn limit from Gerrit server side.

Is it possible that somewhere exception is not catched and connection left open?

2016-11-21 14:18:58,526 Caesium-1-4 DEBUG ServiceRunner [c.m.p.j.gerrit.multipleRepo.MultipleRepoConfigManagerImpl] ssh connection failed
com.sonymobile.tools.gerrit.gerritevents.ssh.SshException: com.jcraft.jsch.JSchException: SSH_MSG_DISCONNECT: 7 Too many concurrent connections
at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionImpl.connect(SshConnectionImpl.java:181)
at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionFactory.getConnection(SshConnectionFactory.java:98)
at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionFactory.getConnection(SshConnectionFactory.java:77)
at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionFactory.getConnection(SshConnectionFactory.java:59)
at com.meetme.plugins.jira.gerrit.multipleRepo.MultipleRepoConfigManagerImpl.createBareClone(MultipleRepoConfigManagerImpl.java:538)
at com.meetme.plugins.jira.gerrit.multipleRepo.MultipleRepoConfigManagerImpl.synchronize(MultipleRepoConfigManagerImpl.java:622)
at com.meetme.plugins.jira.gerrit.index.RevisionIndexer.updateIndexes(RevisionIndexer.java:223)
at com.meetme.plugins.jira.gerrit.scheduling.SynchronizerLauncher.execute(SynchronizerLauncher.java:36)
at com.atlassian.sal.jira.scheduling.JiraPluginScheduler$JobDescriptor.runJob(JiraPluginScheduler.java:110)
at com.atlassian.sal.jira.scheduling.JiraPluginScheduler.runJob(JiraPluginScheduler.java:80)
at com.atlassian.scheduler.core.JobLauncher.runJob(JobLauncher.java:153)
at com.atlassian.scheduler.core.JobLauncher.launchAndBuildResponse(JobLauncher.java:118)
at com.atlassian.scheduler.core.JobLauncher.launch(JobLauncher.java:97)
at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.launchJob(CaesiumSchedulerService.java:443)
at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeLocalJob(CaesiumSchedulerService.java:410)
at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService.executeQueuedJob(CaesiumSchedulerService.java:388)
at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService$1.consume(CaesiumSchedulerService.java:285)
at com.atlassian.scheduler.caesium.impl.CaesiumSchedulerService$1.consume(CaesiumSchedulerService.java:282)
at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.executeJob(SchedulerQueueWorker.java:65)
at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.executeNextJob(SchedulerQueueWorker.java:59)
at com.atlassian.scheduler.caesium.impl.SchedulerQueueWorker.run(SchedulerQueueWorker.java:34)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.jcraft.jsch.JSchException: SSH_MSG_DISCONNECT: 7 Too many concurrent connections
at com.jcraft.jsch.Session.read(Session.java:987)
at com.jcraft.jsch.UserAuthPublicKey.start(UserAuthPublicKey.java:198)
at com.jcraft.jsch.Session.connect(Session.java:463)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.sonymobile.tools.gerrit.gerritevents.ssh.SshConnectionImpl.connect(SshConnectionImpl.java:177)
... 21 more

Regards,
Areg

CommentAdded events considered equal even if they are different comments

We are using the gerrit-trigger plugin as part of a setup at my company to trigger Jenkins builds on certain comments whenever a user would like additional builds performed on their change in Gerrit. For example, we should trigger build 1 when someone comments "requestBuild1" and build 2 when someone comments "requestBuild2". Build 1 sets a different label on the change than build 2 and so we do not want them merged (they have different "server" configurations to set the proper label). However, if a user comments "requestBuild1" and then immediately posts a separate comment with "requestBuild2", gerrit-trigger merges them together and the results of both will only be posted to 1 label.

The gerrit-trigger plugin should be smart enough to know that a comment added event on two different "servers", even if they point to the same Gerrit instance, should be handled separately. However, another issue that allows this is that the gerrit-events library's CommentAdded class considers 2 CommentAdded instances equal if the change and patchset of the two instances are the same, even if there were different comments that generated each one. CommentAdded events should be equal iff the change is the same, the patchset is the same, and the comment is the same.

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.