I am working on a desktop based application that is like drop box, I have a function downloadFile(long fileId) that download file for me from web, desktop side of the application is in java where web service is written in .Net
I have generated WS client using netbeans
The issue is: Some times it happens that downloadFile(long fileId) function get stuck,
What ever the reason behind it, I want if web service function does not give any response till a given time I snatch the control back from that function and generate a new call after some time. Is it possible using java?
EDIT I think that it could be done if can set the request time out of the web service but i don't have idea how to set time out in the client generated by netbeans
In the class FileUpload that is root class of web service(Generated by netBeans) there were some constructors of the class and function of the super class, one of them i was using to create SOAP object. That was looking like
#WebEndpoint(name = "FileUploadSoap")
public FileUploadSoap getFileUploadSoap() {
return super.getPort(new QName("http://svc.qleapahead.com/",
"FileUploadSoap"), FileUploadSoap.class);
}
in this function i made some modifications in order to set time out parameter and this became like
#WebEndpoint(name = "FileUploadSoap")
public FileUploadSoap getFileUploadSoap() {
FileUploadSoap fileUploadSoap = super.getPort(new QName(
"http://svc.qleapahead.com/", "FileUploadSoap"),
FileUploadSoap.class);
((BindingProvider) fileUploadSoap).getRequestContext().put(
"com.sun.xml.internal.ws.request.timeout", 1000 * 2 * 60);
return fileUploadSoap;
}
and problem solved...
in short this statement helped me a lot
((BindingProvider) fileUploadSoap).getRequestContext().put(
"com.sun.xml.internal.ws.request.timeout", 1000 * 2 * 60);
Depending on the framework you use for calling the webservice, there will be some way of setting a readTimeout causing the call to fail with some kind of exception.
Cheers,
Related
I am wondering if there is a way to connect to ldap (389 server) through the apache 2.0.1 java ldap api and then continuously listen for changes to a specific attribute on a set of entries (in this case people with specific qualifications)?
Ideally I would like to run a query on ou=people,dc=test,dc=local
this might initially return
dn: uid=tester1,ou=people,dc=test,dc=local
givenName: tester1
dn: uid=tester2,ou=people,dc=test,dc=local
givenName: tester2
dn: uid=tester3,ou=people,dc=test,dc=local
givenName: tester3
If I then in the background changed tester3's givenName to userTester3 I would like to have a listener that would return some userModified event telling me that tester3 was modified.
As an example of what I would like to happen (psuedo code / non functioning code) I would like to do something along the lines of :
{
PersistentSearch ps = new PersistentSearch();
ps.setChangeType(ChangeType.MODIFY);
SearchRequest sr = ldaputility.createPersistentSearch(qualifiers, attributes, etc, ps);
PersistentSearchListener psl = new PersistentSearchListener(sr){
#Override
public void entryChanged(Entry e){
Log.info("The entry just changed");
}
}
}
There however from what I can tell in the apache 2.0.1 api is not any persistent search listener nor is there any type of listener for search requests in general and the search request gets results and then completes. I know that in the netscape api there is a search listener and that in the apache directory server api there is a persistent search listener. So what I am asking is does anyone know if the apache 2.0.1 ldap api supports a behavior where you make an initial query and any time the results of the query change you can have a listener that is notified of the new changes?
I unfortunately have no debugging code / output since I am not even sure what code to try right now.
It appears that by adding a PersistentSearch control (with changes only set to true and change types set to modifications) to the search request the ldap server won't ever set isDone to true on the search request so then the search request will continue to return the updates as they are available.
I need to implement a basic snmp agent into my application. This agent should be able to answer get and set requests from snmp browsers on my own OID's. Since most examples for snmp4j are quite old and use the "extend the org.snmp4j.agent.BaseAgent.classapproach" there are of little use.
Therefore tried to understand and strip down the org.snmp4j.agent.example.SampleAgentincluded inside the snmp4j-agent-3.2.1.jar. I managed to get an example working with just the mandatory MIB's ( i at least think they are required because the source of the AgentConfigManager states in a comment they are mandatory snmpv2MIB, snmpMpdMib, targetMIB, communityMIB, notificationMIB, frameworkMIB, usmMIB, vacmMIB, tlsTmMib ) provided by the sample config file.
I than added a custom OID to query to the agend using the following code
MOServer server = new DefaultMOServer();
MOServer[] moServers = new MOServer[]{server};
...
AgentConfigManager agent = new AgentConfigManager(new OctetString(MPv3.createLocalEngineID()),
messageDispatcher,
null,
moServers,
ThreadPool.create("SampleAgent", 3),
configurationFactory,
new DefaultMOPersistenceProvider(moServers, configFile),
new EngineBootsCounterFile(bootCounterFile), null, dhKickstartParameters);
...
agent.initialize();
...
server.register(new MOScalar(new OID("1.someIODshere.0"), MOAccessImpl.ACCESS_READ_ONLY, new OctetString("object 1")), null);
Now i'm missing a way to intercept get or set requests from snmp managers / browsers to return a dynamic value or change the program behavior according to the request.
I kind of expect to be able to bind a kind of event listener to this OID to get notified on requests / changes.
How to watch an OID?
I found it. I was looking at the wrong place. I thought a had to add a listener to the agent, but instead i have to add the listener to the server.
server.addLookupListener(new MOServerLookupListener() {
#Override
public void lookupEvent(MOServerLookupEvent event) {
System.out.println();
((MOScalar)event.getLookupResult()).setValue(new OctetString(new Date().toString()));
}
#Override
public void queryEvent(MOServerLookupEvent event) {
System.out.println();
}
},moScalar);
I can now react to the requests. YAY!
In the API documentation for Java Spark (not Apache spark), you can specify a port of 0 to have it automatically select a port. Great!
However, I cannot figure out how to get that port after the server is started. I can see it in the logs:
15:41:12.459 [Thread-2] INFO spark.webserver.JettySparkServer - >> Listening on 0.0.0.0:63134
But I need to be able to get to it programmatically, so that my integration tests are able to run reliably every time.
So how do I get that port?
I could find no way to get this information in the API, and so I filed an issue on their github.
I was able to get at it via an ugly pile of reflection:
/**
* Meant to be called from a different thread, once the spark app is running
* This is probably only going to be used during the integration testing process, not ever in prod!
*
* #return the port it's running on
*/
public static int awaitRunningPort() throws Exception {
awaitInitialization();
//I have to get the port via reflection, which is fugly, but the API doesn't exist :(
//Since we'll only use this in testing, it's not going to kill us
Object instance = getInstance();
Class theClass = instance.getClass();
Field serverField = theClass.getDeclaredField("server");
serverField.setAccessible(true);
Object oneLevelDeepServer = serverField.get(instance);
Class jettyServerClass = oneLevelDeepServer.getClass();
Field jettyServerField = jettyServerClass.getDeclaredField("server");
jettyServerField.setAccessible(true);
//Have to pull in the jetty server stuff to do this mess
Server jettyServer = (Server)jettyServerField.get(oneLevelDeepServer);
int acquiredPort = ((ServerConnector)jettyServer.getConnectors()[0]).getLocalPort();
log.debug("Acquired port: {}", acquiredPort);
return acquiredPort;
}
This works well for me in our integration tests, but I'm not using https, and it does reach about two levels deep into the API via reflection grabbing protected fields. I could not find any other way to do it. Would be quite happy to be proven wrong.
This will work on Spark 2.6.0:
public static int start (String keystoreFile, String keystorePw)
{
secure(keystoreFile, keystorePw, null, null);
port(0);
staticFiles.location("/public");
get(Path.CLOCK, ClockController.time);
get(Path.CALENDAR, CalendarController.date);
// This is the important line. It must be *after* creating the routes and *before* the call to port()
awaitInitialization();
return port();
}
Without the call to awaitInitialization() port() would return 0.
i was trying to call the following web service from my android app, it hung then completed without returning the result:
web service:http://androidexample.com/media/webservice/JsonReturn.php
However when I clicked on the link, it worked fine - the json file displayed. yet it would not work in my app..
but now, it works fine now in my android app, perhaps it was temporarily down is what I am guessing. How can I know if a web service is up and running for an android app to consume ?
Typically, web services are designed to have a status page that can return status text or a HTTP return code to indicate service status.
If it doesn't have that, you can design a function to periodically do a very basic request with a known result to determine state. This is much better than doing a simple ping.
If it was down it would most likely show a HTML error page, which your app would try to parse, which would cause an error.
I had a similar issue, because I needed to know if the user was returning HTML or the correct JSON, to do this I created the ArrayList I was about to use outside of the try/catch of the parse area. You should do the same if you are using a string.
What I mean is, use:
ArrayList<Something> arrayList = new ArrayList<Something>();
String testString = ""; instead of String testString = null;
I was using only ArrayList<Something> arrayList; at one point which is incorrect. If the user then returns HTML, you won't get an error, the user will simply return an empty arraylist or empty string.
You can then plan for that and show some sort of error message. This way you only need one network request but you can still plan for getting the data back, and the server being down.
I have a program that uses javax.xml.ws.Service to call a remote service defined by a WSDL. This program runs on the Google App Engine which, by default, sets the HTTP connection timeout to 5 seconds{1}. I need to increase this timeout value since this service often takes a long time to respond, but since this request is not being made with URLConnection, I cannot figure out how to call URLConnection.setReadTimeout(int){2}, or otherwise change the timeout.
Is there any way to globally set the HTTP connection timeout on the App Engine? And, for purposes of sharing knowledge, how would one go about solving this sort of problem generally?
{1}: https://developers.google.com/appengine/docs/java/urlfetch/overview#Requests
{2}: http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URLConnection.html#setReadTimeout(int)
You could try setting the sun.net.client.defaultConnectTimeout and sun.net.client.defaultReadTimeout system properties documented here, e.g.
System.setProperty("sun.net.client.defaultReadTimeout", "30000");
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
EDIT
Sorry, just re-read and noticed this is on Google App Engine. I don't know for sure, but given the litigious relationship Google and Oracle have lately, I'm guessing GAE doesn't run the Oracle JVM. I'll leave this here in case someone else runs into a similar problem.
Try this:
Port port = service.getPort(endPointInterface); //or another "getPort(...)"
((BindingProvider) port).getRequestContext()
.put(BindingProviderProperties.REQUEST_TIMEOUT, 30);
See https://developers.google.com/appengine/docs/java/urlfetch/usingjavanet
You can do something like this to get a URLConnection:
URL url = new URL("http://www.example.com/atom.xml");
URLConnection tempConnection = url.openConnection();
tempConnection.setReadTimeout(10);
For App Engine with JAX-WS you have to set the request context (tested today with SDK 1.9.15). For normal machines you cannot go higher than 60s and would have to switch to the bigger machines (Bx) for better use a task queue.
For local testing you would normally use BindingProviderProperties.CONNECT_TIMEOUT and BindingProviderProperties.REQUEST_TIMEOUT, but they are not on the App Engine JRE White List and your code inspection might constantly warn you about that.
The equivalent strings can be used though:
com.sun.xml.internal.ws.connect.timeout
com.sun.xml.internal.ws.connect.timeout
For deployment to App Engine:
com.sun.xml.ws.connect.timeout
com.sun.xml.ws.request.timeout
A full example how to apply that to auto-generated code from JAX-WS 2.x, values have to be provided in milliseconds:
#WebEndpoint(name = "Your.RandomServicePort")
public YourServiceInterface getYourRandomServicePort() {
YourRandomServiceInterface port = super.getPort(YOURRANDOMSERVICE_QNAME_PORT, YourRandomServiceInterface.class);
Map<String, Object> requestContext = ((BindingProvider)port).getRequestContext();
requestContext.put("com.sun.xml.ws.connect.timeout", 10000);
requestContext.put("com.sun.xml.ws.request.timeout", 10000);
return port;
}