integrate jasperintelligence with ruby on rails

0
Hi all, can anyone show me how to integrate jasperintelligence with ruby on rails application.

Mainly is
1) Authentication - let rails handle to the authentication

2) url to access reports stored on jasperintelligence
paulc's picture
1
Joined: Oct 1 2006 - 8:35pm
Last seen: 12 years 8 months ago

33 Answers:

1
Hi, I'm actually dealing with it. I just can tell you the url connection as I havent been able to get a "fully" authentication.

Url: "http://localhost/jasperserver/services/repository/"

I've tried to authenticate with this:
conn = Net::HTTP.start('10.128.10.81')
get = Net::HTTP::Get.new('/jasperserver/services/repository/')
get.basic_auth 'jasperadmin', 'jasperadmin'
conn.request(get)
print conn

but it answers ok, but when I try to use any other method, it says "SOAP::HTTPStreamError: 401: Full authentication is required to access this resource". Im still looking into it but I'd really appreciate any suggestion.
rosisr's picture
16
Joined: Sep 14 2006 - 5:27pm
Last seen: 12 years 9 months ago
0

Have you checked out

http://community.jaspersoft.com/questions/514432/jasperintelligence-11-web-services-doc-posted

Sherman
Jaspersoft



Post Edited by Tim Cloonan at 08/25/08 14:12

swood's picture
2377
Joined: Jun 21 2006 - 12:48pm
Last seen: 6 years 8 months ago
0
Thanks but though I've been checking it my Java knowledge is very low. What I need to do is a web service client in Ruby on Rails and I can understand I dont need to rewrite the code, do I? I mean in Ruby is supposed to be just:

JASPER_SERVER = "http://10.128.10.81/jasperserver/services/repository/"
driver = SOAP::RPC::Driver.new(JASPER_SERVER)
driver.add_method('login','username','password')


Thanks in advance for any suggestion.
rosisr's picture
16
Joined: Sep 14 2006 - 5:27pm
Last seen: 12 years 9 months ago
0
I've been toying around with this concept for at least 3 weeks, and I haven't been able to make any meaningful progress. Part of the problem as I see it is the inability for the default JI web service to display its WSDL, where you get the following error message:

<error>
<description>Unable to generate WSDL for this service</description>
<reason>
Either user has not dropped the wsdl into META-INF or operations use message receivers other than RPC.
</reason>
</error>

Another forum post addresses this and recommends deploying the repository.aar file as an axis2 service, with the caveat that you have to have all the required jar files, whatever those are supposed to be. All I ever get there is a faulty axis2 service.

But back to the rails problem specifically. Based on the methods I see as available in the web service (the WSDL is available on the aforementioned forum post), I should be able to use add_method for the RPC driver to create a login method that works. It's obvious that something is wrong with the authentication method that I am using, because I get:

SOAP::HTTPStreamError: 401: Full authentication is required to access this resource

The thing is, I really like JasperIntelligence, and I am evaluating ways to integrate it into other web applications that may or may not be java-based. If I can show a solid success story here, I might even be able to convince my company to abandon Crystal entirely.

Is there any way we can get more meaningful answers to this kind of question? Has anyone implemented a ruby SOAP client that interfaces with the JI web service? I don't guess I have to point out that existing documentation is understandably java-specific, and since I don't have a strong grasp of java in the first place, I don't relish the idea of digging through the iReport plugin to figure out how this works.

Any suggestions?
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
Hi, I've got the same error as you and finally Ive got authentication but I cannot do anything more, with add_method I tried the list method and all I got was
Errno::ECONNREFUSED: Connection refused - connect(2) (, #0)

My class for a web service client:

class WsJasperClient < SOAP::RPC::Driver

JASPER_SERVER = "http://10.128.10.81/jasperserver/services/repository/"

# Authentication works!!!
def new(nameserver)
# nameserver => JASPER_SERVER
driver = SOAP::RPC::Driver.new(JASPER_SERVER)
driver.options["protocol.http.basic_auth"] <<
[JASPER_SERVER, "jasperadmin", "jasperadmin"]
end

# Create driver and set up methods
# It doesnt work yet :-(
def add_methods
# driver = SOAP::RPC::Driver.new("http://10.128.10.81/jasperserver/services/repository/" )
[ %w(login username password),
%w(list uri),
%w(get uri args),
%w(runReport reportUri map)].each do |signature|
self.add_method(*signature)
end
end

end

I hope this can help you though I havent been able to get it works.
Post edited by: rosisr, at: 2006/12/04 10:27
rosisr's picture
16
Joined: Sep 14 2006 - 5:27pm
Last seen: 12 years 9 months ago
0
I got the following (via irb) to generate both a successful authentication and an error:

require 'soap/rpc/driver'

server = "http://localhost:8080/jasperserver/services/repository/"

driver = SOAP::RPC::Driver.new(server)

driver.options["protocol.http.basic_auth"] << [server, "admin", "admin"]

driver.add_method('login','username','password')

driver.login('admin','admin')


The error that is generated:

SOAP::Parser::FormatDecodeError: Unbalanced tag in XML.

from /usr/lib/ruby/1.8/soap/parser.rb:95:in `parse'

from /usr/lib/ruby/1.8/soap/processor.rb:39:in `unmarshal'

from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:232:in `unmarshal'

from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:175:in `route'

from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:141:in `call'

from /usr/lib/ruby/1.8/soap/rpc/driver.rb:178:in `call'

from /usr/lib/ruby/1.8/soap/rpc/driver.rb:232:in `login'

from (irb):6



However, getting this to work in the first place required me to install http-access2, since net/http + soap4r does not support basic authentication ( NotImplementedError: basic_auth is not supported under soap4r + net/http.)

Kudos, though, for figuring out the mechanism for authentication.

Next up, adding the other methods.

I tried:

driver.add_method('list','uri')

which is what your class method attempts to do. I don't get a connection refused, but I do get an error, and it seems that JasperServer is returning this one:

09:49:15,778 ERROR ManagementService,http-8080-Processor23:283 - caught exception: Parsing Error : Content is not allowed in prolog.

Line : 1

Column : 1



Parsing Error : Content is not allowed in prolog.

Line : 1

Column : 1

{file: [not available]; line: 1; column: 1}

....


I suspect I will be able to track that one down, and it's likely just the way I have constructed my argument.

Anyway, I will keep trying to figure that out... In the mean time, I would love to hear from anyone else who has tried this.
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
If you try from a rails console you can get an authentication with:
JASPER_SERVER = "http://10.128.10.81/jasperserver/services/repository/"
driver = SOAP::RPC::Driver.new(JASPER_SERVER)
driver.options["protocol.http.basic_auth"] <<
[JASPER_SERVER, "jasperadmin", "jasperadmin"]

I've also had the same problems as you. I got the authentication with the code above in a rails console and then I got other error when I tried to use list method and what I get is:

ws.list('')
Wire dump:

= Request

POST /jasperserver/services/repository/ HTTP/1.1
! CONNECTION CLOSED
Errno::EPIPE: Broken pipe
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:1135:in `write'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:1135:in `<<'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2/http.rb:185:in `dump'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2/http.rb:386:in `dump'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:1213:in `query'
from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
from /usr/lib/ruby/1.8/timeout.rb:76:in `timeout'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:1211:in `query'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:892:in `query'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:434:in `do_get_block'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:370:in `conn_request'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:285:in `request'
from /usr/lib/ruby/gems/1.8/gems/rubyforge-0.3.1/lib/http-access2.rb:264:in `post'
from /usr/lib/ruby/1.8/soap/streamHandler.rb:199:in `send_post'
from /usr/lib/ruby/1.8/soap/streamHandler.rb:137:in `send'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:170:in `route'
from /usr/lib/ruby/1.8/soap/rpc/proxy.rb:141:in `call'
from /usr/lib/ruby/1.8/soap/rpc/driver.rb:178:in `call'
rosisr's picture
16
Joined: Sep 14 2006 - 5:27pm
Last seen: 12 years 9 months ago
0
I figured a couple of things out this morning with respect to the list operation and authentication. First, the approach we are taking is the correct approach for authentication. Second, the list operation requires an XML document as an argument, not simply a path, like /reports. I found the structure of the XML document that lists the resources in the repository by running Ethereal and digging through the HTTP POST packets generated by iReport with the web service plugin. From that, I was able to construct the following program, which works to get a list of available resources given a URI:


#!/bin/env ruby

require 'soap/rpc/driver'

strUser = 'admin'
strPWD = 'admin'
strServer = 'http://localhost:8080/jasperserver/services/repository/'
strURI = %q{<?xml version="1.0" encoding="UTF-8"?>
<request>
<operation-name>list</operation-name>
<resource-descriptor read-only="false" control-type="0"
is-reference="false" is-new="false" strict-max="false"
data-type="0" mandatory="false" has-data="false"
strict-min="false" main-report="false" version="0">
<uri-string>/reports</uri-string><ws-type>folder</ws-type>
</resource-descriptor></request>
}

driver = SOAP::RPC::Driver.new(strServer)
driver.wiredump_dev = STDERR
driver.options["protocol.http.basic_auth"] << [strServer, strUser, strPWD]

driver.add_method('list','request')

puts driver.list(strURI)


From there, it should be trivial to parse the resulting XML into something that works in rails:


<?xml version="1.0" encoding="UTF-8"?>

<operation-result return-code="0"><resource-descriptors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" read-only="false" control-type="0" is-reference="false" is-new="false" strict-max="false" data-type="0" mandatory="false" has-data="false" strict-min="false" main-report="false" version="0" xsi:type="java:com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceDescriptor">
<name>samples</name><description>Samples</description>
<resource-type>com.jaspersoft.jasperserver.api.metadata.common.domain.Folder
</resource-type><parent-folder>/reports</parent-folder>
<creation-date>2006-11-15T12:27:13.000-06:00</creation-date>
<uri-string>/reports/samples</uri-string><ws-type>folder
</ws-type><label>Samples</label></resource-descriptors>
<version>1.1.0</version></operation-result>


I will hopefully be able to deconstruct a runReport request here in the next couple of hours. Note that it is not necessary to explicitly call the login function, since the headers here are constructed with the authentication present. I believe that was the source of the 500 Internal Server Error mentioned previously.
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
As promised, here's a plain ruby example of how to use the runReport method. I am betting it is pretty easy from this point to integrate this into rails. That's my next step, anyway.

#!/bin/env ruby

require 'soap/rpc/driver'

strUser = 'admin'
strPWD = 'admin'
strServer = 'http://localhost:8080/jasperserver/services/repository/'
strOutputFormat = 'HTML' #JRPRINT, RTF, PDF, etc?
strURI = '/reports/samples/Employees'
strRequest = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request><operation-name>runReport</operation-name><resource-descriptor
read-only="false" control-type="0" is-reference="false"
is-new="false" strict-max="false" data-type="0"
mandatory="false" has-data="false" strict-min="false"
main-report="false" version="0">
<uri-string>#{strURI}</uri-string></resource-descriptor>
<arguments xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.Argument">
<name>RUN_OUTPUT_FORMAT</name><value>#{strOutputFormat}</value></arguments></request>
|

driver = SOAP::RPC::Driver.new(strServer)
driver.wiredump_dev = STDERR
driver.options["protocol.http.basic_auth"] << [strServer, strUser, strPWD]

driver.add_method('runReport','request')

puts driver.runReport(strRequest)
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
Thanks a lot, you've been a great help!! But I still have some problems, when I try to run this:

#!/bin/env ruby

require 'soap/rpc/driver'

strUser = 'jasperadmin'
strPWD = 'jasperadmin'
strServer = 'http://10.128.10.81/jasperserver/services/repository/'

strOutputFormat = 'HTML' #JRPRINT, RTF, PDF, etc?
strURI = '/reports/samples/Employees'
strRequest = %Q{<?xml version="1.0" encoding="UTF-8"?>
<request> <operation-name>runReport</operation-name>
<resource-descriptor
read-only="false" control-type="0" is-reference="false" is-new="false" strict-max="false" data-type="0" mandatory="false" has-data="false" strict-min="false" main-report="false" version="0">
<uri-string>#{strURI}</uri-string>
</resource-descriptor>
<arguments xmlnssi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.Argument">
<name>RUN_OUTPUT_FORMAT</name>
<value>#{strOutputFormat}</value>
</arguments>
</request>
}

driver = SOAP::RPC::Driver.new(strServer)
driver.wiredump_dev = STDERR
driver.options["protocol.http.basic_auth"] << [strServer, strUser, strPWD]

driver.add_method('runReport','request')

puts driver.runReport(strRequest)

What I get is:

<?xml version='1.0 'encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header />
<soapenv:Body><ns1:result xmlns:ns1="http://jasperserver/ws2/namespace1" xmlns:tns="http://ws.apache.org/axis2">&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;operation-result return-code="1">&lt;version>1.1.0&lt;/version>&lt;message>unable to instantiate java.util.List; &lt;/message>&lt;/operation-result></ns1:result></soapenv:Body></soapenv:Envelope>

Any suggestion?
rosisr's picture
16
Joined: Sep 14 2006 - 5:27pm
Last seen: 12 years 9 months ago
0
That looks like an issue with JasperIntelligence, and not with ruby. Try tailing your catalina.out file and see if there is more information there, like a stack trace.

As for my progress in general, I still have to do the following:

1. Figure out how to pass parameters in the request XML
2. Figure out how to view an HTML-exported report inline (in rails)
3. Figure out everything else rails needs to make this work right

Of course I will still be working on it today, but if anyone else comes across this topic and has any suggestions, I would love to hear them. Item number 2 has its own forum thread, since I can't seem to get any meaningful object out of the SOAP::Attachment when I choose HTML as the output format.
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
Ok, after some additional time dedicated to this task, I have managed the following:

1. Provide a rails front-end that lists the reports residing in a specific folder.
2. Create links to those reports that then return the report in an exportable format, such as PDF.

PDF is the only format I have actually gotten to work with the sample reports, but I suspect that other formats should work just fine if the report is set up to handle it.

To accomplish this, I needed a model, a controller, a helper, and a view. Here is the code that I am using. Note that I am storing my JI connection information in the local database, since I don't want the user to know anything about the JI credentials explicitly. My table name for this configuration info is site_configs, and I have a corresponding rails model called site_configs.rb

##### begin app/models/reports.rb #####
require 'soap/rpc/driver'
class Reports < ActiveRecord::Base

class << self
def get_list(strURL, strUser, strPass, strURI)

strRequestBody = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request>
<operation-name>list</operation-name>
<resource-descriptor read-only="false" control-type="0"
is-reference="false" is-new="false" strict-max="false"
data-type="0" mandatory="false" has-data="false"
strict-min="false" main-report="false" version="0">
<uri-string>#{strURI}</uri-string><ws-type>folder</ws-type>
</resource-descriptor></request>
|

driver = SOAP::RPC::Driver.new(strURL)
driver.options["protocol.http.basic_auth"] << [strURL, strUser, strPass]
driver.add_method('list','request')

@report_list = driver.list(strRequestBody)
end

def get_report(strURL, strUser, strPass, strURI, strOutputFmt)

strRequestBody = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request><operation-name>runReport</operation-name><resource-descriptor
read-only="false" control-type="0" is-reference="false"
is-new="false" strict-max="false" data-type="0"
mandatory="false" has-data="false" strict-min="false"
main-report="false" version="0">
<uri-string>#{strURI}</uri-string></resource-descriptor>
<arguments xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.Argument">
<name>RUN_OUTPUT_FORMAT</name><value>#{strOutputFmt}</value></arguments></request>
|

driver = SOAP::RPC::Driver.new(strURL)
driver.options["protocol.http.basic_auth"] << [strURL, strUser, strPass]
driver.add_method('runReport','request')

report = driver.runReport(strRequestBody)["Include"].content
report
end
end

end
##### end app/models/reports.rb #####


##### begin app/helpers/send_doc.rb #####
module SendDoc
def send_doc(strURL, strUser, strPass, strReportName, strReportURI, strOutputFmt)

case strOutputFmt
when 'PDF'
mime_type = 'application/pdf'
extension = 'pdf'
else #rtf
mime_type = 'application/rtf'
extension = 'rtf'
end

send_data Reports.get_report(strURL, strUser, strPass, strReportURI, strOutputFmt),
:filename => "#{strReportName}.#{extension}", :type => mime_type, :disposition => 'inline'
end
end
##### end app/helpers/send_doc.rb #####


##### begin app/controllers/reports_controller.rb #####
require 'rexml/document'
class ReportsController < ApplicationController

include SendDoc

def index
@jasperServer = SiteConfig.find(:first, :conditions => "name = 'JasperServer URL'")["value"]
@jasperUser = SiteConfig.find(:first, :conditions => "name = 'JasperServer User'")["value"]
@jasperPass = SiteConfig.find(:first, :conditions => "name = 'JasperServer Password'")["value"]
@jasperURI = '/reports/samples'

@reportsXML = Reports.get_list(@jasperServer, @jasperUser, @jasperPass, @jasperURI)

doc = REXML::Document.new(@reportsXML)
@report_names = []
@report_labels = []
@res_type = []
@parent_folder = []

doc.elements.each('operation-result/resource-descriptors/name') do |ele|
@report_names << ele.text
end

doc.elements.each('operation-result/resource-descriptors/label') do |ele|
@report_labels << ele.text
end

doc.elements.each('operation-result/resource-descriptors/resource-type') do |ele|
@res_type << ele.text
end

doc.elements.each('operation-result/resource-descriptors/parent-folder') do |ele|
@parent_folder << ele.text
end
end

def run
@jasperServer = SiteConfig.find(:first, :conditions => "name = 'JasperServer URL'")["value"]
@jasperUser = SiteConfig.find(:first, :conditions => "name = 'JasperServer User'")["value"]
@jasperPass = SiteConfig.find(:first, :conditions => "name = 'JasperServer Password'")["value"]

@reportName = params[:reportURI].gsub(/\//, '_')

@report = send_doc(@jasperServer, @jasperUser, @jasperPass, @reportName, params[:reportURI], params[:format])
end
end
##### end app/controllers/reports_controller.rb #####


##### begin app/views/reports/index.rhtml #####
<% @page_title = 'Reports' %>
Folder: <%= @parent_folder[0] %><br/><br/>
<% @report_names.each_with_index do |name, idx| %>
<% if @res_type[idx] == 'com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportUnit' %>
<li><%= @report_labels[idx] %>
<%= link_to(image_tag("/images/pdf.gif", :border => 0), :controller => "reports", :action => "run", :reportURI => "#{@jasperURI}/#{name}", :format => 'PDF')
%>
<% end %>
<% end %>
##### end app/views/reports/index.rhtml #####


If anyone knows how to accomplish this better, I am still interested in learning how. Also, I would like to have a couple other options as far as output goes, so if anyone knows how I can get a native (JRPRINT) report to output from a non-java client, I would be appreciative.

My next real task will be to construct the XML document that contains parameters, since reports aren't always very useful unless you can change your parameters.
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
I tried this and get the same error :pinch:

rosisr wrote:
Thanks a lot, you've been a great help!! But I still have some problems, when I try to run this:

#!/bin/env ruby

require 'soap/rpc/driver'

strUser = 'jasperadmin'
strPWD = 'jasperadmin'
strServer = 'http://10.128.10.81/jasperserver/services/repository/'

strOutputFormat = 'HTML' #JRPRINT, RTF, PDF, etc?
strURI = '/reports/samples/Employees'
strRequest = %Q{<?xml version="1.0" encoding="UTF-8"?>
<request> <operation-name>runReport</operation-name>
<resource-descriptor
read-only="false" control-type="0" is-reference="false" is-new="false" strict-max="false" data-type="0" mandatory="false" has-data="false" strict-min="false" main-report="false" version="0">
<uri-string>#{strURI}</uri-string>
</resource-descriptor>
<arguments xmlnssi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.Argument">
<name>RUN_OUTPUT_FORMAT</name>
<value>#{strOutputFormat}</value>
</arguments>
</request>
}

driver = SOAP::RPC::Driver.new(strServer)
driver.wiredump_dev = STDERR
driver.options["protocol.http.basic_auth"] << [strServer, strUser, strPWD]

driver.add_method('runReport','request')

puts driver.runReport(strRequest)

What I get is:

<?xml version='1.0 'encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header />
<soapenv:Body><ns1:result xmlns:ns1="http://jasperserver/ws2/namespace1" xmlns:tns="http://ws.apache.org/axis2"><?xml version="1.0" encoding="UTF-8"?>
<operation-result return-code="1"><version>1.1.0</version><message>unable to instantiate java.util.List; </message></operation-result></ns1:result></soapenv:Body></soapenv:Envelope>

Any suggestion?


:x
Post edited by: edxerx, at: 2007/03/15 09:16
edxerx's picture
4
Joined: Jul 31 2006 - 10:07am
Last seen: 12 years 10 months ago
0

seems that in the end all I get is

#<:mapping::object:0x2e32f04>: The AXIS engine could not find a target service to invoke! targetService is repository/ (SOAP::FaultError)

btw my code is as below
 

Code:
require 'soap/rpc/driver'
 
 
 
list = <<LIST
 
<?xml version="1.0" encoding="UTF-8" ?>
 
<request operationName="list" locale="en">
 
  <resourceDescriptor name="" wsType="folder" uriString="/reports" isNew="false">
 
    <label>null</label>
 
  </resourceDescriptor>
 
</request>
 
LIST
 
 
 
driver = SOAP::RPC::«»Driver.new("http://localhost:8080/jasperserver/services/repository/"«»)
 
driver.options["protocol.http.basic_auth"] << ["http://localhost:8080/jasperserver/services/repository/", "jasperadmin", "jasperadminpassword"]
 
driver.add_method("list", "request"«»)
 
r = driver.list(list)


I can connect but can't do anything :blink: , anyone got clues?

edxerx's picture
4
Joined: Jul 31 2006 - 10:07am
Last seen: 12 years 10 months ago
0
I believe my original code is now deprecated with the release of JI 1.2, but the good news (so far in my testing) is that you won't need it.

What you should probably do now that the WSDL is generated and exposed, is use the ruby utility wsdl2ruby. To get it to work correctly for me, since it doesn't have HTTP Basic Authentication out of the box, I saved the WSDL file in some location, then used the saved file as the input for the wsdl2ruby script:

$ wsdl2ruby --wsdl jasperserver.wsdl --type client

I didn't have to force anything. The files that are generated (in my case) are:

defaltDriver.rb
defaultMappingRegistry.rb
default.rb
ManagementServiceServiceClient.rb

You need the first three files, but any script you want to write should:

require 'defaultDriver.rb'

ManagementServiceServiceClient.rb is a sample client you can use to test out the available methods. Before you give it a whirl, you should make sure to add the basic authentication method discussed earlier in this thread. Just to get it off the ground, I added the following line after the wiredump_dev line:

obj.options["protocol.http.basic_auth"] << [endpoint_url,"admin_user","admin_password"]

Run the file with ruby -d to get the full request and response for each of the methods. This will show you how you might construct your own requests.

Hopefully, as I get some time, I will be able to rework the code I originally wrote to take advantage of the auto-magic that ruby is capable of. If anyone else manages to get something working, I would love to see it.
Post edited by: MariusAgricola, at: 2007/03/15 22:05
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
thanks for the reply, I will try your solution a.s.a.p :)
edxerx's picture
4
Joined: Jul 31 2006 - 10:07am
Last seen: 12 years 10 months ago
0
One other thing to note in the client file is that in all cases the requestXmlString is set to nil:

requestXmlString = nil

This means that you will still have to construct the request in a particular format. I am not certain if the format is still the same with this version of JI, but a look at the wiredump indicates that it might not be. You could, as an alternative, attempt to get the format from a network analysis tool such as ethereal, while running the same operation inside the updated iReport program. I haven't had a chance to 1) update iReport, and 2) break down the packets.
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
First let me thank you for the work you have done on this project. I have Jasperserver 1.2 installed and have the LIST functionality working with your framework. I just had to modify the strRequestBody values in the reports.rb, and the doument elements in the controller. What really has me stumped is the line of code report = driver.call('runReport', strRequestBody)['Include'].content in the reports model. I get this error: Any help would be greatly appreciated...

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.content

of course if I remove the ['Include'].content... I only get the success response:
<?xml version="1.0" encoding="UTF-8" ?>
- <operationResult version="1.2.0">
- <returnCode>
- <![CDATA[ 0]]>
</returnCode>
</operationResult>

A wiredump indicates that the pdf is being delievered as "chunked" just cannot figure out how to caputure it.. I've tried everything I can think of to inspect the object / response to determine what is going on.. YAML::dump, inspect...
Please forgive me! I'm just hacking away at this. I really don't have a clue about how this stuff really works...
I've built a small ruby script to test the wsdl2ruby method, and I have the same problem
while trying to retrieve the response from runReport.

##### begin test.rb #####

require 'defaultDriver'
strRequestBody = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request operationName="runReport" locale="en">
<argument name="RUN_OUTPUT_FORMAT">PDF</argument>
<resourceDescriptor name="" wsType=""
uriString="/reports/samples/AllAccounts"
isNew="false">
<label>null</label>
</resourceDescriptor>
</request>
|

strRequestBody = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request operationName="runReport" locale="en">
<argument name="RUN_OUTPUT_FORMAT">PDF</argument>
<resourceDescriptor name="" wsType=""
uriString="/reports/samples/AllAccounts"
isNew="false">
<label>null</label>
</resourceDescriptor>
</request>
|
obj = ManagementService.new("http://ubuntu:8080/jasperserver/services/repository")
obj.options["protocol.http.basic_auth"] << ["http://ubuntu:8080/jasperserver/services/repository","jasperadmin","jasp...
puts obj.runReport(strRequestBody)
##### end test.rb #####

My 1.2 almost compliant / almost working hack of the integrate jasperintelligence with ruby on rails stuff follows:

##### begin app/models/reports.rb #####
require 'soap/rpc/driver'
class Reports < ActiveRecord::Base

class << self
def get_list(strURL, strUser, strPass, strURI)


strRequestBody = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request operationName="list" locale="en">
<resourceDescriptor name="" wsType="folder" uriString="#{strURI}" isNew="false">
<label>null</label>
</resourceDescriptor>
</request>
|


driver = SOAP::RPC::Driver.new(strURL)
driver.options["protocol.http.basic_auth"] << [strURL, strUser, strPass]
driver.add_method('list','request')
@report_list = driver.list(strRequestBody)

end


def get_report(strURL, strUser, strPass, strURI, strOutputFmt)


strRequestBody = %Q|<?xml version="1.0" encoding="UTF-8"?>
<request operationName="runReport" locale="en">
<argument name="RUN_OUTPUT_FORMAT">#{strOutputFmt}</argument>
<resourceDescriptor name="" wsType=""
uriString="#{strURI}"
isNew="false">
<label>null</label>
</resourceDescriptor>
</request>
|
driver = SOAP::RPC::Driver.new(strURL)
driver.options["protocol.http.basic_auth"] << [strURL, strUser, strPass]
driver.add_method('runReport','request')


report = driver.call('runReport', strRequestBody)['Include'].content
report
end
end

end

##### end app/models/reports.rb #####

##### begin app/helpers/send_doc.rb #####

module SendDoc
def send_doc(strURL, strUser, strPass, strReportName, strReportURI, strOutputFmt)

case strOutputFmt
when 'PDF'
mime_type = 'application/pdf'
extension = 'pdf'
else #rtf
mime_type = 'application/rtf'
extension = 'rtf'
end


send_data Reports.get_report(strURL, strUser, strPass, strReportURI, strOutputFmt),
:filename => "#{strReportName}.#{extension}", :type => mime_type, :disposition => 'inline'

end
end

##### end app/helpers/send_doc.rb #####

##### begin app/controllers/reports_controller.rb #####
require 'rexml/document'
class ReportsController < ApplicationController

include SendDoc

def index
@jasperServer = SiteConfig.find(:first, :conditions => "name = 'JasperServer URL'")["value"]
@jasperUser = SiteConfig.find(:first, :conditions => "name = 'JasperServer User'")["value"]
@jasperPass = SiteConfig.find(:first, :conditions => "name = 'JasperServer Password'")["value"]
@jasperURI = '/reports/samples'

@reportsXML = Reports.get_list(@jasperServer, @jasperUser, @jasperPass, @jasperURI)

doc = REXML::Document.new(@reportsXML)
@report_names = []
@report_labels = []
@res_type = []
@parent_folder = []


doc.elements.each('operationResult/resourceDescriptor') do |ele|
@report_names << ele.attributes["name"]
end

doc.elements.each('operationResult/resourceDescriptor/label') do |ele|
@report_labels << ele.text
end

doc.elements.each("operationResult/resourceDescriptor/resourceProperty[@name='PROP_RESOURCE_TYPE']/value") do |ele|
@res_type << ele.text
end

doc.elements.each("operationResult/resourceDescriptor/resourceProperty[@name='PROP_PARENT_FOLDER']/value") do |ele|
@parent_folder << ele.text
end

end



def run
@jasperServer = SiteConfig.find(:first, :conditions => "name = 'JasperServer URL'")["value"]
@jasperUser = SiteConfig.find(:first, :conditions => "name = 'JasperServer User'")["value"]
@jasperPass = SiteConfig.find(:first, :conditions => "name = 'JasperServer Password'")["value"]

@reportName = params[:reportURI].gsub(/\//, '_')

@report = send_doc(@jasperServer, @jasperUser, @jasperPass, @reportName, params[:reportURI], params[:format])
end
end
##### end app/controllers/reports_controller.rb #####

##### begin app/views/reports/index.rhtml #####
<% @page_title = 'Reports' %>
Folder: <%= @parent_folder[0] %><br/><br/>
<% @report_names.each_with_index do |name, idx| %>
<% if @res_type[idx] == 'com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportUnit' %>
<li><%= @report_labels[idx] %>
<%= link_to(image_tag("/images/pdf.gif", :border => 0), :controller => "reports", :action => "run", :reportURI => "#{@jasperURI}/#{name}", :format => 'PDF')%>
<% end %>
<% end %>
##### end app/views/reports/index.rhtml #####
lemonyaide's picture
Joined: Mar 7 2007 - 1:09pm
Last seen: 12 years 3 months ago
0
Has anyone been able to solve the chunked problem? I have the same problem. The report PDF is being sent back as a SOAP multipart attachment. I don't know how to read the multipart attachment from the response.
juantar's picture
Joined: May 8 2007 - 1:01am
Last seen: 12 years 1 month ago
0

I modified the SOAP::RPC:Proxy class to return the SOAP::SOAPEnvelope in addition to the response object.
 

Code:
# Modify SOAP::RPC::«»Proxy class to return SOAP Message in addition to object mapping 
 
# to access the SOAP attachments
 
module SOAP
 
module RPC
 
 
 
 
 
class Proxy
 
  include SOAP
 
 
 
  def call(name, *params)
 
    unless op_info = @operation[name]
 
      raise MethodDefinitionError, "method: #{name} not defined"
 
    end
 
    mapping_opt = create_mapping_opt
 
    req_header = create_request_header
 
    req_body = SOAPBody.new(
 
      op_info.request_body(params, @mapping_registry,
 
        @literal_mapping_registry, mapping_opt)
 
    )
 
    reqopt = create_encoding_opt(
 
      :«»soapaction => op_info.soapaction || @soapaction,
 
      :envelopenamespace => @options["soap.envelope.requestnamespace"],
 
      :default_encodingstyle =>
 
        @default_encodingstyle || op_info.request_default_encodingstyle,
 
      :elementformdefault => op_info.elementformdefault,
 
      :attributeformdefault => op_info.attributeformdefault
 
    )
 
    resopt = create_encoding_opt(
 
      :envelopenamespace => @options["soap.envelope.responsenamespace"],
 
      :default_encodingstyle =>
 
        @default_encodingstyle || op_info.response_default_encodingstyle,
 
      :elementformdefault => op_info.elementformdefault,
 
      :attributeformdefault => op_info.attributeformdefault
 
    )
 
    env = route(req_header, req_body, reqopt, resopt)
 
    raise EmptyResponseError unless env
 
    receive_headers(env.header)
 
    begin
 
      check_fault(env.body)
 
    rescue ::«»SOAP::FaultError => e
 
      op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
 
    end
 
    response_obj = op_info.response_obj(env.body, @mapping_registry,
 
      @literal_mapping_registry, mapping_opt)
 
    return response_obj, env
 
  end
 
end
 
 
 
end
 
end


The SOAP::SOAPEnvelope has an attribute called external_content and this is where the SOAP::Attachment objects are stored. The external_content attribute is a hash and to access the desired SOAP::Attachment, use the Content-Id from the multipart attachment. For JasperServer, the Content-Id for the report attachment is 'report'.
 

Code:
@driver = SOAP::RPC::«»Driver.new(@url)
 
@driver.options["protocol.http.basic_auth"] << [@url, @user, @pass]
 
 
 
@driver.add_method('runReport','request')
 
 
 
result, env = @driver.runReport(request.to_s)
 
report = env.external_content['report'].data.content
schmitzc's picture
Joined: Oct 10 2007 - 3:15am
Last seen: 11 years 8 months ago
0
I can't get the above code to work... in fact those modifications to SOAP::RPC::Proxy don't make sense for soap4r -- at least not the latest version (1.5.8). What version of Ruby's SOAP libraries is this supposed to work against?
mzukowski's picture
Joined: Sep 5 2006 - 7:18am
Last seen: 12 years 9 months ago
0
I am not using soap4r. I am only using the SOAP classes included in the Ruby standard library. I included the modifications to the SOAP::RPC::Proxy only in the class that I was using to connect to the Jasper Server Web Service.
schmitzc's picture
Joined: Oct 10 2007 - 3:15am
Last seen: 11 years 8 months ago
0
Okay nevermind... I should double-check before I post. Anyway here's a slightly different version of the above monkeypatch. This one should work against soap4r 1.5.8. Also, it adds the instance variable @env to the response object rather than returning an array with the env data. I think this might be a bit safer since it doesn't break the API.

Code:
<br />
module SOAP<br />
  module RPC<br />
  <br />
    class Proxy<br />
      include SOAP<br />
      <br />
      def call(name, *params)<br />
        # name must be used only for lookup<br />
        op_info = lookup_operation(name)<br />
        mapping_opt = create_mapping_opt<br />
        req_header = create_request_header<br />
        req_body = SOAPBody.new(<br />
          op_info.request_body(params, @mapping_registry,<br />
            @literal_mapping_registry, mapping_opt)<br />
        )<br />
        reqopt = create_encoding_opt(<br />
          :«»soapaction => op_info.soapaction || @soapaction,<br />
          :envelopenamespace => @options["soap.envelope.requestnamespace"],<br />
          :default_encodingstyle =><br />
            @default_encodingstyle || op_info.request_default_encodingstyle,<br />
          :use_default_namespace =><br />
            op_info.use_default_namespace || @use_default_namespace<br />
        )<br />
        resopt = create_encoding_opt(<br />
          :envelopenamespace => @options["soap.envelope.responsenamespace"],<br />
          :default_encodingstyle =><br />
            @default_encodingstyle || op_info.response_default_encodingstyle<br />
        )<br />
        env = route(req_header, req_body, reqopt, resopt)<br />
        if op_info.response_use.nil?<br />
          return nil<br />
        end<br />
        raise EmptyResponseError unless env<br />
        receive_headers(env.header)<br />
        begin<br />
          check_fault(env.body)<br />
        rescue ::«»SOAP::FaultError => e<br />
          op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)<br />
        end<br />
        if @return_response_as_xml<br />
          return resopt[:response_as_xml]<br />
        else<br />
          response_obj = op_info.response_obj(env.body, @mapping_registry,<br />
            @literal_mapping_registry, mapping_opt)<br />
          response_obj.instance_variable_set(:@env, env)<br />
          return response_obj<br />
        end<br />
      end<br />
    end<br />
  <br />
  end<br />
end<br />
</td></tr></tbody></table><br />
<br />
And to use it:<br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre><br />
@driver = SOAP::RPC::«»Driver.new(@url)<br />
<br />
@driver.options["protocol.http.basic_auth"] << [@url, @user, @pass]<br />
<br />
@driver.add_method('runReport','request')<br />
<br />
result = @driver.runReport(request.to_s)<br />
<br />
report = result.instance_variable_get(:@env).external_content['report'].data.content<br />
</td></tr></tbody></table>
mzukowski's picture
Joined: Sep 5 2006 - 7:18am
Last seen: 12 years 9 months ago
0
Okay nevermind... I should double-check before I post. Anyway here's a slightly different version of the above monkeypatch. This one should work against soap4r 1.5.8. Also, it adds the instance variable @env to the response object rather than returning an array with the env data. I think this might be a bit safer since it doesn't break the API.

Code:
<br />
module SOAP<br />
  module RPC<br />
  <br />
    class Proxy<br />
      include SOAP<br />
      <br />
      def call(name, *params)<br />
        # name must be used only for lookup<br />
        op_info = lookup_operation(name)<br />
        mapping_opt = create_mapping_opt<br />
        req_header = create_request_header<br />
        req_body = SOAPBody.new(<br />
          op_info.request_body(params, @mapping_registry,<br />
            @literal_mapping_registry, mapping_opt)<br />
        )<br />
        reqopt = create_encoding_opt(<br />
          :«»soapaction => op_info.soapaction || @soapaction,<br />
          :envelopenamespace => @options["soap.envelope.requestnamespace"],<br />
          :default_encodingstyle =><br />
            @default_encodingstyle || op_info.request_default_encodingstyle,<br />
          :use_default_namespace =><br />
            op_info.use_default_namespace || @use_default_namespace<br />
        )<br />
        resopt = create_encoding_opt(<br />
          :envelopenamespace => @options["soap.envelope.responsenamespace"],<br />
          :default_encodingstyle =><br />
            @default_encodingstyle || op_info.response_default_encodingstyle<br />
        )<br />
        env = route(req_header, req_body, reqopt, resopt)<br />
        if op_info.response_use.nil?<br />
          return nil<br />
        end<br />
        raise EmptyResponseError unless env<br />
        receive_headers(env.header)<br />
        begin<br />
          check_fault(env.body)<br />
        rescue ::«»SOAP::FaultError => e<br />
          op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)<br />
        end<br />
        if @return_response_as_xml<br />
          return resopt[:response_as_xml]<br />
        else<br />
          response_obj = op_info.response_obj(env.body, @mapping_registry,<br />
            @literal_mapping_registry, mapping_opt)<br />
          response_obj.instance_variable_set(:@env, env)<br />
          return response_obj<br />
        end<br />
      end<br />
    end<br />
  <br />
  end<br />
end<br />
</td></tr></tbody></table><br />
<br />
And to use it:<br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre><br />
@driver = SOAP::RPC::«»Driver.new(@url)<br />
<br />
@driver.options["protocol.http.basic_auth"] << [@url, @user, @pass]<br />
<br />
@driver.add_method('runReport','request')<br />
<br />
result = @driver.runReport(request.to_s)<br />
<br />
report = result.instance_variable_get(:@env).external_content['report'].data.content<br />
</td></tr></tbody></table>
mzukowski's picture
Joined: Sep 5 2006 - 7:18am
Last seen: 12 years 9 months ago
0

Post edited by: thevoice, at: 2007/11/23 10:53
thevoice's picture
Joined: Nov 4 2007 - 3:36pm
Last seen: 11 years 7 months ago
0
Hello MariusAgricola,
Really Thank you very much for this great work.
I am looking in google for long how to integrate jasper in ruby.
From your work i able to get idea for how to integrate japser in ruby.

Here i need your help.

I have tried to integrate japser in ruby using your code.
But i got the error.
Following is more information:
-- In ruby application i list the reports that resides on jaspserserver repository.
-- I have installed JasperIntelligence1.0.1.
-- Error Details:

REXML:: ParseException in ReportController#index

Missing end tag for 'HR' (got "body")
Line:
Position:
Last 80 unconsumed characters:
</html>

Full trace:

/usr/lib/ruby/1.8/rexml/parsers/baseparser.rb:315:in `pull'
/usr/lib/ruby/1.8/rexml/parsers/streamparser.rb:16:in `parse'
/usr/lib/ruby/1.8/rexml/document.rb:185:in `parse_stream'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/xsd/xmlparser/rexmlparser.rb:27:in `do_parse'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/parser.rb:102:in `parse'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/processor.rb:39:in `unmarshal'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb:285:in `unmarshal'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb:184:in `route'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb:143:in `call'
/usr/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/rpc/driver.rb:181:in `call'
(eval):6:in `list'
app/models/reports.rb:21:in `get_list'
app/controllers/report_controller.rb:22:in `index'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:1095:in `send'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:1095:in `perform_action_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:632:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/rescue.rb:83:in `perform_action'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:430:in `send'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:430:in `process_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/session_management.rb:114:in `process'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:330:in `process'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/dispatcher.rb:41:in `dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/webrick_server.rb:113:in `handle_dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/webrick_server.rb:79:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/webrick_server.rb:63:in `dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/webrick.rb:59
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/dependencies.rb:495:in `require'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/server.rb:39
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3

Please can you tell me what is reason for this kind of error.
Am i missing anything in installing Jasperintelligence?
What you have installed to use jasper in ruby?
(I mean i wanna to know that which jasperintelligence version u have used?)
What i have to do to solve this problem?

Please help me in solving my this problem.

Thank you
thevoice's picture
Joined: Nov 4 2007 - 3:36pm
Last seen: 11 years 7 months ago
0
it looks like whatever it is you're parsing is not a SOAP response from JasperServer but HTML... are you sure you're fetching data from the right URL? And are you sure JasperServer is returning data correctly at that URL (maybe it's replying with a generic "500 Server Error" HTML page at the URL you're querying?)
mzukowski's picture
Joined: Sep 5 2006 - 7:18am
Last seen: 12 years 9 months ago
0
MariusAgricola, thank you very much for your hard work. The problem I'm running into is defining dynamic queries using the service. For example, if I want to use JasperServer to print shopping carts -- the query would be '... WHERE user=$P{current_user}' -- but how do I pass that information into the service call?

I would love to pull data from the database, format in XML, and pass XML directly to JasperServer in service call -- can I include XML directly in SOAP message?

thanks,
john
jgladden's picture
Joined: Dec 11 2007 - 1:29am
Last seen: 11 years 6 months ago
0
jgladden:

That's essentially the problem I never was able to solve. I had no problem running a report that had no parameters, but I never did figure out how to construct the XML request in such a way that it included parameters that made any sense.

What I would suggest, since I haven't had time to work on it myself, is to fire up a packet sniffer (WireShark, aka Ethereal, works well for this) and use Jasper Reports with the iReport plugin to connect to your Jasper Server. Develop a report that takes parameters and upload it to the server. Then you can use the iReport plugin to browse to the repository and run the report. Do this while running your packet sniffer and you should be able to pick up the relevant packets. Look for the particular XML that contains something like <parameter...> blocks.

The last time I tried this, which was almost a year ago, I was able to see the parameter fields, but I am almost always working with dates. Unfortunately, I couldn't figure out what format the dates were in (they were integers that may have represented something like Unix Epoch time, but I'm not certain).

Anyway, as I keep meaning to return to this, hopefully I can figure something out. Unfortunately, my setup is far outdated with the latest JI release. I'd be ecstatic if someone manages to figure this out and incorporate it into something that others can get at (such as rolling it into a plugin or gem).
aaronhelton's picture
Joined: Oct 25 2006 - 5:01am
Last seen: 6 years 2 weeks ago
0
The Web Services guide shipped with JasperServer describes how to include parameters values in a runReport web service request. Basically parameter values are sent via <paramater> elements inside the resource descriptor:
Code:
<br />
<resourceDescriptor><br />
  ..<br />
  <parameter name="Parameter1Name">Parameter1Value</parameter><br />
  <parameter name="Parameter2Name">Parameter2Value</parameter><br />
  <parameter name="MultiParameterName" isListItem="true">MultiParameterValue1</parameter><br />
  <parameter name="MultiParameterName" isListItem="true">MultiParameterValue2</parameter><br />
</resourceDescriptor><br />
</td></tr></tbody></table><br />
<br />
Dates need to be sent as the number of milliseconds since the Unix epoch (Jan 1st 1970 00:00:00 GMT).<br />
<br />
If anyone intends to implements this, we can offer further assistance on how the JasperServer web service works.<br />
<br />
Regards,<br />
Lucian
lucianc's picture
7055
Joined: Jul 17 2006 - 1:10am
Last seen: 2 weeks 6 days ago
0
Has anyone been able to use this code with a Jruby rails application? I tried it but I got a "basic authentication not implemented in soapr + http" so I installed the httpclient gem. Now the error is that the x509 store constant is missing (I think it is related to jopenssl).

On the other hand you may find this code useful for sending parameters in the request (note that it uses the code from the previous posts):

Code:
 <br />
#Takes a hash that has as keys the name of the jasper report parameter and as <br />
    # a value, the value you want for that parameter. The name of the parameter must be<br />
    # exactly the same as you have it defined in your jasper report.<br />
def create_xml_params(param_values_hash)<br />
      xml_params = ""<br />
      param_values_hash.each do |key, value|<br />
        xml_params << "\n<parameter name=\"#{key.to_s}\">#{value.to_s}</parameter>"<br />
      end<br />
      return xml_params<br />
    end<br />
<br />
 def get_report(strURL, strUser, strPass, strURI, strOutputFmt, params_xml = ""«»)<br />
<br />
      strRequestBody = %Q|<request operationName="runReport" locale="en"><br />
<argument name="RUN_OUTPUT_FORMAT">#{strOutputFmt}</argument><br />
<resourceDescriptor name="" wsType="" uriString="#{strURI}" isNew="false"><br />
<label>null</label><br />
#{params_xml}<br />
</resourceDescriptor><br />
</request><br />
      |<br />
<br />
      driver = SOAP::RPC::«»Driver.new(strURL)<br />
      #driver.wiredump_dev=STDERR<br />
      driver.options["protocol.http.basic_auth"] << [strURL, strUser, strPass]<br />
      driver.add_method('runReport','request')<br />
      #driver.add_method('runReport','request')<br />
      result, env = driver.runReport(strRequestBody.to_s)<br />
      report = env.external_content['report'].data.content<br />
      <br />
      report<br />
      <br />
<br />
<br />
<br />
    end<br />
</td></tr></tbody></table><br />
<br />
Example:<br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>  <br />
    k5_params = {}<br />
    k5_params[:quarter] = "1"<br />
    k5_params[:«»student_id] = 329<br />
  <br />
    report_name = '/reports/k5_progress_rpt'<br />
    report_pdf_file = Reports.get_report(@jasperServer, @jasperUser, @jasperPass, <br />
      report_name, 'PDF', <br />
      Reports.create_xml_params(k5_params))<br />
</td></tr></tbody></table>
juantar's picture
Joined: May 8 2007 - 1:01am
Last seen: 12 years 1 month ago
0

If anyone is interested, there is now a downloadable JasperServer Ruby client available at: http://rubyforge.org/projects/jasper-client/

Development info is on Github under: http://github.com/gunark/jasperserver-client/tree/master

 

Usage on rails looks something like:

Code:
ReportsController < ApplicationController
  def example_report
    output_format = "PDF" 
    report_unit = "/example/my-report" 
    report_params = params[:report_params] # this should be a Hash!
 
    client = JasperServer::Client.new("http://example.com/jasperserver/services/repository",
                                      "jasperadmin", "secret!")
    request = JasperServer::Request.new(report_unit, output_format, report_params)
    pdf_data = client.request_report(request)
 
    filename = params[:action]+" on "+Time.now.iso8601+"."+format.downcase
    send_data(data, :type => Mime::Type.lookup_by_extension(format.downcase), 
              :disposition => 'inline', :filename => filename)
  end
end


Post Edited by Matt Zukowski at 11/12/08 19:01
mzukowski's picture
Joined: Sep 5 2006 - 7:18am
Last seen: 12 years 9 months ago
0
Hi
how do i uses this gem as i am new to rails. Any sample rails application.I
am using Netbeans to develop application.
Plz help.

Vishal
vishal29bhp's picture
Joined: Mar 6 2009 - 3:23am
Last seen: 10 years 3 months ago
Feedback
randomness