-
Notifications
You must be signed in to change notification settings - Fork 109
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
support custom log lines processing via script #40
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Binary compatibility in the constructor needs to be fixed. Some FindBugs issues could be also cleaned up
/** | ||
* Create a new {@link LogstashBuildWrapper}. | ||
*/ | ||
@DataBoundConstructor | ||
public LogstashBuildWrapper() {} | ||
public LogstashBuildWrapper( | ||
@CheckForNull SecureGroovyScript secureGroovyScript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaks the binary compatibility. The default constructor should be retained
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very new to plugin dev task. My gut feeling told me that given jelly is changed, the default constructor will never be called by Jenkins thus retaining a parameterless constructor would be useless.
If you want me to keep one I'm fine with it. Just tell me whether it should be annotated as @DataBoundConstructor
or not. Other than that, it would be an easy change.
@@ -106,9 +118,18 @@ public DescriptorImpl getDescriptor() { | |||
return (DescriptorImpl) super.getDescriptor(); | |||
} | |||
|
|||
public SecureGroovyScript getSecureGroovyScript() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CheckForNull
would be useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look at this. Thanks.
@@ -65,6 +67,9 @@ public static Descriptor getLogstashDescriptor() { | |||
public static final class Descriptor extends ToolDescriptor<LogstashInstallation> { | |||
public IndexerType type; | |||
public SyslogFormat syslogFormat; | |||
@SuppressFBWarnings( | |||
value="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD", | |||
justification="TODO: do we need this?") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you decide to delete it, make it transient first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if this findbug issues are fixed in another pull request as this one is large enough.
I will look at the date formatter issues while waiting for script security plugin though as they appear to be more critical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And thank you for the quick turnaround!
@@ -57,6 +59,9 @@ | |||
} | |||
|
|||
@Override | |||
@SuppressFBWarnings( | |||
value="STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE", | |||
justification="TODO: not sure how to fix this") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a real defect. SimpleDateFormar is not thread-safe, so this code may fall apart at any moment.
I would recommend just instantiating the object instead of using the static field
@@ -65,6 +67,9 @@ | |||
*/ | |||
public class BuildData { | |||
// ISO 8601 date format | |||
@SuppressFBWarnings( | |||
value="STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE", | |||
justification="TODO: not sure how to fix this") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
Hi again, fixed some dependency issues with mockito-core by updating its version to the latest. Also fixed some of the Findbug errors. It would make more sense to me to go over the remaining less critical findbug issues in a separate smaller pull request. Please let me know your desire about the constructor. |
47f2bbe
to
0f59cf5
Compare
I decided to use the less-efficient existing API of script-security plugin until the new one is merged. Functionality is the same and switching to the efficient API will be very easy to do once merged upstream. See commit Now the only problem I see above is compiling with java 1.7. I think this is expected because maven-hpi-plugin has a target of java 1.8. This IMO shouldn't be a problem given we keep target 1.7 in logstash plugin. My suggestion would be to stop compiling the plugin with java 1.7 and only compile with 1.8+ going forward. Alternatively, if you want to keep build support for 1.7, I figured parent plugin pom version could be set to 2.9 instead of the current 3.2. Please let me know how do you prefer me to proceed. |
I'm not sure how big a difference there is between 2.9 and 3.2, but in general I'd prefer to do the changes in smallest feasible increments. Just in case something breaks. |
@@ -207,8 +211,15 @@ public BuildData(Run<?, ?> build, Date currentTime, TaskListener listener) { | |||
} | |||
} | |||
|
|||
// ISO 8601 date format | |||
public static DateFormat isoDateFormatter() { | |||
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a potential performance bottleneck. Every time you create a new instance which means that the formatter needs to parse the string. Having just one instance as before which is reused should be faster
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SimpleDateFormat is not thread safe, as pointed out by Findbugs :)
If we care about performance overhead the easiest replacement is https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/time/FastDateFormat.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see DateTimeFormatter
available on Java 7. Do you want the apache one or keep current approach. Btw if we use the apache commons formatter we will still change API compatibility as it is only a Format
, not DateFormat
.
To me it looks like apache commons formatter would be the immediate preferable choice. But there is another question. I see that the new DateTimeFormatter
comming with Java8 is not inheriting Format
at all. So perhaps BuildData
class can provide a method to format some date instead of returning som formatter object. This will allow in the future to change implementation without breaking public API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting comparison http://optimizationtricks.blogspot.bg/2015/01/datetimeformat-comparison-java-vs-joda.html , please tell me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re. Java 8: right I keep forgetting that it's still building on 7
re. format only: AFAIK we only use it to format, anyhow since 3.2 it supports parsing too
I'm fine with either Joda or FastDateFormat
@jakub-bochenski , 2.9 is from May 2016. 3.2 is from this month. I believe there are mostly differences in the support libraries, not for runtime but I don't know for sure. I can say that 3.2 brought better findbugs validation. As you prefer I updated version to 2.9 to have 1.7 compilation succeed. We can update to 3.2+ later after some testing on jenkins vs java 7. |
Updated to FYI I did a benchmark over the different approaches and there is no significant difference between FastDateFormat and Joda-Time. |
FYI upstream is supporting only builds on java8 going forward. They suggest patching the travis build to stop doing java 7 builds: But this is for a future PR. Please let me know if you see any other necessary changes here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few technical problems.
More broadly, this seems risky since it will fundamentally clash with #18, which involves offloading delivery of most log lines from the master to agent JVM. OTOH that was merely a proof of concept and perhaps any production-quality Logstash support for Pipeline at scale would need to be written from scratch anyway.
(Can this kind of processing not be done after the fact BTW?)
/** | ||
* Create a new {@link LogstashBuildWrapper}. | ||
*/ | ||
@DataBoundConstructor | ||
public LogstashBuildWrapper( | ||
@CheckForNull SecureGroovyScript secureGroovyScript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather use @DataBoundSetter
.
binding = new Binding(); | ||
binding.setVariable("console", new BuildConsoleWrapper()); | ||
|
||
// not sure what the diff is compared to getClass().getClassLoader(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uberClassLoader
would be able to load typed defined in any enabled plugin. LogstashScriptProcessor.class.getClassLoader()
would be able to load only those types accessible at compile time in this plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds like uberClassLoader
gives more flexibility to script writers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it does, but then the scripts will be non portable -- you can have them working in one Jenkins instance but not another.
Security might be another concern, though the scripts need to be pre-approved anyway.
I'd suggest to do the more restrictive thing for now. It's easier to extend the possibilities later than restrict them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can have them working in one Jenkins instance but not another
This is certainly a risk in any case.
Security might be another concern
Sandboxed scripts could only use whitelisted methods anyway.
@SuppressFBWarnings( | ||
value="DM_DEFAULT_ENCODING", | ||
justification="TODO: not sure how to fix this") | ||
private void buildLogPrintln(Object o) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whitelisting a private
method makes no sense. If you intend for scripts to call it (directly), make it public
. Since it seems to be called only indirectly from BuildConsoleWrapper
, it does not need to be annotated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a leftover from my first attempts. Will fix!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm removing the extra whitelist now. Just wondering how can I make the script this method directly? I couldn't see this possible.
|
||
/** Groovy binding for script execution */ | ||
@Nonnull | ||
private final Binding binding; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems unsafe to keep this as a field. Initialize in process
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it unsafe? The main idea is to allow executing the script always with the same binding. This would allow script to create properties for persisting data between executions. The way I understand your suggestion would not allow this. Or did I misunderstand?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if we generate Binding in process()
, that would mean creating a new object per each line of console output.
public JSONObject process(JSONObject payload) throws Exception { | ||
binding.setVariable("payload", payload); | ||
script.evaluate(classLoader, binding); | ||
Object processedPayload = binding.getVariable("payload"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just use the return value from evaluate
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a question that also a colleague raised and it was my initial implementation. But then I thought about writing example usage scripts and at least to me, the code to modify payload
variable is shorter and more reliable.
Script author would need to always think what value is returned by different code paths. e.g. in a very simple use case author wants to add some additional properties to the message
if (payload["message"][0] =~ /whatever/) {
payload["custom_prop"] = "custom_value"
}
If we look at payload
variable the above is enough. If we look at return value, one always has to add the line return payload
. I don't insist on this. It might be only in my head, but IMO it will be a common annoyance to forget that return value.
I will change it if the return value is preferred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My vote would be to use the return value.
Note: in groovy scripts the last statement's value is implicitly returned, so it's not as verbose.
I think we could make this work with some sensible defaults (e.g. returned String overrides message, returned map overrides the whole payload).
What I don't like about the current solution:
- mutating the input binding
- relying on null as magic value
- return value is much more obvious to script readers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reply!
I will change to the return
approach then [1].
wrt relying on null as magic value
, how else do you suggest to signal backend to ignore some message?
wrt returned String overrides message, returned map overrides the whole payload
- this will complicate backend IMO and provided script receives a Map/JSONObject as input, I'm not sure it will make things easier.
wrt mutating the input binding
, not sure what exactly you mean with this. Are you supporting @jglick to create a new binding for each process()
call? I can do this but then there is the question - how to allow persisting some data between script invocations. Perhaps introduce some Map
variable (e.g. cache
), where script can store some values for later? Let me know how you want to see it implemented [1].
Also would be very useful to advise whether this can be merged before #18 and does anybody has a plan for moving #18 forward (and what exactly needs to be fixed in #18 to begin with).
[1] I really don't care much as long as the necessary functionality is available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all all just ideas to improve the readability of the scripts. If you don't think it fits the intended use case please let me know.
how else do you suggest to signal backend to ignore some message?
How about we use the Null-Object pattern? bind something like 'SKIP' etc. to the script, then check for this exact value instead of null.
return SKIP
or
if (someCondition) SKIP
looks much clearer than
return null
his will complicate backend IMO and provided script receives a Map/JSONObject as input, I'm not sure it will make things easier.
IMO, I think it's OK (or even a feature) in loosely typed languages to provide different processing for different types.
My intention here is to enable a short way of transforming just the log message, e.g.
payload["message"][0].replace('_',' ')
introduce some Map variable (e.g. cache), where script can store some values for later
Actually I had something different in mind, but I like this idea. I think this could be done as an improvement later though (provided we mark the current behavior as experimental etc.)
Also would be very useful to advise whether this can be merged before #18 and does anybody has a plan for moving #18 forward
AFAIK it was a POC and there is no plan to move with it any time soon, but @jglick knows best.
script.evaluate(classLoader, binding); | ||
Object processedPayload = binding.getVariable("payload"); | ||
if (processedPayload != null && !(processedPayload instanceof JSONObject)) { | ||
throw new ClassCastException("script returned " + processedPayload.getClass().getName() + " instead of JSONObject"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless. The default ClassCastException
would encode the same information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you confirm that you mean to just remove this check and let line 110 throw it by itself? Sounds good to me, just want to make sure this is your proposal.
<p> | ||
Example script to filter out some console messages by pattern: | ||
<pre><code> | ||
if (payload && payload["message"][0] =~ /my needless pattern/) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&&
@jglick , thanks a lot for chiming in. Besides your existing comments, would you advice about the |
@jglick , I missed your comment about #18. I don't think this pull request conflicts it much. I'm +1 for moving log processing to slaves [1]. So if you have time to move #18 forward, I'll add groovy to the result. Or if you can't do that for the time being, I think it shouldn't be so hard to account in #18 for this one. [1] Although it might be a problem if logstash is in some VPN while slaves are connected from public clouds for example. Could processing be done on slaves but data sent through master? Maybe unnecessary complication, just a thought. |
<p> | ||
The script will be executed once per each line of build console output with the | ||
variable <code>payload</code> set to a JSON payload with the "message" key being | ||
an array with one string element - the current line. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually why a 1 element array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the format of the generated message JSON. At least when using the wrapper. User is free to add/modify lines. In the post-build action there are more elements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK maybe we could clarify here that the whole payload as would be sent to the backend is available here. One could read the above as payload being a map with a single "message" key
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to clarify the text. Let me know if it is better now. Or if you provide me with better wording, I would gladly update with it. I'm not a native english speaker.
public JSONObject process(JSONObject payload) throws Exception { | ||
binding.setVariable("payload", payload); | ||
script.evaluate(classLoader, binding); | ||
Object processedPayload = binding.getVariable("payload"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all all just ideas to improve the readability of the scripts. If you don't think it fits the intended use case please let me know.
how else do you suggest to signal backend to ignore some message?
How about we use the Null-Object pattern? bind something like 'SKIP' etc. to the script, then check for this exact value instead of null.
return SKIP
or
if (someCondition) SKIP
looks much clearer than
return null
his will complicate backend IMO and provided script receives a Map/JSONObject as input, I'm not sure it will make things easier.
IMO, I think it's OK (or even a feature) in loosely typed languages to provide different processing for different types.
My intention here is to enable a short way of transforming just the log message, e.g.
payload["message"][0].replace('_',' ')
introduce some Map variable (e.g. cache), where script can store some values for later
Actually I had something different in mind, but I like this idea. I think this could be done as an improvement later though (provided we mark the current behavior as experimental etc.)
Also would be very useful to advise whether this can be merged before #18 and does anybody has a plan for moving #18 forward
AFAIK it was a POC and there is no plan to move with it any time soon, but @jglick knows best.
when(mockBuild.getRootBuild()).thenReturn(mockBuild); | ||
when(mockBuild.getBuildVariables()).thenReturn(Collections.emptyMap()); | ||
when(mockBuild.getSensitiveBuildVariables()).thenReturn(Collections.emptySet()); | ||
when(mockBuild.getEnvironments()).thenReturn(null); | ||
when(mockBuild.getAction(AbstractTestResultAction.class)).thenReturn(mockTestResultAction); | ||
when(mockBuild.getLog(0)).thenReturn(Arrays.asList()); | ||
// when(mockBuild.getLog(0)).thenReturn(Arrays.asList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't leave commented out code, just delete
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed all occurrences of commented out lines that I could spot (3), thanks
@jakub-bochenski , I missed your other suggestions, now I see them. I see you find the wrt wrt Inspired by above suggestion another interesting approach would be to also allow simple filtering by returning a matcher or a boolean. e.g.
or
or even a pattern
We can also bind the message as a separate variable In all situations though we need to accept the risk of somebody clueless shooting himself in the foot by modifying |
I'm not sure what was the original @jglick point about that. I was just commenting from general principles. I don't think we should worry about creating new objects in Java. Modern GCs hanlde short-lived objects just fine. I'd only worry if the objects have long initialization times (expensive operations in constructor) |
I had that in mind in the previous comment about mutating state. My suggestion here is:
|
good idea, I think this would be useful weather we go with the other changes or no |
+1 to that. |
@@ -85,6 +90,9 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc | |||
} | |||
|
|||
@Override | |||
@SuppressFBWarnings( | |||
value="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE", | |||
justification="TODO: investigate") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't we just leave those cases unsuppressed? or is the build setup to fail in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
build fails
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I think we should disable this on maven level then -- just make it emit warnings for now
let me know if you need help with this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
project automated CI will will show a failure. Is there a way to make it not fail but just warn?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be set somewhere in maven and be overridable -- let me check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will look into that once I catch up with the holiday pile up of tasks.
@@ -85,6 +90,9 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc | |||
} | |||
|
|||
@Override | |||
@SuppressFBWarnings( | |||
value="NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE", | |||
justification="TODO: investigate") | |||
public ToolInstallation newInstance(StaplerRequest req, JSONObject formData) throws FormException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Req is marked as nullable in the interface, so apparently we should handle this gracefully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just suppressed the warning, I don't think I touched anything about this. Good to go after all suppression later and have them fixed.
configured logstash backend. The following variables are available during execution: | ||
<ul> | ||
<li><strong>payload</strong> - JSONObject contaning the payload to be persisted.</li> | ||
<li><strong>console</strong> - a class to output messages to build log without persisting them. It also works in a sandbox: <code>console.println("my logged message")</code>.</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since pipeline is using an echo
statement maybe it would be nice to use the same (at least make it look the same).
echo "my logged message"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how to do this. I didn't find any way to add a method to the binding. And using org.codehaus.groovy.runtime.MethodClosure
to create a closure property in the binding didn't work either with some script security issue (I tried this already). Maybe my groovy shell foo is lacking. Any ideas would be welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not bind groovy.lang.Closure
?
If that doesn't work then lets drop it, it's only nice to have
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will try
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI doing echo "some string"
in script resulted in
RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (Script1 echo java.lang.String)
While echo.call "some string"
worked. I couldn't find a way to get around that.
This means that variables can be saved between script invocations. | ||
</p> | ||
<p> | ||
At the end of the build a payload == null will be submitted. You can use this to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some other ideas on how to not depend on null:
- bind a special marker to do
payload == DONE
instead - bind a status variable e.g.
if (buildFinished)
- accept a completely separate finalizer script
inOrder.verify(mockBuffer).close(); | ||
|
||
// Verify results | ||
assertEquals("Results don't match", "", buffer.toString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That message doesn't really add anything over what the matcher would report. Can we remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think it would be better to use hamcrest here:
assertThat( buffer, hasToString(""))
http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/object/HasToString.html
This will break the other use cases like mine and for #40 where we want to add/remove other fields to the payload. IMO we can't protect users from every possible mistake. Can we let users modify the JSON and return it for the sake of simplicity? Perhaps explain this gotcha in the help. Use case like:
|
You can still make a copy and modify that. If you are worried about the overhead of doing a copy then I think it's OK to leave it mutable. |
pom.xml
Outdated
<dependency> | ||
<groupId>org.jenkins-ci.plugins</groupId> | ||
<artifactId>script-security</artifactId> | ||
<version>1.37</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you were going to use jenkinsci/script-security-plugin#169 here, so we can verify that the proposed API actually works for its supposed purpose? If so, you would need to deploy
a snapshot of the upstream PR, then change this to a timestamped snapshot version, so CI can verify this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jglick , I have verified the API works locally. Would you point me at how to deploy a timestamped snapshot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @jglick meant to put a timestamped snapshot dependency here. If you point me to the artifact you need I think I can make the change.
EDIT: no apparently we also need to deploy it first. Still I think I could help with that but please point me to the exact thing you need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically we need jenkinsci/script-security-plugin#169 built and deployed. Also we need 747a0bc reverted here so that the new API is used. Better let me first do little refactoring of script security pull request and then test it. I just have so much other work since new year. Hope to get back to this next week.
Well, “conflict” to the extent that you could choose to do either remote logging, or script processing, but not both—scripts as implemented here would be master-only. Anyway, do not worry about it much—as I said, it is just as likely any remote logging plugin would be written from scratch, and may not be based on Logstash at all. |
@jglick , and what shall be done to allow both? If nobody can work on the remote logging, then I guess what we have should be good enough. On the other hand I'm willing to change things for a better plugin but I'm very inexperienced with Jenkins. I don't want to delay the feature too much. But I plan to be in Brussels between 1st and 4th if you can lend a hand. |
Wow, thank you for merging. I'm planning to move the more efficient version forward but I'm stuck with other priority work. This merge would definitely help though. |
@akostadinov wait, I didn't intend to merge this into master - I just wanted to resolve the conflicts on your branch I'll have to undo that as the build is not passing |
@akostadinov @jglick @oleg-nenashev sorry about the mixup I've put my attempt at resolving the conflicts into #56 |
ah, it's fine. Thank you for helping with merging conflicts. Issue seem to be some minor things. I really hope to get back to this next week. |
This change requires jenkinsci/script-security-plugin#169 to work.
Please see
help-script.html
for possible use cases.I needed to update parent pom version because of script-security-plugin which led to
the need to suppress additional warnings. Still waiting on
jenkinsci/script-security-plugin#169 to be accepted so not ready to merge. I have an
alternative approach if the pull is not accepted, unfortunately not that performant.
But I will appreciate feedback for this PR in the meanwhile so I can fix issues.
Thank you.