It always catches the exception and outputs "Unable to read data for $dId:$alias" when I run read():
http = new HTTPBuilder('https://somewebsite.com')
def read(http, path, dId, alias, portalFile, outputFileName) {
try {
println "Reading : path:$path, file:$portalFile"
http.get(path: path,
contentType: TEXT,
query: [id:dId, instance:alias, format:'xml', file:portalFile]) {resp, reader ->
println "response status: ${resp.statusLine}"
println 'Headers: -----------'
resp.headers.each { h ->
println " ${h.name} : ${h.value}"
}
new File(outputFileName).withWriter{out -> out << reader}
}
} catch (HttpResponseException h) {
println "Unable to read data for $dId:$alias"
}
}
If I go to the website using my internet browser and click on the xml file that I need, it works. Is there any way I can output the URL that it connects to?
The best thing to do to see where things are going on wrong is to enable wire debugging for http builder - this will show you the exact requests and responses that are happening. From this you can see what URL is being fetched, with what parameters and headers, and what came back from the server.
Enabling debugging is documented here - http://groovy.codehaus.org/modules/http-builder/doc/index.html#Logging_and_Debugging
E.g. add the following to your log4j.properties
log4j.logger.org.apache.http.headers=DEBUG
log4j.logger.org.apache.http.wire=DEBUG
Or, quicker and dirtier, put this right at the top of your groovy script (YMMV)
System.setProperty('org.apache.commons.logging.Log', 'org.apache.commons.logging.impl.SimpleLog')
System.setProperty('org.apache.commons.logging.simplelog.log.org.apache.http.wire', 'DEBUG')
Related
I want to write a code for Response assertion using groovy script , for the Response data like this:
[
{
"fieldId":"947bb60f",
"id":"e7b8ad2b",
"name":"field",
}
]
Tried using the below groovy script for which i am getting error(failure message).
if (!jsonResponse.keySet().containsAll(["fieldId","id","name"] )) {
failureMessage += "The json response body has wrong structure or error msg.\n\n";
}
The same script working fine with the single tree structure as below. Appreciate your help on this with groovy script .
[
"fieldId":"947bb60f",
"id":"e7b8ad2b",
"name":"field",
]
So, you are getting a list of items returned (containing a single item)
Assuming you never expect more than one item, you can check the size of it with:
if (jsonResponse.size() != 1) {
failureMessage += "Expected one item, got ${jsonResponse.size()}.\n\n";
}
Then, you can grab the first element with:
def jsonElement = jsonResponse[0]
And check the field names with:
if (jsonElement.keySet() != ["fieldId","id","name"] as Set) {
failureMessage += "Unexpected fields in response ${jsonElement.keySet()}.\n\n";
}
I would like to send a binary file via an appended MVCResourceCommand I coded for the native journal portlet. But the program is unable to use the OutputStream provided by the resource request.
IOUtils.copy( input, response.getPortletOutputStream() );
Considering:
The code works perfectly on StrutsActions
In custom portlets, it also works
In StrutsActions:
IOUtils.copy( input, response.getOutputStream() );
However, the code throws an IllegalStateException, saying that the writer is being used when I call response.getOutputStream().
I know we can not mix these two
The code is not attempting to do so
I wonder if Liferay is doing something with that request before it reaches my extension of BaseMVCResourceCommand, this is specifically for that native portlet.
I checked the preview feature for a webcontect item, but its URL is for the view mode.
The URL is created from a portlet:resourceURL tag inserted through a JSP fragment and the command is in its own OSGi module.
For sure, the URL is correct and the command logs that it was hit, but the exception is thrown afterwards.
The portlet I am trying to change is the:
"com_liferay_journal_web_portlet_JournalPortlet"
Any thoughts?
PS: I know about the Servlet and Portlet ResponseUtils. but they also eventually try getting the stream, leadin to the same exception.
#Component( immediate = true,
property = {
"javax.portlet.name=" + JOURNAL, "mvc.command.name=/command"
},
service = MVCResourceCommand.class )
public class Resource extends BaseMVCResourceCommand {
#Override
public void doServeResource( ResourceRequest request, ResourceResponse response ) throws PortletException {
try {
response.getPortletOutputStream();
}
catch ( Exception e ) {
throw new PortletException( e );
}
}
}
Caused by: java.lang.IllegalStateException: Unable to obtain OutputStream because Writer is already in use
at com.liferay.portlet.MimeResponseImpl.getPortletOutputStream(MimeResponseImpl.java:75)
Update:
It seems this is the source of my issues (PortletURLImpl), still looking for a solution though:
if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
_copyCurrentRenderParameters = true;
}
When the URL is created it comes with all sources of garbage from the render phase. Including an MVCPath
I want to add a Build step with the Groovy plugin to read a file and trigger a build fail depending on the content of the file.
How can I inject the workspace file path in the groovy plugin ?
myFileDirectory = // Get workspace filepath here ???
myFileName = "output.log"
myFile = new File(myFileDirectory + myFileName)
lastLine = myFile.readLines().get(myFile.readLines().size().toInteger() - 1)
if (lastLine ==~ /.Fatal Error.*/ ){
println "Fatal error found"
System.exit(1)
} else{
println "nothing to see here"
}
I realize this question was about creating a plugin, but since the new Jenkins 2 Pipeline builds use Groovy, I found myself here while trying to figure out how to read a file from a workspace in a Pipeline build. So maybe I can help someone like me out in the future.
Turns out it's very easy, there is a readfile step, and I should have rtfm:
env.WORKSPACE = pwd()
def version = readFile "${env.WORKSPACE}/version.txt"
If you are trying to read a file from the workspace during a pipeline build step, there's a method for that:
readFile('name-of-file.groovy')
For reference, see https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#readfile-read-file-from-workspace.
Based on your comments, you would be better off with Text-finder plugin.
It allows to search file(s), as well as console, for a regular expression and then set the build either unstable or failed if found.
As for the Groovy, you can use the following to access ${WORKSPACE} environment variable:
def workspace = manager.build.getEnvVars()["WORKSPACE"]
Although this question is only related to finding directory path ($WORKSPACE) however I had a requirement to read the file from workspace and parse it into JSON object to read sonar issues ( ignore minor/notes issues )
Might help someone, this is how I did it-
from readFile
jsonParse(readFile('xyz.json'))
and jsonParse method-
#NonCPS
def jsonParse(text) {
return new groovy.json.JsonSlurperClassic().parseText(text);
}
This will also require script approval in ManageJenkins-> In-process script approval
May this help to someone if they have the same requirement.
This will read a file that contains the Jenkins Job name and run them iteratively from one single job.
Please change below code accordingly in your Jenkins.
pipeline {
agent any
stages {
stage('Hello') {
steps {
script{
git branch: 'Your Branch name', credentialsId: 'Your crendiatails', url: ' Your BitBucket Repo URL '
##To read file from workspace which will contain the Jenkins Job Name ###
def filePath = readFile "${WORKSPACE}/ Your File Location"
##To read file line by line ###
def lines = filePath.readLines()
##To iterate and run Jenkins Jobs one by one ####
for (line in lines) {
build(job: "$line/branchName",
parameters:
[string(name: 'vertical', value: "${params.vert}"),
string(name: 'environment', value: "${params.env}"),
string(name: 'branch', value: "${params.branch}"),
string(name: 'project', value: "${params.project}")
]
)
}
}
}
}
}
}
If you already have the Groovy (Postbuild) plugin installed, I think it's a valid desire to get this done with (generic) Groovy instead of installing a (specialized) plugin.
That said, you can get the workspace using manager.build.workspace.getRemote(). Don't forget to add File.separator between path and file name.
As mentioned in a different post Read .txt file from workspace groovy script in Jenkins I was struggling to make it work for the pom modules for a file in the workspace, in the
Extended Choice Parameter. Here is my solution with the printlns:
import groovy.util.XmlSlurper
import java.util.Map
import jenkins.*
import jenkins.model.*
import hudson.*
import hudson.model.*
try{
//get Jenkins instance
def jenkins = Jenkins.instance
//get job Item
def item = jenkins.getItemByFullName("The_JOB_NAME")
println item
// get workspacePath for the job Item
def workspacePath = jenkins.getWorkspaceFor (item)
println workspacePath
def file = new File(workspacePath.toString()+"\\pom.xml")
def pomFile = new XmlSlurper().parse(file)
def pomModules = pomFile.modules.children().join(",")
return pomModules
} catch (Exception ex){
println ex.message
}
I am working on a groovy script that will get all the local html files and parse certain tags in them. I tried using something like html clean and it just is not working. I tried to read each line but that only works when the stuff I need is on 1 line. I have this script up on github, https://github.com/jrock2004/johns-octopress-scripts/blob/master/convertCompiledPosts/convertPosts.groovy. Thanks for any input
Edit: So I am getting closer. I have this code now
def parser = new org.cyberneko.html.parsers.SAXParser()
new XmlParser( parser ).parse( curFile+ "/index.html" ).with { page ->
page.'**'.DIV.grep { it.'#class'?.contains 'entry-content' }.each {
println it
println "--------------------------------"
}
}
And what it prints is
DIV[attributes={class=entry-content}; value=[P[attributes={}; value=[As an automation developer, I have learned how to write code in Java. When I am having an issue, one of the nice things that you can do is debug your code, line by line. For the longest I had wished that something like this existed in PHP. I have come to find out that you can actually debug code, like I do in Java. This is such a helpful task because I do not have to waste time using var_dump and such on variables or results. In your apache/php server you need to install and or enable something called, A[attributes={href=http://xdebug.org/}; value=[Xdebug]], . I will work on a tutorial on how to use xdebug while writing code in Sublime Text 2. So keep an eye out on my blog and or, A[attributes={href=http://www.youtube.com/jrock20041}; value=[YouTube]], channel for this tutorial.]]]]
So basically what I want is I wall the text including the html elements in the div with the class entry-content. If you want to see the page it can be found here -- http://jcwebconcepts.net/blog/2013/02/02/xdebug/
Thanks for your help
It does work... Save the HTML for this page to a file, then you can parse it.
The following code prints the name of the author of every comment on the page:
#Grab('net.sourceforge.nekohtml:nekohtml:1.9.16')
def parser = new org.cyberneko.html.parsers.SAXParser()
new XmlParser( parser ).parse( file ).with { page ->
page.'**'.A.grep { it.'#class'?.contains 'comment-user' }.each {
println it.text()
}
}
When file is set to be a File pointing to the saved HTML (or a String containing the URL of this question), it prints:
tim_yates
jrock2004
tim_yates
Edit:
To print the contents of a given node, you could do (using the example from your edited question):
#Grab('net.sourceforge.nekohtml:nekohtml:1.9.16')
import groovy.xml.*
def parser = new org.cyberneko.html.parsers.SAXParser()
new XmlParser( parser ).parse( 'http://jcwebconcepts.net/blog/2013/02/02/xdebug/' ).with { page ->
page.'**'.DIV.grep { it.'#class'?.contains 'entry-content' }.each { it ->
println XmlUtil.serialize( it )
}
}
I checked SO for the xmlpullparser exception but it's giving me others questions with Android and SOUP. I am using J2me and normal HTTPrequest to get my XML and I am using kXMl to parser the xml text. Below is the code that I am working on. And above it is more parsing code and they work perfectly.
if (parser.getName().equals("comments")) {
event = parser.next();
boolean flag = false;
if (parser.getName().equals("comment")) {
flag = true;
System.out.println("Flag is true");
}
while (flag) {
event = parser.next();
Questioncomments.addComponent(new Label(parser.nextText()));
event = parser.next();
System.out.println("Inside the While");
if (!parser.getName().equals("comment")) {
flag = false;
System.out.println("Flag is false");
}
}
Questioncomments.repaint();
}
XML I am sending this side - <comments><comment>Awesome Question #dulitha<idComment></idComment></comment></comments>
The error is -
org.xmlpull.v1.XmlPullParserException: precondition: START_TAG
(position:TEXT Awesome Question...#1:399 in
java.io.InputStreamReader#f828ed68)
at org.kxml2.io.KXmlParser.exception(+47)
at org.kxml2.io.KXmlParser.nextText(+14)
at
com.petmill.mobile.view.qanda.QuestionCanvas.setData(QuestionCanvas.java:189)
at
com.petmill.mobile.view.qanda.QuestionsList$5$1$1.actionPerformed(QuestionsList.java:119)
The error comes up at the line where I am trying to get the text - parser.nextText(). How can I parse the xml to get the data required... Thanks in advance.
It looks like you are not on the START_TAG event when you call parser.nextText(). Check that you are on a START_TAG event when you call parser.nextText() with the parser.getEventType(). I suspect that you have some whitespace between <comments> and <comment> tag and therefore your parser is not at the event that you expect it to be.
Perhaps you should also consider a safer approach for parsing this xml.
<comments>
<comment>Awesome Question #dulitha
<idComment></idComment>
</comment>
</comments>
this is not valid xml