I am trying to connect to workday HR Web Service. But I am getting:
WebServiceException : Unsupported endpoint address: Human_Resources.
public static void main(String[] args){
HumanResourcesService hrservice=new HumanResourcesService();
HumanResourcesPort hrport=hrservice.getHumanResources();
//further code
}
WebEndpoint Snippet from the HumanResourcesService class:
#WebEndpoint(name = "Human_Resources")
public HumanResourcesPort getHumanResources() {
return super.getPort(new QName("urn:com.workday/bsvc/Human_Resources", "Human_Resources"),
HumanResourcesPort.class);
}
Any help is appreciated.
When defining Workday API endpoints, you need to include the version number at the end of the urn.
For example you have:
urn:com.workday/bsvc/Human_Resources
and it should be (if you use v28)
urn:com.workday/bsvc/Human_Resources/v28.0
Related
I have a streaming (sse) api up and running. It's realized in java and spring boot. The code is given below:
#SpringBootApplication
#RestController
#RequestMapping("sse")
public class SseApplication {
public static void main(String[] args) {
SpringApplication.run(SseApplication.class, args);
}
#GetMapping(path = "/stream-flux", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamFlux() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> "Flux - " + LocalTime.now().toString());
}
#GetMapping("/stream-sse")
public Flux<ServerSentEvent<String>> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> ServerSentEvent.<String> builder()
.id(String.valueOf(sequence))
.event("periodic-event")
.data("SSE - " + LocalTime.now().toString())
.build());
}
}
When it is directly checked through browser and curl, the streaming response is as expected.
I published it on wso2 apim by publisher portal following the official documentation. Then I tested that api through wso2 apim gateway. It does not returning anything just like as it hangs
I am using jersey filter.
In My code logic in AuthenticationFilter.java, if the authorization header is empty, then return the access denied error message.
First time I am hitting the application through rest client tool using the URL without attaching the header
http://localhost:8080/JerseyDemos2/rest/pocservice
Get the status 401 with error message "you cannot access this resource". This is right.
When i tried to hit second time thorugh rest client tool, and server return the exception message.
I deployed my application in tomcat 7.x both windows and linux
Why it give the error when we hit the second time.
How to resolve this
#Provider
public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter {
#Context
private ResourceInfo resourceInfo;
private static final String AUTHORIZATION_PROPERTY = "Authorization";
private static final Response ACCESS_DENIED = Response.status(Response.Status.UNAUTHORIZED).entity("You cannot access this resource").build();
#Override
public void filter(ContainerRequestContext requestContext) {
// Get request headers
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
// Fetch authorization header
final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
// If no authorization information present; block access
if (authorization == null || authorization.isEmpty()) {
requestContext.abortWith(ACCESS_DENIED);
return;
}
}
} }
Error message:
Dec 19, 2016 6:26:18 PM org.glassfish.jersey.server.ServerRuntime$Responder writeResponse
SEVERE: An I/O error has occurred while writing a response message entity to the container output stream.
java.lang.IllegalStateException: The output stream has already been closed.
at org.glassfish.jersey.message.internal.CommittingOutputStream.setStreamProvider(CommittingOutputStream.java:147)
at org.glassfish.jersey.message.internal.OutboundMessageContext.setStreamProvider(OutboundMessageContext.java:803)
......
Please help me
Thanks in advance.
I Removed static variable
private static final Response ACCESS_DENIED = Response.status(Response.Status.UNAUTHORIZED).entity("You cannot access this resource").build();
and i declared local variable. now its working fine.
#Provider
public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter {
#Context
private ResourceInfo resourceInfo;
private static final String AUTHORIZATION_PROPERTY = "Authorization";
#Override
public void filter(ContainerRequestContext requestContext) {
Response ACCESS_DENIED = Response.status(Response.Status.UNAUTHORIZED).entity("You cannot access this resource").build();
// Get request headers
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
// Fetch authorization header
final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
// If no authorization information present; block access
if (authorization == null || authorization.isEmpty()) {
requestContext.abortWith(ACCESS_DENIED);
return;
}
}
} }
You're trying to write in a response that was written before. The full log shows where is it happening. Upload the log and the code where the httpresponse is used/modified.
How to publish a web service class with #WebServiceProvider?What is the endpoint URL in this case?
Could we generate wsdl with #WebServiceProvider as in the case with
#WebService?What does the "wsdlLocation" attribute mean in #WebServiceProvider?
For instance
#ServiceMode(value = Service.Mode.MESSAGE)
#WebServiceProvider(portName = "ProviderPort",serviceName = "ProviderService",
targetNamespace = "http://bean/")
public class WebServiceProviderImpl implements Provider<SOAPMessage>
Simplest way is-
package server;
import javax.xml.ws.Endpoint;
public class Server {
protected Server() throws Exception {
System.out.println("Starting Server");
System.out.println("Starting SoapService1");
Object implementor = new WebServiceProviderImpl();
String address = "http://localhost:8123/SoapContext/SoapPort1";
Endpoint.publish(address, implementor);
}
public static void main(String args[]) throws Exception {
new Server();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
The URL is "address". As far as I understand you can specify it as you like, as long as the port is free.
Alternatively, you could use JAXWsServerFactoryBean which is a part of CXF.
You would do the same thing as you would with an SEI.
And yes, it does generate a WSDL for you.
You can create your client stubs from it using wsimport just like an SEI
Good time.
Suppose there are 8 web-services in the one application. 5 of them require authorization (a client must to provide a JSESSIONID cookie and a corresponding session must not be invalidated), other 3 can be called without the jsessionid cookie. My naive solution is to write a servlet filter which intercepts requests and retrieve their pathInfos (all the services have the same url structure: /service/serviceSuffix). There is a enum which contains the serviceSuffix of each web service that requires authorization. When the request is retrieved the pathInfo is collected; if this pathInfo is contained in the enum and there is the corresponding valid session the request is sent ahead to the filter chain. Otherwise, an error is sent back to a client. After a while I've realized that it is needed to add the possibility to retrieve the wsdl and xsds for the concrete service. So that, two more check were added.
public class SecurityFilter implements Filter {
public static final String WSDL = "wsdl";
public static final String XSD = "xsd=";
/**
* Wittingly left empty
*/
public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse)response;
String pathInfo = servletRequest.getPathInfo();
String queryString = servletRequest.getQueryString();
if (pathInfo != null && SecureWebServices.contains(pathInfo)) {
if (queryString != null && (queryString.equals(WSDL) || queryString.startsWith(XSD))) {
// wsdl or xsd is requested
chain.doFilter(request, response);
} else {
// a web service's method is called
HttpSession requestSession = servletRequest.getSession(false);
if (requestSession != null) { // the session is valid
chain.doFilter(request, response);
} else {
servletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
}
} else {
chain.doFilter(request, response);
}
}
/**
* Wittingly left empty
*/
public void destroy() {}
}
It seems that it is not very secure, because if the request's pathInfo is not in the enum, this request is passed on (just in case of some unexpected system calls).
Could you, please, suggest what to do, how to increase the security level. I want to build a configurable system (that is why I have the enum. It is possible just to add a path there to secure the web service and it is not required to duplicate the security code in the each web service). How to increase
Maybe I do not understand but.
jsessionid has nothink to do with security. you simply just get it.
Next I am not sure if you want authentication or authorization. The code as provided will not provide you with security features.
I suppose you are interested in authentication anyway. Security logic can be provided with standard web container features. Just send in authentication data in the header of request and you are done. web container can be configured to secure only selected resources (urls)
how can I access a webservice through a basic http authentification? I am using the netbeans built in webservice client features. But when I try to access the webservice, I get an exception with a 401 auth failed error message.
How can I pass the right username and password?
Thank you!
You could use BindingProvider or WSBindingProvider class to access a Web Service through a basic http authentification.
The code is as follows.
XxxService service = new XxxService();
Xxx port = service.getXxxPort();
Map<String, Object> reqContext = ((BindingProvider)port).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "username");
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "password");
You can also provide your own Authenticator. That way it will work even if the WDSL itself is protected by basic HTTP authentication.
#WebServiceRef(wsdlLocation = "https://laka/sito?wsdl")
static XxxService service;
public static void main(String[] args) {
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "password".toCharArray());
}
});
service = new XxxService();
Xxx port = service.getXxxPort();
// invoke webservice and print response
XxxResponse resp = port.foo();
System.out.println(resp.toString());
}