Java web services to allow large file streaming - java

I am building a java web services server that needs to scale and to be highly available. User can upload large file (~20M) through the services. SOAP is preferred.
My question are: is there any such a web service framework which support large file streaming? Any building blocks that I should consider? Any good practices?
Any thoughts would be appreciated. Thanks.

If you need high performance, webservices are not great.
You can try (Streaming SOAP Attachments):
http://docs.oracle.com/cd/E12840_01/wls/docs103/webserv_adv/mtom.html
example
http://www.mkyong.com/webservices/jax-ws/jax-ws-attachment-with-mtom/
File : ImageServer.java
//Service Endpoint Interface
package com.mkyong.ws;
import java.awt.Image;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
#WebService
#SOAPBinding(style = Style.RPC)
public interface ImageServer{
//download a image from server
#WebMethod Image downloadImage(String name);
//update image to server
#WebMethod String uploadImage(Image data);
}
//File : ImageServerImpl.java
package com.mkyong.ws;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.jws.WebService;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.MTOM;
//Service Implementation Bean
#MTOM
#WebService(endpointInterface = "com.mkyong.ws.ImageServer")
public class ImageServerImpl implements ImageServer{
#Override
public Image downloadImage(String name) {
try {
File image = new File("c:\\images\\" + name);
return ImageIO.read(image);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
public String uploadImage(Image data) {
if(data!=null){
//store somewhere
return "Upload Successful";
}
throw new WebServiceException("Upload Failed!");
}
}

Related

Prometheus 'expected label name, got "BCLOSE"' error

I have an application running on port 7070 on my local. It exposes and endpoint /metrics and shows all the tags that are available. Prometheus is not able to get these data and it says 'expected label name, got "BCLOSE"'.
I have been trying to figure this out but not sure why this code doesn't work:
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.exporter.common.TextFormat;
import metrics.PrometheusRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
#Path("/metrics")
public class MetricsController {
private final PrometheusMeterRegistry prometheusRegistry = PrometheusRegistry.INSTANCE();
#GET
public Response getMetrics(#Context HttpHeaders headers) {
Writer writer = new StringWriter();
try {
TextFormat.write004(writer, prometheusRegistry.getPrometheusRegistry().metricFamilySamples());
} catch (IOException e) {
e.printStackTrace();
}
return writer.toString();
}
}
Also, the application is neither a sprintboot nor a spring project.
Tried this:
#GET
public Response getMetrics(#Context HttpHeaders headers) {
String accept = headers.getRequestHeader("Accept").get(0);
System.out.println("Accept Header --------------------------> " + accept);
return Response.ok(prometheusRegistry.scrape(), "application/openmetrics-text").build();
}
Even then the same error as above SS.
This worked for me:
#GET
public Response getMetrics() {
return Response.ok(prometheusRegistry.scrape(), TextFormat.CONTENT_TYPE_004).build();
}

javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type text/plain and type interface java.util.List

I'm trying to store a response comprising of a list of channels into a List Object in the client, so that it can display its contents in a JSP.
Right now, I wrapped the list into a GenericEntity, because I know it will only compile this way.
UPDATE: I'm using REST 3.1.3-Final-all, and I have also added all the JARs in them. From research, I thought the reason was that I don't have the jackson provider jars, but this has not solved the problem.
I also am wrapping the list in a GenericType from the other side.
I'm confused as to what a "MessageBodyReader" is, as I'm getting an exception that shows the following:
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Client created.
Exception in thread "main" javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type text/plain and type interface java.util.List
at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:42)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:75)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:52)
at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.aroundReadFrom(GZIPDecodingInterceptor.java:59)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:55)
at org.jboss.resteasy.security.doseta.DigitalVerificationInterceptor.aroundReadFrom(DigitalVerificationInterceptor.java:36)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:55)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:251)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:181)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:225)
at examples.pubhub.utilities.test.main(test.java:33)
The segment of code I'm trying to test is as follows:
client (tested in an offline main class):
package examples.pubhub.utilities;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.SyncInvoker;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import examples.pubhub.model.Channel;
public class test {
#SuppressWarnings("unchecked")
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
System.out.println("Client created.");
WebTarget target = client.target("http://localhost:8080/RESTService/service/authorchannels/channels/");
Response response = target.request().accept(MediaType.TEXT_PLAIN).get();
List<Channel> channels = response.readEntity(new GenericType<List<Channel>>() {});
if (response.getStatus() != 200) {
System.out.println("ChannelDAOImpl utilized, but channels could not be retrieved!" );
} else {
System.out.println(response.getMediaType().toString());
System.out.println(response.readEntity(String.class));
System.out.println("Channels? " + channels);
System.out.println("ChannelDAOImpl utilized; channels succesfully acquired.");
}
}
}
and the RESTFUL Service class with method:
package methods;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import model.Channel;
import resources.DAOUtilities;
#Path("/authorchannels")
public class AuthorChannel {
#SuppressWarnings("unchecked")
#GET
#Path("/channels")
public Response getAllChannels() {
System.out.println("Accessing RESTService, and acquiring channels...");
SessionFactory sessionFactory = DAOUtilities.getSessionFactory();
System.out.println("Session Factory acquired.");
Session session = sessionFactory.openSession();
System.out.println("Session opened.");
session.beginTransaction();
Query query = session.createQuery("from Channel");
List<Channel> channels = (List<Channel>) query.list();
GenericEntity<List<Channel>> list = new GenericEntity<List<Channel>>(channels) {};
System.out.println("Did we get the channels? " + channels);
System.out.println("Channel users? " + ((List<Channel>) channels).get(0).getChannel_user());
System.out.println("Channel bios? " + ((List<Channel>) channels).get(0).getChannel_bio());
session.getTransaction().commit();
//prepare response status to be returned to client
ResponseBuilder respBuilder = null;
if (channels != null)
respBuilder = Response.status(Response.Status.OK);
else
respBuilder = Response.status(Response.Status.NOT_FOUND);
//deliver response to client, indicating that the channels have been acquired.
return respBuilder.status(200).entity(list).build();
}
}
A few things to note:
I'm not using Maven, as I only want to display each one in MediaType.TEXT_PLAIN, but if its easier to switch to APPLICATION_XML or APPLICATION_JSON, then please let me know.
My intention is to simply convert the list Response into a javatype list, so that I can display each of its elements in a table in a JSP later on.
If someone can explain to me what a MessageBodyReader is, I would greatly appreciate it.

How to create Couchbase bucket via java API?

I am Using Spring data couchbase .
package com.CouchbaseMine.config;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import com.couchbase.client.CouchbaseClient;
#Configuration
#EnableAutoConfiguration
public class CouchbaseMineCouchBaseConfig extends AbstractCouchbaseConfiguration {
#Value("${couchbase.cluster.bucket}")
private String bucketName;
#Value("${couchbase.cluster.password}")
private String password;
#Value("${couchbase.cluster.ip}")
private String ip;
#Override
protected String getBucketName() {
List<URI> uris=new LinkedList<URI>();
uris.add(URI.create("5x.xx.xxx.xx9"));
CouchbaseClient client=null;
try {
System.err.println("-- > - > i am in ");
client=new CouchbaseClient(uris,"default","");
} catch (IOException e) {
System.err.println("IOException connetion to couchbase:"+e.getMessage() );
System.exit(1);
}
return this.bucketName;
}
#Override
protected String getBucketPassword() {
return this.password;
}
#Override
protected List<String> bootstrapHosts() {
// TODO Auto-generated method stub
//return Collections.singletonList("54.89.127.249");
return Arrays.asList(this.ip);
}
}
This is configuration class used for establish connection
Follow application properties file
server.port=3000
couchbase.cluster.ip 5x.xx.xxx.xx9
couchbase.cluster.bucket DHxxxar
couchbase.cluster.password 1221
Bottom line: I have created the bucket (Dhxxxar) manually in couchbase.But i need to automatically create the bucket(database) while i run my spring boot application.
So give me any suggestion regards the same . Thanks in advance
Try this:
Cluster cluster = CouchbaseCluster.create("127.0.0.1");
ClusterManager clusterManager = cluster.clusterManager("Administrator", "12345");
BucketSettings bucketSettings = new DefaultBucketSettings.Builder()
.type(BucketType.COUCHBASE)
.name("hello")
.quota(120)
.build();
clusterManager.insertBucket(bucketSettings);
More details:
https://developer.couchbase.com/documentation/server/current/sdk/java/managing-clusters.html
IgorekPotworek's answer is great for Couchbase Java SDK version 2.x.
For version 3.x, the code looks a little different:
Cluster cluster = Cluster.connect("localhost", "Administrator", "password");
BucketManager bucketManager = cluster.buckets();
bucketManager.createBucket(
BucketSettings.create("bucketName")
.ramQuotaMB(100));

ActiveMQ Handling Messages thru REST

I am new to ActiveMQ, we had a ActiveMQ Server else where location, we are unable to connect thru tcp socket, But able to cousume the message using REST command
http://admin:admin#localhost:8161/api/message?destination=queue://orders.input
I have 99K+ messages in ActiveMQ, need consume using REST command and need to store in a text file,
import static com.jayway.restassured.RestAssured.given;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import com.dnb.e2e.automation.util.CommonUtil;
import com.dnb.e2e.automation.util.WebServiceUtil;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.config.SSLConfig;
import com.jayway.restassured.config.SessionConfig;
import com.jayway.restassured.response.Headers;
public class MQwithRest {
public static String getResponse() throws Exception
{
String url = "http://admin:admin#localhost:8161/api/message?destination=queue://SAMPLEQUEUE";
String response = "a";
while(response!=""){
try {
response = given().header("content-type", "application/json")
.request()
.config(RestAssured.config().sslConfig(new SSLConfig().allowAllHostnames()))
.when().get(url).asString();
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
return "empty";
}
public static void main(String args[]) throws Exception
{
System.out.println(MQwithRest.getResponse());
}
}
In the above code i am displaying consumed messages at output side. When I am implementing thru rest i am able to consume only one message at a time per session.
Can any body help for Consuming 99k+ message with in a single session using REST service?
You can also tunnel JMS client over HTTP.
That way, you can get bypass any non-HTTP restrictions in your network and still use the JMS terminology.
Using the rest web app bundled you are a bit limited to the semantics of retrieving messages. Anyway, you should be able to get all messages using plain HTTP/Rest anyway. Simply use a loop to get messages.

How to access web service using an ordinary java class?

**My Web service class**
import javax.jws.WebMethod;
import javax.jws.WebService;
/**
* #author edward
*
*/
#WebService
public class HelloWeb {
#WebMethod
public String sayGreeting(String name) {
return "Greeting " + name + "....!";
}
}
My Server java class
import javax.xml.ws.Endpoint;
public class Server {
public static void main(String[] args) {
Endpoint.publish("http://localhost:9090/HelloWeb", new HelloWeb());
System.out.println("Hello Web service is ready");
}
}
Server is running properly, and i am able to access the service using url that returns WSDL code.But i want to access the server using unique URL in java.I have the following client java code.
Client to access HelloWeb Service
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
public class WebClient {
String wsdl = "http://172.21.1.65:9090/HelloWeb?wsdl";
String namespace = "http://helloweb.com";
String serviceName = "HelloWebService";
QName serviceQN = new QName(namespace, serviceName);
{
try{
ServiceFactory serviceFactory = ServiceFactory.newInstance();
Service service = serviceFactory.createService(new URL(wsdl), serviceQN);
}catch (Exception e) {
}
}
}
try this, note that I compiled and ran your server in "test" package, it's important. This is just a basic example to start with JAX-WS.
package test;
import java.net.URL;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class WebClient {
#WebService(name = "HelloWeb", targetNamespace = "http://test/")
public interface HelloWeb {
#WebMethod
String sayGreeting(String name);
}
public static void main(String[] args) throws Exception {
Service serv = Service.create(new URL(
"http://localhost:9090/HelloWeb?wsdl"),
new QName("http://test/", "HelloWebService"));
HelloWeb p = serv.getPort(HelloWeb.class);
System.out.println(p.sayGreeting("John"));
}
}

Categories