com.geosiris.etp.utils.ETPUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of etpproto-java Show documentation
Show all versions of etpproto-java Show documentation
A simple client to communicate with ETP standard
/*
Copyright 2019 GEOSIRIS
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.geosiris.etp.utils;
import Energistics.Etp.v12.Datatypes.MessageHeader;
import com.geosiris.etp.communication.Message;
import com.geosiris.etp.communication.MessageEncoding;
import com.geosiris.etp.communication.MessageFlags;
import com.geosiris.etp.communication.ProtocolsUtility;
import org.apache.avro.io.*;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.avro.specific.SpecificRecordBase;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WriteCallback;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.*;
public class ETPUtils {
public static final Logger logger = LogManager.getLogger(ETPUtils.class);
private final static int integerBitCount = Integer.toBinaryString(Integer.MAX_VALUE).length();
public static byte[] getWrittenBytes(T object) throws IOException{
ByteArrayOutputStream bf = new ByteArrayOutputStream();
BinaryEncoder binaryEncoder = EncoderFactory.get().binaryEncoder(bf, null);
SpecificDatumWriter headerWriter = new SpecificDatumWriter<>(object.getSchema());
headerWriter.write(object, binaryEncoder);
binaryEncoder.flush();
byte[] array = bf.toByteArray();
bf.flush();
bf.close();
return array;
}
public static long sendDatum(
T header, M srb, Session s, long maxMessageSize) throws IOException {
// logger.info("======== Sending message [" + header.getProtocol() + "][" + header.getMessageType() + "] " + srb.getClass() + " ========");
// Send data
header.setMessageFlags((header.getMessageFlags() | MessageFlags.FINALPART));
byte[] bytes_Header = getWrittenBytes(header);
byte[] bytes_msg = getWrittenBytes(srb);
// On retranche la taille du header car il sera remis à chaque fois.
int nbSplit = (int) Math.ceil( ((float)bytes_msg.length - bytes_Header.length) / (int)maxMessageSize);
long f = 0;
if(nbSplit<=1) {
byte[] finalMsg = new byte[bytes_Header.length + bytes_msg.length];
System.arraycopy(bytes_Header, 0, finalMsg, 0, bytes_Header.length);
System.arraycopy(bytes_msg, 0, finalMsg, bytes_Header.length, bytes_msg.length);
f = sendBytes(finalMsg, s);
logger.info("======== SENDING BINARY (" + f + " bytes) : ========");
}else {
header.setMessageFlags((Integer.MAX_VALUE ^ MessageFlags.FINALPART));
byte[] bytes_Header_not_fin = getWrittenBytes(header);
for(int part_i=0; part_i void sendDatumJson(
T obj, M srb, Session s, long maxMessageSize) throws IOException {
logger.info("SENDING JSON : ");
ByteArrayOutputStream out = new ByteArrayOutputStream();
logger.info("Sending message Protocol[" + obj.getProtocol() + "]Type[" + obj.getMessageType() + "]");
JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(
obj.getSchema(), out);
SpecificDatumWriter headerWriter = new SpecificDatumWriter<>(
obj.getSchema());
headerWriter.write(obj, jsonEncoder);
jsonEncoder.flush();
//logger.info("HEADER : " + out.toString());
String firstPart = out.toString();
// Json not accept to update schema internally in the method write,so we
// have to assign with the new schema. This same reasoning is applied in
// the decodification part
out = new ByteArrayOutputStream();
jsonEncoder = EncoderFactory.get().jsonEncoder(srb.getSchema(), out);
SpecificDatumWriter bodyWriter = new SpecificDatumWriter<>(
srb.getSchema());
bodyWriter.write(srb, jsonEncoder);
jsonEncoder.flush();
String second = out.toString();
// Send data
out.close();
logger.info("Sending message : \n" + firstPart + ";" + second);
s.getRemote().sendString(firstPart + ";" + second, new WriteCallback() {
@Override
public void writeSuccess() {
logger.info("> sending succed");
}
@Override
public void writeFailed(Throwable arg0) {
logger.info("> sending data failed");
logger.error(arg0.getMessage());
logger.debug(arg0.getMessage(), arg0);
}
});
}
private static Message readMessages(MessageHeader mh, Decoder dec, byte[] byteMsg) {
SpecificDatumReader headerReader = new SpecificDatumReader<>(
mh.getSchema(), mh.getSchema());
try {
headerReader.read(mh, dec);
} catch (EOFException ex1) {
logger.info("No bytes are in file");
} catch (IOException e2) { logger.error(e2.getMessage()); logger.debug(e2.getMessage(), e2); }
// logger.info("]==> Recieved message has flags : " + byteArrayToString(toBitArrayLeftToRight(mh.getMessageFlags())) );
// logger.info("Header " + mh.getMessageType() + " " + mh.getCorrelationId() + " -id-> " + mh.getMessageId());
// if (supportedProtocol.containsKey(mh.getProtocol())) {
/*
* When the message type and the protocol are 0, it means the message was built
* using the default constructor, and thus contains no information
* */
if (mh.getMessageType() == 0 && mh.getProtocol() == 0){
logger.error("null protocol or message type");
return null;
}else {
byte[] b_msgHeader = Message.encode(mh);
int header_bytes_len = b_msgHeader.length;
// logger.info(mh);
// logger.info("MSG FLAG : " + mh.getMessageFlags());
Object decoded_msg = Arrays.copyOfRange(byteMsg, header_bytes_len, byteMsg.length);
if(Message.isFinalePartialMsg(mh) ) { //|| mh.getMessageType()>1000
try {
decoded_msg = ProtocolsUtility.handleMessage(mh, dec);
}catch (Exception e) {
logger.error(e.getMessage());
logger.debug(e.getMessage(), e);
logger.error(" err handling " + ((byte[])decoded_msg).length);
}
}
// logger.info("DECODED : " + decoded_msg);
return new Message(null, mh, (SpecificRecordBase) decoded_msg);
}
}
private static Object readMessagesJSON(MessageHeader mh, String msg) {
/**
* When the message type and the protocol are 0, it means the message was built
* using the default constructor, and thus contains no information
* */
if (mh.getMessageType() == 0 && mh.getProtocol() == 0){
logger.error("null protocol or message type");
return null;
}else {
return ProtocolsUtility.handleMessageJSON(mh, msg);
}
}
public static Pair readMessagesJSON(String msg){
MessageHeader mh = new MessageHeader();
try {
JsonDecoder dec = DecoderFactory.get().jsonDecoder(mh.getSchema(), msg);
if (dec != null) {
SpecificDatumReader headerReader = new SpecificDatumReader<>(
mh.getSchema(), mh.getSchema());
try {
headerReader.read(mh, dec);
} catch (EOFException ex1) { logger.info("Empty message");
} catch (IOException e2) { logger.error(e2.getMessage()); logger.debug(e2.getMessage(), e2); }
return new Pair<>(mh.getMessageId(), readMessagesJSON(mh, msg.substring(msg.indexOf(";") + 1)));
}
} catch (IOException e) { logger.error(e.getMessage()); logger.debug(e.getMessage(), e); }
return null;
}
public static Message readMessages(byte[] payload){
MessageHeader mh = new MessageHeader();
Decoder dec = DecoderFactory.get().binaryDecoder(payload, null);
if (dec != null) {
return readMessages(mh, dec, payload);
} else {
return null;
}
}
public static long sendBytes(byte[] bArray, Session s)
throws IOException {
// byte[] bArray = bf.toByteArray();
// Send data
ByteBuffer byteBuffer = ByteBuffer.wrap(bArray);
s.getRemote().sendBytes(byteBuffer);
return bArray.length;
}
public static Byte[] toBitArrayLeftToRight(int v) {
String bitRep = Integer.toBinaryString(v);
Byte[] bitArray = new Byte[integerBitCount];
int bitRepLength = bitRep.length();
for(int i=0; i Map concat(Map a, Map b){
Map res = new HashMap<>();
res.putAll(a);
res.putAll(b);
return res;
}
public static Collection concat(Map a, Collection b){
return concat(b,a);
}
public static Collection concat(Collection a, Map b){
return concat(a, b.values());
}
public static Collection concat(Collection a, Collection b){
Collection res = new ArrayList<>();
res.addAll(a);
res.addAll(b);
return res;
}
public static Collection concat(Object a, Object b){
if(a instanceof Collection){
if(b instanceof Collection)
return concat((Collection>)a, (Collection>) b);
else if(b instanceof Map)
return concat((Collection>)a, (Map,?>) b);
}else if(a instanceof Map,?>){
if(b instanceof Collection)
return concat((Map,?>)a, (Collection>) b);
else if(b instanceof Map)
return concat((Map,?>)a, (Map,?>) b);
}
return null;
}
public static String upperCaseFirstChar(String in){
return in.substring(0,1).toUpperCase() + in.substring(1);
}
public static void setAttributeValue(Object out, String attribName, Object value) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
for(Method m_set : out.getClass().getMethods()){
if(m_set.getName().compareTo("set" + upperCaseFirstChar(attribName)) == 0){
try {
m_set.invoke(out, value);
}catch (Exception e){
logger.error(m_set + " ==> " + value);
logger.error(e.getMessage());
logger.debug(e.getMessage(), e);
}
}
}
}
public static Object getAttributeValue(Object obj, String attribName) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
for(Method m_set : obj.getClass().getMethods()){
if(m_set.getName().compareTo("get" + upperCaseFirstChar(attribName)) == 0){
return m_set.invoke(obj);
}
}
return null;
}
public static String getFirstAttributeMatchingType_name(Object obj, Class> paramClass) {
if(obj != null){
for(Method m : obj.getClass().getMethods()){
if(m.getName().startsWith("get") && paramClass.isAssignableFrom(m.getReturnType())){
try {
return m.getName().substring(3);
}catch (Exception e){e.printStackTrace();}
}
}
}
return null;
}
public static Object getFirstAttributeMatchingType_value(Object obj, Class> paramClass) {
if(obj != null){
for(Method m : obj.getClass().getMethods()){
if(m.getName().startsWith("get") && paramClass.isAssignableFrom(m.getReturnType())){
try {
return m.invoke(obj);
}catch (Exception e){e.printStackTrace();}
}
}
}
return null;
}
public static T concatWithArrayCopy(T array1, T array2) {
if (!array1.getClass().isArray() || !array2.getClass().isArray()) {
throw new IllegalArgumentException("Only arrays are accepted.");
}
Class> compType1 = array1.getClass().getComponentType();
Class> compType2 = array2.getClass().getComponentType();
if (!compType1.equals(compType2)) {
throw new IllegalArgumentException("Two arrays have different types.");
}
int len1 = Array.getLength(array1);
int len2 = Array.getLength(array2);
@SuppressWarnings("unchecked")
//the cast is safe due to the previous checks
T result = (T) Array.newInstance(compType1, len1 + len2);
System.arraycopy(array1, 0, result, 0, len1);
System.arraycopy(array2, 0, result, len1, len2);
return result;
}
public static byte[] asBytes(UUID uuid) {
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return bb.array();
}
public static UUID asUuid(byte[] bytes) {
ByteBuffer bb = ByteBuffer.wrap(bytes);
long firstLong = bb.getLong();
long secondLong = bb.getLong();
return new UUID(firstLong, secondLong);
}
public static void main(String [] argv) {
logger.info(Integer.toBinaryString(Integer.MAX_VALUE ^ MessageFlags.FINALPART));
logger.info((int) Math.ceil(((float)2)/3));
logger.info(Integer.toBinaryString(Integer.MAX_VALUE));
logger.info(byteArrayToString(toBitArrayLeftToRight(19)));
logger.info(2 & MessageFlags.FINALPART);
int[] firstArray = {23,45,12,78,4,90,1}; //source array
int[] secondArray = {77,11,45,88,32,56,3}; //destination array
int fal = firstArray.length; //determines length of firstArray
int sal = secondArray.length; //determines length of secondArray
int[] result = new int[fal + sal]; //resultant array of size first array and second array
System.arraycopy(firstArray, 0, result, 0, fal);
System.arraycopy(secondArray, 0, result, 0, sal);
logger.info(Arrays.toString(result)); //prints the resultant array
List partialList = new ArrayList<>();
int[] f0 = {1,2,3};
int[] f1 = {4,5,6};
int[] f2 = {7,8,9};
partialList.add(f0);
partialList.add(f1);
partialList.add(f2);
int fullSize = partialList.stream().map(ll -> ll.length).reduce(0, Integer::sum);
int[] entireMsg = new int[fullSize];
logger.info(fullSize);
int accumulator = 0;
for(int [] partialMsg : partialList) {
System.arraycopy(partialMsg, 0, entireMsg, accumulator, partialMsg.length);
accumulator += partialMsg.length;
}
for (int j : entireMsg) {
System.out.print(j + ",");
}
}
}