package envoy.client; import java.time.Instant; import java.util.Arrays; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import envoy.schema.Message; import envoy.schema.Message.MetaData.MessageState; import envoy.schema.Messages; import envoy.schema.ObjectFactory; import envoy.schema.User; import envoy.schema.Users; /** * Project: envoy-client
* File: Client.java
* Created: 28 Sep 2019
* * @author Kai S. K. Engelbart * @author Maximilian Käfer * @author Leon Hofmeister * @since Envoy 0.1 */ public class Client { private ObjectFactory objectFactory = new ObjectFactory(); private DatatypeFactory datatypeFactory; private Config config; private User sender, recipient; public Client(Config config, String username) { this.config = config; try { datatypeFactory = DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException e) { e.printStackTrace(); } sender = getUser(username); } /** * Sends a message with text content to the server.
* Because sending a request is a blocking operation, it is executed * asynchronously. * * @param sender name of the sender * @param recipient name of the recipient * @param textContent content (text) of the message */ public void sendMessage(Message message) { new Thread(() -> { // Wrap single message into messages list Messages messages = wrapMessages(message); // Print message XML to console JAXBContext jc; try { jc = JAXBContext.newInstance("envoy.schema"); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); m.marshal(messages, System.out); } catch (JAXBException e) { e.printStackTrace(); } // Send message javax.ws.rs.client.Client client = ClientBuilder.newClient(); WebTarget target = client .target(String.format("%s:%d/envoy-server/rest/message/send", config.getServer(), config.getPort())); Response response = target.request().post(Entity.entity(messages, "application/xml")); System.out.println("Response code: " + response.getStatus()); response.close(); client.close(); }).start(); } /** * Creates a {@link Message} object serializable to XML. * * @param textContent The content (text) of the message * @return prepared {@link Message} object */ public Message createMessage(String textContent) { Message.MetaData metaData = objectFactory.createMessageMetaData(); metaData.setSender(sender.getID()); metaData.setRecipient(recipient.getID()); metaData.setState(MessageState.WAITING); metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); Message.Content content = objectFactory.createMessageContent(); content.setType("text"); content.setText(textContent); Message message = objectFactory.createMessage(); message.setMetaData(metaData); message.getContent().add(content); return message; } public Users getUsersListXml() { return get(String.format("%s:%d/envoy-server/rest/user", config.getServer(), config.getPort()), Users.class); } public Messages getUnreadMessages(long userId) { return get(String.format("%s:%d/envoy-server/rest/message/receive?userId=%d", config.getServer(), config.getPort(), userId), Messages.class); } /** * Returns a {@link User} with a specific name by name. * * @param name - the name of the {@link User} * @return a {@link User} with the specified name * @since Envoy v0.1-alpha */ private User getUser(String name) { return get(String.format("%s:%d/envoy-server/rest/user/sender?name=%s", config.getServer(), config.getPort(), name), Users.class).getUser() .get(0); } /** * Invokes the GET method of a web service. * * @param the type of the object returned by the web service * @param uri the URI of the web service * @param responseClass the class of the object returned by the web service * @return the object returned by the web service * @since Envoy v0.1-alpha */ private T get(String uri, Class responseClass) { javax.ws.rs.client.Client client = ClientBuilder.newClient(); WebTarget target = client.target(uri); Response response = target.request("application/xml").get(); T responseObject = response.readEntity(responseClass); System.out.println("Response code: " + response.getStatus()); response.close(); client.close(); return responseObject; } /** * Wraps one or more {@link Message} objects into a {@link Messages} object. * * @param messages the {@link Message} objects to wrap * @return {@link Messages} object with all messages as its children * @since Envoy v0.1-alpha */ private Messages wrapMessages(Message... messages) { Messages wrapper = objectFactory.createMessages(); wrapper.getMessage().addAll(Arrays.asList(messages)); return wrapper; } /** * @return the sender object that represents this client * @since Envoy v0.1-alpha */ public User getSender() { return sender; } public User getRecipient() { return recipient; } public void setRecipient(User recipient) { this.recipient = recipient; } public boolean hasRecipient() { return recipient != null; } }