diff --git a/.gitignore b/.gitignore index 6bb47c581906a2d592173e1b0532486f4ace9bdc..a52a8756ab293e8c4b045439bcbfe5dc19a05f31 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,8 @@ .settings .DS_Store target -thrift *.swp *.pyc findbugs-results *.launch +/thrift diff --git a/build.xml b/build.xml index 0a3eb4bcdf095b74b5a1eb32ba8d19bbc63b33c9..0f97f63306fe1d76a459e998bbfa036f1fb75e5c 100644 --- a/build.xml +++ b/build.xml @@ -43,7 +43,6 @@ <property name="floodlight-test-jar" location="${target}/floodlight-test.jar"/> <property name="thrift.dir" value="${basedir}/src/main/thrift"/> <property name="thrift.out.dir" value="lib/gen-java"/> - <property name="thrift.package" value="net/floodlightcontroller/packetstreamer/thrift"/> <property name="ant.build.javac.source" value="1.6"/> <property name="ant.build.javac.target" value="1.6"/> <property name="findbugs.home" value="../build/findbugs-2.0.2"/> @@ -53,14 +52,19 @@ <patternset id="lib"> <include name="logback-classic-1.0.0.jar"/> <include name="logback-core-1.0.0.jar"/> - <include name="jackson-core-asl-1.8.6.jar"/> - <include name="jackson-mapper-asl-1.8.6.jar"/> + <include name="jackson-core-2.1.4.jar"/> + <include name="jackson-annotations-2.1.4.jar"/> + <include name="jackson-databind-2.1.4.jar"/> + <include name="jackson-dataformat-smile-2.1.4.jar"/> + <include name="jackson-dataformat-xml-2.1.4.jar"/> + <include name="jackson-dataformat-yaml-2.1.4.jar"/> + <include name="jackson-dataformat-csv-2.1.4.jar"/> <include name="slf4j-api-1.6.4.jar"/> - <include name="org.restlet-2.1-RC1.jar"/> - <include name="org.restlet.ext.jackson-2.1-RC1.jar"/> - <include name="org.restlet.ext.simple-2.1-RC1.jar"/> - <include name="org.restlet.ext.slf4j-2.1-RC1.jar"/> - <include name="simple-4.1.21.jar"/> + <include name="org.restlet-2.2M3.jar"/> + <include name="org.restlet.ext.jackson-2.2M3.jar"/> + <include name="org.restlet.ext.simple-2.2M3.jar"/> + <include name="org.restlet.ext.slf4j-2.2M3.jar"/> + <include name="simple-5.1.1.jar"/> <include name="netty-3.2.6.Final.jar"/> <include name="args4j-2.0.16.jar"/> <include name="concurrentlinkedhashmap-lru-1.2.jar"/> @@ -69,6 +73,7 @@ <include name="guava-13.0.1.jar" /> <include name="findbugs-annotations-2.0.1.jar" /> <include name="findbugs-jsr305-2.0.1.jar" /> + <include name="derby-10.9.1.0.jar"/> </patternset> <path id="classpath"> @@ -131,20 +136,35 @@ destdir="${build-test}"/> </target> - <!-- Thrift build based on http://www.flester.com/blog/2009/04/26/using-thrift-from-ant --> - <fileset id="thrift.files" dir="${thrift.dir}"> - <include name="**/*.thrift"/> - </fileset> - <target name="gen-thrift" depends="init"> - <pathconvert property="thrift.file.list" refid="thrift.files" - pathsep=" " dirsep="/"> - </pathconvert> - <echo message="Running thrift generator on ${thrift.file.list}"/> - <exec executable="thrift" dir="${basedir}" failonerror="true"> - <arg line="--strict -v --gen java -o ${thrift.out.dir}/.. '${thrift.file.list}'"/> + <echo message="Running thrift on '${thrift.dir}'"/> + <apply executable="./thrift/compiler/cpp/thrift"> + <fileset dir="${thrift.dir}" casesensitive="yes"> + <include name="**/*.thrift"/> + </fileset> + <arg value="--strict"/> + <arg value="-v"/> + <arg value="--gen"/> + <arg value="java"/> + <arg value="-o"/> + <arg value="${thrift.out.dir}/.."/> + </apply> + <echo message="Adding @SuppressWarning annotations"/> + <replaceregexp byline="true"> + <regexp pattern="^public "/> + <substitution expression='@SuppressWarnings("all") public '/> + <fileset id="thrift.output.files" dir="${thrift.out.dir}/.."> + <include name="**/*.java"/> + </fileset> + </replaceregexp> + </target> + + <target name="do-gen-thrift"> + <exec executable="./thrift/compiler/cpp/thrift" dir="${basedir}" failonerror="true"> + <arg line="--strict -v --gen java -o ${thrift.out.dir}/.. '${foreach.file}'"/> </exec> <!-- Get rid of annoying warnings in thrift java: at annotations --> + <echo message="Adding @SuppressWarning annotations"/> <replaceregexp byline="true"> <regexp pattern="^public "/> diff --git a/lib/derby-10.9.1.0.jar b/lib/derby-10.9.1.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..26feece9e6b1568531ffdb38b173736c35f4d260 Binary files /dev/null and b/lib/derby-10.9.1.0.jar differ diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java index f4e8ae512734dbf2253f92b2bde0f2387ca0eed2..d7e454716c55d7359c34b442d0d050783f5645b6 100644 --- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java +++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java @@ -1618,8 +1618,6 @@ import org.slf4j.LoggerFactory; private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { try { - // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. - __isset_bit_vector = new BitSet(1); read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); } catch (org.apache.thrift.TException te) { throw new java.io.IOException(te); diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/AsyncMessageHeader.java b/lib/gen-java/org/sdnplatform/sync/thrift/AsyncMessageHeader.java new file mode 100644 index 0000000000000000000000000000000000000000..1a454a2d5a89f12b4578aa4eee4b4714ce650ba0 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/AsyncMessageHeader.java @@ -0,0 +1,315 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class AsyncMessageHeader implements org.apache.thrift.TBase<AsyncMessageHeader, AsyncMessageHeader._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("AsyncMessageHeader"); + + private static final org.apache.thrift.protocol.TField TRANSACTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("transactionId", org.apache.thrift.protocol.TType.I32, (short)1); + + public int transactionId; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + TRANSACTION_ID((short)1, "transactionId"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // TRANSACTION_ID + return TRANSACTION_ID; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __TRANSACTIONID_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.TRANSACTION_ID, new org.apache.thrift.meta_data.FieldMetaData("transactionId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(AsyncMessageHeader.class, metaDataMap); + } + + public AsyncMessageHeader() { + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public AsyncMessageHeader(AsyncMessageHeader other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + this.transactionId = other.transactionId; + } + + public AsyncMessageHeader deepCopy() { + return new AsyncMessageHeader(this); + } + + @Override + public void clear() { + setTransactionIdIsSet(false); + this.transactionId = 0; + } + + public int getTransactionId() { + return this.transactionId; + } + + public AsyncMessageHeader setTransactionId(int transactionId) { + this.transactionId = transactionId; + setTransactionIdIsSet(true); + return this; + } + + public void unsetTransactionId() { + __isset_bit_vector.clear(__TRANSACTIONID_ISSET_ID); + } + + /** Returns true if field transactionId is set (has been assigned a value) and false otherwise */ + public boolean isSetTransactionId() { + return __isset_bit_vector.get(__TRANSACTIONID_ISSET_ID); + } + + public void setTransactionIdIsSet(boolean value) { + __isset_bit_vector.set(__TRANSACTIONID_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case TRANSACTION_ID: + if (value == null) { + unsetTransactionId(); + } else { + setTransactionId((Integer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case TRANSACTION_ID: + return Integer.valueOf(getTransactionId()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case TRANSACTION_ID: + return isSetTransactionId(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof AsyncMessageHeader) + return this.equals((AsyncMessageHeader)that); + return false; + } + + public boolean equals(AsyncMessageHeader that) { + if (that == null) + return false; + + boolean this_present_transactionId = true && this.isSetTransactionId(); + boolean that_present_transactionId = true && that.isSetTransactionId(); + if (this_present_transactionId || that_present_transactionId) { + if (!(this_present_transactionId && that_present_transactionId)) + return false; + if (this.transactionId != that.transactionId) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(AsyncMessageHeader other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + AsyncMessageHeader typedOther = (AsyncMessageHeader)other; + + lastComparison = Boolean.valueOf(isSetTransactionId()).compareTo(typedOther.isSetTransactionId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTransactionId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.transactionId, typedOther.transactionId); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // TRANSACTION_ID + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.transactionId = iprot.readI32(); + setTransactionIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (isSetTransactionId()) { + oprot.writeFieldBegin(TRANSACTION_ID_FIELD_DESC); + oprot.writeI32(this.transactionId); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("AsyncMessageHeader("); + boolean first = true; + + if (isSetTransactionId()) { + sb.append("transactionId:"); + sb.append(this.transactionId); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/ClockEntry.java b/lib/gen-java/org/sdnplatform/sync/thrift/ClockEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..5a199b072d2d12b29583b74aaf8b60b01f2bb17f --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/ClockEntry.java @@ -0,0 +1,411 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class ClockEntry implements org.apache.thrift.TBase<ClockEntry, ClockEntry._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ClockEntry"); + + private static final org.apache.thrift.protocol.TField NODE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("nodeId", org.apache.thrift.protocol.TType.I16, (short)1); + private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.I64, (short)2); + + public short nodeId; // required + public long version; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + NODE_ID((short)1, "nodeId"), + VERSION((short)2, "version"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // NODE_ID + return NODE_ID; + case 2: // VERSION + return VERSION; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __NODEID_ISSET_ID = 0; + private static final int __VERSION_ISSET_ID = 1; + private BitSet __isset_bit_vector = new BitSet(2); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.NODE_ID, new org.apache.thrift.meta_data.FieldMetaData("nodeId", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ClockEntry.class, metaDataMap); + } + + public ClockEntry() { + } + + public ClockEntry( + short nodeId, + long version) + { + this(); + this.nodeId = nodeId; + setNodeIdIsSet(true); + this.version = version; + setVersionIsSet(true); + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public ClockEntry(ClockEntry other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + this.nodeId = other.nodeId; + this.version = other.version; + } + + public ClockEntry deepCopy() { + return new ClockEntry(this); + } + + @Override + public void clear() { + setNodeIdIsSet(false); + this.nodeId = 0; + setVersionIsSet(false); + this.version = 0; + } + + public short getNodeId() { + return this.nodeId; + } + + public ClockEntry setNodeId(short nodeId) { + this.nodeId = nodeId; + setNodeIdIsSet(true); + return this; + } + + public void unsetNodeId() { + __isset_bit_vector.clear(__NODEID_ISSET_ID); + } + + /** Returns true if field nodeId is set (has been assigned a value) and false otherwise */ + public boolean isSetNodeId() { + return __isset_bit_vector.get(__NODEID_ISSET_ID); + } + + public void setNodeIdIsSet(boolean value) { + __isset_bit_vector.set(__NODEID_ISSET_ID, value); + } + + public long getVersion() { + return this.version; + } + + public ClockEntry setVersion(long version) { + this.version = version; + setVersionIsSet(true); + return this; + } + + public void unsetVersion() { + __isset_bit_vector.clear(__VERSION_ISSET_ID); + } + + /** Returns true if field version is set (has been assigned a value) and false otherwise */ + public boolean isSetVersion() { + return __isset_bit_vector.get(__VERSION_ISSET_ID); + } + + public void setVersionIsSet(boolean value) { + __isset_bit_vector.set(__VERSION_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case NODE_ID: + if (value == null) { + unsetNodeId(); + } else { + setNodeId((Short)value); + } + break; + + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((Long)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case NODE_ID: + return Short.valueOf(getNodeId()); + + case VERSION: + return Long.valueOf(getVersion()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case NODE_ID: + return isSetNodeId(); + case VERSION: + return isSetVersion(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof ClockEntry) + return this.equals((ClockEntry)that); + return false; + } + + public boolean equals(ClockEntry that) { + if (that == null) + return false; + + boolean this_present_nodeId = true; + boolean that_present_nodeId = true; + if (this_present_nodeId || that_present_nodeId) { + if (!(this_present_nodeId && that_present_nodeId)) + return false; + if (this.nodeId != that.nodeId) + return false; + } + + boolean this_present_version = true; + boolean that_present_version = true; + if (this_present_version || that_present_version) { + if (!(this_present_version && that_present_version)) + return false; + if (this.version != that.version) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(ClockEntry other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + ClockEntry typedOther = (ClockEntry)other; + + lastComparison = Boolean.valueOf(isSetNodeId()).compareTo(typedOther.isSetNodeId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetNodeId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nodeId, typedOther.nodeId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersion()).compareTo(typedOther.isSetVersion()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersion()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, typedOther.version); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // NODE_ID + if (field.type == org.apache.thrift.protocol.TType.I16) { + this.nodeId = iprot.readI16(); + setNodeIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // VERSION + if (field.type == org.apache.thrift.protocol.TType.I64) { + this.version = iprot.readI64(); + setVersionIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + if (!isSetNodeId()) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'nodeId' was not found in serialized data! Struct: " + toString()); + } + if (!isSetVersion()) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'version' was not found in serialized data! Struct: " + toString()); + } + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(NODE_ID_FIELD_DESC); + oprot.writeI16(this.nodeId); + oprot.writeFieldEnd(); + oprot.writeFieldBegin(VERSION_FIELD_DESC); + oprot.writeI64(this.version); + oprot.writeFieldEnd(); + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("ClockEntry("); + boolean first = true; + + sb.append("nodeId:"); + sb.append(this.nodeId); + first = false; + if (!first) sb.append(", "); + sb.append("version:"); + sb.append(this.version); + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + // alas, we cannot check 'nodeId' because it's a primitive and you chose the non-beans generator. + // alas, we cannot check 'version' because it's a primitive and you chose the non-beans generator. + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/Constants.java b/lib/gen-java/org/sdnplatform/sync/thrift/Constants.java new file mode 100644 index 0000000000000000000000000000000000000000..f134de66a2dc5b65feaece382bc63c638d526b4e --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/Constants.java @@ -0,0 +1,27 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class Constants { + + public static final String VERSION = "1.0.0"; + +} diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/CursorRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/CursorRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..bbca2d5f5261ba8a0efb6e2a65306f1b2679b913 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/CursorRequestMessage.java @@ -0,0 +1,589 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class CursorRequestMessage implements org.apache.thrift.TBase<CursorRequestMessage, CursorRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("CursorRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("storeName", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField CURSOR_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("cursorId", org.apache.thrift.protocol.TType.I32, (short)3); + private static final org.apache.thrift.protocol.TField CLOSE_FIELD_DESC = new org.apache.thrift.protocol.TField("close", org.apache.thrift.protocol.TType.BOOL, (short)4); + + public AsyncMessageHeader header; // required + public String storeName; // required + public int cursorId; // required + public boolean close; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE_NAME((short)2, "storeName"), + CURSOR_ID((short)3, "cursorId"), + CLOSE((short)4, "close"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE_NAME + return STORE_NAME; + case 3: // CURSOR_ID + return CURSOR_ID; + case 4: // CLOSE + return CLOSE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __CURSORID_ISSET_ID = 0; + private static final int __CLOSE_ISSET_ID = 1; + private BitSet __isset_bit_vector = new BitSet(2); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE_NAME, new org.apache.thrift.meta_data.FieldMetaData("storeName", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.CURSOR_ID, new org.apache.thrift.meta_data.FieldMetaData("cursorId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.CLOSE, new org.apache.thrift.meta_data.FieldMetaData("close", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(CursorRequestMessage.class, metaDataMap); + } + + public CursorRequestMessage() { + } + + public CursorRequestMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public CursorRequestMessage(CursorRequestMessage other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStoreName()) { + this.storeName = other.storeName; + } + this.cursorId = other.cursorId; + this.close = other.close; + } + + public CursorRequestMessage deepCopy() { + return new CursorRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.storeName = null; + setCursorIdIsSet(false); + this.cursorId = 0; + setCloseIsSet(false); + this.close = false; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public CursorRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public String getStoreName() { + return this.storeName; + } + + public CursorRequestMessage setStoreName(String storeName) { + this.storeName = storeName; + return this; + } + + public void unsetStoreName() { + this.storeName = null; + } + + /** Returns true if field storeName is set (has been assigned a value) and false otherwise */ + public boolean isSetStoreName() { + return this.storeName != null; + } + + public void setStoreNameIsSet(boolean value) { + if (!value) { + this.storeName = null; + } + } + + public int getCursorId() { + return this.cursorId; + } + + public CursorRequestMessage setCursorId(int cursorId) { + this.cursorId = cursorId; + setCursorIdIsSet(true); + return this; + } + + public void unsetCursorId() { + __isset_bit_vector.clear(__CURSORID_ISSET_ID); + } + + /** Returns true if field cursorId is set (has been assigned a value) and false otherwise */ + public boolean isSetCursorId() { + return __isset_bit_vector.get(__CURSORID_ISSET_ID); + } + + public void setCursorIdIsSet(boolean value) { + __isset_bit_vector.set(__CURSORID_ISSET_ID, value); + } + + public boolean isClose() { + return this.close; + } + + public CursorRequestMessage setClose(boolean close) { + this.close = close; + setCloseIsSet(true); + return this; + } + + public void unsetClose() { + __isset_bit_vector.clear(__CLOSE_ISSET_ID); + } + + /** Returns true if field close is set (has been assigned a value) and false otherwise */ + public boolean isSetClose() { + return __isset_bit_vector.get(__CLOSE_ISSET_ID); + } + + public void setCloseIsSet(boolean value) { + __isset_bit_vector.set(__CLOSE_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE_NAME: + if (value == null) { + unsetStoreName(); + } else { + setStoreName((String)value); + } + break; + + case CURSOR_ID: + if (value == null) { + unsetCursorId(); + } else { + setCursorId((Integer)value); + } + break; + + case CLOSE: + if (value == null) { + unsetClose(); + } else { + setClose((Boolean)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE_NAME: + return getStoreName(); + + case CURSOR_ID: + return Integer.valueOf(getCursorId()); + + case CLOSE: + return Boolean.valueOf(isClose()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE_NAME: + return isSetStoreName(); + case CURSOR_ID: + return isSetCursorId(); + case CLOSE: + return isSetClose(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof CursorRequestMessage) + return this.equals((CursorRequestMessage)that); + return false; + } + + public boolean equals(CursorRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_storeName = true && this.isSetStoreName(); + boolean that_present_storeName = true && that.isSetStoreName(); + if (this_present_storeName || that_present_storeName) { + if (!(this_present_storeName && that_present_storeName)) + return false; + if (!this.storeName.equals(that.storeName)) + return false; + } + + boolean this_present_cursorId = true && this.isSetCursorId(); + boolean that_present_cursorId = true && that.isSetCursorId(); + if (this_present_cursorId || that_present_cursorId) { + if (!(this_present_cursorId && that_present_cursorId)) + return false; + if (this.cursorId != that.cursorId) + return false; + } + + boolean this_present_close = true && this.isSetClose(); + boolean that_present_close = true && that.isSetClose(); + if (this_present_close || that_present_close) { + if (!(this_present_close && that_present_close)) + return false; + if (this.close != that.close) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(CursorRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + CursorRequestMessage typedOther = (CursorRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStoreName()).compareTo(typedOther.isSetStoreName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStoreName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeName, typedOther.storeName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCursorId()).compareTo(typedOther.isSetCursorId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCursorId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cursorId, typedOther.cursorId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetClose()).compareTo(typedOther.isSetClose()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetClose()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.close, typedOther.close); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE_NAME + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.storeName = iprot.readString(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // CURSOR_ID + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.cursorId = iprot.readI32(); + setCursorIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // CLOSE + if (field.type == org.apache.thrift.protocol.TType.BOOL) { + this.close = iprot.readBool(); + setCloseIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.storeName != null) { + if (isSetStoreName()) { + oprot.writeFieldBegin(STORE_NAME_FIELD_DESC); + oprot.writeString(this.storeName); + oprot.writeFieldEnd(); + } + } + if (isSetCursorId()) { + oprot.writeFieldBegin(CURSOR_ID_FIELD_DESC); + oprot.writeI32(this.cursorId); + oprot.writeFieldEnd(); + } + if (isSetClose()) { + oprot.writeFieldBegin(CLOSE_FIELD_DESC); + oprot.writeBool(this.close); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CursorRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (isSetStoreName()) { + if (!first) sb.append(", "); + sb.append("storeName:"); + if (this.storeName == null) { + sb.append("null"); + } else { + sb.append(this.storeName); + } + first = false; + } + if (isSetCursorId()) { + if (!first) sb.append(", "); + sb.append("cursorId:"); + sb.append(this.cursorId); + first = false; + } + if (isSetClose()) { + if (!first) sb.append(", "); + sb.append("close:"); + sb.append(this.close); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/CursorResponseMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/CursorResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..f9aa036fa141d4a4e12a6f028373f0012d41ea41 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/CursorResponseMessage.java @@ -0,0 +1,543 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class CursorResponseMessage implements org.apache.thrift.TBase<CursorResponseMessage, CursorResponseMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("CursorResponseMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField CURSOR_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("cursorId", org.apache.thrift.protocol.TType.I32, (short)2); + private static final org.apache.thrift.protocol.TField VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("values", org.apache.thrift.protocol.TType.LIST, (short)3); + + public AsyncMessageHeader header; // required + public int cursorId; // required + public List<KeyedValues> values; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + CURSOR_ID((short)2, "cursorId"), + VALUES((short)3, "values"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // CURSOR_ID + return CURSOR_ID; + case 3: // VALUES + return VALUES; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __CURSORID_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.CURSOR_ID, new org.apache.thrift.meta_data.FieldMetaData("cursorId", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.VALUES, new org.apache.thrift.meta_data.FieldMetaData("values", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyedValues.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(CursorResponseMessage.class, metaDataMap); + } + + public CursorResponseMessage() { + } + + public CursorResponseMessage( + AsyncMessageHeader header, + int cursorId, + List<KeyedValues> values) + { + this(); + this.header = header; + this.cursorId = cursorId; + setCursorIdIsSet(true); + this.values = values; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public CursorResponseMessage(CursorResponseMessage other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + this.cursorId = other.cursorId; + if (other.isSetValues()) { + List<KeyedValues> __this__values = new ArrayList<KeyedValues>(); + for (KeyedValues other_element : other.values) { + __this__values.add(new KeyedValues(other_element)); + } + this.values = __this__values; + } + } + + public CursorResponseMessage deepCopy() { + return new CursorResponseMessage(this); + } + + @Override + public void clear() { + this.header = null; + setCursorIdIsSet(false); + this.cursorId = 0; + this.values = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public CursorResponseMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public int getCursorId() { + return this.cursorId; + } + + public CursorResponseMessage setCursorId(int cursorId) { + this.cursorId = cursorId; + setCursorIdIsSet(true); + return this; + } + + public void unsetCursorId() { + __isset_bit_vector.clear(__CURSORID_ISSET_ID); + } + + /** Returns true if field cursorId is set (has been assigned a value) and false otherwise */ + public boolean isSetCursorId() { + return __isset_bit_vector.get(__CURSORID_ISSET_ID); + } + + public void setCursorIdIsSet(boolean value) { + __isset_bit_vector.set(__CURSORID_ISSET_ID, value); + } + + public int getValuesSize() { + return (this.values == null) ? 0 : this.values.size(); + } + + public java.util.Iterator<KeyedValues> getValuesIterator() { + return (this.values == null) ? null : this.values.iterator(); + } + + public void addToValues(KeyedValues elem) { + if (this.values == null) { + this.values = new ArrayList<KeyedValues>(); + } + this.values.add(elem); + } + + public List<KeyedValues> getValues() { + return this.values; + } + + public CursorResponseMessage setValues(List<KeyedValues> values) { + this.values = values; + return this; + } + + public void unsetValues() { + this.values = null; + } + + /** Returns true if field values is set (has been assigned a value) and false otherwise */ + public boolean isSetValues() { + return this.values != null; + } + + public void setValuesIsSet(boolean value) { + if (!value) { + this.values = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case CURSOR_ID: + if (value == null) { + unsetCursorId(); + } else { + setCursorId((Integer)value); + } + break; + + case VALUES: + if (value == null) { + unsetValues(); + } else { + setValues((List<KeyedValues>)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case CURSOR_ID: + return Integer.valueOf(getCursorId()); + + case VALUES: + return getValues(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case CURSOR_ID: + return isSetCursorId(); + case VALUES: + return isSetValues(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof CursorResponseMessage) + return this.equals((CursorResponseMessage)that); + return false; + } + + public boolean equals(CursorResponseMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_cursorId = true; + boolean that_present_cursorId = true; + if (this_present_cursorId || that_present_cursorId) { + if (!(this_present_cursorId && that_present_cursorId)) + return false; + if (this.cursorId != that.cursorId) + return false; + } + + boolean this_present_values = true && this.isSetValues(); + boolean that_present_values = true && that.isSetValues(); + if (this_present_values || that_present_values) { + if (!(this_present_values && that_present_values)) + return false; + if (!this.values.equals(that.values)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(CursorResponseMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + CursorResponseMessage typedOther = (CursorResponseMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCursorId()).compareTo(typedOther.isSetCursorId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCursorId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cursorId, typedOther.cursorId); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValues()).compareTo(typedOther.isSetValues()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValues()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.values, typedOther.values); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // CURSOR_ID + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.cursorId = iprot.readI32(); + setCursorIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // VALUES + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list28 = iprot.readListBegin(); + this.values = new ArrayList<KeyedValues>(_list28.size); + for (int _i29 = 0; _i29 < _list28.size; ++_i29) + { + KeyedValues _elem30; // required + _elem30 = new KeyedValues(); + _elem30.read(iprot); + this.values.add(_elem30); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + if (!isSetCursorId()) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'cursorId' was not found in serialized data! Struct: " + toString()); + } + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(CURSOR_ID_FIELD_DESC); + oprot.writeI32(this.cursorId); + oprot.writeFieldEnd(); + if (this.values != null) { + oprot.writeFieldBegin(VALUES_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.values.size())); + for (KeyedValues _iter31 : this.values) + { + _iter31.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CursorResponseMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("cursorId:"); + sb.append(this.cursorId); + first = false; + if (!first) sb.append(", "); + sb.append("values:"); + if (this.values == null) { + sb.append("null"); + } else { + sb.append(this.values); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + // alas, we cannot check 'cursorId' because it's a primitive and you chose the non-beans generator. + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/DeleteRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/DeleteRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..f9f6a09125156cd9a2b39752b5e021074d43b2a9 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/DeleteRequestMessage.java @@ -0,0 +1,610 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class DeleteRequestMessage implements org.apache.thrift.TBase<DeleteRequestMessage, DeleteRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DeleteRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("storeName", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)3); + private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRUCT, (short)4); + + public AsyncMessageHeader header; // required + public String storeName; // required + public ByteBuffer key; // required + public VectorClock version; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE_NAME((short)2, "storeName"), + KEY((short)3, "key"), + VERSION((short)4, "version"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE_NAME + return STORE_NAME; + case 3: // KEY + return KEY; + case 4: // VERSION + return VERSION; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE_NAME, new org.apache.thrift.meta_data.FieldMetaData("storeName", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, VectorClock.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DeleteRequestMessage.class, metaDataMap); + } + + public DeleteRequestMessage() { + } + + public DeleteRequestMessage( + AsyncMessageHeader header, + String storeName, + ByteBuffer key) + { + this(); + this.header = header; + this.storeName = storeName; + this.key = key; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public DeleteRequestMessage(DeleteRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStoreName()) { + this.storeName = other.storeName; + } + if (other.isSetKey()) { + this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetVersion()) { + this.version = new VectorClock(other.version); + } + } + + public DeleteRequestMessage deepCopy() { + return new DeleteRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.storeName = null; + this.key = null; + this.version = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public DeleteRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public String getStoreName() { + return this.storeName; + } + + public DeleteRequestMessage setStoreName(String storeName) { + this.storeName = storeName; + return this; + } + + public void unsetStoreName() { + this.storeName = null; + } + + /** Returns true if field storeName is set (has been assigned a value) and false otherwise */ + public boolean isSetStoreName() { + return this.storeName != null; + } + + public void setStoreNameIsSet(boolean value) { + if (!value) { + this.storeName = null; + } + } + + public byte[] getKey() { + setKey(org.apache.thrift.TBaseHelper.rightSize(key)); + return key == null ? null : key.array(); + } + + public ByteBuffer bufferForKey() { + return key; + } + + public DeleteRequestMessage setKey(byte[] key) { + setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key)); + return this; + } + + public DeleteRequestMessage setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been assigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public VectorClock getVersion() { + return this.version; + } + + public DeleteRequestMessage setVersion(VectorClock version) { + this.version = version; + return this; + } + + public void unsetVersion() { + this.version = null; + } + + /** Returns true if field version is set (has been assigned a value) and false otherwise */ + public boolean isSetVersion() { + return this.version != null; + } + + public void setVersionIsSet(boolean value) { + if (!value) { + this.version = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE_NAME: + if (value == null) { + unsetStoreName(); + } else { + setStoreName((String)value); + } + break; + + case KEY: + if (value == null) { + unsetKey(); + } else { + setKey((ByteBuffer)value); + } + break; + + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((VectorClock)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE_NAME: + return getStoreName(); + + case KEY: + return getKey(); + + case VERSION: + return getVersion(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE_NAME: + return isSetStoreName(); + case KEY: + return isSetKey(); + case VERSION: + return isSetVersion(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof DeleteRequestMessage) + return this.equals((DeleteRequestMessage)that); + return false; + } + + public boolean equals(DeleteRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_storeName = true && this.isSetStoreName(); + boolean that_present_storeName = true && that.isSetStoreName(); + if (this_present_storeName || that_present_storeName) { + if (!(this_present_storeName && that_present_storeName)) + return false; + if (!this.storeName.equals(that.storeName)) + return false; + } + + boolean this_present_key = true && this.isSetKey(); + boolean that_present_key = true && that.isSetKey(); + if (this_present_key || that_present_key) { + if (!(this_present_key && that_present_key)) + return false; + if (!this.key.equals(that.key)) + return false; + } + + boolean this_present_version = true && this.isSetVersion(); + boolean that_present_version = true && that.isSetVersion(); + if (this_present_version || that_present_version) { + if (!(this_present_version && that_present_version)) + return false; + if (!this.version.equals(that.version)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(DeleteRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + DeleteRequestMessage typedOther = (DeleteRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStoreName()).compareTo(typedOther.isSetStoreName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStoreName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeName, typedOther.storeName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersion()).compareTo(typedOther.isSetVersion()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersion()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, typedOther.version); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE_NAME + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.storeName = iprot.readString(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // KEY + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.key = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // VERSION + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.version = new VectorClock(); + this.version.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.storeName != null) { + oprot.writeFieldBegin(STORE_NAME_FIELD_DESC); + oprot.writeString(this.storeName); + oprot.writeFieldEnd(); + } + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.version != null) { + if (isSetVersion()) { + oprot.writeFieldBegin(VERSION_FIELD_DESC); + this.version.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("DeleteRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("storeName:"); + if (this.storeName == null) { + sb.append("null"); + } else { + sb.append(this.storeName); + } + first = false; + if (!first) sb.append(", "); + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.key, sb); + } + first = false; + if (isSetVersion()) { + if (!first) sb.append(", "); + sb.append("version:"); + if (this.version == null) { + sb.append("null"); + } else { + sb.append(this.version); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (storeName == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'storeName' was not present! Struct: " + toString()); + } + if (key == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/DeleteResponseMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/DeleteResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..82bc0803d20e171834bb26f47a43c324dbf8af19 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/DeleteResponseMessage.java @@ -0,0 +1,407 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class DeleteResponseMessage implements org.apache.thrift.TBase<DeleteResponseMessage, DeleteResponseMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DeleteResponseMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField DELETED_FIELD_DESC = new org.apache.thrift.protocol.TField("deleted", org.apache.thrift.protocol.TType.BOOL, (short)2); + + public AsyncMessageHeader header; // required + public boolean deleted; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + DELETED((short)2, "deleted"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // DELETED + return DELETED; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __DELETED_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.DELETED, new org.apache.thrift.meta_data.FieldMetaData("deleted", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DeleteResponseMessage.class, metaDataMap); + } + + public DeleteResponseMessage() { + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public DeleteResponseMessage(DeleteResponseMessage other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + this.deleted = other.deleted; + } + + public DeleteResponseMessage deepCopy() { + return new DeleteResponseMessage(this); + } + + @Override + public void clear() { + this.header = null; + setDeletedIsSet(false); + this.deleted = false; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public DeleteResponseMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public boolean isDeleted() { + return this.deleted; + } + + public DeleteResponseMessage setDeleted(boolean deleted) { + this.deleted = deleted; + setDeletedIsSet(true); + return this; + } + + public void unsetDeleted() { + __isset_bit_vector.clear(__DELETED_ISSET_ID); + } + + /** Returns true if field deleted is set (has been assigned a value) and false otherwise */ + public boolean isSetDeleted() { + return __isset_bit_vector.get(__DELETED_ISSET_ID); + } + + public void setDeletedIsSet(boolean value) { + __isset_bit_vector.set(__DELETED_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case DELETED: + if (value == null) { + unsetDeleted(); + } else { + setDeleted((Boolean)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case DELETED: + return Boolean.valueOf(isDeleted()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case DELETED: + return isSetDeleted(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof DeleteResponseMessage) + return this.equals((DeleteResponseMessage)that); + return false; + } + + public boolean equals(DeleteResponseMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_deleted = true && this.isSetDeleted(); + boolean that_present_deleted = true && that.isSetDeleted(); + if (this_present_deleted || that_present_deleted) { + if (!(this_present_deleted && that_present_deleted)) + return false; + if (this.deleted != that.deleted) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(DeleteResponseMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + DeleteResponseMessage typedOther = (DeleteResponseMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetDeleted()).compareTo(typedOther.isSetDeleted()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDeleted()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.deleted, typedOther.deleted); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // DELETED + if (field.type == org.apache.thrift.protocol.TType.BOOL) { + this.deleted = iprot.readBool(); + setDeletedIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + if (isSetHeader()) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + } + if (isSetDeleted()) { + oprot.writeFieldBegin(DELETED_FIELD_DESC); + oprot.writeBool(this.deleted); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("DeleteResponseMessage("); + boolean first = true; + + if (isSetHeader()) { + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + } + if (isSetDeleted()) { + if (!first) sb.append(", "); + sb.append("deleted:"); + sb.append(this.deleted); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/EchoReplyMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/EchoReplyMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..a5fce6cf500415ae3bc40f91275b77d10c41b151 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/EchoReplyMessage.java @@ -0,0 +1,323 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class EchoReplyMessage implements org.apache.thrift.TBase<EchoReplyMessage, EchoReplyMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("EchoReplyMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + public AsyncMessageHeader header; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(EchoReplyMessage.class, metaDataMap); + } + + public EchoReplyMessage() { + } + + public EchoReplyMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public EchoReplyMessage(EchoReplyMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + } + + public EchoReplyMessage deepCopy() { + return new EchoReplyMessage(this); + } + + @Override + public void clear() { + this.header = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public EchoReplyMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof EchoReplyMessage) + return this.equals((EchoReplyMessage)that); + return false; + } + + public boolean equals(EchoReplyMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(EchoReplyMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + EchoReplyMessage typedOther = (EchoReplyMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("EchoReplyMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/EchoRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/EchoRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..1d01226d71d93bf92458e43b1bea662b31ee19c5 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/EchoRequestMessage.java @@ -0,0 +1,323 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class EchoRequestMessage implements org.apache.thrift.TBase<EchoRequestMessage, EchoRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("EchoRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + public AsyncMessageHeader header; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(EchoRequestMessage.class, metaDataMap); + } + + public EchoRequestMessage() { + } + + public EchoRequestMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public EchoRequestMessage(EchoRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + } + + public EchoRequestMessage deepCopy() { + return new EchoRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public EchoRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof EchoRequestMessage) + return this.equals((EchoRequestMessage)that); + return false; + } + + public boolean equals(EchoRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(EchoRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + EchoRequestMessage typedOther = (EchoRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("EchoRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/ErrorMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/ErrorMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..451afa192b7063fcd627731c54580d077f3c373e --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/ErrorMessage.java @@ -0,0 +1,522 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class ErrorMessage implements org.apache.thrift.TBase<ErrorMessage, ErrorMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ErrorMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField ERROR_FIELD_DESC = new org.apache.thrift.protocol.TField("error", org.apache.thrift.protocol.TType.STRUCT, (short)2); + private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)3); + + public AsyncMessageHeader header; // required + public SyncError error; // required + /** + * + * @see MessageType + */ + public MessageType type; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + ERROR((short)2, "error"), + /** + * + * @see MessageType + */ + TYPE((short)3, "type"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // ERROR + return ERROR; + case 3: // TYPE + return TYPE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.ERROR, new org.apache.thrift.meta_data.FieldMetaData("error", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SyncError.class))); + tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, MessageType.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ErrorMessage.class, metaDataMap); + } + + public ErrorMessage() { + } + + public ErrorMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public ErrorMessage(ErrorMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetError()) { + this.error = new SyncError(other.error); + } + if (other.isSetType()) { + this.type = other.type; + } + } + + public ErrorMessage deepCopy() { + return new ErrorMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.error = null; + this.type = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public ErrorMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public SyncError getError() { + return this.error; + } + + public ErrorMessage setError(SyncError error) { + this.error = error; + return this; + } + + public void unsetError() { + this.error = null; + } + + /** Returns true if field error is set (has been assigned a value) and false otherwise */ + public boolean isSetError() { + return this.error != null; + } + + public void setErrorIsSet(boolean value) { + if (!value) { + this.error = null; + } + } + + /** + * + * @see MessageType + */ + public MessageType getType() { + return this.type; + } + + /** + * + * @see MessageType + */ + public ErrorMessage setType(MessageType type) { + this.type = type; + return this; + } + + public void unsetType() { + this.type = null; + } + + /** Returns true if field type is set (has been assigned a value) and false otherwise */ + public boolean isSetType() { + return this.type != null; + } + + public void setTypeIsSet(boolean value) { + if (!value) { + this.type = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case ERROR: + if (value == null) { + unsetError(); + } else { + setError((SyncError)value); + } + break; + + case TYPE: + if (value == null) { + unsetType(); + } else { + setType((MessageType)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case ERROR: + return getError(); + + case TYPE: + return getType(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case ERROR: + return isSetError(); + case TYPE: + return isSetType(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof ErrorMessage) + return this.equals((ErrorMessage)that); + return false; + } + + public boolean equals(ErrorMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_error = true && this.isSetError(); + boolean that_present_error = true && that.isSetError(); + if (this_present_error || that_present_error) { + if (!(this_present_error && that_present_error)) + return false; + if (!this.error.equals(that.error)) + return false; + } + + boolean this_present_type = true && this.isSetType(); + boolean that_present_type = true && that.isSetType(); + if (this_present_type || that_present_type) { + if (!(this_present_type && that_present_type)) + return false; + if (!this.type.equals(that.type)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(ErrorMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + ErrorMessage typedOther = (ErrorMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetError()).compareTo(typedOther.isSetError()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetError()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.error, typedOther.error); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetType()).compareTo(typedOther.isSetType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, typedOther.type); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // ERROR + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.error = new SyncError(); + this.error.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // TYPE + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.type = MessageType.findByValue(iprot.readI32()); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.error != null) { + if (isSetError()) { + oprot.writeFieldBegin(ERROR_FIELD_DESC); + this.error.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.type != null) { + if (isSetType()) { + oprot.writeFieldBegin(TYPE_FIELD_DESC); + oprot.writeI32(this.type.getValue()); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("ErrorMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (isSetError()) { + if (!first) sb.append(", "); + sb.append("error:"); + if (this.error == null) { + sb.append("null"); + } else { + sb.append(this.error); + } + first = false; + } + if (isSetType()) { + if (!first) sb.append(", "); + sb.append("type:"); + if (this.type == null) { + sb.append("null"); + } else { + sb.append(this.type); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/FullSyncRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/FullSyncRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..20afd157e5bcccddaba97be407129f7f9aa3f91f --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/FullSyncRequestMessage.java @@ -0,0 +1,323 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class FullSyncRequestMessage implements org.apache.thrift.TBase<FullSyncRequestMessage, FullSyncRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("FullSyncRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + public AsyncMessageHeader header; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(FullSyncRequestMessage.class, metaDataMap); + } + + public FullSyncRequestMessage() { + } + + public FullSyncRequestMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public FullSyncRequestMessage(FullSyncRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + } + + public FullSyncRequestMessage deepCopy() { + return new FullSyncRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public FullSyncRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof FullSyncRequestMessage) + return this.equals((FullSyncRequestMessage)that); + return false; + } + + public boolean equals(FullSyncRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(FullSyncRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + FullSyncRequestMessage typedOther = (FullSyncRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("FullSyncRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/GetRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/GetRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..83e91ebc9812de13a0768d3cf594107694b98839 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/GetRequestMessage.java @@ -0,0 +1,518 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class GetRequestMessage implements org.apache.thrift.TBase<GetRequestMessage, GetRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("GetRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("storeName", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)3); + + public AsyncMessageHeader header; // required + public String storeName; // required + public ByteBuffer key; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE_NAME((short)2, "storeName"), + KEY((short)3, "key"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE_NAME + return STORE_NAME; + case 3: // KEY + return KEY; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE_NAME, new org.apache.thrift.meta_data.FieldMetaData("storeName", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(GetRequestMessage.class, metaDataMap); + } + + public GetRequestMessage() { + } + + public GetRequestMessage( + AsyncMessageHeader header, + String storeName, + ByteBuffer key) + { + this(); + this.header = header; + this.storeName = storeName; + this.key = key; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public GetRequestMessage(GetRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStoreName()) { + this.storeName = other.storeName; + } + if (other.isSetKey()) { + this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key); +; + } + } + + public GetRequestMessage deepCopy() { + return new GetRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.storeName = null; + this.key = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public GetRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public String getStoreName() { + return this.storeName; + } + + public GetRequestMessage setStoreName(String storeName) { + this.storeName = storeName; + return this; + } + + public void unsetStoreName() { + this.storeName = null; + } + + /** Returns true if field storeName is set (has been assigned a value) and false otherwise */ + public boolean isSetStoreName() { + return this.storeName != null; + } + + public void setStoreNameIsSet(boolean value) { + if (!value) { + this.storeName = null; + } + } + + public byte[] getKey() { + setKey(org.apache.thrift.TBaseHelper.rightSize(key)); + return key == null ? null : key.array(); + } + + public ByteBuffer bufferForKey() { + return key; + } + + public GetRequestMessage setKey(byte[] key) { + setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key)); + return this; + } + + public GetRequestMessage setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been assigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE_NAME: + if (value == null) { + unsetStoreName(); + } else { + setStoreName((String)value); + } + break; + + case KEY: + if (value == null) { + unsetKey(); + } else { + setKey((ByteBuffer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE_NAME: + return getStoreName(); + + case KEY: + return getKey(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE_NAME: + return isSetStoreName(); + case KEY: + return isSetKey(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof GetRequestMessage) + return this.equals((GetRequestMessage)that); + return false; + } + + public boolean equals(GetRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_storeName = true && this.isSetStoreName(); + boolean that_present_storeName = true && that.isSetStoreName(); + if (this_present_storeName || that_present_storeName) { + if (!(this_present_storeName && that_present_storeName)) + return false; + if (!this.storeName.equals(that.storeName)) + return false; + } + + boolean this_present_key = true && this.isSetKey(); + boolean that_present_key = true && that.isSetKey(); + if (this_present_key || that_present_key) { + if (!(this_present_key && that_present_key)) + return false; + if (!this.key.equals(that.key)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(GetRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + GetRequestMessage typedOther = (GetRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStoreName()).compareTo(typedOther.isSetStoreName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStoreName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeName, typedOther.storeName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE_NAME + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.storeName = iprot.readString(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // KEY + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.key = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.storeName != null) { + oprot.writeFieldBegin(STORE_NAME_FIELD_DESC); + oprot.writeString(this.storeName); + oprot.writeFieldEnd(); + } + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("GetRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("storeName:"); + if (this.storeName == null) { + sb.append("null"); + } else { + sb.append(this.storeName); + } + first = false; + if (!first) sb.append(", "); + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.key, sb); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (storeName == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'storeName' was not present! Struct: " + toString()); + } + if (key == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/GetResponseMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/GetResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..5bfe48dbdcaa85ee1ad6d89b955c84481376c437 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/GetResponseMessage.java @@ -0,0 +1,542 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class GetResponseMessage implements org.apache.thrift.TBase<GetResponseMessage, GetResponseMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("GetResponseMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("values", org.apache.thrift.protocol.TType.LIST, (short)2); + private static final org.apache.thrift.protocol.TField ERROR_FIELD_DESC = new org.apache.thrift.protocol.TField("error", org.apache.thrift.protocol.TType.STRUCT, (short)3); + + public AsyncMessageHeader header; // required + public List<VersionedValue> values; // required + public SyncError error; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + VALUES((short)2, "values"), + ERROR((short)3, "error"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // VALUES + return VALUES; + case 3: // ERROR + return ERROR; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.VALUES, new org.apache.thrift.meta_data.FieldMetaData("values", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, VersionedValue.class)))); + tmpMap.put(_Fields.ERROR, new org.apache.thrift.meta_data.FieldMetaData("error", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SyncError.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(GetResponseMessage.class, metaDataMap); + } + + public GetResponseMessage() { + } + + public GetResponseMessage( + AsyncMessageHeader header, + List<VersionedValue> values) + { + this(); + this.header = header; + this.values = values; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public GetResponseMessage(GetResponseMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetValues()) { + List<VersionedValue> __this__values = new ArrayList<VersionedValue>(); + for (VersionedValue other_element : other.values) { + __this__values.add(new VersionedValue(other_element)); + } + this.values = __this__values; + } + if (other.isSetError()) { + this.error = new SyncError(other.error); + } + } + + public GetResponseMessage deepCopy() { + return new GetResponseMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.values = null; + this.error = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public GetResponseMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public int getValuesSize() { + return (this.values == null) ? 0 : this.values.size(); + } + + public java.util.Iterator<VersionedValue> getValuesIterator() { + return (this.values == null) ? null : this.values.iterator(); + } + + public void addToValues(VersionedValue elem) { + if (this.values == null) { + this.values = new ArrayList<VersionedValue>(); + } + this.values.add(elem); + } + + public List<VersionedValue> getValues() { + return this.values; + } + + public GetResponseMessage setValues(List<VersionedValue> values) { + this.values = values; + return this; + } + + public void unsetValues() { + this.values = null; + } + + /** Returns true if field values is set (has been assigned a value) and false otherwise */ + public boolean isSetValues() { + return this.values != null; + } + + public void setValuesIsSet(boolean value) { + if (!value) { + this.values = null; + } + } + + public SyncError getError() { + return this.error; + } + + public GetResponseMessage setError(SyncError error) { + this.error = error; + return this; + } + + public void unsetError() { + this.error = null; + } + + /** Returns true if field error is set (has been assigned a value) and false otherwise */ + public boolean isSetError() { + return this.error != null; + } + + public void setErrorIsSet(boolean value) { + if (!value) { + this.error = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case VALUES: + if (value == null) { + unsetValues(); + } else { + setValues((List<VersionedValue>)value); + } + break; + + case ERROR: + if (value == null) { + unsetError(); + } else { + setError((SyncError)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case VALUES: + return getValues(); + + case ERROR: + return getError(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case VALUES: + return isSetValues(); + case ERROR: + return isSetError(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof GetResponseMessage) + return this.equals((GetResponseMessage)that); + return false; + } + + public boolean equals(GetResponseMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_values = true && this.isSetValues(); + boolean that_present_values = true && that.isSetValues(); + if (this_present_values || that_present_values) { + if (!(this_present_values && that_present_values)) + return false; + if (!this.values.equals(that.values)) + return false; + } + + boolean this_present_error = true && this.isSetError(); + boolean that_present_error = true && that.isSetError(); + if (this_present_error || that_present_error) { + if (!(this_present_error && that_present_error)) + return false; + if (!this.error.equals(that.error)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(GetResponseMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + GetResponseMessage typedOther = (GetResponseMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValues()).compareTo(typedOther.isSetValues()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValues()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.values, typedOther.values); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetError()).compareTo(typedOther.isSetError()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetError()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.error, typedOther.error); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // VALUES + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list12 = iprot.readListBegin(); + this.values = new ArrayList<VersionedValue>(_list12.size); + for (int _i13 = 0; _i13 < _list12.size; ++_i13) + { + VersionedValue _elem14; // required + _elem14 = new VersionedValue(); + _elem14.read(iprot); + this.values.add(_elem14); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // ERROR + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.error = new SyncError(); + this.error.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.values != null) { + oprot.writeFieldBegin(VALUES_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.values.size())); + for (VersionedValue _iter15 : this.values) + { + _iter15.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + if (this.error != null) { + if (isSetError()) { + oprot.writeFieldBegin(ERROR_FIELD_DESC); + this.error.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("GetResponseMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("values:"); + if (this.values == null) { + sb.append("null"); + } else { + sb.append(this.values); + } + first = false; + if (isSetError()) { + if (!first) sb.append(", "); + sb.append("error:"); + if (this.error == null) { + sb.append("null"); + } else { + sb.append(this.error); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/HelloMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/HelloMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..a18bc0c8c73344d3f38992b0bb8489b320311f95 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/HelloMessage.java @@ -0,0 +1,413 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class HelloMessage implements org.apache.thrift.TBase<HelloMessage, HelloMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("HelloMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField NODE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("nodeId", org.apache.thrift.protocol.TType.I16, (short)2); + + public AsyncMessageHeader header; // required + public short nodeId; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + NODE_ID((short)2, "nodeId"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // NODE_ID + return NODE_ID; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __NODEID_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.NODE_ID, new org.apache.thrift.meta_data.FieldMetaData("nodeId", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(HelloMessage.class, metaDataMap); + } + + public HelloMessage() { + } + + public HelloMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public HelloMessage(HelloMessage other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + this.nodeId = other.nodeId; + } + + public HelloMessage deepCopy() { + return new HelloMessage(this); + } + + @Override + public void clear() { + this.header = null; + setNodeIdIsSet(false); + this.nodeId = 0; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public HelloMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public short getNodeId() { + return this.nodeId; + } + + public HelloMessage setNodeId(short nodeId) { + this.nodeId = nodeId; + setNodeIdIsSet(true); + return this; + } + + public void unsetNodeId() { + __isset_bit_vector.clear(__NODEID_ISSET_ID); + } + + /** Returns true if field nodeId is set (has been assigned a value) and false otherwise */ + public boolean isSetNodeId() { + return __isset_bit_vector.get(__NODEID_ISSET_ID); + } + + public void setNodeIdIsSet(boolean value) { + __isset_bit_vector.set(__NODEID_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case NODE_ID: + if (value == null) { + unsetNodeId(); + } else { + setNodeId((Short)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case NODE_ID: + return Short.valueOf(getNodeId()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case NODE_ID: + return isSetNodeId(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof HelloMessage) + return this.equals((HelloMessage)that); + return false; + } + + public boolean equals(HelloMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_nodeId = true && this.isSetNodeId(); + boolean that_present_nodeId = true && that.isSetNodeId(); + if (this_present_nodeId || that_present_nodeId) { + if (!(this_present_nodeId && that_present_nodeId)) + return false; + if (this.nodeId != that.nodeId) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(HelloMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + HelloMessage typedOther = (HelloMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetNodeId()).compareTo(typedOther.isSetNodeId()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetNodeId()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nodeId, typedOther.nodeId); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // NODE_ID + if (field.type == org.apache.thrift.protocol.TType.I16) { + this.nodeId = iprot.readI16(); + setNodeIdIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (isSetNodeId()) { + oprot.writeFieldBegin(NODE_ID_FIELD_DESC); + oprot.writeI16(this.nodeId); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("HelloMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (isSetNodeId()) { + if (!first) sb.append(", "); + sb.append("nodeId:"); + sb.append(this.nodeId); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/KeyedValues.java b/lib/gen-java/org/sdnplatform/sync/thrift/KeyedValues.java new file mode 100644 index 0000000000000000000000000000000000000000..a286c55fcbb1252ddf21b862d1158e716184b1e2 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/KeyedValues.java @@ -0,0 +1,463 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class KeyedValues implements org.apache.thrift.TBase<KeyedValues, KeyedValues._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyedValues"); + + private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("values", org.apache.thrift.protocol.TType.LIST, (short)2); + + public ByteBuffer key; // required + public List<VersionedValue> values; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + KEY((short)1, "key"), + VALUES((short)2, "values"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // KEY + return KEY; + case 2: // VALUES + return VALUES; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.VALUES, new org.apache.thrift.meta_data.FieldMetaData("values", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, VersionedValue.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(KeyedValues.class, metaDataMap); + } + + public KeyedValues() { + } + + public KeyedValues( + ByteBuffer key, + List<VersionedValue> values) + { + this(); + this.key = key; + this.values = values; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public KeyedValues(KeyedValues other) { + if (other.isSetKey()) { + this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetValues()) { + List<VersionedValue> __this__values = new ArrayList<VersionedValue>(); + for (VersionedValue other_element : other.values) { + __this__values.add(new VersionedValue(other_element)); + } + this.values = __this__values; + } + } + + public KeyedValues deepCopy() { + return new KeyedValues(this); + } + + @Override + public void clear() { + this.key = null; + this.values = null; + } + + public byte[] getKey() { + setKey(org.apache.thrift.TBaseHelper.rightSize(key)); + return key == null ? null : key.array(); + } + + public ByteBuffer bufferForKey() { + return key; + } + + public KeyedValues setKey(byte[] key) { + setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key)); + return this; + } + + public KeyedValues setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been assigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public int getValuesSize() { + return (this.values == null) ? 0 : this.values.size(); + } + + public java.util.Iterator<VersionedValue> getValuesIterator() { + return (this.values == null) ? null : this.values.iterator(); + } + + public void addToValues(VersionedValue elem) { + if (this.values == null) { + this.values = new ArrayList<VersionedValue>(); + } + this.values.add(elem); + } + + public List<VersionedValue> getValues() { + return this.values; + } + + public KeyedValues setValues(List<VersionedValue> values) { + this.values = values; + return this; + } + + public void unsetValues() { + this.values = null; + } + + /** Returns true if field values is set (has been assigned a value) and false otherwise */ + public boolean isSetValues() { + return this.values != null; + } + + public void setValuesIsSet(boolean value) { + if (!value) { + this.values = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case KEY: + if (value == null) { + unsetKey(); + } else { + setKey((ByteBuffer)value); + } + break; + + case VALUES: + if (value == null) { + unsetValues(); + } else { + setValues((List<VersionedValue>)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case KEY: + return getKey(); + + case VALUES: + return getValues(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case KEY: + return isSetKey(); + case VALUES: + return isSetValues(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof KeyedValues) + return this.equals((KeyedValues)that); + return false; + } + + public boolean equals(KeyedValues that) { + if (that == null) + return false; + + boolean this_present_key = true && this.isSetKey(); + boolean that_present_key = true && that.isSetKey(); + if (this_present_key || that_present_key) { + if (!(this_present_key && that_present_key)) + return false; + if (!this.key.equals(that.key)) + return false; + } + + boolean this_present_values = true && this.isSetValues(); + boolean that_present_values = true && that.isSetValues(); + if (this_present_values || that_present_values) { + if (!(this_present_values && that_present_values)) + return false; + if (!this.values.equals(that.values)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(KeyedValues other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + KeyedValues typedOther = (KeyedValues)other; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValues()).compareTo(typedOther.isSetValues()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValues()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.values, typedOther.values); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEY + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.key = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // VALUES + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list4 = iprot.readListBegin(); + this.values = new ArrayList<VersionedValue>(_list4.size); + for (int _i5 = 0; _i5 < _list4.size; ++_i5) + { + VersionedValue _elem6; // required + _elem6 = new VersionedValue(); + _elem6.read(iprot); + this.values.add(_elem6); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.values != null) { + oprot.writeFieldBegin(VALUES_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.values.size())); + for (VersionedValue _iter7 : this.values) + { + _iter7.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("KeyedValues("); + boolean first = true; + + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.key, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("values:"); + if (this.values == null) { + sb.append("null"); + } else { + sb.append(this.values); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (key == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + if (values == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'values' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/KeyedVersions.java b/lib/gen-java/org/sdnplatform/sync/thrift/KeyedVersions.java new file mode 100644 index 0000000000000000000000000000000000000000..ee153a4cda4e058b3dcaa65ea71bb80753d0ad72 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/KeyedVersions.java @@ -0,0 +1,463 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class KeyedVersions implements org.apache.thrift.TBase<KeyedVersions, KeyedVersions._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyedVersions"); + + private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField VERSIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("versions", org.apache.thrift.protocol.TType.LIST, (short)2); + + public ByteBuffer key; // required + public List<VectorClock> versions; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + KEY((short)1, "key"), + VERSIONS((short)2, "versions"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // KEY + return KEY; + case 2: // VERSIONS + return VERSIONS; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.VERSIONS, new org.apache.thrift.meta_data.FieldMetaData("versions", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, VectorClock.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(KeyedVersions.class, metaDataMap); + } + + public KeyedVersions() { + } + + public KeyedVersions( + ByteBuffer key, + List<VectorClock> versions) + { + this(); + this.key = key; + this.versions = versions; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public KeyedVersions(KeyedVersions other) { + if (other.isSetKey()) { + this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetVersions()) { + List<VectorClock> __this__versions = new ArrayList<VectorClock>(); + for (VectorClock other_element : other.versions) { + __this__versions.add(new VectorClock(other_element)); + } + this.versions = __this__versions; + } + } + + public KeyedVersions deepCopy() { + return new KeyedVersions(this); + } + + @Override + public void clear() { + this.key = null; + this.versions = null; + } + + public byte[] getKey() { + setKey(org.apache.thrift.TBaseHelper.rightSize(key)); + return key == null ? null : key.array(); + } + + public ByteBuffer bufferForKey() { + return key; + } + + public KeyedVersions setKey(byte[] key) { + setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key)); + return this; + } + + public KeyedVersions setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been assigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public int getVersionsSize() { + return (this.versions == null) ? 0 : this.versions.size(); + } + + public java.util.Iterator<VectorClock> getVersionsIterator() { + return (this.versions == null) ? null : this.versions.iterator(); + } + + public void addToVersions(VectorClock elem) { + if (this.versions == null) { + this.versions = new ArrayList<VectorClock>(); + } + this.versions.add(elem); + } + + public List<VectorClock> getVersions() { + return this.versions; + } + + public KeyedVersions setVersions(List<VectorClock> versions) { + this.versions = versions; + return this; + } + + public void unsetVersions() { + this.versions = null; + } + + /** Returns true if field versions is set (has been assigned a value) and false otherwise */ + public boolean isSetVersions() { + return this.versions != null; + } + + public void setVersionsIsSet(boolean value) { + if (!value) { + this.versions = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case KEY: + if (value == null) { + unsetKey(); + } else { + setKey((ByteBuffer)value); + } + break; + + case VERSIONS: + if (value == null) { + unsetVersions(); + } else { + setVersions((List<VectorClock>)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case KEY: + return getKey(); + + case VERSIONS: + return getVersions(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case KEY: + return isSetKey(); + case VERSIONS: + return isSetVersions(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof KeyedVersions) + return this.equals((KeyedVersions)that); + return false; + } + + public boolean equals(KeyedVersions that) { + if (that == null) + return false; + + boolean this_present_key = true && this.isSetKey(); + boolean that_present_key = true && that.isSetKey(); + if (this_present_key || that_present_key) { + if (!(this_present_key && that_present_key)) + return false; + if (!this.key.equals(that.key)) + return false; + } + + boolean this_present_versions = true && this.isSetVersions(); + boolean that_present_versions = true && that.isSetVersions(); + if (this_present_versions || that_present_versions) { + if (!(this_present_versions && that_present_versions)) + return false; + if (!this.versions.equals(that.versions)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(KeyedVersions other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + KeyedVersions typedOther = (KeyedVersions)other; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersions()).compareTo(typedOther.isSetVersions()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersions()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versions, typedOther.versions); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEY + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.key = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // VERSIONS + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list8 = iprot.readListBegin(); + this.versions = new ArrayList<VectorClock>(_list8.size); + for (int _i9 = 0; _i9 < _list8.size; ++_i9) + { + VectorClock _elem10; // required + _elem10 = new VectorClock(); + _elem10.read(iprot); + this.versions.add(_elem10); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.versions != null) { + oprot.writeFieldBegin(VERSIONS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.versions.size())); + for (VectorClock _iter11 : this.versions) + { + _iter11.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("KeyedVersions("); + boolean first = true; + + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.key, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("versions:"); + if (this.versions == null) { + sb.append("null"); + } else { + sb.append(this.versions); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (key == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + if (versions == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'versions' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/MessageType.java b/lib/gen-java/org/sdnplatform/sync/thrift/MessageType.java new file mode 100644 index 0000000000000000000000000000000000000000..e39c860dd1c24053920826af82e78db6663d1d72 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/MessageType.java @@ -0,0 +1,95 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + + +import java.util.Map; +import java.util.HashMap; +import org.apache.thrift.TEnum; + +@SuppressWarnings("all") public enum MessageType implements org.apache.thrift.TEnum { + HELLO(1), + ERROR(2), + ECHO_REQUEST(3), + ECHO_REPLY(4), + GET_REQUEST(5), + GET_RESPONSE(6), + PUT_REQUEST(7), + PUT_RESPONSE(8), + DELETE_REQUEST(9), + DELETE_RESPONSE(10), + SYNC_VALUE(11), + SYNC_VALUE_RESPONSE(12), + SYNC_OFFER(13), + SYNC_REQUEST(14), + FULL_SYNC_REQUEST(15), + CURSOR_REQUEST(16), + CURSOR_RESPONSE(17), + REGISTER_REQUEST(18), + REGISTER_RESPONSE(19); + + private final int value; + + private MessageType(int value) { + this.value = value; + } + + /** + * Get the integer value of this enum value, as defined in the Thrift IDL. + */ + public int getValue() { + return value; + } + + /** + * Find a the enum type by its integer value, as defined in the Thrift IDL. + * @return null if the value is not found. + */ + public static MessageType findByValue(int value) { + switch (value) { + case 1: + return HELLO; + case 2: + return ERROR; + case 3: + return ECHO_REQUEST; + case 4: + return ECHO_REPLY; + case 5: + return GET_REQUEST; + case 6: + return GET_RESPONSE; + case 7: + return PUT_REQUEST; + case 8: + return PUT_RESPONSE; + case 9: + return DELETE_REQUEST; + case 10: + return DELETE_RESPONSE; + case 11: + return SYNC_VALUE; + case 12: + return SYNC_VALUE_RESPONSE; + case 13: + return SYNC_OFFER; + case 14: + return SYNC_REQUEST; + case 15: + return FULL_SYNC_REQUEST; + case 16: + return CURSOR_REQUEST; + case 17: + return CURSOR_RESPONSE; + case 18: + return REGISTER_REQUEST; + case 19: + return REGISTER_RESPONSE; + default: + return null; + } + } +} diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/PutRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/PutRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..c60e13e0ceff8b65f45f7e6f03cd07c719021072 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/PutRequestMessage.java @@ -0,0 +1,712 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class PutRequestMessage implements org.apache.thrift.TBase<PutRequestMessage, PutRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("PutRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("storeName", org.apache.thrift.protocol.TType.STRING, (short)2); + private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)3); + private static final org.apache.thrift.protocol.TField VERSIONED_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("versionedValue", org.apache.thrift.protocol.TType.STRUCT, (short)4); + private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)5); + + public AsyncMessageHeader header; // required + public String storeName; // required + public ByteBuffer key; // required + public VersionedValue versionedValue; // required + public ByteBuffer value; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE_NAME((short)2, "storeName"), + KEY((short)3, "key"), + VERSIONED_VALUE((short)4, "versionedValue"), + VALUE((short)5, "value"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE_NAME + return STORE_NAME; + case 3: // KEY + return KEY; + case 4: // VERSIONED_VALUE + return VERSIONED_VALUE; + case 5: // VALUE + return VALUE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE_NAME, new org.apache.thrift.meta_data.FieldMetaData("storeName", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.VERSIONED_VALUE, new org.apache.thrift.meta_data.FieldMetaData("versionedValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, VersionedValue.class))); + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(PutRequestMessage.class, metaDataMap); + } + + public PutRequestMessage() { + } + + public PutRequestMessage( + AsyncMessageHeader header, + String storeName, + ByteBuffer key) + { + this(); + this.header = header; + this.storeName = storeName; + this.key = key; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public PutRequestMessage(PutRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStoreName()) { + this.storeName = other.storeName; + } + if (other.isSetKey()) { + this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetVersionedValue()) { + this.versionedValue = new VersionedValue(other.versionedValue); + } + if (other.isSetValue()) { + this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value); +; + } + } + + public PutRequestMessage deepCopy() { + return new PutRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.storeName = null; + this.key = null; + this.versionedValue = null; + this.value = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public PutRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public String getStoreName() { + return this.storeName; + } + + public PutRequestMessage setStoreName(String storeName) { + this.storeName = storeName; + return this; + } + + public void unsetStoreName() { + this.storeName = null; + } + + /** Returns true if field storeName is set (has been assigned a value) and false otherwise */ + public boolean isSetStoreName() { + return this.storeName != null; + } + + public void setStoreNameIsSet(boolean value) { + if (!value) { + this.storeName = null; + } + } + + public byte[] getKey() { + setKey(org.apache.thrift.TBaseHelper.rightSize(key)); + return key == null ? null : key.array(); + } + + public ByteBuffer bufferForKey() { + return key; + } + + public PutRequestMessage setKey(byte[] key) { + setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key)); + return this; + } + + public PutRequestMessage setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been assigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public VersionedValue getVersionedValue() { + return this.versionedValue; + } + + public PutRequestMessage setVersionedValue(VersionedValue versionedValue) { + this.versionedValue = versionedValue; + return this; + } + + public void unsetVersionedValue() { + this.versionedValue = null; + } + + /** Returns true if field versionedValue is set (has been assigned a value) and false otherwise */ + public boolean isSetVersionedValue() { + return this.versionedValue != null; + } + + public void setVersionedValueIsSet(boolean value) { + if (!value) { + this.versionedValue = null; + } + } + + public byte[] getValue() { + setValue(org.apache.thrift.TBaseHelper.rightSize(value)); + return value == null ? null : value.array(); + } + + public ByteBuffer bufferForValue() { + return value; + } + + public PutRequestMessage setValue(byte[] value) { + setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value)); + return this; + } + + public PutRequestMessage setValue(ByteBuffer value) { + this.value = value; + return this; + } + + public void unsetValue() { + this.value = null; + } + + /** Returns true if field value is set (has been assigned a value) and false otherwise */ + public boolean isSetValue() { + return this.value != null; + } + + public void setValueIsSet(boolean value) { + if (!value) { + this.value = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE_NAME: + if (value == null) { + unsetStoreName(); + } else { + setStoreName((String)value); + } + break; + + case KEY: + if (value == null) { + unsetKey(); + } else { + setKey((ByteBuffer)value); + } + break; + + case VERSIONED_VALUE: + if (value == null) { + unsetVersionedValue(); + } else { + setVersionedValue((VersionedValue)value); + } + break; + + case VALUE: + if (value == null) { + unsetValue(); + } else { + setValue((ByteBuffer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE_NAME: + return getStoreName(); + + case KEY: + return getKey(); + + case VERSIONED_VALUE: + return getVersionedValue(); + + case VALUE: + return getValue(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE_NAME: + return isSetStoreName(); + case KEY: + return isSetKey(); + case VERSIONED_VALUE: + return isSetVersionedValue(); + case VALUE: + return isSetValue(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof PutRequestMessage) + return this.equals((PutRequestMessage)that); + return false; + } + + public boolean equals(PutRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_storeName = true && this.isSetStoreName(); + boolean that_present_storeName = true && that.isSetStoreName(); + if (this_present_storeName || that_present_storeName) { + if (!(this_present_storeName && that_present_storeName)) + return false; + if (!this.storeName.equals(that.storeName)) + return false; + } + + boolean this_present_key = true && this.isSetKey(); + boolean that_present_key = true && that.isSetKey(); + if (this_present_key || that_present_key) { + if (!(this_present_key && that_present_key)) + return false; + if (!this.key.equals(that.key)) + return false; + } + + boolean this_present_versionedValue = true && this.isSetVersionedValue(); + boolean that_present_versionedValue = true && that.isSetVersionedValue(); + if (this_present_versionedValue || that_present_versionedValue) { + if (!(this_present_versionedValue && that_present_versionedValue)) + return false; + if (!this.versionedValue.equals(that.versionedValue)) + return false; + } + + boolean this_present_value = true && this.isSetValue(); + boolean that_present_value = true && that.isSetValue(); + if (this_present_value || that_present_value) { + if (!(this_present_value && that_present_value)) + return false; + if (!this.value.equals(that.value)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(PutRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + PutRequestMessage typedOther = (PutRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStoreName()).compareTo(typedOther.isSetStoreName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStoreName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeName, typedOther.storeName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersionedValue()).compareTo(typedOther.isSetVersionedValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersionedValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versionedValue, typedOther.versionedValue); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValue()).compareTo(typedOther.isSetValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, typedOther.value); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE_NAME + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.storeName = iprot.readString(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // KEY + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.key = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // VERSIONED_VALUE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.versionedValue = new VersionedValue(); + this.versionedValue.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 5: // VALUE + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.value = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.storeName != null) { + oprot.writeFieldBegin(STORE_NAME_FIELD_DESC); + oprot.writeString(this.storeName); + oprot.writeFieldEnd(); + } + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.versionedValue != null) { + if (isSetVersionedValue()) { + oprot.writeFieldBegin(VERSIONED_VALUE_FIELD_DESC); + this.versionedValue.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.value != null) { + if (isSetValue()) { + oprot.writeFieldBegin(VALUE_FIELD_DESC); + oprot.writeBinary(this.value); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("PutRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("storeName:"); + if (this.storeName == null) { + sb.append("null"); + } else { + sb.append(this.storeName); + } + first = false; + if (!first) sb.append(", "); + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.key, sb); + } + first = false; + if (isSetVersionedValue()) { + if (!first) sb.append(", "); + sb.append("versionedValue:"); + if (this.versionedValue == null) { + sb.append("null"); + } else { + sb.append(this.versionedValue); + } + first = false; + } + if (isSetValue()) { + if (!first) sb.append(", "); + sb.append("value:"); + if (this.value == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.value, sb); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (storeName == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'storeName' was not present! Struct: " + toString()); + } + if (key == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/PutResponseMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/PutResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..01153eacf5caa1fe31fe4607151b3779f88a8067 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/PutResponseMessage.java @@ -0,0 +1,323 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class PutResponseMessage implements org.apache.thrift.TBase<PutResponseMessage, PutResponseMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("PutResponseMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + public AsyncMessageHeader header; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(PutResponseMessage.class, metaDataMap); + } + + public PutResponseMessage() { + } + + public PutResponseMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public PutResponseMessage(PutResponseMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + } + + public PutResponseMessage deepCopy() { + return new PutResponseMessage(this); + } + + @Override + public void clear() { + this.header = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public PutResponseMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof PutResponseMessage) + return this.equals((PutResponseMessage)that); + return false; + } + + public boolean equals(PutResponseMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(PutResponseMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + PutResponseMessage typedOther = (PutResponseMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("PutResponseMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/RegisterRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/RegisterRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..e87e460c92b7e6f7bcea90f0ed319a91853fe65d --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/RegisterRequestMessage.java @@ -0,0 +1,416 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class RegisterRequestMessage implements org.apache.thrift.TBase<RegisterRequestMessage, RegisterRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RegisterRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_FIELD_DESC = new org.apache.thrift.protocol.TField("store", org.apache.thrift.protocol.TType.STRUCT, (short)2); + + public AsyncMessageHeader header; // required + public Store store; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE((short)2, "store"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE + return STORE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE, new org.apache.thrift.meta_data.FieldMetaData("store", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Store.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RegisterRequestMessage.class, metaDataMap); + } + + public RegisterRequestMessage() { + } + + public RegisterRequestMessage( + AsyncMessageHeader header, + Store store) + { + this(); + this.header = header; + this.store = store; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public RegisterRequestMessage(RegisterRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStore()) { + this.store = new Store(other.store); + } + } + + public RegisterRequestMessage deepCopy() { + return new RegisterRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.store = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public RegisterRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public Store getStore() { + return this.store; + } + + public RegisterRequestMessage setStore(Store store) { + this.store = store; + return this; + } + + public void unsetStore() { + this.store = null; + } + + /** Returns true if field store is set (has been assigned a value) and false otherwise */ + public boolean isSetStore() { + return this.store != null; + } + + public void setStoreIsSet(boolean value) { + if (!value) { + this.store = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE: + if (value == null) { + unsetStore(); + } else { + setStore((Store)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE: + return getStore(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE: + return isSetStore(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof RegisterRequestMessage) + return this.equals((RegisterRequestMessage)that); + return false; + } + + public boolean equals(RegisterRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_store = true && this.isSetStore(); + boolean that_present_store = true && that.isSetStore(); + if (this_present_store || that_present_store) { + if (!(this_present_store && that_present_store)) + return false; + if (!this.store.equals(that.store)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(RegisterRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + RegisterRequestMessage typedOther = (RegisterRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStore()).compareTo(typedOther.isSetStore()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStore()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.store, typedOther.store); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.store = new Store(); + this.store.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.store != null) { + oprot.writeFieldBegin(STORE_FIELD_DESC); + this.store.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("RegisterRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("store:"); + if (this.store == null) { + sb.append("null"); + } else { + sb.append(this.store); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (store == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'store' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/RegisterResponseMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/RegisterResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..613a4d56882be16592577d01f66dedc01e7d6cc1 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/RegisterResponseMessage.java @@ -0,0 +1,323 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class RegisterResponseMessage implements org.apache.thrift.TBase<RegisterResponseMessage, RegisterResponseMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RegisterResponseMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + public AsyncMessageHeader header; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RegisterResponseMessage.class, metaDataMap); + } + + public RegisterResponseMessage() { + } + + public RegisterResponseMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public RegisterResponseMessage(RegisterResponseMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + } + + public RegisterResponseMessage deepCopy() { + return new RegisterResponseMessage(this); + } + + @Override + public void clear() { + this.header = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public RegisterResponseMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof RegisterResponseMessage) + return this.equals((RegisterResponseMessage)that); + return false; + } + + public boolean equals(RegisterResponseMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(RegisterResponseMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + RegisterResponseMessage typedOther = (RegisterResponseMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("RegisterResponseMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/Scope.java b/lib/gen-java/org/sdnplatform/sync/thrift/Scope.java new file mode 100644 index 0000000000000000000000000000000000000000..a310deda54287e32b90fc2af038d3449c40655bd --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/Scope.java @@ -0,0 +1,44 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + + +import java.util.Map; +import java.util.HashMap; +import org.apache.thrift.TEnum; + +@SuppressWarnings("all") public enum Scope implements org.apache.thrift.TEnum { + GLOBAL(0), + LOCAL(1); + + private final int value; + + private Scope(int value) { + this.value = value; + } + + /** + * Get the integer value of this enum value, as defined in the Thrift IDL. + */ + public int getValue() { + return value; + } + + /** + * Find a the enum type by its integer value, as defined in the Thrift IDL. + * @return null if the value is not found. + */ + public static Scope findByValue(int value) { + switch (value) { + case 0: + return GLOBAL; + case 1: + return LOCAL; + default: + return null; + } + } +} diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/Store.java b/lib/gen-java/org/sdnplatform/sync/thrift/Store.java new file mode 100644 index 0000000000000000000000000000000000000000..453aeb071f72f2e74377c19a44497b21d04ee262 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/Store.java @@ -0,0 +1,519 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class Store implements org.apache.thrift.TBase<Store, Store._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Store"); + + private static final org.apache.thrift.protocol.TField STORE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("storeName", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField SCOPE_FIELD_DESC = new org.apache.thrift.protocol.TField("scope", org.apache.thrift.protocol.TType.I32, (short)2); + private static final org.apache.thrift.protocol.TField PERSIST_FIELD_DESC = new org.apache.thrift.protocol.TField("persist", org.apache.thrift.protocol.TType.BOOL, (short)3); + + public String storeName; // required + /** + * + * @see Scope + */ + public Scope scope; // required + public boolean persist; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + STORE_NAME((short)1, "storeName"), + /** + * + * @see Scope + */ + SCOPE((short)2, "scope"), + PERSIST((short)3, "persist"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // STORE_NAME + return STORE_NAME; + case 2: // SCOPE + return SCOPE; + case 3: // PERSIST + return PERSIST; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __PERSIST_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.STORE_NAME, new org.apache.thrift.meta_data.FieldMetaData("storeName", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.SCOPE, new org.apache.thrift.meta_data.FieldMetaData("scope", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Scope.class))); + tmpMap.put(_Fields.PERSIST, new org.apache.thrift.meta_data.FieldMetaData("persist", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Store.class, metaDataMap); + } + + public Store() { + } + + public Store( + String storeName) + { + this(); + this.storeName = storeName; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public Store(Store other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetStoreName()) { + this.storeName = other.storeName; + } + if (other.isSetScope()) { + this.scope = other.scope; + } + this.persist = other.persist; + } + + public Store deepCopy() { + return new Store(this); + } + + @Override + public void clear() { + this.storeName = null; + this.scope = null; + setPersistIsSet(false); + this.persist = false; + } + + public String getStoreName() { + return this.storeName; + } + + public Store setStoreName(String storeName) { + this.storeName = storeName; + return this; + } + + public void unsetStoreName() { + this.storeName = null; + } + + /** Returns true if field storeName is set (has been assigned a value) and false otherwise */ + public boolean isSetStoreName() { + return this.storeName != null; + } + + public void setStoreNameIsSet(boolean value) { + if (!value) { + this.storeName = null; + } + } + + /** + * + * @see Scope + */ + public Scope getScope() { + return this.scope; + } + + /** + * + * @see Scope + */ + public Store setScope(Scope scope) { + this.scope = scope; + return this; + } + + public void unsetScope() { + this.scope = null; + } + + /** Returns true if field scope is set (has been assigned a value) and false otherwise */ + public boolean isSetScope() { + return this.scope != null; + } + + public void setScopeIsSet(boolean value) { + if (!value) { + this.scope = null; + } + } + + public boolean isPersist() { + return this.persist; + } + + public Store setPersist(boolean persist) { + this.persist = persist; + setPersistIsSet(true); + return this; + } + + public void unsetPersist() { + __isset_bit_vector.clear(__PERSIST_ISSET_ID); + } + + /** Returns true if field persist is set (has been assigned a value) and false otherwise */ + public boolean isSetPersist() { + return __isset_bit_vector.get(__PERSIST_ISSET_ID); + } + + public void setPersistIsSet(boolean value) { + __isset_bit_vector.set(__PERSIST_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case STORE_NAME: + if (value == null) { + unsetStoreName(); + } else { + setStoreName((String)value); + } + break; + + case SCOPE: + if (value == null) { + unsetScope(); + } else { + setScope((Scope)value); + } + break; + + case PERSIST: + if (value == null) { + unsetPersist(); + } else { + setPersist((Boolean)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case STORE_NAME: + return getStoreName(); + + case SCOPE: + return getScope(); + + case PERSIST: + return Boolean.valueOf(isPersist()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case STORE_NAME: + return isSetStoreName(); + case SCOPE: + return isSetScope(); + case PERSIST: + return isSetPersist(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof Store) + return this.equals((Store)that); + return false; + } + + public boolean equals(Store that) { + if (that == null) + return false; + + boolean this_present_storeName = true && this.isSetStoreName(); + boolean that_present_storeName = true && that.isSetStoreName(); + if (this_present_storeName || that_present_storeName) { + if (!(this_present_storeName && that_present_storeName)) + return false; + if (!this.storeName.equals(that.storeName)) + return false; + } + + boolean this_present_scope = true && this.isSetScope(); + boolean that_present_scope = true && that.isSetScope(); + if (this_present_scope || that_present_scope) { + if (!(this_present_scope && that_present_scope)) + return false; + if (!this.scope.equals(that.scope)) + return false; + } + + boolean this_present_persist = true && this.isSetPersist(); + boolean that_present_persist = true && that.isSetPersist(); + if (this_present_persist || that_present_persist) { + if (!(this_present_persist && that_present_persist)) + return false; + if (this.persist != that.persist) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(Store other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + Store typedOther = (Store)other; + + lastComparison = Boolean.valueOf(isSetStoreName()).compareTo(typedOther.isSetStoreName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStoreName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.storeName, typedOther.storeName); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetScope()).compareTo(typedOther.isSetScope()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetScope()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.scope, typedOther.scope); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPersist()).compareTo(typedOther.isSetPersist()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPersist()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.persist, typedOther.persist); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // STORE_NAME + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.storeName = iprot.readString(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // SCOPE + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.scope = Scope.findByValue(iprot.readI32()); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // PERSIST + if (field.type == org.apache.thrift.protocol.TType.BOOL) { + this.persist = iprot.readBool(); + setPersistIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.storeName != null) { + oprot.writeFieldBegin(STORE_NAME_FIELD_DESC); + oprot.writeString(this.storeName); + oprot.writeFieldEnd(); + } + if (this.scope != null) { + if (isSetScope()) { + oprot.writeFieldBegin(SCOPE_FIELD_DESC); + oprot.writeI32(this.scope.getValue()); + oprot.writeFieldEnd(); + } + } + if (isSetPersist()) { + oprot.writeFieldBegin(PERSIST_FIELD_DESC); + oprot.writeBool(this.persist); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Store("); + boolean first = true; + + sb.append("storeName:"); + if (this.storeName == null) { + sb.append("null"); + } else { + sb.append(this.storeName); + } + first = false; + if (isSetScope()) { + if (!first) sb.append(", "); + sb.append("scope:"); + if (this.scope == null) { + sb.append("null"); + } else { + sb.append(this.scope); + } + first = false; + } + if (isSetPersist()) { + if (!first) sb.append(", "); + sb.append("persist:"); + sb.append(this.persist); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (storeName == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'storeName' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncError.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncError.java new file mode 100644 index 0000000000000000000000000000000000000000..aebf77603423990e8c6d17f4dc004b3a4b9749f3 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncError.java @@ -0,0 +1,408 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncError implements org.apache.thrift.TBase<SyncError, SyncError._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncError"); + + private static final org.apache.thrift.protocol.TField ERROR_CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("errorCode", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)2); + + public int errorCode; // required + public String message; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + ERROR_CODE((short)1, "errorCode"), + MESSAGE((short)2, "message"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // ERROR_CODE + return ERROR_CODE; + case 2: // MESSAGE + return MESSAGE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __ERRORCODE_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.ERROR_CODE, new org.apache.thrift.meta_data.FieldMetaData("errorCode", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncError.class, metaDataMap); + } + + public SyncError() { + } + + public SyncError( + int errorCode, + String message) + { + this(); + this.errorCode = errorCode; + setErrorCodeIsSet(true); + this.message = message; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncError(SyncError other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + this.errorCode = other.errorCode; + if (other.isSetMessage()) { + this.message = other.message; + } + } + + public SyncError deepCopy() { + return new SyncError(this); + } + + @Override + public void clear() { + setErrorCodeIsSet(false); + this.errorCode = 0; + this.message = null; + } + + public int getErrorCode() { + return this.errorCode; + } + + public SyncError setErrorCode(int errorCode) { + this.errorCode = errorCode; + setErrorCodeIsSet(true); + return this; + } + + public void unsetErrorCode() { + __isset_bit_vector.clear(__ERRORCODE_ISSET_ID); + } + + /** Returns true if field errorCode is set (has been assigned a value) and false otherwise */ + public boolean isSetErrorCode() { + return __isset_bit_vector.get(__ERRORCODE_ISSET_ID); + } + + public void setErrorCodeIsSet(boolean value) { + __isset_bit_vector.set(__ERRORCODE_ISSET_ID, value); + } + + public String getMessage() { + return this.message; + } + + public SyncError setMessage(String message) { + this.message = message; + return this; + } + + public void unsetMessage() { + this.message = null; + } + + /** Returns true if field message is set (has been assigned a value) and false otherwise */ + public boolean isSetMessage() { + return this.message != null; + } + + public void setMessageIsSet(boolean value) { + if (!value) { + this.message = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case ERROR_CODE: + if (value == null) { + unsetErrorCode(); + } else { + setErrorCode((Integer)value); + } + break; + + case MESSAGE: + if (value == null) { + unsetMessage(); + } else { + setMessage((String)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case ERROR_CODE: + return Integer.valueOf(getErrorCode()); + + case MESSAGE: + return getMessage(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case ERROR_CODE: + return isSetErrorCode(); + case MESSAGE: + return isSetMessage(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncError) + return this.equals((SyncError)that); + return false; + } + + public boolean equals(SyncError that) { + if (that == null) + return false; + + boolean this_present_errorCode = true; + boolean that_present_errorCode = true; + if (this_present_errorCode || that_present_errorCode) { + if (!(this_present_errorCode && that_present_errorCode)) + return false; + if (this.errorCode != that.errorCode) + return false; + } + + boolean this_present_message = true && this.isSetMessage(); + boolean that_present_message = true && that.isSetMessage(); + if (this_present_message || that_present_message) { + if (!(this_present_message && that_present_message)) + return false; + if (!this.message.equals(that.message)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncError other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncError typedOther = (SyncError)other; + + lastComparison = Boolean.valueOf(isSetErrorCode()).compareTo(typedOther.isSetErrorCode()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetErrorCode()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.errorCode, typedOther.errorCode); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetMessage()).compareTo(typedOther.isSetMessage()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetMessage()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, typedOther.message); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // ERROR_CODE + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.errorCode = iprot.readI32(); + setErrorCodeIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // MESSAGE + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.message = iprot.readString(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + oprot.writeFieldBegin(ERROR_CODE_FIELD_DESC); + oprot.writeI32(this.errorCode); + oprot.writeFieldEnd(); + if (this.message != null) { + oprot.writeFieldBegin(MESSAGE_FIELD_DESC); + oprot.writeString(this.message); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncError("); + boolean first = true; + + sb.append("errorCode:"); + sb.append(this.errorCode); + first = false; + if (!first) sb.append(", "); + sb.append("message:"); + if (this.message == null) { + sb.append("null"); + } else { + sb.append(this.message); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..e068c82499103b095637fd534dc0a8f9b10cf9d2 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncMessage.java @@ -0,0 +1,2086 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncMessage implements org.apache.thrift.TBase<SyncMessage, SyncMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncMessage"); + + private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.I32, (short)1); + private static final org.apache.thrift.protocol.TField HELLO_FIELD_DESC = new org.apache.thrift.protocol.TField("hello", org.apache.thrift.protocol.TType.STRUCT, (short)2); + private static final org.apache.thrift.protocol.TField ERROR_FIELD_DESC = new org.apache.thrift.protocol.TField("error", org.apache.thrift.protocol.TType.STRUCT, (short)3); + private static final org.apache.thrift.protocol.TField ECHO_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("echoRequest", org.apache.thrift.protocol.TType.STRUCT, (short)4); + private static final org.apache.thrift.protocol.TField ECHO_REPLY_FIELD_DESC = new org.apache.thrift.protocol.TField("echoReply", org.apache.thrift.protocol.TType.STRUCT, (short)5); + private static final org.apache.thrift.protocol.TField GET_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("getRequest", org.apache.thrift.protocol.TType.STRUCT, (short)6); + private static final org.apache.thrift.protocol.TField GET_RESPONSE_FIELD_DESC = new org.apache.thrift.protocol.TField("getResponse", org.apache.thrift.protocol.TType.STRUCT, (short)7); + private static final org.apache.thrift.protocol.TField PUT_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("putRequest", org.apache.thrift.protocol.TType.STRUCT, (short)8); + private static final org.apache.thrift.protocol.TField PUT_RESPONSE_FIELD_DESC = new org.apache.thrift.protocol.TField("putResponse", org.apache.thrift.protocol.TType.STRUCT, (short)9); + private static final org.apache.thrift.protocol.TField DELETE_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("deleteRequest", org.apache.thrift.protocol.TType.STRUCT, (short)10); + private static final org.apache.thrift.protocol.TField DELETE_RESPONSE_FIELD_DESC = new org.apache.thrift.protocol.TField("deleteResponse", org.apache.thrift.protocol.TType.STRUCT, (short)11); + private static final org.apache.thrift.protocol.TField SYNC_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("syncValue", org.apache.thrift.protocol.TType.STRUCT, (short)12); + private static final org.apache.thrift.protocol.TField SYNC_VALUE_RESPONSE_FIELD_DESC = new org.apache.thrift.protocol.TField("syncValueResponse", org.apache.thrift.protocol.TType.STRUCT, (short)13); + private static final org.apache.thrift.protocol.TField SYNC_OFFER_FIELD_DESC = new org.apache.thrift.protocol.TField("syncOffer", org.apache.thrift.protocol.TType.STRUCT, (short)14); + private static final org.apache.thrift.protocol.TField SYNC_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("syncRequest", org.apache.thrift.protocol.TType.STRUCT, (short)15); + private static final org.apache.thrift.protocol.TField FULL_SYNC_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("fullSyncRequest", org.apache.thrift.protocol.TType.STRUCT, (short)16); + private static final org.apache.thrift.protocol.TField CURSOR_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("cursorRequest", org.apache.thrift.protocol.TType.STRUCT, (short)17); + private static final org.apache.thrift.protocol.TField CURSOR_RESPONSE_FIELD_DESC = new org.apache.thrift.protocol.TField("cursorResponse", org.apache.thrift.protocol.TType.STRUCT, (short)18); + private static final org.apache.thrift.protocol.TField REGISTER_REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("registerRequest", org.apache.thrift.protocol.TType.STRUCT, (short)19); + private static final org.apache.thrift.protocol.TField REGISTER_RESPONSE_FIELD_DESC = new org.apache.thrift.protocol.TField("registerResponse", org.apache.thrift.protocol.TType.STRUCT, (short)20); + + /** + * + * @see MessageType + */ + public MessageType type; // required + public HelloMessage hello; // required + public ErrorMessage error; // required + public EchoRequestMessage echoRequest; // required + public EchoReplyMessage echoReply; // required + public GetRequestMessage getRequest; // required + public GetResponseMessage getResponse; // required + public PutRequestMessage putRequest; // required + public PutResponseMessage putResponse; // required + public DeleteRequestMessage deleteRequest; // required + public DeleteResponseMessage deleteResponse; // required + public SyncValueMessage syncValue; // required + public SyncValueResponseMessage syncValueResponse; // required + public SyncOfferMessage syncOffer; // required + public SyncRequestMessage syncRequest; // required + public FullSyncRequestMessage fullSyncRequest; // required + public CursorRequestMessage cursorRequest; // required + public CursorResponseMessage cursorResponse; // required + public RegisterRequestMessage registerRequest; // required + public RegisterResponseMessage registerResponse; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + /** + * + * @see MessageType + */ + TYPE((short)1, "type"), + HELLO((short)2, "hello"), + ERROR((short)3, "error"), + ECHO_REQUEST((short)4, "echoRequest"), + ECHO_REPLY((short)5, "echoReply"), + GET_REQUEST((short)6, "getRequest"), + GET_RESPONSE((short)7, "getResponse"), + PUT_REQUEST((short)8, "putRequest"), + PUT_RESPONSE((short)9, "putResponse"), + DELETE_REQUEST((short)10, "deleteRequest"), + DELETE_RESPONSE((short)11, "deleteResponse"), + SYNC_VALUE((short)12, "syncValue"), + SYNC_VALUE_RESPONSE((short)13, "syncValueResponse"), + SYNC_OFFER((short)14, "syncOffer"), + SYNC_REQUEST((short)15, "syncRequest"), + FULL_SYNC_REQUEST((short)16, "fullSyncRequest"), + CURSOR_REQUEST((short)17, "cursorRequest"), + CURSOR_RESPONSE((short)18, "cursorResponse"), + REGISTER_REQUEST((short)19, "registerRequest"), + REGISTER_RESPONSE((short)20, "registerResponse"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // TYPE + return TYPE; + case 2: // HELLO + return HELLO; + case 3: // ERROR + return ERROR; + case 4: // ECHO_REQUEST + return ECHO_REQUEST; + case 5: // ECHO_REPLY + return ECHO_REPLY; + case 6: // GET_REQUEST + return GET_REQUEST; + case 7: // GET_RESPONSE + return GET_RESPONSE; + case 8: // PUT_REQUEST + return PUT_REQUEST; + case 9: // PUT_RESPONSE + return PUT_RESPONSE; + case 10: // DELETE_REQUEST + return DELETE_REQUEST; + case 11: // DELETE_RESPONSE + return DELETE_RESPONSE; + case 12: // SYNC_VALUE + return SYNC_VALUE; + case 13: // SYNC_VALUE_RESPONSE + return SYNC_VALUE_RESPONSE; + case 14: // SYNC_OFFER + return SYNC_OFFER; + case 15: // SYNC_REQUEST + return SYNC_REQUEST; + case 16: // FULL_SYNC_REQUEST + return FULL_SYNC_REQUEST; + case 17: // CURSOR_REQUEST + return CURSOR_REQUEST; + case 18: // CURSOR_RESPONSE + return CURSOR_RESPONSE; + case 19: // REGISTER_REQUEST + return REGISTER_REQUEST; + case 20: // REGISTER_RESPONSE + return REGISTER_RESPONSE; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, MessageType.class))); + tmpMap.put(_Fields.HELLO, new org.apache.thrift.meta_data.FieldMetaData("hello", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, HelloMessage.class))); + tmpMap.put(_Fields.ERROR, new org.apache.thrift.meta_data.FieldMetaData("error", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ErrorMessage.class))); + tmpMap.put(_Fields.ECHO_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("echoRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, EchoRequestMessage.class))); + tmpMap.put(_Fields.ECHO_REPLY, new org.apache.thrift.meta_data.FieldMetaData("echoReply", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, EchoReplyMessage.class))); + tmpMap.put(_Fields.GET_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("getRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, GetRequestMessage.class))); + tmpMap.put(_Fields.GET_RESPONSE, new org.apache.thrift.meta_data.FieldMetaData("getResponse", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, GetResponseMessage.class))); + tmpMap.put(_Fields.PUT_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("putRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, PutRequestMessage.class))); + tmpMap.put(_Fields.PUT_RESPONSE, new org.apache.thrift.meta_data.FieldMetaData("putResponse", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, PutResponseMessage.class))); + tmpMap.put(_Fields.DELETE_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("deleteRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, DeleteRequestMessage.class))); + tmpMap.put(_Fields.DELETE_RESPONSE, new org.apache.thrift.meta_data.FieldMetaData("deleteResponse", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, DeleteResponseMessage.class))); + tmpMap.put(_Fields.SYNC_VALUE, new org.apache.thrift.meta_data.FieldMetaData("syncValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SyncValueMessage.class))); + tmpMap.put(_Fields.SYNC_VALUE_RESPONSE, new org.apache.thrift.meta_data.FieldMetaData("syncValueResponse", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SyncValueResponseMessage.class))); + tmpMap.put(_Fields.SYNC_OFFER, new org.apache.thrift.meta_data.FieldMetaData("syncOffer", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SyncOfferMessage.class))); + tmpMap.put(_Fields.SYNC_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("syncRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SyncRequestMessage.class))); + tmpMap.put(_Fields.FULL_SYNC_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("fullSyncRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, FullSyncRequestMessage.class))); + tmpMap.put(_Fields.CURSOR_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("cursorRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CursorRequestMessage.class))); + tmpMap.put(_Fields.CURSOR_RESPONSE, new org.apache.thrift.meta_data.FieldMetaData("cursorResponse", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, CursorResponseMessage.class))); + tmpMap.put(_Fields.REGISTER_REQUEST, new org.apache.thrift.meta_data.FieldMetaData("registerRequest", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, RegisterRequestMessage.class))); + tmpMap.put(_Fields.REGISTER_RESPONSE, new org.apache.thrift.meta_data.FieldMetaData("registerResponse", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, RegisterResponseMessage.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncMessage.class, metaDataMap); + } + + public SyncMessage() { + } + + public SyncMessage( + MessageType type) + { + this(); + this.type = type; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncMessage(SyncMessage other) { + if (other.isSetType()) { + this.type = other.type; + } + if (other.isSetHello()) { + this.hello = new HelloMessage(other.hello); + } + if (other.isSetError()) { + this.error = new ErrorMessage(other.error); + } + if (other.isSetEchoRequest()) { + this.echoRequest = new EchoRequestMessage(other.echoRequest); + } + if (other.isSetEchoReply()) { + this.echoReply = new EchoReplyMessage(other.echoReply); + } + if (other.isSetGetRequest()) { + this.getRequest = new GetRequestMessage(other.getRequest); + } + if (other.isSetGetResponse()) { + this.getResponse = new GetResponseMessage(other.getResponse); + } + if (other.isSetPutRequest()) { + this.putRequest = new PutRequestMessage(other.putRequest); + } + if (other.isSetPutResponse()) { + this.putResponse = new PutResponseMessage(other.putResponse); + } + if (other.isSetDeleteRequest()) { + this.deleteRequest = new DeleteRequestMessage(other.deleteRequest); + } + if (other.isSetDeleteResponse()) { + this.deleteResponse = new DeleteResponseMessage(other.deleteResponse); + } + if (other.isSetSyncValue()) { + this.syncValue = new SyncValueMessage(other.syncValue); + } + if (other.isSetSyncValueResponse()) { + this.syncValueResponse = new SyncValueResponseMessage(other.syncValueResponse); + } + if (other.isSetSyncOffer()) { + this.syncOffer = new SyncOfferMessage(other.syncOffer); + } + if (other.isSetSyncRequest()) { + this.syncRequest = new SyncRequestMessage(other.syncRequest); + } + if (other.isSetFullSyncRequest()) { + this.fullSyncRequest = new FullSyncRequestMessage(other.fullSyncRequest); + } + if (other.isSetCursorRequest()) { + this.cursorRequest = new CursorRequestMessage(other.cursorRequest); + } + if (other.isSetCursorResponse()) { + this.cursorResponse = new CursorResponseMessage(other.cursorResponse); + } + if (other.isSetRegisterRequest()) { + this.registerRequest = new RegisterRequestMessage(other.registerRequest); + } + if (other.isSetRegisterResponse()) { + this.registerResponse = new RegisterResponseMessage(other.registerResponse); + } + } + + public SyncMessage deepCopy() { + return new SyncMessage(this); + } + + @Override + public void clear() { + this.type = null; + this.hello = null; + this.error = null; + this.echoRequest = null; + this.echoReply = null; + this.getRequest = null; + this.getResponse = null; + this.putRequest = null; + this.putResponse = null; + this.deleteRequest = null; + this.deleteResponse = null; + this.syncValue = null; + this.syncValueResponse = null; + this.syncOffer = null; + this.syncRequest = null; + this.fullSyncRequest = null; + this.cursorRequest = null; + this.cursorResponse = null; + this.registerRequest = null; + this.registerResponse = null; + } + + /** + * + * @see MessageType + */ + public MessageType getType() { + return this.type; + } + + /** + * + * @see MessageType + */ + public SyncMessage setType(MessageType type) { + this.type = type; + return this; + } + + public void unsetType() { + this.type = null; + } + + /** Returns true if field type is set (has been assigned a value) and false otherwise */ + public boolean isSetType() { + return this.type != null; + } + + public void setTypeIsSet(boolean value) { + if (!value) { + this.type = null; + } + } + + public HelloMessage getHello() { + return this.hello; + } + + public SyncMessage setHello(HelloMessage hello) { + this.hello = hello; + return this; + } + + public void unsetHello() { + this.hello = null; + } + + /** Returns true if field hello is set (has been assigned a value) and false otherwise */ + public boolean isSetHello() { + return this.hello != null; + } + + public void setHelloIsSet(boolean value) { + if (!value) { + this.hello = null; + } + } + + public ErrorMessage getError() { + return this.error; + } + + public SyncMessage setError(ErrorMessage error) { + this.error = error; + return this; + } + + public void unsetError() { + this.error = null; + } + + /** Returns true if field error is set (has been assigned a value) and false otherwise */ + public boolean isSetError() { + return this.error != null; + } + + public void setErrorIsSet(boolean value) { + if (!value) { + this.error = null; + } + } + + public EchoRequestMessage getEchoRequest() { + return this.echoRequest; + } + + public SyncMessage setEchoRequest(EchoRequestMessage echoRequest) { + this.echoRequest = echoRequest; + return this; + } + + public void unsetEchoRequest() { + this.echoRequest = null; + } + + /** Returns true if field echoRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetEchoRequest() { + return this.echoRequest != null; + } + + public void setEchoRequestIsSet(boolean value) { + if (!value) { + this.echoRequest = null; + } + } + + public EchoReplyMessage getEchoReply() { + return this.echoReply; + } + + public SyncMessage setEchoReply(EchoReplyMessage echoReply) { + this.echoReply = echoReply; + return this; + } + + public void unsetEchoReply() { + this.echoReply = null; + } + + /** Returns true if field echoReply is set (has been assigned a value) and false otherwise */ + public boolean isSetEchoReply() { + return this.echoReply != null; + } + + public void setEchoReplyIsSet(boolean value) { + if (!value) { + this.echoReply = null; + } + } + + public GetRequestMessage getGetRequest() { + return this.getRequest; + } + + public SyncMessage setGetRequest(GetRequestMessage getRequest) { + this.getRequest = getRequest; + return this; + } + + public void unsetGetRequest() { + this.getRequest = null; + } + + /** Returns true if field getRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetGetRequest() { + return this.getRequest != null; + } + + public void setGetRequestIsSet(boolean value) { + if (!value) { + this.getRequest = null; + } + } + + public GetResponseMessage getGetResponse() { + return this.getResponse; + } + + public SyncMessage setGetResponse(GetResponseMessage getResponse) { + this.getResponse = getResponse; + return this; + } + + public void unsetGetResponse() { + this.getResponse = null; + } + + /** Returns true if field getResponse is set (has been assigned a value) and false otherwise */ + public boolean isSetGetResponse() { + return this.getResponse != null; + } + + public void setGetResponseIsSet(boolean value) { + if (!value) { + this.getResponse = null; + } + } + + public PutRequestMessage getPutRequest() { + return this.putRequest; + } + + public SyncMessage setPutRequest(PutRequestMessage putRequest) { + this.putRequest = putRequest; + return this; + } + + public void unsetPutRequest() { + this.putRequest = null; + } + + /** Returns true if field putRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetPutRequest() { + return this.putRequest != null; + } + + public void setPutRequestIsSet(boolean value) { + if (!value) { + this.putRequest = null; + } + } + + public PutResponseMessage getPutResponse() { + return this.putResponse; + } + + public SyncMessage setPutResponse(PutResponseMessage putResponse) { + this.putResponse = putResponse; + return this; + } + + public void unsetPutResponse() { + this.putResponse = null; + } + + /** Returns true if field putResponse is set (has been assigned a value) and false otherwise */ + public boolean isSetPutResponse() { + return this.putResponse != null; + } + + public void setPutResponseIsSet(boolean value) { + if (!value) { + this.putResponse = null; + } + } + + public DeleteRequestMessage getDeleteRequest() { + return this.deleteRequest; + } + + public SyncMessage setDeleteRequest(DeleteRequestMessage deleteRequest) { + this.deleteRequest = deleteRequest; + return this; + } + + public void unsetDeleteRequest() { + this.deleteRequest = null; + } + + /** Returns true if field deleteRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetDeleteRequest() { + return this.deleteRequest != null; + } + + public void setDeleteRequestIsSet(boolean value) { + if (!value) { + this.deleteRequest = null; + } + } + + public DeleteResponseMessage getDeleteResponse() { + return this.deleteResponse; + } + + public SyncMessage setDeleteResponse(DeleteResponseMessage deleteResponse) { + this.deleteResponse = deleteResponse; + return this; + } + + public void unsetDeleteResponse() { + this.deleteResponse = null; + } + + /** Returns true if field deleteResponse is set (has been assigned a value) and false otherwise */ + public boolean isSetDeleteResponse() { + return this.deleteResponse != null; + } + + public void setDeleteResponseIsSet(boolean value) { + if (!value) { + this.deleteResponse = null; + } + } + + public SyncValueMessage getSyncValue() { + return this.syncValue; + } + + public SyncMessage setSyncValue(SyncValueMessage syncValue) { + this.syncValue = syncValue; + return this; + } + + public void unsetSyncValue() { + this.syncValue = null; + } + + /** Returns true if field syncValue is set (has been assigned a value) and false otherwise */ + public boolean isSetSyncValue() { + return this.syncValue != null; + } + + public void setSyncValueIsSet(boolean value) { + if (!value) { + this.syncValue = null; + } + } + + public SyncValueResponseMessage getSyncValueResponse() { + return this.syncValueResponse; + } + + public SyncMessage setSyncValueResponse(SyncValueResponseMessage syncValueResponse) { + this.syncValueResponse = syncValueResponse; + return this; + } + + public void unsetSyncValueResponse() { + this.syncValueResponse = null; + } + + /** Returns true if field syncValueResponse is set (has been assigned a value) and false otherwise */ + public boolean isSetSyncValueResponse() { + return this.syncValueResponse != null; + } + + public void setSyncValueResponseIsSet(boolean value) { + if (!value) { + this.syncValueResponse = null; + } + } + + public SyncOfferMessage getSyncOffer() { + return this.syncOffer; + } + + public SyncMessage setSyncOffer(SyncOfferMessage syncOffer) { + this.syncOffer = syncOffer; + return this; + } + + public void unsetSyncOffer() { + this.syncOffer = null; + } + + /** Returns true if field syncOffer is set (has been assigned a value) and false otherwise */ + public boolean isSetSyncOffer() { + return this.syncOffer != null; + } + + public void setSyncOfferIsSet(boolean value) { + if (!value) { + this.syncOffer = null; + } + } + + public SyncRequestMessage getSyncRequest() { + return this.syncRequest; + } + + public SyncMessage setSyncRequest(SyncRequestMessage syncRequest) { + this.syncRequest = syncRequest; + return this; + } + + public void unsetSyncRequest() { + this.syncRequest = null; + } + + /** Returns true if field syncRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetSyncRequest() { + return this.syncRequest != null; + } + + public void setSyncRequestIsSet(boolean value) { + if (!value) { + this.syncRequest = null; + } + } + + public FullSyncRequestMessage getFullSyncRequest() { + return this.fullSyncRequest; + } + + public SyncMessage setFullSyncRequest(FullSyncRequestMessage fullSyncRequest) { + this.fullSyncRequest = fullSyncRequest; + return this; + } + + public void unsetFullSyncRequest() { + this.fullSyncRequest = null; + } + + /** Returns true if field fullSyncRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetFullSyncRequest() { + return this.fullSyncRequest != null; + } + + public void setFullSyncRequestIsSet(boolean value) { + if (!value) { + this.fullSyncRequest = null; + } + } + + public CursorRequestMessage getCursorRequest() { + return this.cursorRequest; + } + + public SyncMessage setCursorRequest(CursorRequestMessage cursorRequest) { + this.cursorRequest = cursorRequest; + return this; + } + + public void unsetCursorRequest() { + this.cursorRequest = null; + } + + /** Returns true if field cursorRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetCursorRequest() { + return this.cursorRequest != null; + } + + public void setCursorRequestIsSet(boolean value) { + if (!value) { + this.cursorRequest = null; + } + } + + public CursorResponseMessage getCursorResponse() { + return this.cursorResponse; + } + + public SyncMessage setCursorResponse(CursorResponseMessage cursorResponse) { + this.cursorResponse = cursorResponse; + return this; + } + + public void unsetCursorResponse() { + this.cursorResponse = null; + } + + /** Returns true if field cursorResponse is set (has been assigned a value) and false otherwise */ + public boolean isSetCursorResponse() { + return this.cursorResponse != null; + } + + public void setCursorResponseIsSet(boolean value) { + if (!value) { + this.cursorResponse = null; + } + } + + public RegisterRequestMessage getRegisterRequest() { + return this.registerRequest; + } + + public SyncMessage setRegisterRequest(RegisterRequestMessage registerRequest) { + this.registerRequest = registerRequest; + return this; + } + + public void unsetRegisterRequest() { + this.registerRequest = null; + } + + /** Returns true if field registerRequest is set (has been assigned a value) and false otherwise */ + public boolean isSetRegisterRequest() { + return this.registerRequest != null; + } + + public void setRegisterRequestIsSet(boolean value) { + if (!value) { + this.registerRequest = null; + } + } + + public RegisterResponseMessage getRegisterResponse() { + return this.registerResponse; + } + + public SyncMessage setRegisterResponse(RegisterResponseMessage registerResponse) { + this.registerResponse = registerResponse; + return this; + } + + public void unsetRegisterResponse() { + this.registerResponse = null; + } + + /** Returns true if field registerResponse is set (has been assigned a value) and false otherwise */ + public boolean isSetRegisterResponse() { + return this.registerResponse != null; + } + + public void setRegisterResponseIsSet(boolean value) { + if (!value) { + this.registerResponse = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case TYPE: + if (value == null) { + unsetType(); + } else { + setType((MessageType)value); + } + break; + + case HELLO: + if (value == null) { + unsetHello(); + } else { + setHello((HelloMessage)value); + } + break; + + case ERROR: + if (value == null) { + unsetError(); + } else { + setError((ErrorMessage)value); + } + break; + + case ECHO_REQUEST: + if (value == null) { + unsetEchoRequest(); + } else { + setEchoRequest((EchoRequestMessage)value); + } + break; + + case ECHO_REPLY: + if (value == null) { + unsetEchoReply(); + } else { + setEchoReply((EchoReplyMessage)value); + } + break; + + case GET_REQUEST: + if (value == null) { + unsetGetRequest(); + } else { + setGetRequest((GetRequestMessage)value); + } + break; + + case GET_RESPONSE: + if (value == null) { + unsetGetResponse(); + } else { + setGetResponse((GetResponseMessage)value); + } + break; + + case PUT_REQUEST: + if (value == null) { + unsetPutRequest(); + } else { + setPutRequest((PutRequestMessage)value); + } + break; + + case PUT_RESPONSE: + if (value == null) { + unsetPutResponse(); + } else { + setPutResponse((PutResponseMessage)value); + } + break; + + case DELETE_REQUEST: + if (value == null) { + unsetDeleteRequest(); + } else { + setDeleteRequest((DeleteRequestMessage)value); + } + break; + + case DELETE_RESPONSE: + if (value == null) { + unsetDeleteResponse(); + } else { + setDeleteResponse((DeleteResponseMessage)value); + } + break; + + case SYNC_VALUE: + if (value == null) { + unsetSyncValue(); + } else { + setSyncValue((SyncValueMessage)value); + } + break; + + case SYNC_VALUE_RESPONSE: + if (value == null) { + unsetSyncValueResponse(); + } else { + setSyncValueResponse((SyncValueResponseMessage)value); + } + break; + + case SYNC_OFFER: + if (value == null) { + unsetSyncOffer(); + } else { + setSyncOffer((SyncOfferMessage)value); + } + break; + + case SYNC_REQUEST: + if (value == null) { + unsetSyncRequest(); + } else { + setSyncRequest((SyncRequestMessage)value); + } + break; + + case FULL_SYNC_REQUEST: + if (value == null) { + unsetFullSyncRequest(); + } else { + setFullSyncRequest((FullSyncRequestMessage)value); + } + break; + + case CURSOR_REQUEST: + if (value == null) { + unsetCursorRequest(); + } else { + setCursorRequest((CursorRequestMessage)value); + } + break; + + case CURSOR_RESPONSE: + if (value == null) { + unsetCursorResponse(); + } else { + setCursorResponse((CursorResponseMessage)value); + } + break; + + case REGISTER_REQUEST: + if (value == null) { + unsetRegisterRequest(); + } else { + setRegisterRequest((RegisterRequestMessage)value); + } + break; + + case REGISTER_RESPONSE: + if (value == null) { + unsetRegisterResponse(); + } else { + setRegisterResponse((RegisterResponseMessage)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case TYPE: + return getType(); + + case HELLO: + return getHello(); + + case ERROR: + return getError(); + + case ECHO_REQUEST: + return getEchoRequest(); + + case ECHO_REPLY: + return getEchoReply(); + + case GET_REQUEST: + return getGetRequest(); + + case GET_RESPONSE: + return getGetResponse(); + + case PUT_REQUEST: + return getPutRequest(); + + case PUT_RESPONSE: + return getPutResponse(); + + case DELETE_REQUEST: + return getDeleteRequest(); + + case DELETE_RESPONSE: + return getDeleteResponse(); + + case SYNC_VALUE: + return getSyncValue(); + + case SYNC_VALUE_RESPONSE: + return getSyncValueResponse(); + + case SYNC_OFFER: + return getSyncOffer(); + + case SYNC_REQUEST: + return getSyncRequest(); + + case FULL_SYNC_REQUEST: + return getFullSyncRequest(); + + case CURSOR_REQUEST: + return getCursorRequest(); + + case CURSOR_RESPONSE: + return getCursorResponse(); + + case REGISTER_REQUEST: + return getRegisterRequest(); + + case REGISTER_RESPONSE: + return getRegisterResponse(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case TYPE: + return isSetType(); + case HELLO: + return isSetHello(); + case ERROR: + return isSetError(); + case ECHO_REQUEST: + return isSetEchoRequest(); + case ECHO_REPLY: + return isSetEchoReply(); + case GET_REQUEST: + return isSetGetRequest(); + case GET_RESPONSE: + return isSetGetResponse(); + case PUT_REQUEST: + return isSetPutRequest(); + case PUT_RESPONSE: + return isSetPutResponse(); + case DELETE_REQUEST: + return isSetDeleteRequest(); + case DELETE_RESPONSE: + return isSetDeleteResponse(); + case SYNC_VALUE: + return isSetSyncValue(); + case SYNC_VALUE_RESPONSE: + return isSetSyncValueResponse(); + case SYNC_OFFER: + return isSetSyncOffer(); + case SYNC_REQUEST: + return isSetSyncRequest(); + case FULL_SYNC_REQUEST: + return isSetFullSyncRequest(); + case CURSOR_REQUEST: + return isSetCursorRequest(); + case CURSOR_RESPONSE: + return isSetCursorResponse(); + case REGISTER_REQUEST: + return isSetRegisterRequest(); + case REGISTER_RESPONSE: + return isSetRegisterResponse(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncMessage) + return this.equals((SyncMessage)that); + return false; + } + + public boolean equals(SyncMessage that) { + if (that == null) + return false; + + boolean this_present_type = true && this.isSetType(); + boolean that_present_type = true && that.isSetType(); + if (this_present_type || that_present_type) { + if (!(this_present_type && that_present_type)) + return false; + if (!this.type.equals(that.type)) + return false; + } + + boolean this_present_hello = true && this.isSetHello(); + boolean that_present_hello = true && that.isSetHello(); + if (this_present_hello || that_present_hello) { + if (!(this_present_hello && that_present_hello)) + return false; + if (!this.hello.equals(that.hello)) + return false; + } + + boolean this_present_error = true && this.isSetError(); + boolean that_present_error = true && that.isSetError(); + if (this_present_error || that_present_error) { + if (!(this_present_error && that_present_error)) + return false; + if (!this.error.equals(that.error)) + return false; + } + + boolean this_present_echoRequest = true && this.isSetEchoRequest(); + boolean that_present_echoRequest = true && that.isSetEchoRequest(); + if (this_present_echoRequest || that_present_echoRequest) { + if (!(this_present_echoRequest && that_present_echoRequest)) + return false; + if (!this.echoRequest.equals(that.echoRequest)) + return false; + } + + boolean this_present_echoReply = true && this.isSetEchoReply(); + boolean that_present_echoReply = true && that.isSetEchoReply(); + if (this_present_echoReply || that_present_echoReply) { + if (!(this_present_echoReply && that_present_echoReply)) + return false; + if (!this.echoReply.equals(that.echoReply)) + return false; + } + + boolean this_present_getRequest = true && this.isSetGetRequest(); + boolean that_present_getRequest = true && that.isSetGetRequest(); + if (this_present_getRequest || that_present_getRequest) { + if (!(this_present_getRequest && that_present_getRequest)) + return false; + if (!this.getRequest.equals(that.getRequest)) + return false; + } + + boolean this_present_getResponse = true && this.isSetGetResponse(); + boolean that_present_getResponse = true && that.isSetGetResponse(); + if (this_present_getResponse || that_present_getResponse) { + if (!(this_present_getResponse && that_present_getResponse)) + return false; + if (!this.getResponse.equals(that.getResponse)) + return false; + } + + boolean this_present_putRequest = true && this.isSetPutRequest(); + boolean that_present_putRequest = true && that.isSetPutRequest(); + if (this_present_putRequest || that_present_putRequest) { + if (!(this_present_putRequest && that_present_putRequest)) + return false; + if (!this.putRequest.equals(that.putRequest)) + return false; + } + + boolean this_present_putResponse = true && this.isSetPutResponse(); + boolean that_present_putResponse = true && that.isSetPutResponse(); + if (this_present_putResponse || that_present_putResponse) { + if (!(this_present_putResponse && that_present_putResponse)) + return false; + if (!this.putResponse.equals(that.putResponse)) + return false; + } + + boolean this_present_deleteRequest = true && this.isSetDeleteRequest(); + boolean that_present_deleteRequest = true && that.isSetDeleteRequest(); + if (this_present_deleteRequest || that_present_deleteRequest) { + if (!(this_present_deleteRequest && that_present_deleteRequest)) + return false; + if (!this.deleteRequest.equals(that.deleteRequest)) + return false; + } + + boolean this_present_deleteResponse = true && this.isSetDeleteResponse(); + boolean that_present_deleteResponse = true && that.isSetDeleteResponse(); + if (this_present_deleteResponse || that_present_deleteResponse) { + if (!(this_present_deleteResponse && that_present_deleteResponse)) + return false; + if (!this.deleteResponse.equals(that.deleteResponse)) + return false; + } + + boolean this_present_syncValue = true && this.isSetSyncValue(); + boolean that_present_syncValue = true && that.isSetSyncValue(); + if (this_present_syncValue || that_present_syncValue) { + if (!(this_present_syncValue && that_present_syncValue)) + return false; + if (!this.syncValue.equals(that.syncValue)) + return false; + } + + boolean this_present_syncValueResponse = true && this.isSetSyncValueResponse(); + boolean that_present_syncValueResponse = true && that.isSetSyncValueResponse(); + if (this_present_syncValueResponse || that_present_syncValueResponse) { + if (!(this_present_syncValueResponse && that_present_syncValueResponse)) + return false; + if (!this.syncValueResponse.equals(that.syncValueResponse)) + return false; + } + + boolean this_present_syncOffer = true && this.isSetSyncOffer(); + boolean that_present_syncOffer = true && that.isSetSyncOffer(); + if (this_present_syncOffer || that_present_syncOffer) { + if (!(this_present_syncOffer && that_present_syncOffer)) + return false; + if (!this.syncOffer.equals(that.syncOffer)) + return false; + } + + boolean this_present_syncRequest = true && this.isSetSyncRequest(); + boolean that_present_syncRequest = true && that.isSetSyncRequest(); + if (this_present_syncRequest || that_present_syncRequest) { + if (!(this_present_syncRequest && that_present_syncRequest)) + return false; + if (!this.syncRequest.equals(that.syncRequest)) + return false; + } + + boolean this_present_fullSyncRequest = true && this.isSetFullSyncRequest(); + boolean that_present_fullSyncRequest = true && that.isSetFullSyncRequest(); + if (this_present_fullSyncRequest || that_present_fullSyncRequest) { + if (!(this_present_fullSyncRequest && that_present_fullSyncRequest)) + return false; + if (!this.fullSyncRequest.equals(that.fullSyncRequest)) + return false; + } + + boolean this_present_cursorRequest = true && this.isSetCursorRequest(); + boolean that_present_cursorRequest = true && that.isSetCursorRequest(); + if (this_present_cursorRequest || that_present_cursorRequest) { + if (!(this_present_cursorRequest && that_present_cursorRequest)) + return false; + if (!this.cursorRequest.equals(that.cursorRequest)) + return false; + } + + boolean this_present_cursorResponse = true && this.isSetCursorResponse(); + boolean that_present_cursorResponse = true && that.isSetCursorResponse(); + if (this_present_cursorResponse || that_present_cursorResponse) { + if (!(this_present_cursorResponse && that_present_cursorResponse)) + return false; + if (!this.cursorResponse.equals(that.cursorResponse)) + return false; + } + + boolean this_present_registerRequest = true && this.isSetRegisterRequest(); + boolean that_present_registerRequest = true && that.isSetRegisterRequest(); + if (this_present_registerRequest || that_present_registerRequest) { + if (!(this_present_registerRequest && that_present_registerRequest)) + return false; + if (!this.registerRequest.equals(that.registerRequest)) + return false; + } + + boolean this_present_registerResponse = true && this.isSetRegisterResponse(); + boolean that_present_registerResponse = true && that.isSetRegisterResponse(); + if (this_present_registerResponse || that_present_registerResponse) { + if (!(this_present_registerResponse && that_present_registerResponse)) + return false; + if (!this.registerResponse.equals(that.registerResponse)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncMessage typedOther = (SyncMessage)other; + + lastComparison = Boolean.valueOf(isSetType()).compareTo(typedOther.isSetType()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetType()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, typedOther.type); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetHello()).compareTo(typedOther.isSetHello()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHello()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.hello, typedOther.hello); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetError()).compareTo(typedOther.isSetError()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetError()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.error, typedOther.error); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEchoRequest()).compareTo(typedOther.isSetEchoRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEchoRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.echoRequest, typedOther.echoRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetEchoReply()).compareTo(typedOther.isSetEchoReply()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetEchoReply()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.echoReply, typedOther.echoReply); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetGetRequest()).compareTo(typedOther.isSetGetRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetGetRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.getRequest, typedOther.getRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetGetResponse()).compareTo(typedOther.isSetGetResponse()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetGetResponse()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.getResponse, typedOther.getResponse); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPutRequest()).compareTo(typedOther.isSetPutRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPutRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.putRequest, typedOther.putRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPutResponse()).compareTo(typedOther.isSetPutResponse()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPutResponse()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.putResponse, typedOther.putResponse); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetDeleteRequest()).compareTo(typedOther.isSetDeleteRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDeleteRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.deleteRequest, typedOther.deleteRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetDeleteResponse()).compareTo(typedOther.isSetDeleteResponse()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDeleteResponse()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.deleteResponse, typedOther.deleteResponse); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSyncValue()).compareTo(typedOther.isSetSyncValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSyncValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.syncValue, typedOther.syncValue); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSyncValueResponse()).compareTo(typedOther.isSetSyncValueResponse()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSyncValueResponse()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.syncValueResponse, typedOther.syncValueResponse); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSyncOffer()).compareTo(typedOther.isSetSyncOffer()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSyncOffer()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.syncOffer, typedOther.syncOffer); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSyncRequest()).compareTo(typedOther.isSetSyncRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSyncRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.syncRequest, typedOther.syncRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetFullSyncRequest()).compareTo(typedOther.isSetFullSyncRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetFullSyncRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fullSyncRequest, typedOther.fullSyncRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCursorRequest()).compareTo(typedOther.isSetCursorRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCursorRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cursorRequest, typedOther.cursorRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCursorResponse()).compareTo(typedOther.isSetCursorResponse()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCursorResponse()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cursorResponse, typedOther.cursorResponse); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRegisterRequest()).compareTo(typedOther.isSetRegisterRequest()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRegisterRequest()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.registerRequest, typedOther.registerRequest); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetRegisterResponse()).compareTo(typedOther.isSetRegisterResponse()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetRegisterResponse()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.registerResponse, typedOther.registerResponse); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // TYPE + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.type = MessageType.findByValue(iprot.readI32()); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // HELLO + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.hello = new HelloMessage(); + this.hello.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // ERROR + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.error = new ErrorMessage(); + this.error.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // ECHO_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.echoRequest = new EchoRequestMessage(); + this.echoRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 5: // ECHO_REPLY + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.echoReply = new EchoReplyMessage(); + this.echoReply.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 6: // GET_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.getRequest = new GetRequestMessage(); + this.getRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 7: // GET_RESPONSE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.getResponse = new GetResponseMessage(); + this.getResponse.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 8: // PUT_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.putRequest = new PutRequestMessage(); + this.putRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 9: // PUT_RESPONSE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.putResponse = new PutResponseMessage(); + this.putResponse.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 10: // DELETE_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.deleteRequest = new DeleteRequestMessage(); + this.deleteRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 11: // DELETE_RESPONSE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.deleteResponse = new DeleteResponseMessage(); + this.deleteResponse.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 12: // SYNC_VALUE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.syncValue = new SyncValueMessage(); + this.syncValue.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 13: // SYNC_VALUE_RESPONSE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.syncValueResponse = new SyncValueResponseMessage(); + this.syncValueResponse.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 14: // SYNC_OFFER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.syncOffer = new SyncOfferMessage(); + this.syncOffer.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 15: // SYNC_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.syncRequest = new SyncRequestMessage(); + this.syncRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 16: // FULL_SYNC_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.fullSyncRequest = new FullSyncRequestMessage(); + this.fullSyncRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 17: // CURSOR_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.cursorRequest = new CursorRequestMessage(); + this.cursorRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 18: // CURSOR_RESPONSE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.cursorResponse = new CursorResponseMessage(); + this.cursorResponse.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 19: // REGISTER_REQUEST + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.registerRequest = new RegisterRequestMessage(); + this.registerRequest.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 20: // REGISTER_RESPONSE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.registerResponse = new RegisterResponseMessage(); + this.registerResponse.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.type != null) { + oprot.writeFieldBegin(TYPE_FIELD_DESC); + oprot.writeI32(this.type.getValue()); + oprot.writeFieldEnd(); + } + if (this.hello != null) { + if (isSetHello()) { + oprot.writeFieldBegin(HELLO_FIELD_DESC); + this.hello.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.error != null) { + if (isSetError()) { + oprot.writeFieldBegin(ERROR_FIELD_DESC); + this.error.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.echoRequest != null) { + if (isSetEchoRequest()) { + oprot.writeFieldBegin(ECHO_REQUEST_FIELD_DESC); + this.echoRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.echoReply != null) { + if (isSetEchoReply()) { + oprot.writeFieldBegin(ECHO_REPLY_FIELD_DESC); + this.echoReply.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.getRequest != null) { + if (isSetGetRequest()) { + oprot.writeFieldBegin(GET_REQUEST_FIELD_DESC); + this.getRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.getResponse != null) { + if (isSetGetResponse()) { + oprot.writeFieldBegin(GET_RESPONSE_FIELD_DESC); + this.getResponse.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.putRequest != null) { + if (isSetPutRequest()) { + oprot.writeFieldBegin(PUT_REQUEST_FIELD_DESC); + this.putRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.putResponse != null) { + if (isSetPutResponse()) { + oprot.writeFieldBegin(PUT_RESPONSE_FIELD_DESC); + this.putResponse.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.deleteRequest != null) { + if (isSetDeleteRequest()) { + oprot.writeFieldBegin(DELETE_REQUEST_FIELD_DESC); + this.deleteRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.deleteResponse != null) { + if (isSetDeleteResponse()) { + oprot.writeFieldBegin(DELETE_RESPONSE_FIELD_DESC); + this.deleteResponse.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.syncValue != null) { + if (isSetSyncValue()) { + oprot.writeFieldBegin(SYNC_VALUE_FIELD_DESC); + this.syncValue.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.syncValueResponse != null) { + if (isSetSyncValueResponse()) { + oprot.writeFieldBegin(SYNC_VALUE_RESPONSE_FIELD_DESC); + this.syncValueResponse.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.syncOffer != null) { + if (isSetSyncOffer()) { + oprot.writeFieldBegin(SYNC_OFFER_FIELD_DESC); + this.syncOffer.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.syncRequest != null) { + if (isSetSyncRequest()) { + oprot.writeFieldBegin(SYNC_REQUEST_FIELD_DESC); + this.syncRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.fullSyncRequest != null) { + if (isSetFullSyncRequest()) { + oprot.writeFieldBegin(FULL_SYNC_REQUEST_FIELD_DESC); + this.fullSyncRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.cursorRequest != null) { + if (isSetCursorRequest()) { + oprot.writeFieldBegin(CURSOR_REQUEST_FIELD_DESC); + this.cursorRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.cursorResponse != null) { + if (isSetCursorResponse()) { + oprot.writeFieldBegin(CURSOR_RESPONSE_FIELD_DESC); + this.cursorResponse.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.registerRequest != null) { + if (isSetRegisterRequest()) { + oprot.writeFieldBegin(REGISTER_REQUEST_FIELD_DESC); + this.registerRequest.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.registerResponse != null) { + if (isSetRegisterResponse()) { + oprot.writeFieldBegin(REGISTER_RESPONSE_FIELD_DESC); + this.registerResponse.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncMessage("); + boolean first = true; + + sb.append("type:"); + if (this.type == null) { + sb.append("null"); + } else { + sb.append(this.type); + } + first = false; + if (isSetHello()) { + if (!first) sb.append(", "); + sb.append("hello:"); + if (this.hello == null) { + sb.append("null"); + } else { + sb.append(this.hello); + } + first = false; + } + if (isSetError()) { + if (!first) sb.append(", "); + sb.append("error:"); + if (this.error == null) { + sb.append("null"); + } else { + sb.append(this.error); + } + first = false; + } + if (isSetEchoRequest()) { + if (!first) sb.append(", "); + sb.append("echoRequest:"); + if (this.echoRequest == null) { + sb.append("null"); + } else { + sb.append(this.echoRequest); + } + first = false; + } + if (isSetEchoReply()) { + if (!first) sb.append(", "); + sb.append("echoReply:"); + if (this.echoReply == null) { + sb.append("null"); + } else { + sb.append(this.echoReply); + } + first = false; + } + if (isSetGetRequest()) { + if (!first) sb.append(", "); + sb.append("getRequest:"); + if (this.getRequest == null) { + sb.append("null"); + } else { + sb.append(this.getRequest); + } + first = false; + } + if (isSetGetResponse()) { + if (!first) sb.append(", "); + sb.append("getResponse:"); + if (this.getResponse == null) { + sb.append("null"); + } else { + sb.append(this.getResponse); + } + first = false; + } + if (isSetPutRequest()) { + if (!first) sb.append(", "); + sb.append("putRequest:"); + if (this.putRequest == null) { + sb.append("null"); + } else { + sb.append(this.putRequest); + } + first = false; + } + if (isSetPutResponse()) { + if (!first) sb.append(", "); + sb.append("putResponse:"); + if (this.putResponse == null) { + sb.append("null"); + } else { + sb.append(this.putResponse); + } + first = false; + } + if (isSetDeleteRequest()) { + if (!first) sb.append(", "); + sb.append("deleteRequest:"); + if (this.deleteRequest == null) { + sb.append("null"); + } else { + sb.append(this.deleteRequest); + } + first = false; + } + if (isSetDeleteResponse()) { + if (!first) sb.append(", "); + sb.append("deleteResponse:"); + if (this.deleteResponse == null) { + sb.append("null"); + } else { + sb.append(this.deleteResponse); + } + first = false; + } + if (isSetSyncValue()) { + if (!first) sb.append(", "); + sb.append("syncValue:"); + if (this.syncValue == null) { + sb.append("null"); + } else { + sb.append(this.syncValue); + } + first = false; + } + if (isSetSyncValueResponse()) { + if (!first) sb.append(", "); + sb.append("syncValueResponse:"); + if (this.syncValueResponse == null) { + sb.append("null"); + } else { + sb.append(this.syncValueResponse); + } + first = false; + } + if (isSetSyncOffer()) { + if (!first) sb.append(", "); + sb.append("syncOffer:"); + if (this.syncOffer == null) { + sb.append("null"); + } else { + sb.append(this.syncOffer); + } + first = false; + } + if (isSetSyncRequest()) { + if (!first) sb.append(", "); + sb.append("syncRequest:"); + if (this.syncRequest == null) { + sb.append("null"); + } else { + sb.append(this.syncRequest); + } + first = false; + } + if (isSetFullSyncRequest()) { + if (!first) sb.append(", "); + sb.append("fullSyncRequest:"); + if (this.fullSyncRequest == null) { + sb.append("null"); + } else { + sb.append(this.fullSyncRequest); + } + first = false; + } + if (isSetCursorRequest()) { + if (!first) sb.append(", "); + sb.append("cursorRequest:"); + if (this.cursorRequest == null) { + sb.append("null"); + } else { + sb.append(this.cursorRequest); + } + first = false; + } + if (isSetCursorResponse()) { + if (!first) sb.append(", "); + sb.append("cursorResponse:"); + if (this.cursorResponse == null) { + sb.append("null"); + } else { + sb.append(this.cursorResponse); + } + first = false; + } + if (isSetRegisterRequest()) { + if (!first) sb.append(", "); + sb.append("registerRequest:"); + if (this.registerRequest == null) { + sb.append("null"); + } else { + sb.append(this.registerRequest); + } + first = false; + } + if (isSetRegisterResponse()) { + if (!first) sb.append(", "); + sb.append("registerResponse:"); + if (this.registerResponse == null) { + sb.append("null"); + } else { + sb.append(this.registerResponse); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (type == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'type' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncOffer.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncOffer.java new file mode 100644 index 0000000000000000000000000000000000000000..504200e457fe102b54689753ba75d559db9719a1 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncOffer.java @@ -0,0 +1,323 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncOffer implements org.apache.thrift.TBase<SyncOffer, SyncOffer._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncOffer"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + + public AsyncMessageHeader header; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncOffer.class, metaDataMap); + } + + public SyncOffer() { + } + + public SyncOffer( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncOffer(SyncOffer other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + } + + public SyncOffer deepCopy() { + return new SyncOffer(this); + } + + @Override + public void clear() { + this.header = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public SyncOffer setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncOffer) + return this.equals((SyncOffer)that); + return false; + } + + public boolean equals(SyncOffer that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncOffer other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncOffer typedOther = (SyncOffer)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncOffer("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncOfferMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncOfferMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..9685230fb8d13a0816f929b62fbf1da3ce81a7d2 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncOfferMessage.java @@ -0,0 +1,543 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncOfferMessage implements org.apache.thrift.TBase<SyncOfferMessage, SyncOfferMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncOfferMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_FIELD_DESC = new org.apache.thrift.protocol.TField("store", org.apache.thrift.protocol.TType.STRUCT, (short)2); + private static final org.apache.thrift.protocol.TField VERSIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("versions", org.apache.thrift.protocol.TType.LIST, (short)3); + + public AsyncMessageHeader header; // required + public Store store; // required + public List<KeyedVersions> versions; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE((short)2, "store"), + VERSIONS((short)3, "versions"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE + return STORE; + case 3: // VERSIONS + return VERSIONS; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE, new org.apache.thrift.meta_data.FieldMetaData("store", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Store.class))); + tmpMap.put(_Fields.VERSIONS, new org.apache.thrift.meta_data.FieldMetaData("versions", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyedVersions.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncOfferMessage.class, metaDataMap); + } + + public SyncOfferMessage() { + } + + public SyncOfferMessage( + AsyncMessageHeader header, + Store store, + List<KeyedVersions> versions) + { + this(); + this.header = header; + this.store = store; + this.versions = versions; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncOfferMessage(SyncOfferMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStore()) { + this.store = new Store(other.store); + } + if (other.isSetVersions()) { + List<KeyedVersions> __this__versions = new ArrayList<KeyedVersions>(); + for (KeyedVersions other_element : other.versions) { + __this__versions.add(new KeyedVersions(other_element)); + } + this.versions = __this__versions; + } + } + + public SyncOfferMessage deepCopy() { + return new SyncOfferMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.store = null; + this.versions = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public SyncOfferMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public Store getStore() { + return this.store; + } + + public SyncOfferMessage setStore(Store store) { + this.store = store; + return this; + } + + public void unsetStore() { + this.store = null; + } + + /** Returns true if field store is set (has been assigned a value) and false otherwise */ + public boolean isSetStore() { + return this.store != null; + } + + public void setStoreIsSet(boolean value) { + if (!value) { + this.store = null; + } + } + + public int getVersionsSize() { + return (this.versions == null) ? 0 : this.versions.size(); + } + + public java.util.Iterator<KeyedVersions> getVersionsIterator() { + return (this.versions == null) ? null : this.versions.iterator(); + } + + public void addToVersions(KeyedVersions elem) { + if (this.versions == null) { + this.versions = new ArrayList<KeyedVersions>(); + } + this.versions.add(elem); + } + + public List<KeyedVersions> getVersions() { + return this.versions; + } + + public SyncOfferMessage setVersions(List<KeyedVersions> versions) { + this.versions = versions; + return this; + } + + public void unsetVersions() { + this.versions = null; + } + + /** Returns true if field versions is set (has been assigned a value) and false otherwise */ + public boolean isSetVersions() { + return this.versions != null; + } + + public void setVersionsIsSet(boolean value) { + if (!value) { + this.versions = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE: + if (value == null) { + unsetStore(); + } else { + setStore((Store)value); + } + break; + + case VERSIONS: + if (value == null) { + unsetVersions(); + } else { + setVersions((List<KeyedVersions>)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE: + return getStore(); + + case VERSIONS: + return getVersions(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE: + return isSetStore(); + case VERSIONS: + return isSetVersions(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncOfferMessage) + return this.equals((SyncOfferMessage)that); + return false; + } + + public boolean equals(SyncOfferMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_store = true && this.isSetStore(); + boolean that_present_store = true && that.isSetStore(); + if (this_present_store || that_present_store) { + if (!(this_present_store && that_present_store)) + return false; + if (!this.store.equals(that.store)) + return false; + } + + boolean this_present_versions = true && this.isSetVersions(); + boolean that_present_versions = true && that.isSetVersions(); + if (this_present_versions || that_present_versions) { + if (!(this_present_versions && that_present_versions)) + return false; + if (!this.versions.equals(that.versions)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncOfferMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncOfferMessage typedOther = (SyncOfferMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStore()).compareTo(typedOther.isSetStore()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStore()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.store, typedOther.store); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersions()).compareTo(typedOther.isSetVersions()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersions()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versions, typedOther.versions); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.store = new Store(); + this.store.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // VERSIONS + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list20 = iprot.readListBegin(); + this.versions = new ArrayList<KeyedVersions>(_list20.size); + for (int _i21 = 0; _i21 < _list20.size; ++_i21) + { + KeyedVersions _elem22; // required + _elem22 = new KeyedVersions(); + _elem22.read(iprot); + this.versions.add(_elem22); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.store != null) { + oprot.writeFieldBegin(STORE_FIELD_DESC); + this.store.write(oprot); + oprot.writeFieldEnd(); + } + if (this.versions != null) { + oprot.writeFieldBegin(VERSIONS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.versions.size())); + for (KeyedVersions _iter23 : this.versions) + { + _iter23.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncOfferMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("store:"); + if (this.store == null) { + sb.append("null"); + } else { + sb.append(this.store); + } + first = false; + if (!first) sb.append(", "); + sb.append("versions:"); + if (this.versions == null) { + sb.append("null"); + } else { + sb.append(this.versions); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (store == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'store' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncRequestMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncRequestMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..dc869a030d248a1a70ebe9ed3e721b4b4f58e678 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncRequestMessage.java @@ -0,0 +1,546 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncRequestMessage implements org.apache.thrift.TBase<SyncRequestMessage, SyncRequestMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncRequestMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_FIELD_DESC = new org.apache.thrift.protocol.TField("store", org.apache.thrift.protocol.TType.STRUCT, (short)2); + private static final org.apache.thrift.protocol.TField KEYS_FIELD_DESC = new org.apache.thrift.protocol.TField("keys", org.apache.thrift.protocol.TType.LIST, (short)3); + + public AsyncMessageHeader header; // required + public Store store; // required + public List<ByteBuffer> keys; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE((short)2, "store"), + KEYS((short)3, "keys"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE + return STORE; + case 3: // KEYS + return KEYS; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE, new org.apache.thrift.meta_data.FieldMetaData("store", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Store.class))); + tmpMap.put(_Fields.KEYS, new org.apache.thrift.meta_data.FieldMetaData("keys", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncRequestMessage.class, metaDataMap); + } + + public SyncRequestMessage() { + } + + public SyncRequestMessage( + AsyncMessageHeader header, + Store store) + { + this(); + this.header = header; + this.store = store; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncRequestMessage(SyncRequestMessage other) { + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStore()) { + this.store = new Store(other.store); + } + if (other.isSetKeys()) { + List<ByteBuffer> __this__keys = new ArrayList<ByteBuffer>(); + for (ByteBuffer other_element : other.keys) { + ByteBuffer temp_binary_element = org.apache.thrift.TBaseHelper.copyBinary(other_element); +; + __this__keys.add(temp_binary_element); + } + this.keys = __this__keys; + } + } + + public SyncRequestMessage deepCopy() { + return new SyncRequestMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.store = null; + this.keys = null; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public SyncRequestMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public Store getStore() { + return this.store; + } + + public SyncRequestMessage setStore(Store store) { + this.store = store; + return this; + } + + public void unsetStore() { + this.store = null; + } + + /** Returns true if field store is set (has been assigned a value) and false otherwise */ + public boolean isSetStore() { + return this.store != null; + } + + public void setStoreIsSet(boolean value) { + if (!value) { + this.store = null; + } + } + + public int getKeysSize() { + return (this.keys == null) ? 0 : this.keys.size(); + } + + public java.util.Iterator<ByteBuffer> getKeysIterator() { + return (this.keys == null) ? null : this.keys.iterator(); + } + + public void addToKeys(ByteBuffer elem) { + if (this.keys == null) { + this.keys = new ArrayList<ByteBuffer>(); + } + this.keys.add(elem); + } + + public List<ByteBuffer> getKeys() { + return this.keys; + } + + public SyncRequestMessage setKeys(List<ByteBuffer> keys) { + this.keys = keys; + return this; + } + + public void unsetKeys() { + this.keys = null; + } + + /** Returns true if field keys is set (has been assigned a value) and false otherwise */ + public boolean isSetKeys() { + return this.keys != null; + } + + public void setKeysIsSet(boolean value) { + if (!value) { + this.keys = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE: + if (value == null) { + unsetStore(); + } else { + setStore((Store)value); + } + break; + + case KEYS: + if (value == null) { + unsetKeys(); + } else { + setKeys((List<ByteBuffer>)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE: + return getStore(); + + case KEYS: + return getKeys(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE: + return isSetStore(); + case KEYS: + return isSetKeys(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncRequestMessage) + return this.equals((SyncRequestMessage)that); + return false; + } + + public boolean equals(SyncRequestMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_store = true && this.isSetStore(); + boolean that_present_store = true && that.isSetStore(); + if (this_present_store || that_present_store) { + if (!(this_present_store && that_present_store)) + return false; + if (!this.store.equals(that.store)) + return false; + } + + boolean this_present_keys = true && this.isSetKeys(); + boolean that_present_keys = true && that.isSetKeys(); + if (this_present_keys || that_present_keys) { + if (!(this_present_keys && that_present_keys)) + return false; + if (!this.keys.equals(that.keys)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncRequestMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncRequestMessage typedOther = (SyncRequestMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStore()).compareTo(typedOther.isSetStore()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStore()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.store, typedOther.store); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetKeys()).compareTo(typedOther.isSetKeys()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKeys()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.keys, typedOther.keys); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.store = new Store(); + this.store.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // KEYS + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list24 = iprot.readListBegin(); + this.keys = new ArrayList<ByteBuffer>(_list24.size); + for (int _i25 = 0; _i25 < _list24.size; ++_i25) + { + ByteBuffer _elem26; // required + _elem26 = iprot.readBinary(); + this.keys.add(_elem26); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.store != null) { + oprot.writeFieldBegin(STORE_FIELD_DESC); + this.store.write(oprot); + oprot.writeFieldEnd(); + } + if (this.keys != null) { + if (isSetKeys()) { + oprot.writeFieldBegin(KEYS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, this.keys.size())); + for (ByteBuffer _iter27 : this.keys) + { + oprot.writeBinary(_iter27); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncRequestMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("store:"); + if (this.store == null) { + sb.append("null"); + } else { + sb.append(this.store); + } + first = false; + if (isSetKeys()) { + if (!first) sb.append(", "); + sb.append("keys:"); + if (this.keys == null) { + sb.append("null"); + } else { + sb.append(this.keys); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (store == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'store' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncValueMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncValueMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..b44935c9384c6529186a3fc38b05b5bcd0787ecc --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncValueMessage.java @@ -0,0 +1,633 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncValueMessage implements org.apache.thrift.TBase<SyncValueMessage, SyncValueMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncValueMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField STORE_FIELD_DESC = new org.apache.thrift.protocol.TField("store", org.apache.thrift.protocol.TType.STRUCT, (short)2); + private static final org.apache.thrift.protocol.TField VALUES_FIELD_DESC = new org.apache.thrift.protocol.TField("values", org.apache.thrift.protocol.TType.LIST, (short)3); + private static final org.apache.thrift.protocol.TField RESPONSE_TO_FIELD_DESC = new org.apache.thrift.protocol.TField("responseTo", org.apache.thrift.protocol.TType.I32, (short)4); + + public AsyncMessageHeader header; // required + public Store store; // required + public List<KeyedValues> values; // required + public int responseTo; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + STORE((short)2, "store"), + VALUES((short)3, "values"), + RESPONSE_TO((short)4, "responseTo"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // STORE + return STORE; + case 3: // VALUES + return VALUES; + case 4: // RESPONSE_TO + return RESPONSE_TO; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __RESPONSETO_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.STORE, new org.apache.thrift.meta_data.FieldMetaData("store", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Store.class))); + tmpMap.put(_Fields.VALUES, new org.apache.thrift.meta_data.FieldMetaData("values", org.apache.thrift.TFieldRequirementType.DEFAULT, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, KeyedValues.class)))); + tmpMap.put(_Fields.RESPONSE_TO, new org.apache.thrift.meta_data.FieldMetaData("responseTo", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncValueMessage.class, metaDataMap); + } + + public SyncValueMessage() { + } + + public SyncValueMessage( + AsyncMessageHeader header, + Store store, + List<KeyedValues> values) + { + this(); + this.header = header; + this.store = store; + this.values = values; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncValueMessage(SyncValueMessage other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + if (other.isSetStore()) { + this.store = new Store(other.store); + } + if (other.isSetValues()) { + List<KeyedValues> __this__values = new ArrayList<KeyedValues>(); + for (KeyedValues other_element : other.values) { + __this__values.add(new KeyedValues(other_element)); + } + this.values = __this__values; + } + this.responseTo = other.responseTo; + } + + public SyncValueMessage deepCopy() { + return new SyncValueMessage(this); + } + + @Override + public void clear() { + this.header = null; + this.store = null; + this.values = null; + setResponseToIsSet(false); + this.responseTo = 0; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public SyncValueMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public Store getStore() { + return this.store; + } + + public SyncValueMessage setStore(Store store) { + this.store = store; + return this; + } + + public void unsetStore() { + this.store = null; + } + + /** Returns true if field store is set (has been assigned a value) and false otherwise */ + public boolean isSetStore() { + return this.store != null; + } + + public void setStoreIsSet(boolean value) { + if (!value) { + this.store = null; + } + } + + public int getValuesSize() { + return (this.values == null) ? 0 : this.values.size(); + } + + public java.util.Iterator<KeyedValues> getValuesIterator() { + return (this.values == null) ? null : this.values.iterator(); + } + + public void addToValues(KeyedValues elem) { + if (this.values == null) { + this.values = new ArrayList<KeyedValues>(); + } + this.values.add(elem); + } + + public List<KeyedValues> getValues() { + return this.values; + } + + public SyncValueMessage setValues(List<KeyedValues> values) { + this.values = values; + return this; + } + + public void unsetValues() { + this.values = null; + } + + /** Returns true if field values is set (has been assigned a value) and false otherwise */ + public boolean isSetValues() { + return this.values != null; + } + + public void setValuesIsSet(boolean value) { + if (!value) { + this.values = null; + } + } + + public int getResponseTo() { + return this.responseTo; + } + + public SyncValueMessage setResponseTo(int responseTo) { + this.responseTo = responseTo; + setResponseToIsSet(true); + return this; + } + + public void unsetResponseTo() { + __isset_bit_vector.clear(__RESPONSETO_ISSET_ID); + } + + /** Returns true if field responseTo is set (has been assigned a value) and false otherwise */ + public boolean isSetResponseTo() { + return __isset_bit_vector.get(__RESPONSETO_ISSET_ID); + } + + public void setResponseToIsSet(boolean value) { + __isset_bit_vector.set(__RESPONSETO_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case STORE: + if (value == null) { + unsetStore(); + } else { + setStore((Store)value); + } + break; + + case VALUES: + if (value == null) { + unsetValues(); + } else { + setValues((List<KeyedValues>)value); + } + break; + + case RESPONSE_TO: + if (value == null) { + unsetResponseTo(); + } else { + setResponseTo((Integer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case STORE: + return getStore(); + + case VALUES: + return getValues(); + + case RESPONSE_TO: + return Integer.valueOf(getResponseTo()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case STORE: + return isSetStore(); + case VALUES: + return isSetValues(); + case RESPONSE_TO: + return isSetResponseTo(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncValueMessage) + return this.equals((SyncValueMessage)that); + return false; + } + + public boolean equals(SyncValueMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_store = true && this.isSetStore(); + boolean that_present_store = true && that.isSetStore(); + if (this_present_store || that_present_store) { + if (!(this_present_store && that_present_store)) + return false; + if (!this.store.equals(that.store)) + return false; + } + + boolean this_present_values = true && this.isSetValues(); + boolean that_present_values = true && that.isSetValues(); + if (this_present_values || that_present_values) { + if (!(this_present_values && that_present_values)) + return false; + if (!this.values.equals(that.values)) + return false; + } + + boolean this_present_responseTo = true && this.isSetResponseTo(); + boolean that_present_responseTo = true && that.isSetResponseTo(); + if (this_present_responseTo || that_present_responseTo) { + if (!(this_present_responseTo && that_present_responseTo)) + return false; + if (this.responseTo != that.responseTo) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncValueMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncValueMessage typedOther = (SyncValueMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetStore()).compareTo(typedOther.isSetStore()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetStore()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.store, typedOther.store); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValues()).compareTo(typedOther.isSetValues()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValues()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.values, typedOther.values); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetResponseTo()).compareTo(typedOther.isSetResponseTo()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetResponseTo()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.responseTo, typedOther.responseTo); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // STORE + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.store = new Store(); + this.store.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // VALUES + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list16 = iprot.readListBegin(); + this.values = new ArrayList<KeyedValues>(_list16.size); + for (int _i17 = 0; _i17 < _list16.size; ++_i17) + { + KeyedValues _elem18; // required + _elem18 = new KeyedValues(); + _elem18.read(iprot); + this.values.add(_elem18); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // RESPONSE_TO + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.responseTo = iprot.readI32(); + setResponseToIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (this.store != null) { + oprot.writeFieldBegin(STORE_FIELD_DESC); + this.store.write(oprot); + oprot.writeFieldEnd(); + } + if (this.values != null) { + oprot.writeFieldBegin(VALUES_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.values.size())); + for (KeyedValues _iter19 : this.values) + { + _iter19.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + if (isSetResponseTo()) { + oprot.writeFieldBegin(RESPONSE_TO_FIELD_DESC); + oprot.writeI32(this.responseTo); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncValueMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (!first) sb.append(", "); + sb.append("store:"); + if (this.store == null) { + sb.append("null"); + } else { + sb.append(this.store); + } + first = false; + if (!first) sb.append(", "); + sb.append("values:"); + if (this.values == null) { + sb.append("null"); + } else { + sb.append(this.values); + } + first = false; + if (isSetResponseTo()) { + if (!first) sb.append(", "); + sb.append("responseTo:"); + sb.append(this.responseTo); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + if (store == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'store' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/SyncValueResponseMessage.java b/lib/gen-java/org/sdnplatform/sync/thrift/SyncValueResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..20754c3ce22593867a668785f9921977451f908a --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/SyncValueResponseMessage.java @@ -0,0 +1,413 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class SyncValueResponseMessage implements org.apache.thrift.TBase<SyncValueResponseMessage, SyncValueResponseMessage._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SyncValueResponseMessage"); + + private static final org.apache.thrift.protocol.TField HEADER_FIELD_DESC = new org.apache.thrift.protocol.TField("header", org.apache.thrift.protocol.TType.STRUCT, (short)1); + private static final org.apache.thrift.protocol.TField COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("count", org.apache.thrift.protocol.TType.I32, (short)2); + + public AsyncMessageHeader header; // required + public int count; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + HEADER((short)1, "header"), + COUNT((short)2, "count"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // HEADER + return HEADER; + case 2: // COUNT + return COUNT; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __COUNT_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.HEADER, new org.apache.thrift.meta_data.FieldMetaData("header", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, AsyncMessageHeader.class))); + tmpMap.put(_Fields.COUNT, new org.apache.thrift.meta_data.FieldMetaData("count", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SyncValueResponseMessage.class, metaDataMap); + } + + public SyncValueResponseMessage() { + } + + public SyncValueResponseMessage( + AsyncMessageHeader header) + { + this(); + this.header = header; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public SyncValueResponseMessage(SyncValueResponseMessage other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetHeader()) { + this.header = new AsyncMessageHeader(other.header); + } + this.count = other.count; + } + + public SyncValueResponseMessage deepCopy() { + return new SyncValueResponseMessage(this); + } + + @Override + public void clear() { + this.header = null; + setCountIsSet(false); + this.count = 0; + } + + public AsyncMessageHeader getHeader() { + return this.header; + } + + public SyncValueResponseMessage setHeader(AsyncMessageHeader header) { + this.header = header; + return this; + } + + public void unsetHeader() { + this.header = null; + } + + /** Returns true if field header is set (has been assigned a value) and false otherwise */ + public boolean isSetHeader() { + return this.header != null; + } + + public void setHeaderIsSet(boolean value) { + if (!value) { + this.header = null; + } + } + + public int getCount() { + return this.count; + } + + public SyncValueResponseMessage setCount(int count) { + this.count = count; + setCountIsSet(true); + return this; + } + + public void unsetCount() { + __isset_bit_vector.clear(__COUNT_ISSET_ID); + } + + /** Returns true if field count is set (has been assigned a value) and false otherwise */ + public boolean isSetCount() { + return __isset_bit_vector.get(__COUNT_ISSET_ID); + } + + public void setCountIsSet(boolean value) { + __isset_bit_vector.set(__COUNT_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case HEADER: + if (value == null) { + unsetHeader(); + } else { + setHeader((AsyncMessageHeader)value); + } + break; + + case COUNT: + if (value == null) { + unsetCount(); + } else { + setCount((Integer)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case HEADER: + return getHeader(); + + case COUNT: + return Integer.valueOf(getCount()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case HEADER: + return isSetHeader(); + case COUNT: + return isSetCount(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof SyncValueResponseMessage) + return this.equals((SyncValueResponseMessage)that); + return false; + } + + public boolean equals(SyncValueResponseMessage that) { + if (that == null) + return false; + + boolean this_present_header = true && this.isSetHeader(); + boolean that_present_header = true && that.isSetHeader(); + if (this_present_header || that_present_header) { + if (!(this_present_header && that_present_header)) + return false; + if (!this.header.equals(that.header)) + return false; + } + + boolean this_present_count = true && this.isSetCount(); + boolean that_present_count = true && that.isSetCount(); + if (this_present_count || that_present_count) { + if (!(this_present_count && that_present_count)) + return false; + if (this.count != that.count) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(SyncValueResponseMessage other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + SyncValueResponseMessage typedOther = (SyncValueResponseMessage)other; + + lastComparison = Boolean.valueOf(isSetHeader()).compareTo(typedOther.isSetHeader()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetHeader()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.header, typedOther.header); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetCount()).compareTo(typedOther.isSetCount()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCount()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.count, typedOther.count); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // HEADER + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.header = new AsyncMessageHeader(); + this.header.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // COUNT + if (field.type == org.apache.thrift.protocol.TType.I32) { + this.count = iprot.readI32(); + setCountIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.header != null) { + oprot.writeFieldBegin(HEADER_FIELD_DESC); + this.header.write(oprot); + oprot.writeFieldEnd(); + } + if (isSetCount()) { + oprot.writeFieldBegin(COUNT_FIELD_DESC); + oprot.writeI32(this.count); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("SyncValueResponseMessage("); + boolean first = true; + + sb.append("header:"); + if (this.header == null) { + sb.append("null"); + } else { + sb.append(this.header); + } + first = false; + if (isSetCount()) { + if (!first) sb.append(", "); + sb.append("count:"); + sb.append(this.count); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (header == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'header' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/VectorClock.java b/lib/gen-java/org/sdnplatform/sync/thrift/VectorClock.java new file mode 100644 index 0000000000000000000000000000000000000000..7c26bc81088ec600c034a0bb84a2f6f37df0ebbf --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/VectorClock.java @@ -0,0 +1,444 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class VectorClock implements org.apache.thrift.TBase<VectorClock, VectorClock._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("VectorClock"); + + private static final org.apache.thrift.protocol.TField VERSIONS_FIELD_DESC = new org.apache.thrift.protocol.TField("versions", org.apache.thrift.protocol.TType.LIST, (short)1); + private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short)2); + + public List<ClockEntry> versions; // required + public long timestamp; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + VERSIONS((short)1, "versions"), + TIMESTAMP((short)2, "timestamp"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // VERSIONS + return VERSIONS; + case 2: // TIMESTAMP + return TIMESTAMP; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + private static final int __TIMESTAMP_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.VERSIONS, new org.apache.thrift.meta_data.FieldMetaData("versions", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ClockEntry.class)))); + tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(VectorClock.class, metaDataMap); + } + + public VectorClock() { + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public VectorClock(VectorClock other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetVersions()) { + List<ClockEntry> __this__versions = new ArrayList<ClockEntry>(); + for (ClockEntry other_element : other.versions) { + __this__versions.add(new ClockEntry(other_element)); + } + this.versions = __this__versions; + } + this.timestamp = other.timestamp; + } + + public VectorClock deepCopy() { + return new VectorClock(this); + } + + @Override + public void clear() { + this.versions = null; + setTimestampIsSet(false); + this.timestamp = 0; + } + + public int getVersionsSize() { + return (this.versions == null) ? 0 : this.versions.size(); + } + + public java.util.Iterator<ClockEntry> getVersionsIterator() { + return (this.versions == null) ? null : this.versions.iterator(); + } + + public void addToVersions(ClockEntry elem) { + if (this.versions == null) { + this.versions = new ArrayList<ClockEntry>(); + } + this.versions.add(elem); + } + + public List<ClockEntry> getVersions() { + return this.versions; + } + + public VectorClock setVersions(List<ClockEntry> versions) { + this.versions = versions; + return this; + } + + public void unsetVersions() { + this.versions = null; + } + + /** Returns true if field versions is set (has been assigned a value) and false otherwise */ + public boolean isSetVersions() { + return this.versions != null; + } + + public void setVersionsIsSet(boolean value) { + if (!value) { + this.versions = null; + } + } + + public long getTimestamp() { + return this.timestamp; + } + + public VectorClock setTimestamp(long timestamp) { + this.timestamp = timestamp; + setTimestampIsSet(true); + return this; + } + + public void unsetTimestamp() { + __isset_bit_vector.clear(__TIMESTAMP_ISSET_ID); + } + + /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */ + public boolean isSetTimestamp() { + return __isset_bit_vector.get(__TIMESTAMP_ISSET_ID); + } + + public void setTimestampIsSet(boolean value) { + __isset_bit_vector.set(__TIMESTAMP_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case VERSIONS: + if (value == null) { + unsetVersions(); + } else { + setVersions((List<ClockEntry>)value); + } + break; + + case TIMESTAMP: + if (value == null) { + unsetTimestamp(); + } else { + setTimestamp((Long)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case VERSIONS: + return getVersions(); + + case TIMESTAMP: + return Long.valueOf(getTimestamp()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case VERSIONS: + return isSetVersions(); + case TIMESTAMP: + return isSetTimestamp(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof VectorClock) + return this.equals((VectorClock)that); + return false; + } + + public boolean equals(VectorClock that) { + if (that == null) + return false; + + boolean this_present_versions = true && this.isSetVersions(); + boolean that_present_versions = true && that.isSetVersions(); + if (this_present_versions || that_present_versions) { + if (!(this_present_versions && that_present_versions)) + return false; + if (!this.versions.equals(that.versions)) + return false; + } + + boolean this_present_timestamp = true && this.isSetTimestamp(); + boolean that_present_timestamp = true && that.isSetTimestamp(); + if (this_present_timestamp || that_present_timestamp) { + if (!(this_present_timestamp && that_present_timestamp)) + return false; + if (this.timestamp != that.timestamp) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(VectorClock other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + VectorClock typedOther = (VectorClock)other; + + lastComparison = Boolean.valueOf(isSetVersions()).compareTo(typedOther.isSetVersions()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersions()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.versions, typedOther.versions); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(typedOther.isSetTimestamp()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetTimestamp()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, typedOther.timestamp); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // VERSIONS + if (field.type == org.apache.thrift.protocol.TType.LIST) { + { + org.apache.thrift.protocol.TList _list0 = iprot.readListBegin(); + this.versions = new ArrayList<ClockEntry>(_list0.size); + for (int _i1 = 0; _i1 < _list0.size; ++_i1) + { + ClockEntry _elem2; // required + _elem2 = new ClockEntry(); + _elem2.read(iprot); + this.versions.add(_elem2); + } + iprot.readListEnd(); + } + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // TIMESTAMP + if (field.type == org.apache.thrift.protocol.TType.I64) { + this.timestamp = iprot.readI64(); + setTimestampIsSet(true); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.versions != null) { + if (isSetVersions()) { + oprot.writeFieldBegin(VERSIONS_FIELD_DESC); + { + oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, this.versions.size())); + for (ClockEntry _iter3 : this.versions) + { + _iter3.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + } + if (isSetTimestamp()) { + oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC); + oprot.writeI64(this.timestamp); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("VectorClock("); + boolean first = true; + + if (isSetVersions()) { + sb.append("versions:"); + if (this.versions == null) { + sb.append("null"); + } else { + sb.append(this.versions); + } + first = false; + } + if (isSetTimestamp()) { + if (!first) sb.append(", "); + sb.append("timestamp:"); + sb.append(this.timestamp); + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor. + __isset_bit_vector = new BitSet(1); + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/gen-java/org/sdnplatform/sync/thrift/VersionedValue.java b/lib/gen-java/org/sdnplatform/sync/thrift/VersionedValue.java new file mode 100644 index 0000000000000000000000000000000000000000..9ff855f4181815d02c14fc514eec3b5b125fa8c5 --- /dev/null +++ b/lib/gen-java/org/sdnplatform/sync/thrift/VersionedValue.java @@ -0,0 +1,425 @@ +/** + * Autogenerated by Thrift Compiler (0.7.0) + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.sdnplatform.sync.thrift; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("all") public class VersionedValue implements org.apache.thrift.TBase<VersionedValue, VersionedValue._Fields>, java.io.Serializable, Cloneable { + private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("VersionedValue"); + + private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)1); + private static final org.apache.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.thrift.protocol.TField("version", org.apache.thrift.protocol.TType.STRUCT, (short)2); + + public ByteBuffer value; // required + public VectorClock version; // required + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements org.apache.thrift.TFieldIdEnum { + VALUE((short)1, "value"), + VERSION((short)2, "version"); + + private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); + + static { + for (_Fields field : EnumSet.allOf(_Fields.class)) { + byName.put(field.getFieldName(), field); + } + } + + /** + * Find the _Fields constant that matches fieldId, or null if its not found. + */ + public static _Fields findByThriftId(int fieldId) { + switch(fieldId) { + case 1: // VALUE + return VALUE; + case 2: // VERSION + return VERSION; + default: + return null; + } + } + + /** + * Find the _Fields constant that matches fieldId, throwing an exception + * if it is not found. + */ + public static _Fields findByThriftIdOrThrow(int fieldId) { + _Fields fields = findByThriftId(fieldId); + if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!"); + return fields; + } + + /** + * Find the _Fields constant that matches name, or null if its not found. + */ + public static _Fields findByName(String name) { + return byName.get(name); + } + + private final short _thriftId; + private final String _fieldName; + + _Fields(short thriftId, String fieldName) { + _thriftId = thriftId; + _fieldName = fieldName; + } + + public short getThriftFieldId() { + return _thriftId; + } + + public String getFieldName() { + return _fieldName; + } + } + + // isset id assignments + + public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; + static { + Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.OPTIONAL, + new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING , true))); + tmpMap.put(_Fields.VERSION, new org.apache.thrift.meta_data.FieldMetaData("version", org.apache.thrift.TFieldRequirementType.REQUIRED, + new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, VectorClock.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(VersionedValue.class, metaDataMap); + } + + public VersionedValue() { + } + + public VersionedValue( + VectorClock version) + { + this(); + this.version = version; + } + + /** + * Performs a deep copy on <i>other</i>. + */ + public VersionedValue(VersionedValue other) { + if (other.isSetValue()) { + this.value = org.apache.thrift.TBaseHelper.copyBinary(other.value); +; + } + if (other.isSetVersion()) { + this.version = new VectorClock(other.version); + } + } + + public VersionedValue deepCopy() { + return new VersionedValue(this); + } + + @Override + public void clear() { + this.value = null; + this.version = null; + } + + public byte[] getValue() { + setValue(org.apache.thrift.TBaseHelper.rightSize(value)); + return value == null ? null : value.array(); + } + + public ByteBuffer bufferForValue() { + return value; + } + + public VersionedValue setValue(byte[] value) { + setValue(value == null ? (ByteBuffer)null : ByteBuffer.wrap(value)); + return this; + } + + public VersionedValue setValue(ByteBuffer value) { + this.value = value; + return this; + } + + public void unsetValue() { + this.value = null; + } + + /** Returns true if field value is set (has been assigned a value) and false otherwise */ + public boolean isSetValue() { + return this.value != null; + } + + public void setValueIsSet(boolean value) { + if (!value) { + this.value = null; + } + } + + public VectorClock getVersion() { + return this.version; + } + + public VersionedValue setVersion(VectorClock version) { + this.version = version; + return this; + } + + public void unsetVersion() { + this.version = null; + } + + /** Returns true if field version is set (has been assigned a value) and false otherwise */ + public boolean isSetVersion() { + return this.version != null; + } + + public void setVersionIsSet(boolean value) { + if (!value) { + this.version = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case VALUE: + if (value == null) { + unsetValue(); + } else { + setValue((ByteBuffer)value); + } + break; + + case VERSION: + if (value == null) { + unsetVersion(); + } else { + setVersion((VectorClock)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case VALUE: + return getValue(); + + case VERSION: + return getVersion(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case VALUE: + return isSetValue(); + case VERSION: + return isSetVersion(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof VersionedValue) + return this.equals((VersionedValue)that); + return false; + } + + public boolean equals(VersionedValue that) { + if (that == null) + return false; + + boolean this_present_value = true && this.isSetValue(); + boolean that_present_value = true && that.isSetValue(); + if (this_present_value || that_present_value) { + if (!(this_present_value && that_present_value)) + return false; + if (!this.value.equals(that.value)) + return false; + } + + boolean this_present_version = true && this.isSetVersion(); + boolean that_present_version = true && that.isSetVersion(); + if (this_present_version || that_present_version) { + if (!(this_present_version && that_present_version)) + return false; + if (!this.version.equals(that.version)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public int compareTo(VersionedValue other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + VersionedValue typedOther = (VersionedValue)other; + + lastComparison = Boolean.valueOf(isSetValue()).compareTo(typedOther.isSetValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValue()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.value, typedOther.value); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetVersion()).compareTo(typedOther.isSetVersion()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetVersion()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.version, typedOther.version); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { + org.apache.thrift.protocol.TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == org.apache.thrift.protocol.TType.STOP) { + break; + } + switch (field.id) { + case 1: // VALUE + if (field.type == org.apache.thrift.protocol.TType.STRING) { + this.value = iprot.readBinary(); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // VERSION + if (field.type == org.apache.thrift.protocol.TType.STRUCT) { + this.version = new VectorClock(); + this.version.read(iprot); + } else { + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + break; + default: + org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.value != null) { + if (isSetValue()) { + oprot.writeFieldBegin(VALUE_FIELD_DESC); + oprot.writeBinary(this.value); + oprot.writeFieldEnd(); + } + } + if (this.version != null) { + oprot.writeFieldBegin(VERSION_FIELD_DESC); + this.version.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("VersionedValue("); + boolean first = true; + + if (isSetValue()) { + sb.append("value:"); + if (this.value == null) { + sb.append("null"); + } else { + org.apache.thrift.TBaseHelper.toString(this.value, sb); + } + first = false; + } + if (!first) sb.append(", "); + sb.append("version:"); + if (this.version == null) { + sb.append("null"); + } else { + sb.append(this.version); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws org.apache.thrift.TException { + // check for required fields + if (version == null) { + throw new org.apache.thrift.protocol.TProtocolException("Required field 'version' was not present! Struct: " + toString()); + } + } + + private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { + try { + write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + + private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { + try { + read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); + } catch (org.apache.thrift.TException te) { + throw new java.io.IOException(te); + } + } + +} + diff --git a/lib/jackson-annotations-2.1.4.jar b/lib/jackson-annotations-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..143edf44b0daa4cef1a452ecccac21aee22a8d77 Binary files /dev/null and b/lib/jackson-annotations-2.1.4.jar differ diff --git a/lib/jackson-core-2.1.4.jar b/lib/jackson-core-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..0f144685f7140d2694eeba5609322b4cd79f0bf8 Binary files /dev/null and b/lib/jackson-core-2.1.4.jar differ diff --git a/lib/jackson-core-asl-1.8.6.jar b/lib/jackson-core-asl-1.8.6.jar deleted file mode 100644 index fe6c6606fe88b7eecd3568674f2cbf7ffb7eacc2..0000000000000000000000000000000000000000 Binary files a/lib/jackson-core-asl-1.8.6.jar and /dev/null differ diff --git a/lib/jackson-databind-2.1.4.jar b/lib/jackson-databind-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..ce125d1df292a1d8fa4b86cf39770d0d9c4636cc Binary files /dev/null and b/lib/jackson-databind-2.1.4.jar differ diff --git a/lib/jackson-dataformat-csv-2.1.4.jar b/lib/jackson-dataformat-csv-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..e97503cb161c44ca54d096ec669b707e522f0004 Binary files /dev/null and b/lib/jackson-dataformat-csv-2.1.4.jar differ diff --git a/lib/jackson-dataformat-smile-2.1.4.jar b/lib/jackson-dataformat-smile-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..e907c7726c5679a572e098293581bba28ac63fa1 Binary files /dev/null and b/lib/jackson-dataformat-smile-2.1.4.jar differ diff --git a/lib/jackson-dataformat-xml-2.1.4.jar b/lib/jackson-dataformat-xml-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..15c82e69c86703363e16d47cb8cb3c3de1919c43 Binary files /dev/null and b/lib/jackson-dataformat-xml-2.1.4.jar differ diff --git a/lib/jackson-dataformat-yaml-2.1.4.jar b/lib/jackson-dataformat-yaml-2.1.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..444ef88653e9574fb90246679835448e02170ee8 Binary files /dev/null and b/lib/jackson-dataformat-yaml-2.1.4.jar differ diff --git a/lib/jackson-mapper-asl-1.8.6.jar b/lib/jackson-mapper-asl-1.8.6.jar deleted file mode 100644 index f3dd1a6ba56faf5dabd6bcfda96eb7f00d4557be..0000000000000000000000000000000000000000 Binary files a/lib/jackson-mapper-asl-1.8.6.jar and /dev/null differ diff --git a/lib/org.restlet-2.1-RC1.jar b/lib/org.restlet-2.1-RC1.jar deleted file mode 100644 index 6b931a034dbff19839dd80852c8f55f598aee904..0000000000000000000000000000000000000000 Binary files a/lib/org.restlet-2.1-RC1.jar and /dev/null differ diff --git a/lib/org.restlet-2.2M3.jar b/lib/org.restlet-2.2M3.jar new file mode 100644 index 0000000000000000000000000000000000000000..a23f783d8312bd2a9a8728f96c3379454fb7a1ac Binary files /dev/null and b/lib/org.restlet-2.2M3.jar differ diff --git a/lib/org.restlet.ext.jackson-2.1-RC1.jar b/lib/org.restlet.ext.jackson-2.1-RC1.jar deleted file mode 100644 index 5ff6ce7b3b7f23a54095da740e5bb851d72ae2af..0000000000000000000000000000000000000000 Binary files a/lib/org.restlet.ext.jackson-2.1-RC1.jar and /dev/null differ diff --git a/lib/org.restlet.ext.jackson-2.2M3.jar b/lib/org.restlet.ext.jackson-2.2M3.jar new file mode 100644 index 0000000000000000000000000000000000000000..f4f95781d05a8af3e1e96fb0647e148f7a0a7f6a Binary files /dev/null and b/lib/org.restlet.ext.jackson-2.2M3.jar differ diff --git a/lib/org.restlet.ext.simple-2.1-RC1.jar b/lib/org.restlet.ext.simple-2.1-RC1.jar deleted file mode 100644 index 3cd9f7ffa88f5e3c6384d8b8deaa2e157064f56c..0000000000000000000000000000000000000000 Binary files a/lib/org.restlet.ext.simple-2.1-RC1.jar and /dev/null differ diff --git a/lib/org.restlet.ext.simple-2.2M3.jar b/lib/org.restlet.ext.simple-2.2M3.jar new file mode 100644 index 0000000000000000000000000000000000000000..c870c7cf50c075b1daf0be3db1a6fb8fe231d948 Binary files /dev/null and b/lib/org.restlet.ext.simple-2.2M3.jar differ diff --git a/lib/org.restlet.ext.slf4j-2.1-RC1.jar b/lib/org.restlet.ext.slf4j-2.1-RC1.jar deleted file mode 100644 index 99346d15b26dda49ead5575f0e47d2a050486e97..0000000000000000000000000000000000000000 Binary files a/lib/org.restlet.ext.slf4j-2.1-RC1.jar and /dev/null differ diff --git a/lib/org.restlet.ext.slf4j-2.2M3.jar b/lib/org.restlet.ext.slf4j-2.2M3.jar new file mode 100644 index 0000000000000000000000000000000000000000..83eed674e2fde6deed5e67593ff909ba0001fc29 Binary files /dev/null and b/lib/org.restlet.ext.slf4j-2.2M3.jar differ diff --git a/lib/simple-4.1.21.jar b/lib/simple-4.1.21.jar deleted file mode 100644 index b7fb53c756d88910cbd149b416a419391b3d77f4..0000000000000000000000000000000000000000 Binary files a/lib/simple-4.1.21.jar and /dev/null differ diff --git a/lib/simple-5.1.1.jar b/lib/simple-5.1.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..b536f4098086a35ccecd50035c728b02b5e11cfb Binary files /dev/null and b/lib/simple-5.1.1.jar differ diff --git a/logback.xml b/logback.xml index b85b463f507fd1b4037f809bc1ed566394a67195..aad2c58da2c1c276b866e1f3cfebc109d034fd07 100644 --- a/logback.xml +++ b/logback.xml @@ -11,4 +11,5 @@ <logger name="LogService" level="WARN"/> <!-- Restlet access logging --> <logger name="net.floodlightcontroller" level="INFO"/> <logger name="net.floodlightcontroller.logging" level="WARN"/> + <logger name="org.sdnplatform" level="INFO"/> </configuration> diff --git a/setup-eclipse.sh b/setup-eclipse.sh index 4224a3c5c982f4fee5768a0e5bd788ea36f0b765..3be048a516d4bad794267f68f8182d234bc8b5db 100755 --- a/setup-eclipse.sh +++ b/setup-eclipse.sh @@ -56,6 +56,22 @@ cat > "$d/Floodlight-Quantum-Conf.launch" << EOF </launchConfiguration> EOF +cat >"$d/SyncClient.launch" << EOF +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication"> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/floodlight/src/main/java/org/sdnplatform/sync/client/SyncClient.java"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.sdnplatform.sync.client.SyncClient"/> +<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="--hostname localhost --port 6642"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="bigfloodlight"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/> +</launchConfiguration> +EOF + cat >"$d/.classpath" <<EOF <?xml version="1.0" encoding="UTF-8"?> <classpath> diff --git a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java index 8b201b325c55fce36f800697a2739a324b28e9b7..3da2f4e9d2cfd7d0f2e27ad013ed5cafeebdfe3b 100644 --- a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java +++ b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java @@ -49,10 +49,10 @@ import net.floodlightcontroller.threadpool.IThreadPoolService; import net.floodlightcontroller.util.MACAddress; import net.floodlightcontroller.util.TimedCache; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.annotate.JsonSerialize; -import org.codehaus.jackson.map.ser.ToStringSerializer; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.jboss.netty.channel.Channel; import org.openflow.protocol.OFBarrierRequest; import org.openflow.protocol.OFFeaturesReply; diff --git a/src/main/java/net/floodlightcontroller/core/RoleInfo.java b/src/main/java/net/floodlightcontroller/core/RoleInfo.java index 26c1a510bd556e5cedb5eb0b91f45e45ebe0e456..09ac98b1fb3d4c0b116fa1e6b5a692cf09df22a8 100644 --- a/src/main/java/net/floodlightcontroller/core/RoleInfo.java +++ b/src/main/java/net/floodlightcontroller/core/RoleInfo.java @@ -22,7 +22,7 @@ import java.util.TimeZone; import net.floodlightcontroller.core.IFloodlightProviderService.Role; -import org.codehaus.jackson.annotate.JsonProperty; +import com.fasterxml.jackson.annotation.JsonProperty; public class RoleInfo { diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index 3b90773ae7b261a1de21d04a8da2f3252fb2a4d2..8999f92ed4af1bfc964384d67d07abf5132b74c3 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -141,7 +141,7 @@ public class Controller implements IFloodlightProviderService, protected static Logger log = LoggerFactory.getLogger(Controller.class); - private static final String ERROR_DATABASE = + static final String ERROR_DATABASE = "The controller could not communicate with the system database."; protected BasicFactory factory; @@ -1817,7 +1817,7 @@ public class Controller implements IFloodlightProviderService, this.connectedSwitches = new HashSet<IOFSwitch>(); this.controllerNodeIPsCache = new HashMap<String, String>(); this.updates = new LinkedBlockingQueue<IUpdate>(); - this.factory = new BasicFactory(); + this.factory = BasicFactory.getInstance(); this.providerMap = new HashMap<String, List<IInfoProvider>>(); setConfigParams(configParams); this.role = getInitialRole(configParams); diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java index 295e9679db82dd4c65148adb65e4f3ed2c507f7a..25edf396c943dfce728f79610910162ebd608a12 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFMessageDecoder.java @@ -34,7 +34,7 @@ import org.openflow.protocol.factory.OFMessageFactory; */ public class OFMessageDecoder extends FrameDecoder { - OFMessageFactory factory = new BasicFactory(); + OFMessageFactory factory = BasicFactory.getInstance(); @Override protected Object decode(ChannelHandlerContext ctx, Channel channel, diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java index a3809a1b80e7cfbc6b1e2f86d880ff95e3a37a35..d924ce255353a5e67ccfefa9fa933c3c35d15cab 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java @@ -19,7 +19,7 @@ package net.floodlightcontroller.core.internal; import java.util.List; -import org.codehaus.jackson.annotate.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.openflow.protocol.statistics.OFDescriptionStatistics; import net.floodlightcontroller.core.OFSwitchBase; diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java index 66c33f55bfbf5262049c9cf60c2c730fcd69a04a..ce4d3ba3c51480ad3ab3b488c398727efb6d85b4 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java @@ -19,10 +19,10 @@ package net.floodlightcontroller.core.web.serializers; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/DPIDSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/DPIDSerializer.java index e74cc01c1001d576148c0adc80eacf8e6547451c..6df067ead245a209b12ce20347c237913a8f7b29 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/DPIDSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/DPIDSerializer.java @@ -19,10 +19,10 @@ package net.floodlightcontroller.core.web.serializers; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/IPv4Serializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/IPv4Serializer.java index f4a58778656144be714ad25e4a11e7697e39bd62..db93b66ac46af312c37f59c36febe4357389e188 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/IPv4Serializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/IPv4Serializer.java @@ -21,10 +21,10 @@ import java.io.IOException; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; /** * Serialize an integer as an IPv4 Address in dotted decimal format diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/MACSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/MACSerializer.java index a7c9fb7d909438326d767f445d7c4e4c7df641ed..c797681edf2e8779365293188e89f51b9b4c30a1 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/MACSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/MACSerializer.java @@ -19,10 +19,10 @@ package net.floodlightcontroller.core.web.serializers; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java index c125c76fc6138924f4ac04ceb918ca7dcbe80d90..c5f1fa9a1ec6d39b0ce35ef777fc6a1d80a80771 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java @@ -19,10 +19,10 @@ package net.floodlightcontroller.core.web.serializers; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; /** * Serialize a short value as an unsigned short diff --git a/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java b/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java index 742616371e09fe8031cbd819ec873bff8d22aa79..d4ee9459ee59ae67b1e2c26069d06e2ee2c0a74f 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/SwitchPort.java @@ -19,8 +19,8 @@ package net.floodlightcontroller.devicemanager; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; -import org.codehaus.jackson.map.annotate.JsonSerialize; -import org.codehaus.jackson.map.ser.ToStringSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; /** * A simple switch DPID/port pair diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java index ebdc8b11ff4061a283af39559c11c0f273512e04..e7e103221916291f3eb7420d47efd2c8e8886523 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java @@ -29,7 +29,7 @@ import java.util.List; import java.util.Map; import java.util.TreeSet; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.openflow.util.HexString; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java index 5949a19e22d40542b83eef1660478a4655f8cce8..db8d8e9fb3ff92256e0e9db55751e9345e6765fa 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/Entity.java @@ -24,8 +24,8 @@ import net.floodlightcontroller.core.web.serializers.MACSerializer; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java index e946d7b8aa7674ad598ba022e75e556ca9780297..26b2027aaa34ece55d1541a3f60bb058d27e74e3 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/web/DeviceSerializer.java @@ -23,10 +23,10 @@ import net.floodlightcontroller.devicemanager.SwitchPort; import net.floodlightcontroller.devicemanager.internal.Device; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java index 34a7771672c0f6dda39726d13e6022c4edfa3041..2f731db49e1911849745b43982ee9d74edba91d2 100644 --- a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java +++ b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java @@ -19,10 +19,10 @@ package net.floodlightcontroller.firewall; import java.io.IOException; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.restlet.resource.Post; import org.restlet.resource.Get; import org.restlet.resource.ServerResource; diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java index 1b187f310901b521ba7897d25917e36f7359f357..f457ce8d9e85510f91fdefe2bb2f3ac84276eec4 100644 --- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java +++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java @@ -17,7 +17,7 @@ package net.floodlightcontroller.firewall; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.openflow.protocol.OFMatch; import net.floodlightcontroller.packet.Ethernet; diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRuleSerializer.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRuleSerializer.java index b8fa6322e87e05618b739efc592339fa9a93b5f7..3180968d1dd1786ef183933bc8584a5b896b123d 100644 --- a/src/main/java/net/floodlightcontroller/firewall/FirewallRuleSerializer.java +++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRuleSerializer.java @@ -22,10 +22,10 @@ import java.io.IOException; import net.floodlightcontroller.packet.IPv4; import net.floodlightcontroller.util.MACAddress; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java index 66d9dce6248cf42bde73992c83b629e679789abe..b72f983dd3edafe2a92521f7cdd35afd5494e990 100644 --- a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java +++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java @@ -21,10 +21,10 @@ import java.io.IOException; import java.util.Iterator; import java.util.List; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.openflow.util.HexString; import org.restlet.resource.Delete; import org.restlet.resource.Post; diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java index a7d996d022a0cbbd94f3ddfad3def876a2122568..e4e109ca46fea5d8605109aea8f497c6300edcb6 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java @@ -16,8 +16,8 @@ package net.floodlightcontroller.linkdiscovery; -import org.codehaus.jackson.map.annotate.JsonSerialize; -import org.codehaus.jackson.map.ser.ToStringSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.openflow.util.HexString; public interface ILinkDiscovery { diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java index cb52ba6dc63b62031d6e4712a28ff3e8b1dbb14c..5cfabd821f167bfb0d112323de301bfb24991398 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyCluster.java @@ -18,8 +18,8 @@ package net.floodlightcontroller.linkdiscovery.internal; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; /*** * Topology Cluster merge/split event history related classes and members diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java index dc061c6f4c11733a8813e79a1e5ff8f05bb8ddee..b8d3e143c31b8529134f63ee5575a1559113229f 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologyLink.java @@ -18,8 +18,8 @@ package net.floodlightcontroller.linkdiscovery.internal; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; /*** * Topology link up/down event history related classes and members diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java index 3b27c8eef9e82ed8a2ecd30986a1c13d0a39eb36..f8c79837f68cc55c10f174e9aadf0d7bc951cc57 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/EventHistoryTopologySwitch.java @@ -19,8 +19,8 @@ package net.floodlightcontroller.linkdiscovery.internal; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; import net.floodlightcontroller.core.web.serializers.IPv4Serializer; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; /*** * Topology Switch event history related classes and members diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java b/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java index a09cc12ab01a8941d72fbfd8a86cbe0957cf2af8..8de425b168a166aa8d14435a27616b19d8f0ec55 100644 --- a/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java +++ b/src/main/java/net/floodlightcontroller/linkdiscovery/web/LinkWithType.java @@ -18,11 +18,11 @@ package net.floodlightcontroller.linkdiscovery.web; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.openflow.util.HexString; import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LinkDirection; diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LBMember.java b/src/main/java/net/floodlightcontroller/loadbalancer/LBMember.java index c3976e3c3f8dfd7361bf6f4ac8ad8cb9916af94e..40569b478bd171f212d969b6e61cf9d1da3c5c12 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LBMember.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LBMember.java @@ -16,7 +16,7 @@ package net.floodlightcontroller.loadbalancer; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** * Data structure for Load Balancer based on diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LBMemberSerializer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LBMemberSerializer.java index 1653b00d04ee173df4cdad81fa3955ccfb46b06d..bb723e01ab4b87fb6adc49ac2ba8cc5cfc0a8179 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LBMemberSerializer.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LBMemberSerializer.java @@ -18,10 +18,10 @@ package net.floodlightcontroller.loadbalancer; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; public class LBMemberSerializer extends JsonSerializer<LBMember>{ diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LBPool.java b/src/main/java/net/floodlightcontroller/loadbalancer/LBPool.java index 07961150e0feb8e7c6f6910c1d8bcc8233a9ff31..2e06fb123267b6f6e57139b686569ab0a8b6d15c 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LBPool.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LBPool.java @@ -18,7 +18,7 @@ package net.floodlightcontroller.loadbalancer; import java.util.ArrayList; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import net.floodlightcontroller.loadbalancer.LoadBalancer.IPClient; diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LBPoolSerializer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LBPoolSerializer.java index 042c13ccbef1b5658ec409c143c84f3503e62372..4cb3ae1eaecef9685786103015ad18e0baf38ff9 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LBPoolSerializer.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LBPoolSerializer.java @@ -18,10 +18,10 @@ package net.floodlightcontroller.loadbalancer; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; public class LBPoolSerializer extends JsonSerializer<LBPool>{ diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LBVip.java b/src/main/java/net/floodlightcontroller/loadbalancer/LBVip.java index 10e3de375bcfae4056573f640f53c536709dcf5a..1d0a9bdadd16cca75dccb00cb3251cd4b160e59b 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LBVip.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LBVip.java @@ -18,7 +18,7 @@ package net.floodlightcontroller.loadbalancer; import java.util.ArrayList; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import net.floodlightcontroller.loadbalancer.LoadBalancer.IPClient; import net.floodlightcontroller.util.MACAddress; diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LBVipSerializer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LBVipSerializer.java index 4421a9c3b4c6ba41a40a1dee60cf9af9aa9b2d3b..9a853b37d317abe899a8888b4c0e42c4e29fa00f 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/LBVipSerializer.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/LBVipSerializer.java @@ -17,10 +17,10 @@ package net.floodlightcontroller.loadbalancer; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; public class LBVipSerializer extends JsonSerializer<LBVip>{ diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/MembersResource.java b/src/main/java/net/floodlightcontroller/loadbalancer/MembersResource.java index 43c808bd1cbd5c146f3c28925c8f34c572945e66..b18ad040f4e7bdbb1b07b42176413573893d0b5e 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/MembersResource.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/MembersResource.java @@ -21,10 +21,10 @@ import java.util.Collection; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/MonitorsResource.java b/src/main/java/net/floodlightcontroller/loadbalancer/MonitorsResource.java index 3f378ef334bb112fc7a596f0d49a30981ad2904a..928039c1f00f695d502261273192623c270a7f68 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/MonitorsResource.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/MonitorsResource.java @@ -19,10 +19,11 @@ package net.floodlightcontroller.loadbalancer; import java.io.IOException; import java.util.Collection; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; + import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/PoolsResource.java b/src/main/java/net/floodlightcontroller/loadbalancer/PoolsResource.java index 42d0477b5511bd54577692ed2452cf69e1e82297..8feb2eb03d1668eb23d0589ac3f1f8f21e58597d 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/PoolsResource.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/PoolsResource.java @@ -21,10 +21,10 @@ import java.util.Collection; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/VipsResource.java b/src/main/java/net/floodlightcontroller/loadbalancer/VipsResource.java index da64998b5e9c814881fb6c26071f683d63d5510e..9fe63886e9016317b6cb46090bfa13b9f71ce001 100644 --- a/src/main/java/net/floodlightcontroller/loadbalancer/VipsResource.java +++ b/src/main/java/net/floodlightcontroller/loadbalancer/VipsResource.java @@ -21,10 +21,10 @@ import java.util.Collection; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; diff --git a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java index 0db2aa89156e9969d393778b54a144a0933d08b3..9d6531889becf37f29ee9df1894d0a0401016c12 100644 --- a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java +++ b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import net.floodlightcontroller.core.IOFMessageListener; diff --git a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java index bd2b98447482f7db6b027d3d3e4687b618bb246a..8dbeba100644899b523d034fe0a0a198d5169b0e 100644 --- a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java +++ b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucketJSONSerializer.java @@ -20,10 +20,10 @@ import java.io.IOException; import java.sql.Timestamp; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; public class CumulativeTimeBucketJSONSerializer extends JsonSerializer<CumulativeTimeBucket> { diff --git a/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java b/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java index 02e56920d7fedcacb22f5b8219e2544a91d14804..b14c18c41b7b3be5c86914fcda676cb7ed225ee6 100644 --- a/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java +++ b/src/main/java/net/floodlightcontroller/perfmon/OneComponentTime.java @@ -16,7 +16,7 @@ package net.floodlightcontroller.perfmon; -import org.codehaus.jackson.annotate.JsonProperty; +import com.fasterxml.jackson.annotation.JsonProperty; import net.floodlightcontroller.core.IOFMessageListener; diff --git a/src/main/java/net/floodlightcontroller/routing/Link.java b/src/main/java/net/floodlightcontroller/routing/Link.java index b79b9a9bc942aeb425a046f42aa790b0d29f011d..abe88cfc1d8edf9bf1ddf22543cae8b18035170b 100755 --- a/src/main/java/net/floodlightcontroller/routing/Link.java +++ b/src/main/java/net/floodlightcontroller/routing/Link.java @@ -20,8 +20,8 @@ package net.floodlightcontroller.routing; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; import net.floodlightcontroller.core.web.serializers.UShortSerializer; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.openflow.util.HexString; public class Link implements Comparable<Link> { diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java index fc12b3edb165ed47330ad0bb62649d8f3a863d8f..1eb337e2b2f7e6abfb42982138bc7c2efb4f258b 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java @@ -34,10 +34,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.openflow.protocol.OFFlowMod; import org.openflow.protocol.OFMatch; import org.openflow.protocol.OFPacketOut; diff --git a/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java b/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java index fcfa96f40d6b0e27271f48b9a91524d5b6a52a0e..a439809ba8236c36e0c78a9ff7a1bb4e5266b0e7 100644 --- a/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java +++ b/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java @@ -24,8 +24,8 @@ import java.util.Map; import net.floodlightcontroller.storage.IStorageSourceService; import net.floodlightcontroller.storage.StorageSourceNotification; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; import org.restlet.resource.Post; import org.restlet.resource.ServerResource; import org.slf4j.Logger; diff --git a/src/main/java/net/floodlightcontroller/threadpool/ThreadPool.java b/src/main/java/net/floodlightcontroller/threadpool/ThreadPool.java index 5b0c3c7133a54a10214b0a03bf7c15bc43e840da..0970b36f692a5148dd3bb313df8864f61e4fe858 100644 --- a/src/main/java/net/floodlightcontroller/threadpool/ThreadPool.java +++ b/src/main/java/net/floodlightcontroller/threadpool/ThreadPool.java @@ -22,6 +22,8 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; @@ -70,7 +72,17 @@ public class ThreadPool implements IThreadPoolService, IFloodlightModule { @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { - executor = Executors.newScheduledThreadPool(15); + final ThreadGroup tg = new ThreadGroup("Scheduled Task Threads"); + ThreadFactory f = new ThreadFactory() { + AtomicInteger id = new AtomicInteger(); + + @Override + public Thread newThread(Runnable runnable) { + return new Thread(tg, runnable, + "Scheduled-" + id.getAndIncrement()); + } + }; + executor = Executors.newScheduledThreadPool(5, f); } @Override diff --git a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java index 8711551b82e321b8aa261845dae3e24fefba3552..8c5645143ac0edc54df86582d9b83273bd30ed56 100644 --- a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java +++ b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java @@ -19,8 +19,8 @@ package net.floodlightcontroller.topology; import net.floodlightcontroller.core.web.serializers.DPIDSerializer; import net.floodlightcontroller.core.web.serializers.UShortSerializer; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.openflow.util.HexString; /** diff --git a/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java b/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java index f0de370d992bad0a1817e1f6b9a93e5c2e2777c3..8568d0d576484361db2ab45f8f2d091e34ebec10 100644 --- a/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java +++ b/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfo.java @@ -16,7 +16,7 @@ package net.floodlightcontroller.util; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonSerialize(using=EventHistoryBaseInfoJSONSerializer.class) public class EventHistoryBaseInfo { diff --git a/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfoJSONSerializer.java b/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfoJSONSerializer.java index 6f1d1ff8bdf677bbe3c59fcdaec9cdac0985f0a2..ad14372607371e0aa70357092b02430b7b99651d 100644 --- a/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfoJSONSerializer.java +++ b/src/main/java/net/floodlightcontroller/util/EventHistoryBaseInfoJSONSerializer.java @@ -21,10 +21,10 @@ import java.io.IOException; import java.sql.Timestamp; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; /** diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java index dec2319b2cd0569c9e6f9771c7923a3c62602b3b..03f0a63ae3b93f20a1b370048fd81884bbd83cf5 100644 --- a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java +++ b/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java @@ -20,10 +20,10 @@ import java.io.IOException; import net.floodlightcontroller.util.MACAddress; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.restlet.data.Status; import org.restlet.resource.Delete; import org.restlet.resource.Put; diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java index 746490bc6b2897a560c8d654f20c4cd8e93ce115..35ff629f4c557f5185585c3440fbaa22e77d43c9 100644 --- a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java +++ b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java @@ -21,10 +21,10 @@ import java.util.Collection; import net.floodlightcontroller.packet.IPv4; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; -import org.codehaus.jackson.map.MappingJsonFactory; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.MappingJsonFactory; import org.restlet.data.Status; import org.restlet.resource.Delete; import org.restlet.resource.Get; diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java index 03eedd3382cff0483e4bd2743a60452e99dafc81..a73c72ef7f889bcd8ef2253f4bfdb6d2c81818cf 100644 --- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java +++ b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java @@ -19,7 +19,7 @@ package net.floodlightcontroller.virtualnetwork; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import net.floodlightcontroller.util.MACAddress; diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java index 487fb8dbe9bf2816f3400d63889c88541240f3b7..6f61b3859a8083838f7a052bb536913f5bc47a5b 100644 --- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java +++ b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java @@ -21,10 +21,10 @@ import java.util.Iterator; import net.floodlightcontroller.util.MACAddress; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; /** * Serialize a VirtualNetwork object diff --git a/src/main/java/org/openflow/protocol/OFFeaturesReply.java b/src/main/java/org/openflow/protocol/OFFeaturesReply.java index d3af5741a325a559f0aa5609bdd841d82f87a053..6152bed7ee8ce699fadbd96fce21660a49ac6edc 100644 --- a/src/main/java/org/openflow/protocol/OFFeaturesReply.java +++ b/src/main/java/org/openflow/protocol/OFFeaturesReply.java @@ -21,7 +21,7 @@ import java.util.ArrayList; import java.util.List; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; import org.openflow.protocol.serializers.OFFeaturesReplyJSONSerializer; import org.openflow.util.U16; diff --git a/src/main/java/org/openflow/protocol/OFMatch.java b/src/main/java/org/openflow/protocol/OFMatch.java index c17bc0d29c0dd2febf7dc58ed792d244b6c5ee4b..86b9a28f13dcfd3717ad3400ac05af30c66d7161 100644 --- a/src/main/java/org/openflow/protocol/OFMatch.java +++ b/src/main/java/org/openflow/protocol/OFMatch.java @@ -23,7 +23,7 @@ import java.util.Arrays; import net.floodlightcontroller.packet.Ethernet; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; import org.openflow.protocol.serializers.OFMatchJSONSerializer; import org.openflow.util.HexString; diff --git a/src/main/java/org/openflow/protocol/OFPhysicalPort.java b/src/main/java/org/openflow/protocol/OFPhysicalPort.java index c8c9a6b9e3a05801b14995b566bc618977e4716d..06a98e6f7b91b43e671cd74ea3f03de3ab684c21 100644 --- a/src/main/java/org/openflow/protocol/OFPhysicalPort.java +++ b/src/main/java/org/openflow/protocol/OFPhysicalPort.java @@ -24,7 +24,7 @@ import java.util.Arrays; import net.floodlightcontroller.core.web.serializers.ByteArrayMACSerializer; import net.floodlightcontroller.core.web.serializers.UShortSerializer; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; import org.openflow.util.HexString; diff --git a/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java b/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java index 68327280da6dad4ef3a8dcfae298e4c6038529ba..de6a92bb6dd51ef9018f31fab94cf376bb722c16 100644 --- a/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java +++ b/src/main/java/org/openflow/protocol/action/OFActionDataLayer.java @@ -24,7 +24,7 @@ import java.util.Arrays; import net.floodlightcontroller.core.web.serializers.ByteArrayMACSerializer; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; import org.openflow.protocol.OFPhysicalPort; diff --git a/src/main/java/org/openflow/protocol/factory/BasicFactory.java b/src/main/java/org/openflow/protocol/factory/BasicFactory.java index c4d148337526ecbae5ea8d9aa67d89e657404da7..f484a167f5cd64f1eaec92dd366a4f0ff02a8ece 100644 --- a/src/main/java/org/openflow/protocol/factory/BasicFactory.java +++ b/src/main/java/org/openflow/protocol/factory/BasicFactory.java @@ -43,15 +43,21 @@ import org.openflow.protocol.vendor.OFVendorId; * @author Rob Sherwood (rob.sherwood@stanford.edu) * */ -public class BasicFactory implements OFMessageFactory, OFActionFactory, +public enum BasicFactory implements OFMessageFactory, OFActionFactory, OFStatisticsFactory, OFVendorDataFactory { + SINGLETON_INSTANCE; + private final OFVendorActionRegistry vendorActionRegistry; - public BasicFactory() { + private BasicFactory() { vendorActionRegistry = OFVendorActionRegistry.getInstance(); } + public static BasicFactory getInstance() { + return SINGLETON_INSTANCE; + } + /** * create and return a new instance of a message for OFType t. Also injects * factories for those message types that implement the *FactoryAware diff --git a/src/main/java/org/openflow/protocol/serializers/OFFeaturesReplyJSONSerializer.java b/src/main/java/org/openflow/protocol/serializers/OFFeaturesReplyJSONSerializer.java index ad57312f11a7bea45050d1dcf1ea65a6d7479521..1102dc78653263a2e33a4967b8d4a3935f44df67 100644 --- a/src/main/java/org/openflow/protocol/serializers/OFFeaturesReplyJSONSerializer.java +++ b/src/main/java/org/openflow/protocol/serializers/OFFeaturesReplyJSONSerializer.java @@ -19,10 +19,10 @@ package org.openflow.protocol.serializers; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.protocol.OFFeaturesReply; import org.openflow.util.HexString; diff --git a/src/main/java/org/openflow/protocol/serializers/OFMatchJSONSerializer.java b/src/main/java/org/openflow/protocol/serializers/OFMatchJSONSerializer.java index 69312feb5667855d36c3419f2749658b4ef43eee..2ae2d1c467d095491b88d8c78a15479ed04bdbae 100644 --- a/src/main/java/org/openflow/protocol/serializers/OFMatchJSONSerializer.java +++ b/src/main/java/org/openflow/protocol/serializers/OFMatchJSONSerializer.java @@ -19,10 +19,10 @@ package org.openflow.protocol.serializers; import java.io.IOException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.map.JsonSerializer; -import org.codehaus.jackson.map.SerializerProvider; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import org.openflow.protocol.OFMatch; import org.openflow.util.HexString; diff --git a/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java index 7dec16b69d8d295985363703585fb82ab08f3da1..0c86006b0919e1a87120ab96dec2caed96cd48da 100644 --- a/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java +++ b/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java @@ -18,7 +18,7 @@ package org.openflow.protocol.statistics; -import org.codehaus.jackson.annotate.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.jboss.netty.buffer.ChannelBuffer; /** diff --git a/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java index bea7f1e3b064a947a95d1398696462ae886cf697..8907e74b355593dfe607152180c56295a46d667f 100644 --- a/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java +++ b/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java @@ -19,7 +19,7 @@ package org.openflow.protocol.statistics; import java.util.List; -import org.codehaus.jackson.annotate.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.jboss.netty.buffer.ChannelBuffer; import org.openflow.protocol.OFMatch; import org.openflow.protocol.action.OFAction; diff --git a/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java index 9a84aad1edfba2357480c27dcde53f68e45ef595..15192bbc4d495fa4fd1f8f064adf0058f348d581 100644 --- a/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java +++ b/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java @@ -20,8 +20,8 @@ package org.openflow.protocol.statistics; import net.floodlightcontroller.core.web.serializers.UShortSerializer; -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.map.annotate.JsonSerialize; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.jboss.netty.buffer.ChannelBuffer; /** diff --git a/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java index 03cbb9cef0c87b3056a57fef8c309e2ad2d1ed23..34a9e18200bc73ff5a7d628c671bb641cd243068 100644 --- a/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java +++ b/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java @@ -18,7 +18,7 @@ package org.openflow.protocol.statistics; -import org.codehaus.jackson.annotate.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.jboss.netty.buffer.ChannelBuffer; /** diff --git a/src/main/java/org/sdnplatform/sync/IClosableIterator.java b/src/main/java/org/sdnplatform/sync/IClosableIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..c2c2f7797c7e316c61d46a3a6befd6b1d0f86af6 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/IClosableIterator.java @@ -0,0 +1,35 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync; + +import java.io.Closeable; +import java.util.Iterator; + +/** + * An iterator that must be closed after use + * + * + * @param <T> The type being iterated over + */ +public interface IClosableIterator<T> extends Iterator<T>,Closeable { + + /** + * Close the iterator + */ + public void close(); + +} diff --git a/src/main/java/org/sdnplatform/sync/IInconsistencyResolver.java b/src/main/java/org/sdnplatform/sync/IInconsistencyResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..67ed911a660eda236f20f17052c2e5b73c7954c9 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/IInconsistencyResolver.java @@ -0,0 +1,46 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync; + +import java.util.List; + +/** + * A method for resolving inconsistent object values into a single value. + * Applications can implement this to provide a method for reconciling conflicts + * that cannot be resolved simply by the version information. + * + * + */ +public interface IInconsistencyResolver<T> { + + /** + * Take two different versions of an object and combine them into a single + * version of the object Implementations must maintain the contract that + * <ol> + * <li> + * {@code resolveConflict([null, null]) == null}</li> + * <li> + * if {@code t != null}, then + * + * {@code resolveConflict([null, t]) == resolveConflict([t, null]) == t}</li> + * + * @param items The items to be resolved + * @return The united object + */ + public List<T> resolveConflicts(List<T> items); + +} diff --git a/src/main/java/org/sdnplatform/sync/IStoreClient.java b/src/main/java/org/sdnplatform/sync/IStoreClient.java new file mode 100644 index 0000000000000000000000000000000000000000..bb2a64212e36c2dabba03ef1af4d90ad03b2a4a0 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/IStoreClient.java @@ -0,0 +1,178 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync; + +import java.util.Iterator; +import java.util.Map.Entry; + +import org.sdnplatform.sync.error.ObsoleteVersionException; +import org.sdnplatform.sync.error.SyncException; + + +/** + * The user-facing interface to a sync store. Gives basic put/get/delete + * plus helper functions. + * + * @param <K> The type of the key being stored + * @param <V> The type of the value being stored + */ +public interface IStoreClient<K, V> { + + /** + * Get the value associated with the given key or null if there is no value + * associated with this key. This method strips off all version information + * and is only useful when no further storage operations will be done on + * this key. In general, you should prefer the get() method that returns + * version information unless. + * + * @param key The key + * @throws SyncException + */ + public V getValue(K key) throws SyncException; + + /** + * Get the value associated with the given key or defaultValue if there is + * no value associated with the key. This method strips off all version + * information and is only useful when no further storage operations will be + * done on this key.In general, you should prefer the get() method that returns + * version information unless. + * + * @param key The key for which to fetch the associated value + * @param defaultValue A value to return if there is no value associated + * with this key + * @return Either the value stored for the key or the default value. + * @throws SyncException + */ + public V getValue(K key, V defaultValue) throws SyncException; + + /** + * Get the versioned value associated with the given key. Note that while + * this function will never return null, the {@link Versioned} returned + * can have a null value (i.e. {@link Versioned#getValue() can be null} + * if the key is not present. + * + * @param key The key for which to fetch the value. + * @return The versioned value + * @throws SyncException + */ + public Versioned<V> get(K key) throws SyncException; + + /** + * Get the versioned value associated with the given key or the defaultValue + * if no value is associated with the key. + * + * @param key The key for which to fetch the value. + * @return The versioned value, or the defaultValue if no value is stored + * for this key. + * @throws SyncException + */ + public Versioned<V> get(K key, Versioned<V> defaultValue) + throws SyncException; + + /** + * Get an iterator that will get all the entries in the store. Note + * that this has the potential to miss any values added while you're + * iterating through the collection, and it's possible that items will + * be deleted before you get to the end. + * + * Note that you *must* close the {@link IClosableIterator} when you are + * finished with it or there may be resource leaks. An example of how you + * should use this iterator to ensure that it is closed even if there are + * exceptions follows: + * <code> + * IClosableIterator iter = store.entries(); + * try { + * // do your iteration + * } finally { + * iter.close(); + * } + * </code> + * + * Another important caveat is that because {@link IClosableIterator} + * extends {@link Iterator}, there is no checked exception declared in + * {@link Iterator#next()}. Because of this, calling + * {@link Iterator#next()} on the iterator returned here may throw a + * SyncRuntimeException wrapping a SyncException such as might be + * returned by {@link IStoreClient#get(Object)} + * @return + * @throws SyncException + */ + public IClosableIterator<Entry<K, Versioned<V>>> entries() + throws SyncException; + + /** + * Associated the given value to the key, clobbering any existing values + * stored for the key. + * + * @param key The key + * @param value The value + * @return version The version of the object + * @throws SyncException + */ + public IVersion put(K key, V value) throws SyncException; + + /** + * Put the given Versioned value into the store for the given key if the + * version is greater to or concurrent with existing values. Throw an + * ObsoleteVersionException otherwise. + * + * @param key The key + * @param versioned The value and its versioned + * @throws ObsoleteVersionException + * @throws SyncException + */ + public IVersion put(K key, Versioned<V> versioned) + throws SyncException; + + /** + * Put the versioned value to the key, ignoring any ObsoleteVersionException + * that may be thrown + * + * @param key The key + * @param versioned The versioned value + * @return true if the put succeeded + * @throws SyncException + */ + public boolean putIfNotObsolete(K key, Versioned<V> versioned) + throws SyncException; + + /** + * Delete the key by writing a null tombstone to the store + * + * @param key The key + * @throws SyncException + */ + public void delete(K key) throws SyncException; + + /** + * Delete the key by writing a null tombstone to the store using the + * provided {@link IVersion}. + * + * @param key The key to delete + * @param version The version of the key + * @throws SyncException + */ + public void delete(K key, IVersion version) throws SyncException; + + /** + * Add a listener that will be notified about changes to the given store. + * @param listener the {@link IStoreListener} that will receive the + * notifications + */ + public void addStoreListener(IStoreListener<K> listener); + +} diff --git a/src/main/java/org/sdnplatform/sync/IStoreListener.java b/src/main/java/org/sdnplatform/sync/IStoreListener.java new file mode 100644 index 0000000000000000000000000000000000000000..48a12f25d025356730be7a13741356c8e619b6fb --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/IStoreListener.java @@ -0,0 +1,34 @@ +package org.sdnplatform.sync; + +import java.util.Iterator; + +/** + * A listener interface that will receive updates on a particular store + * @author readams + * @param <K> the key type for the store + */ +public interface IStoreListener<K> { + /** + * The origin of the update + * @author readams + */ + public enum UpdateType { + /** + * An update that originated from a write to the local store + */ + LOCAL, + /** + * An update that originated from a value synchronized from a remote + * node. Note that it is still possible that this includes only + * information that originated from the current node. + */ + REMOTE + }; + + /** + * Called when keys in the store are modified or deleted. + * @param type the type of the update + * @see UpdateType + */ + public void keysModified(Iterator<K> keys, UpdateType type); +} diff --git a/src/main/java/org/sdnplatform/sync/ISyncService.java b/src/main/java/org/sdnplatform/sync/ISyncService.java new file mode 100644 index 0000000000000000000000000000000000000000..6518420603b2bc5f47f75124334355ce2e4fa019 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/ISyncService.java @@ -0,0 +1,121 @@ +package org.sdnplatform.sync; + +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.UnknownStoreException; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.core.type.TypeReference; + + +import net.floodlightcontroller.core.module.IFloodlightService; + +/** + * The sync service provides a high-performance in-memory database for + * fault and partition-tolerant replication of state data. It provides + * eventually consistent semantics with versioning through vector clocks + * and allows custom handling of resolution of inconsistent writes. + * + * An important caveat to keep in mind is that keys should not be constructed + * using any hash tables, because the serialized version will contain a + * a potentially-inconsistent ordering of elements resulting in a failure + * for keys to match. Using a java bean or a {@link JsonNode} will avoid this + * problem. Using strings as keys also avoids this problem. + * @author readams + */ +public interface ISyncService extends IFloodlightService { + public enum Scope { + GLOBAL, + LOCAL + } + + /** + * Create a store with the given store name and scope + * @param storeName the name of the store + * @param scope the distribution scope for the data + * @throws SyncException + */ + public void registerStore(String storeName, Scope scope) + throws SyncException; + + /** + * Create a store with the given store name and scope that will be + * persistent across reboots. The performance will be dramatically slower + * @param storeName the name of the store + * @param scope the distribution scope for the data + */ + public void registerPersistentStore(String storeName, Scope scope) + throws SyncException; + + /** + * Get a store client for the given store. The store client will use + * a default inconsistency resolution strategy which will use the + * timestamps of any concurrent updates and choose the later update + * @param storeName the name of the store to retrieve + * @param keyClass the class for the underlying key needed for + * deserialization + * @param valueClass the class for the underlying value needed for + * deserialization + * @return the store client + * @throws UnknownStoreException + */ + public <K, V> IStoreClient<K, V> getStoreClient(String storeName, + Class<K> keyClass, + Class<V> valueClass) + throws UnknownStoreException; + + /** + * Get a store client that will use the provided inconsistency resolver + * to resolve concurrent updates. + * @param storeName the name of the store to retrieve + * @param keyClass the class for the underlying key needed for + * deserialization + * @param valueClass the class for the underlying value needed for + * deserialization + * @param resolver the inconsistency resolver to use for the store + * @return the store client + * @throws UnknownStoreException + */ + public <K, V> IStoreClient<K, V> + getStoreClient(String storeName, + Class<K> keyClass, + Class<V> valueClass, + IInconsistencyResolver<Versioned<V>> resolver) + throws UnknownStoreException; + + /** + * Get a store client for the given store. The store client will use + * a default inconsistency resolution strategy which will use the + * timestamps of any concurrent updates and choose the later update + * @param storeName the name of the store to retrieve + * @param keyType the type reference for the underlying key needed for + * deserialization + * @param valueType the type reference for the underlying value needed for + * deserialization + * @return the store client + * @throws UnknownStoreException + */ + public <K, V> IStoreClient<K, V> getStoreClient(String storeName, + TypeReference<K> keyType, + TypeReference<V> valueType) + throws UnknownStoreException; + + /** + * Get a store client that will use the provided inconsistency resolver + * to resolve concurrent updates. + * @param storeName the name of the store to retrieve + * @param keyType the type reference for the underlying key needed for + * deserialization + * @param valueType the type reference for the underlying value needed for + * deserialization + * @param resolver the inconsistency resolver to use for the store + * @return the store client + * @throws UnknownStoreException + */ + public <K, V> IStoreClient<K, V> + getStoreClient(String storeName, + TypeReference<K> keyType, + TypeReference<V> valueType, + IInconsistencyResolver<Versioned<V>> resolver) + throws UnknownStoreException; + +} diff --git a/src/main/java/org/sdnplatform/sync/IVersion.java b/src/main/java/org/sdnplatform/sync/IVersion.java new file mode 100644 index 0000000000000000000000000000000000000000..3af0e802271333361944fcf9f723bf918d2acf72 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/IVersion.java @@ -0,0 +1,50 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync; + +/** + * An interface that allows us to determine if a given version happened before + * or after another version. + * + * This could have been done using the comparable interface but that is + * confusing, because the numeric codes are easily confused, and because + * concurrent versions are not necessarily "equal" in the normal sense. + * + * + */ + +public interface IVersion { + /** + * The result of comparing two times--either t1 is BEFORE t2, + * t1 is AFTER t2, or t1 happens CONCURRENTLY to t2. + */ + public enum Occurred { + BEFORE, + AFTER, + CONCURRENTLY + } + + /** + * Return whether or not the given version preceeded this one, succeeded it, + * or is concurrant with it + * + * @param v The other version + */ + public Occurred compare(IVersion v); + +} diff --git a/src/main/java/org/sdnplatform/sync/Versioned.java b/src/main/java/org/sdnplatform/sync/Versioned.java new file mode 100644 index 0000000000000000000000000000000000000000..73617a7e2c18f416baba3f89878f25579cb260fa --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/Versioned.java @@ -0,0 +1,183 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Comparator; + +import org.sdnplatform.sync.IVersion.Occurred; +import org.sdnplatform.sync.internal.version.VectorClock; + +import com.google.common.base.Objects; + +/** + * A wrapper for an object that adds a Version. + * + * + */ +public class Versioned<T> implements Serializable { + + private static final long serialVersionUID = 1; + + private volatile VectorClock version; + private volatile T value; + + public Versioned(T object) { + this(object, new VectorClock()); + } + + public Versioned(T object, + IVersion version) { + this.version = version == null ? new VectorClock() : (VectorClock) version; + this.value = object; + } + + public IVersion getVersion() { + return version; + } + + public void increment(int nodeId, long time) { + this.version = version.incremented(nodeId, time); + } + + public T getValue() { + return value; + } + + public void setValue(T object) { + this.value = object; + } + + /** + * Determines if two objects are equal as determined by + * {@link Object#equals(Object)}, or "deeply equal" if both are arrays. + * <p> + * If both objects are null, true is returned; if both objects are array, + * the corresponding {@link Arrays#deepEquals(Object[], Object[])}, or + * {@link Arrays#equals(int[], int[])} or the like are called to determine + * equality. + * <p> + * Note that this method does not "deeply" compare the fields of the + * objects. + */ + private static boolean deepEquals(Object o1, Object o2) { + if(o1 == o2) { + return true; + } + if(o1 == null || o2 == null) { + return false; + } + + Class<?> type1 = o1.getClass(); + Class<?> type2 = o2.getClass(); + if(!(type1.isArray() && type2.isArray())) { + return o1.equals(o2); + } + if(o1 instanceof Object[] && o2 instanceof Object[]) { + return Arrays.deepEquals((Object[]) o1, (Object[]) o2); + } + if(type1 != type2) { + return false; + } + if(o1 instanceof boolean[]) { + return Arrays.equals((boolean[]) o1, (boolean[]) o2); + } + if(o1 instanceof char[]) { + return Arrays.equals((char[]) o1, (char[]) o2); + } + if(o1 instanceof byte[]) { + return Arrays.equals((byte[]) o1, (byte[]) o2); + } + if(o1 instanceof short[]) { + return Arrays.equals((short[]) o1, (short[]) o2); + } + if(o1 instanceof int[]) { + return Arrays.equals((int[]) o1, (int[]) o2); + } + if(o1 instanceof long[]) { + return Arrays.equals((long[]) o1, (long[]) o2); + } + if(o1 instanceof float[]) { + return Arrays.equals((float[]) o1, (float[]) o2); + } + if(o1 instanceof double[]) { + return Arrays.equals((double[]) o1, (double[]) o2); + } + throw new AssertionError(); + } + + @Override + public boolean equals(Object o) { + if(o == this) + return true; + else if(!(o instanceof Versioned<?>)) + return false; + + Versioned<?> versioned = (Versioned<?>) o; + return Objects.equal(getVersion(), versioned.getVersion()) + && deepEquals(getValue(), versioned.getValue()); + } + + @Override + public int hashCode() { + int v = 31 + version.hashCode(); + if(value != null) { + v += 31 * value.hashCode(); + } + return v; + } + + @Override + public String toString() { + return "[" + value + ", " + version + "]"; + } + + /** + * Create a clone of this Versioned object such that the object pointed to + * is the same, but the VectorClock and Versioned wrapper is a shallow copy. + */ + public Versioned<T> cloneVersioned() { + return new Versioned<T>(this.getValue(), this.version.clone()); + } + + public static <S> Versioned<S> value(S s) { + return new Versioned<S>(s, new VectorClock()); + } + + public static <S> Versioned<S> value(S s, IVersion v) { + return new Versioned<S>(s, v); + } + + public static <S> Versioned<S> emptyVersioned() { + return new Versioned<S>(null, new VectorClock(0)); + } + + public static final class HappenedBeforeComparator<S> implements Comparator<Versioned<S>> { + + public int compare(Versioned<S> v1, Versioned<S> v2) { + Occurred occurred = v1.getVersion().compare(v2.getVersion()); + if(occurred == Occurred.BEFORE) + return -1; + else if(occurred == Occurred.AFTER) + return 1; + else + return 0; + } + } + +} diff --git a/src/main/java/org/sdnplatform/sync/client/ShellCommand.java b/src/main/java/org/sdnplatform/sync/client/ShellCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..7d3cfbf5d8041231862190f27e3ea6a33d3f161a --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/client/ShellCommand.java @@ -0,0 +1,68 @@ +package org.sdnplatform.sync.client; + +import java.io.IOException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.MappingJsonFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * A user command for the command line client + * @author readams + */ +public abstract class ShellCommand { + + protected static final ObjectMapper mapper = new ObjectMapper(); + protected static final MappingJsonFactory mjf = + new MappingJsonFactory(mapper); + + static { + mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, + true); + } + + /** + * Execute the command on the given tokens + * @param tokens the argument tokens. The first token will be the command + * @param line the whole command line + * @return whether to exit the shell after the command + */ + public abstract boolean execute(String[] tokens, + String line) throws Exception; + + /** + * Return syntax description + * @return the syntax string + */ + public abstract String syntaxString(); + + /** + * Parse a JSON object + * @param jp the JSON parse + * @return the JSON node + * @throws IOException + */ + protected JsonNode validateJson(JsonParser jp) throws IOException { + JsonNode parsed = null; + + try { + parsed = jp.readValueAsTree(); + } catch (JsonProcessingException e) { + System.err.println("Could not parse JSON: " + e.getMessage()); + return null; + } + return parsed; + } + + /** + * Serialize a JSON object as bytes + * @param value the object to serialize + * @return the serialized bytes + * @throws Exception + */ + protected byte[] serializeJson(JsonNode value) throws Exception { + return mapper.writeValueAsBytes(value); + } +} diff --git a/src/main/java/org/sdnplatform/sync/client/SyncClient.java b/src/main/java/org/sdnplatform/sync/client/SyncClient.java new file mode 100644 index 0000000000000000000000000000000000000000..dc4cca161fed53395e305a856dd4fea3bd580858 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/client/SyncClient.java @@ -0,0 +1,449 @@ +package org.sdnplatform.sync.client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map.Entry; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.threadpool.IThreadPoolService; +import net.floodlightcontroller.threadpool.ThreadPool; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.core.JsonParser; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; +import org.sdnplatform.sync.IStoreClient; +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.error.UnknownStoreException; +import org.sdnplatform.sync.internal.remote.RemoteSyncManager; + + +public class SyncClient { + RemoteSyncManager syncManager; + IStoreClient<JsonNode, JsonNode> storeClient; + + /** + * Shell commands + */ + protected HashMap<String, ShellCommand> commands; + + /** + * Command-line settings + */ + protected SyncClientSettings settings; + + /** + * Stream to use for output + */ + protected PrintStream out = System.out; + + /** + * Stream to use for errors + */ + protected PrintStream err = System.err; + + public SyncClient(SyncClientSettings settings) { + this.settings = settings; + + commands = new HashMap<String, ShellCommand>(); + commands.put("quit", new QuitCommand()); + commands.put("help", new HelpCommand()); + commands.put("put", new PutCommand()); + commands.put("delete", new DeleteCommand()); + commands.put("get", new GetCommand()); + commands.put("getfull", new GetFullCommand()); + commands.put("store", new StoreCommand()); + commands.put("register", new RegisterCommand()); + } + + protected boolean connect() + throws Exception { + FloodlightModuleContext fmc = new FloodlightModuleContext(); + ThreadPool tp = new ThreadPool(); + syncManager = new RemoteSyncManager(); + fmc.addService(IThreadPoolService.class, tp); + fmc.addService(ISyncService.class, syncManager); + fmc.addConfigParam(syncManager, "hostname", settings.hostname); + fmc.addConfigParam(syncManager, "port", + Integer.toString(settings.port)); + tp.init(fmc); + syncManager.init(fmc); + tp.startUp(fmc); + syncManager.startUp(fmc); + + if (settings.storeName != null) + getStoreClient(); + + out.println("Connected to " + + settings.hostname + ":" + settings.port); + return true; + } + + protected void getStoreClient() + throws UnknownStoreException { + storeClient = syncManager.getStoreClient(settings.storeName, + JsonNode.class, + JsonNode.class); + } + + protected boolean checkStoreSettings() { + if (settings.storeName == null) { + err.println("No store selected. Select using \"store\" command."); + return false; + } + return true; + } + + /** + * Quit command + * @author readams + * + */ + protected static class QuitCommand extends ShellCommand { + @Override + public boolean execute(String[] tokens, String line) { + return true; + } + + @Override + public String syntaxString() { + return "quit"; + } + } + + /** + * Help command + * @author readams + * + */ + protected class HelpCommand extends ShellCommand { + @Override + public boolean execute(String[] tokens, String line) { + out.println("Commands: "); + for (Entry<String, ShellCommand> entry : commands.entrySet()) { + out.println(entry.getValue().syntaxString()); + } + return false; + } + + @Override + public String syntaxString() { + return "help"; + } + } + + /** + * Get command + * @author readams + * + */ + protected class GetCommand extends ShellCommand { + ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); + + @Override + public boolean execute(String[] tokens, String line) throws Exception { + if (tokens.length < 2) { + err.println("Usage: " + syntaxString()); + return false; + } + if (!checkStoreSettings()) return false; + + StringReader sr = new StringReader(line); + while (sr.read() != ' '); + JsonParser jp = mjf.createJsonParser(sr); + + JsonNode keyNode = validateJson(jp); + if (keyNode == null) return false; + + out.println("Getting Key:"); + out.println(writer.writeValueAsString(keyNode)); + out.println(""); + Versioned<JsonNode> value = storeClient.get(keyNode); + display(value); + + return false; + } + + protected void display(Versioned<JsonNode> value) throws Exception { + if (value.getValue() == null) { + out.println("Not found"); + } else { + out.println("Value:"); + out.println(writer.writeValueAsString(value.getValue())); + } + } + + @Override + public String syntaxString() { + return "get [key]"; + } + } + + protected class GetFullCommand extends GetCommand { + @Override + protected void display(Versioned<JsonNode> value) throws Exception { + if (value.getValue() == null) { + out.println("Not found"); + } else { + out.println("Version:"); + out.println(value.getVersion()); + out.println("Value:"); + out.println(writer.writeValueAsString(value.getValue())); + } + } + + @Override + public String syntaxString() { + return "getfull [key]"; + } + } + + /** + * Put command + * @author readams + * + */ + protected class PutCommand extends ShellCommand { + @Override + public boolean execute(String[] tokens, String line) throws Exception { + if (tokens.length < 3) { + err.println("Usage: " + syntaxString()); + return false; + + } + if (!checkStoreSettings()) return false; + + StringReader sr = new StringReader(line); + while (sr.read() != ' '); + JsonParser jp = mjf.createJsonParser(sr); + + JsonNode keyNode = validateJson(jp); + if (keyNode == null) return false; + JsonNode valueNode = validateJson(jp); + if (valueNode == null) return false; + + ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); + out.println("Putting Key:"); + out.println(writer.writeValueAsString(keyNode)); + out.println("\nValue:"); + out.println(writer.writeValueAsString(valueNode)); + out.flush(); + + storeClient.put(keyNode, valueNode); + out.println("Success"); + + return false; + } + + @Override + public String syntaxString() { + return "put [key] [value]"; + } + } + + /** + * Delete command + * @author readams + * + */ + protected class DeleteCommand extends ShellCommand { + @Override + public boolean execute(String[] tokens, String line) throws Exception { + if (tokens.length < 2) { + err.println("Usage: " + syntaxString()); + return false; + } + if (!checkStoreSettings()) return false; + + StringReader sr = new StringReader(line); + while (sr.read() != ' '); + JsonParser jp = mjf.createJsonParser(sr); + + JsonNode keyNode = validateJson(jp); + if (keyNode == null) return false; + + ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); + out.println("Deleting Key:"); + out.println(writer.writeValueAsString(keyNode)); + out.println(""); + + storeClient.delete(keyNode); + out.println("Success"); + + return false; + } + + @Override + public String syntaxString() { + return "delete [key]"; + } + } + + /** + * Choose the store + * @author readams + */ + protected class StoreCommand extends ShellCommand { + + @Override + public boolean execute(String[] tokens, String line) + throws Exception { + if (tokens.length < 2) { + err.println("Usage: " + syntaxString()); + return false; + } + + settings.storeName = tokens[1]; + getStoreClient(); + return false; + } + + @Override + public String syntaxString() { + return "store [storeName]"; + } + + } + + /** + * Register a new store + * @author readams + */ + protected class RegisterCommand extends ShellCommand { + + @Override + public boolean execute(String[] tokens, String line) + throws Exception { + if (tokens.length < 3) { + err.println("Usage: " + syntaxString()); + return false; + } + Scope scope = Scope.LOCAL; + if ("global".equals(tokens[2])) + scope = Scope.GLOBAL; + + settings.storeName = tokens[1]; + syncManager.registerStore(settings.storeName, scope); + getStoreClient(); + return false; + } + + @Override + public String syntaxString() { + return "register [storeName] [local|global]"; + } + + } + + protected void cleanup() throws InterruptedException { + syncManager.shutdown(); + } + + protected boolean executeCommandLine(String line) { + String[] tokens = line.split("\\s+"); + if (tokens.length > 0) { + ShellCommand command = commands.get(tokens[0]); + if (command != null) { + try { + if (command.execute(tokens, line)) + return true; + } catch (Exception e) { + err.println("Failed to execute command: " + + line); + if (settings.debug) + e.printStackTrace(err); + else + err.println(e.getClass().getSimpleName() + + ": " + e.getMessage()); + } + } else { + err.println("Unrecognized command: \"" + + tokens[0] + "\""); + } + } + return false; + } + + protected void startShell(SyncClientSettings settings) + throws InterruptedException { + BufferedReader br = + new BufferedReader(new InputStreamReader(System.in)); + String line; + try { + while (true) { + err.print("> "); + line = br.readLine(); + if (line == null) break; + if (executeCommandLine(line)) break; + } + } catch (IOException e) { + err.println("Could not read input: " + e.getMessage()); + } + } + + protected static class SyncClientSettings { + @Option(name="--help", + usage="Server hostname") + protected boolean help; + + @Option(name="--hostname", aliases="-h", + usage="Server hostname", required=true) + protected String hostname; + + @Option(name="--port", aliases="-p", usage="Server port", required=true) + protected int port; + + @Option(name="--store", aliases="-s", + usage="Store name to access") + protected String storeName; + + @Option(name="--command", aliases="-c", + usage="If set, execute a command") + protected String command; + + @Option(name="--debug", + usage="Show full error information") + protected boolean debug; + } + + /** + * @param args + * @throws InterruptedException + */ + public static void main(String[] args) throws Exception { + SyncClientSettings settings = new SyncClientSettings(); + CmdLineParser parser = new CmdLineParser(settings); + try { + parser.parseArgument(args); + } catch (CmdLineException e) { + System.err.println(e.getMessage()); + parser.printUsage(System.err); + System.exit(1); + } + if (settings.help) { + parser.printUsage(System.err); + System.exit(1); + } + + SyncClient client = new SyncClient(settings); + try { + if (false == client.connect()) { + return; + } + if (settings.command == null) { + client.startShell(settings); + } else { + client.executeCommandLine(settings.command); + } + } finally { + client.cleanup(); + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/error/HandshakeTimeoutException.java b/src/main/java/org/sdnplatform/sync/error/HandshakeTimeoutException.java new file mode 100644 index 0000000000000000000000000000000000000000..4a2d6b8ecb6cfdf98872d2d31e5174c7292a1aa3 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/HandshakeTimeoutException.java @@ -0,0 +1,16 @@ +/** +* Copyright 2011,2013, Big Switch Networks, Inc. +**/ + +package org.sdnplatform.sync.error; + +/** + * Exception is thrown when the handshake fails to complete + * before a specified time + * @author readams + */ +public class HandshakeTimeoutException extends SyncException { + + private static final long serialVersionUID = 6859880268940337312L; + +} diff --git a/src/main/java/org/sdnplatform/sync/error/InconsistentDataException.java b/src/main/java/org/sdnplatform/sync/error/InconsistentDataException.java new file mode 100644 index 0000000000000000000000000000000000000000..f3644b3bcacfdaa514b5eb66e806146da7c7118d --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/InconsistentDataException.java @@ -0,0 +1,45 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.error; + +import java.util.List; + +/** + * Thrown when the inconsistency resolver fails to resolve down to a single + * value + */ +public class InconsistentDataException extends SyncException { + + private static final long serialVersionUID = 1050277622160468516L; + List<?> unresolvedVersions; + + public InconsistentDataException(String message, List<?> versions) { + super(message); + this.unresolvedVersions = versions; + } + + public List<?> getUnresolvedVersions() { + return unresolvedVersions; + } + + @Override + public ErrorType getErrorCode() { + return ErrorType.INCONSISTENT_DATA; + } + +} diff --git a/src/main/java/org/sdnplatform/sync/error/ObsoleteVersionException.java b/src/main/java/org/sdnplatform/sync/error/ObsoleteVersionException.java new file mode 100644 index 0000000000000000000000000000000000000000..2ec532abed4f0344aa46adedaa5ab3aa429ee37c --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/ObsoleteVersionException.java @@ -0,0 +1,33 @@ +package org.sdnplatform.sync.error; + +/** + * This exception is thrown when attempting to write a value into a store + * that is older than the value already in the store. If you get + * this exception, you need to redo your read/modify/write operation. + */ +public class ObsoleteVersionException extends SyncException { + + private static final long serialVersionUID = 7128132048300845832L; + + public ObsoleteVersionException() { + super(); + } + + public ObsoleteVersionException(String message, Throwable cause) { + super(message, cause); + } + + public ObsoleteVersionException(String message) { + super(message); + } + + public ObsoleteVersionException(Throwable cause) { + super(cause); + } + + @Override + public ErrorType getErrorCode() { + return ErrorType.OBSOLETE_VERSION; + } + +} diff --git a/src/main/java/org/sdnplatform/sync/error/PersistException.java b/src/main/java/org/sdnplatform/sync/error/PersistException.java new file mode 100644 index 0000000000000000000000000000000000000000..2d557e8fe29c108d6ea0da77d6d6454e70247a77 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/PersistException.java @@ -0,0 +1,31 @@ +package org.sdnplatform.sync.error; + +/** + * An error with a persistence layer + * @author readams + * + */ +public class PersistException extends SyncException { + private static final long serialVersionUID = -1374782534201553648L; + + public PersistException() { + super(); + } + + public PersistException(String message, Throwable cause) { + super(message, cause); + } + + public PersistException(String message) { + super(message); + } + + public PersistException(Throwable cause) { + super(cause); + } + + @Override + public ErrorType getErrorCode() { + return ErrorType.PERSIST; + } +} diff --git a/src/main/java/org/sdnplatform/sync/error/RemoteStoreException.java b/src/main/java/org/sdnplatform/sync/error/RemoteStoreException.java new file mode 100644 index 0000000000000000000000000000000000000000..b6d2353417b4bbfe71809c7fbe14bf5ca4c0f21b --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/RemoteStoreException.java @@ -0,0 +1,27 @@ +package org.sdnplatform.sync.error; + +/** + * An exception related to retrieving data from a remote store + * @author readams + */ +public class RemoteStoreException extends SyncException { + + private static final long serialVersionUID = -8098015934951853774L; + + public RemoteStoreException() { + super(); + } + + public RemoteStoreException(String message, Throwable cause) { + super(message, cause); + } + + public RemoteStoreException(String message) { + super(message); + } + + public RemoteStoreException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/org/sdnplatform/sync/error/SerializationException.java b/src/main/java/org/sdnplatform/sync/error/SerializationException.java new file mode 100644 index 0000000000000000000000000000000000000000..dcf0524cf929eeb11e489543a0b0fb66eabe2c93 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/SerializationException.java @@ -0,0 +1,31 @@ +package org.sdnplatform.sync.error; + +/** + * An error occurred while serializing or deserializing objects + * @author readams + */ +public class SerializationException extends SyncException { + + private static final long serialVersionUID = 6633759330354187L; + + public SerializationException() { + super(); + } + + public SerializationException(String message, Throwable cause) { + super(message, cause); + } + + public SerializationException(String message) { + super(message); + } + + public SerializationException(Throwable cause) { + super(cause); + } + + @Override + public ErrorType getErrorCode() { + return ErrorType.SERIALIZATION; + } +} diff --git a/src/main/java/org/sdnplatform/sync/error/SyncException.java b/src/main/java/org/sdnplatform/sync/error/SyncException.java new file mode 100644 index 0000000000000000000000000000000000000000..a364dae30d451a2ad111873e6792656ce0207232 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/SyncException.java @@ -0,0 +1,75 @@ +package org.sdnplatform.sync.error; + +/** + * Generic exception type for sync service exceptions + * @author readams + */ +public class SyncException extends Exception { + + private static final long serialVersionUID = -6150348258087759055L; + + public enum ErrorType { + SUCCESS(0), + GENERIC(1), + INCONSISTENT_DATA(2), + OBSOLETE_VERSION(3), + UNKNOWN_STORE(4), + SERIALIZATION(5), + PERSIST(6), + HANDSHAKE_TIMEOUT(7), + REMOTE_STORE(8); + + private final int value; + + ErrorType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + public SyncException() { + super(); + } + + public SyncException(String message, Throwable cause) { + super(message, cause); + } + + public SyncException(String message) { + super(message); + } + + public SyncException(Throwable cause) { + super(cause); + } + + public ErrorType getErrorCode() { + return ErrorType.GENERIC; + } + + public static SyncException newInstance(ErrorType type, + String message, Throwable cause) { + switch (type) { + case INCONSISTENT_DATA: + return new InconsistentDataException(message, null); + case OBSOLETE_VERSION: + return new ObsoleteVersionException(message, cause); + case UNKNOWN_STORE: + return new UnknownStoreException(message, cause); + case SERIALIZATION: + return new SerializationException(message, cause); + case PERSIST: + return new PersistException(message, cause); + case HANDSHAKE_TIMEOUT: + return new HandshakeTimeoutException(); + case REMOTE_STORE: + return new RemoteStoreException(message, cause); + case GENERIC: + default: + return new SyncException(message, cause); + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/error/SyncRuntimeException.java b/src/main/java/org/sdnplatform/sync/error/SyncRuntimeException.java new file mode 100644 index 0000000000000000000000000000000000000000..54f762b9c6de156ed8c06720a3c0c9318a82902b --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/SyncRuntimeException.java @@ -0,0 +1,19 @@ +package org.sdnplatform.sync.error; + +/** + * A runtime exception that wraps a SyncException. This is thrown from + * standard interfaces that don't support an appropriate exceptional type. + * @author readams + */ +public class SyncRuntimeException extends RuntimeException { + + private static final long serialVersionUID = -5357245946596447913L; + + public SyncRuntimeException(String message, SyncException cause) { + super(message, cause); + } + + public SyncRuntimeException(SyncException cause) { + super(cause); + } +} diff --git a/src/main/java/org/sdnplatform/sync/error/UnknownStoreException.java b/src/main/java/org/sdnplatform/sync/error/UnknownStoreException.java new file mode 100644 index 0000000000000000000000000000000000000000..055715e798e47fd2b5db59efc35eb0e959d16517 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/error/UnknownStoreException.java @@ -0,0 +1,31 @@ +package org.sdnplatform.sync.error; + +/** + * Thrown when attempting to perform an operation on an unknown store + * @author readams + */ +public class UnknownStoreException extends SyncException { + + private static final long serialVersionUID = 6633759330354187L; + + public UnknownStoreException() { + super(); + } + + public UnknownStoreException(String message, Throwable cause) { + super(message, cause); + } + + public UnknownStoreException(String message) { + super(message); + } + + public UnknownStoreException(Throwable cause) { + super(cause); + } + + @Override + public ErrorType getErrorCode() { + return ErrorType.UNKNOWN_STORE; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/AbstractStoreClient.java b/src/main/java/org/sdnplatform/sync/internal/AbstractStoreClient.java new file mode 100644 index 0000000000000000000000000000000000000000..3d767d66836b45d451acd0cef08863a69a989459 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/AbstractStoreClient.java @@ -0,0 +1,79 @@ +package org.sdnplatform.sync.internal; + +import java.util.List; + +import org.sdnplatform.sync.IStoreClient; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.ObsoleteVersionException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.version.VectorClock; + + +public abstract class AbstractStoreClient<K,V> implements IStoreClient<K, V> { + + @Override + public V getValue(K key) throws SyncException { + return getValue(key, null); + } + + @Override + public V getValue(K key, V defaultValue) throws SyncException { + Versioned<V> val = get(key); + if (val == null || val.getValue() == null) return defaultValue; + return val.getValue(); + } + + /** + * Get the versions for a key + * @param key the key + * @return the versions + * @throws SyncException + */ + protected abstract List<IVersion> getVersions(K key) throws SyncException; + + @Override + public Versioned<V> get(K key) throws SyncException { + return get(key, null); + } + + @Override + public IVersion put(K key, V value) throws SyncException { + List<IVersion> versions = getVersions(key); + Versioned<V> versioned; + if(versions.isEmpty()) + versioned = Versioned.value(value, new VectorClock()); + else if(versions.size() == 1) + versioned = Versioned.value(value, versions.get(0)); + else { + versioned = get(key, null); + if(versioned == null) + versioned = Versioned.value(value, new VectorClock()); + else + versioned.setValue(value); + } + return put(key, versioned); + } + + @Override + public boolean putIfNotObsolete(K key, Versioned<V> versioned) + throws SyncException { + try { + put(key, versioned); + return true; + } catch (ObsoleteVersionException e) { + return false; + } + } + + @Override + public void delete(K key) throws SyncException { + put(key, (V)null); + } + + @Override + public void delete(K key, IVersion version) throws SyncException { + put(key, new Versioned<V>((V)null, version)); + } + +} diff --git a/src/main/java/org/sdnplatform/sync/internal/AbstractSyncManager.java b/src/main/java/org/sdnplatform/sync/internal/AbstractSyncManager.java new file mode 100644 index 0000000000000000000000000000000000000000..5b20aeb1cfa7123d81ecec4a39da95d11e6ab17c --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/AbstractSyncManager.java @@ -0,0 +1,176 @@ +package org.sdnplatform.sync.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.sdnplatform.sync.IInconsistencyResolver; +import org.sdnplatform.sync.IStoreClient; +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.UnknownStoreException; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.JacksonStore; +import org.sdnplatform.sync.internal.store.MappingStoreListener; +import org.sdnplatform.sync.internal.util.ByteArray; + +import net.floodlightcontroller.core.module.IFloodlightModule; +import net.floodlightcontroller.core.module.IFloodlightService; +import com.fasterxml.jackson.core.type.TypeReference; + + +/** + * An abstract base class for modules providing {@link ISyncService} + * @author readams + */ +public abstract class AbstractSyncManager + implements ISyncService, IFloodlightModule { + + // ************ + // ISyncService + // ************ + + @Override + public <K, V> IStoreClient<K, V> + getStoreClient(String storeName, + Class<K> keyClass, + Class<V> valueClass) + throws UnknownStoreException { + return getStoreClient(storeName, keyClass, null, + valueClass, null, null); + } + + @Override + public <K, V>IStoreClient<K, V> + getStoreClient(String storeName, + TypeReference<K> keyType, + TypeReference<V> valueType) + throws UnknownStoreException { + return getStoreClient(storeName, null, keyType, + null, valueType, null); + } + + @Override + public <K, V> IStoreClient<K, V> + getStoreClient(String storeName, + TypeReference<K> keyType, + TypeReference<V> valueType, + IInconsistencyResolver<Versioned<V>> resolver) + throws UnknownStoreException { + return getStoreClient(storeName, null, keyType, + null, valueType, resolver); + } + + @Override + public <K, V> IStoreClient<K, V> + getStoreClient(String storeName, + Class<K> keyClass, + Class<V> valueClass, + IInconsistencyResolver<Versioned<V>> resolver) + throws UnknownStoreException { + return getStoreClient(storeName, keyClass, null, + valueClass, null, resolver); + } + + // ***************** + // IFloodlightModule + // ***************** + + @Override + public Collection<Class<? extends IFloodlightService>> + getModuleServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(ISyncService.class); + return l; + } + + @Override + public Map<Class<? extends IFloodlightService>, IFloodlightService> + getServiceImpls() { + Map<Class<? extends IFloodlightService>, + IFloodlightService> m = + new HashMap<Class<? extends IFloodlightService>, + IFloodlightService>(); + // We are the class that implements the service + m.put(ISyncService.class, this); + return m; + } + + // ******************* + // AbstractSyncManager + // ******************* + + /** + * The "real" version of getStoreClient that will be called by all + * the others + * @param storeName the store name + * @param keyClass the key class + * @param keyType the key type + * @param valueClass the value class + * @param valueType the value type + * @param resolver the inconsistency resolver + * @return a {@link DefaultStoreClient} using the given parameters. + * @throws UnknownStoreException + */ + public <K, V> IStoreClient<K, V> + getStoreClient(String storeName, + Class<K> keyClass, + TypeReference<K> keyType, + Class<V> valueClass, + TypeReference<V> valueType, + IInconsistencyResolver<Versioned<V>> resolver) + throws UnknownStoreException { + IStore<ByteArray,byte[]> store = getStore(storeName); + IStore<K, V> serializingStore; + if (valueType != null && keyType != null) { + serializingStore = + new JacksonStore<K, V>(store, keyType, valueType); + } else if (valueClass != null && keyClass != null) { + serializingStore = + new JacksonStore<K, V>(store, keyClass, valueClass); + } else { + throw new IllegalArgumentException("Must include type reference" + + " or value class"); + } + + DefaultStoreClient<K, V> storeClient = + new DefaultStoreClient<K, V>(serializingStore, + resolver, + this, + keyClass, + keyType); + return storeClient; + } + + /** + * Get a store object corresponding to the given store name + * @param storeName the store name + * @return the {@link IStore} + * @throws UnknownStoreException + */ + public abstract IStore<ByteArray,byte[]> getStore(String storeName) + throws UnknownStoreException; + + /** + * Get the local ID of the local node + * @return the node ID + */ + public abstract short getLocalNodeId(); + + /** + * Add a listener to the specified store + * @param storeName the name of the store + * @param listener the listener to add + * @throws UnknownStoreException + */ + public abstract void addListener(String storeName, + MappingStoreListener listener) + throws UnknownStoreException; + + /** + * Shut down the sync manager. Tear down any communicating threads + */ + public abstract void shutdown(); +} diff --git a/src/main/java/org/sdnplatform/sync/internal/Cursor.java b/src/main/java/org/sdnplatform/sync/internal/Cursor.java new file mode 100644 index 0000000000000000000000000000000000000000..a9fbc224bd75791a82dfb02ff787bdae29a4f1bb --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/Cursor.java @@ -0,0 +1,49 @@ +package org.sdnplatform.sync.internal; + +import java.util.List; +import java.util.Map.Entry; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.internal.util.ByteArray; + + +public class Cursor implements + IClosableIterator<Entry<ByteArray, List<Versioned<byte[]>>>> { + private final int cursorId; + private final + IClosableIterator<Entry<ByteArray, + List<Versioned<byte[]>>>> delegate; + + public Cursor(int cursorId, + IClosableIterator<Entry<ByteArray, + List<Versioned<byte[]>>>> delegate) { + super(); + this.cursorId = cursorId; + this.delegate = delegate; + } + + @Override + public boolean hasNext() { + return delegate.hasNext(); + } + + @Override + public Entry<ByteArray, List<Versioned<byte[]>>> next() { + return delegate.next(); + } + + @Override + public void remove() { + delegate.remove(); + } + + @Override + public void close() { + delegate.close(); + } + + public int getCursorId() { + return this.cursorId; + } +} \ No newline at end of file diff --git a/src/main/java/org/sdnplatform/sync/internal/DefaultStoreClient.java b/src/main/java/org/sdnplatform/sync/internal/DefaultStoreClient.java new file mode 100644 index 0000000000000000000000000000000000000000..56d000d4f74a6000de763ea3f8efa9a4e2f732b3 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/DefaultStoreClient.java @@ -0,0 +1,191 @@ +package org.sdnplatform.sync.internal; + +import java.util.List; +import java.util.Map.Entry; + +import com.fasterxml.jackson.core.type.TypeReference; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IInconsistencyResolver; +import org.sdnplatform.sync.IStoreListener; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.InconsistentDataException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.UnknownStoreException; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.MappingStoreListener; +import org.sdnplatform.sync.internal.util.Pair; +import org.sdnplatform.sync.internal.version.ChainedResolver; +import org.sdnplatform.sync.internal.version.TimeBasedInconsistencyResolver; +import org.sdnplatform.sync.internal.version.VectorClock; +import org.sdnplatform.sync.internal.version.VectorClockInconsistencyResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Default implementation of a store client used for accessing a store + * locally in process. + * @author readams + * + * @param <K> the key type + * @param <V> the value type + */ +public class DefaultStoreClient<K, V> extends AbstractStoreClient<K, V> { + protected static final Logger logger = + LoggerFactory.getLogger(DefaultStoreClient.class.getName()); + + private IStore<K, V> delegate; + private IInconsistencyResolver<Versioned<V>> resolver; + private AbstractSyncManager syncManager; + private Class<K> keyClass; + private TypeReference<K> keyType; + + @SuppressWarnings("unchecked") + public DefaultStoreClient(IStore<K, V> delegate, + IInconsistencyResolver<Versioned<V>> resolver, + AbstractSyncManager syncManager, + Class<K> keyClass, + TypeReference<K> keyType) { + super(); + this.delegate = delegate; + this.syncManager = syncManager; + this.keyClass = keyClass; + this.keyType = keyType; + + IInconsistencyResolver<Versioned<V>> vcir = + new VectorClockInconsistencyResolver<V>(); + IInconsistencyResolver<Versioned<V>> secondary = resolver; + if (secondary == null) + secondary = new TimeBasedInconsistencyResolver<V>(); + this.resolver = new ChainedResolver<Versioned<V>>(vcir, secondary); + } + + // ****************** + // IStoreClient<K,V> + // ****************** + + @Override + public Versioned<V> get(K key, Versioned<V> defaultValue) + throws SyncException { + List<Versioned<V>> raw = delegate.get(key); + return handleGet(key, defaultValue, raw); + } + + @Override + public IClosableIterator<Entry<K, Versioned<V>>> entries() throws SyncException { + return new StoreClientIterator(delegate.entries()); + } + + @Override + public IVersion put(K key, Versioned<V> versioned) + throws SyncException { + VectorClock vc = (VectorClock)versioned.getVersion(); + + vc = vc.incremented(syncManager.getLocalNodeId(), + System.currentTimeMillis()); + versioned = Versioned.value(versioned.getValue(), vc); + + delegate.put(key, versioned); + return versioned.getVersion(); + } + + @Override + public void addStoreListener(IStoreListener<K> listener) { + if (listener == null) + throw new IllegalArgumentException("Must include listener"); + MappingStoreListener msl = + new MappingStoreListener(keyType, keyClass, listener); + try { + syncManager.addListener(delegate.getName(), msl); + } catch (UnknownStoreException e) { + // this shouldn't happen since we already have a store client, + // unless the store has been deleted somehow + logger.error("Unexpected internal state: unknown store " + + "from store client. Could not register listener", e); + } + } + + // ************************ + // AbstractStoreClient<K,V> + // ************************ + + @Override + protected List<IVersion> getVersions(K key) throws SyncException { + return delegate.getVersions(key); + } + + // ********************* + // Private local methods + // ********************* + + protected Versioned<V> handleGet(K key, + Versioned<V> defaultValue, + List<Versioned<V>> raw) + throws InconsistentDataException { + if (raw == null) return defaultValue(defaultValue); + List<Versioned<V>> vs = resolver.resolveConflicts(raw); + return getItemOrThrow(key, defaultValue, vs); + } + + protected Versioned<V> defaultValue(Versioned<V> defaultValue) { + if (defaultValue == null) + return Versioned.emptyVersioned(); + return defaultValue; + } + + protected Versioned<V> getItemOrThrow(K key, + Versioned<V> defaultValue, + List<Versioned<V>> items) + throws InconsistentDataException { + if(items.size() == 0) + return defaultValue(defaultValue); + else if(items.size() == 1) + return items.get(0); + else + throw new InconsistentDataException("Resolver failed to resolve" + + " conflict: " + items.size() + " unresolved items", items); + } + + + protected class StoreClientIterator implements + IClosableIterator<Entry<K, Versioned<V>>> { + + IClosableIterator<Entry<K, List<Versioned<V>>>> delegate; + + public StoreClientIterator(IClosableIterator<Entry<K, + List<Versioned<V>>>> delegate) { + super(); + this.delegate = delegate; + } + + @Override + public boolean hasNext() { + return delegate.hasNext(); + } + + @Override + public Entry<K, Versioned<V>> next() { + Entry<K, List<Versioned<V>>> n = delegate.next(); + try { + return new Pair<K, Versioned<V>>(n.getKey(), + handleGet(n.getKey(), null, n.getValue())); + } catch (SyncException e) { + logger.error("Failed to construct next value", e); + return null; + } + } + + @Override + public void remove() { + delegate.remove(); + } + + @Override + public void close() { + delegate.close(); + } + + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/StoreRegistry.java b/src/main/java/org/sdnplatform/sync/internal/StoreRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..a23b1f75ded060ebce9b6a0b7604543944c77c84 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/StoreRegistry.java @@ -0,0 +1,280 @@ +package org.sdnplatform.sync.internal; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.sql.ConnectionPoolDataSource; + +import net.floodlightcontroller.core.annotations.LogMessageDoc; + +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.error.PersistException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.store.InMemoryStorageEngine; +import org.sdnplatform.sync.internal.store.JavaDBStorageEngine; +import org.sdnplatform.sync.internal.store.SynchronizingStorageEngine; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Manage registered stores and associated metadata + * @author readams + */ +public class StoreRegistry { + protected static final Logger logger = + LoggerFactory.getLogger(StoreRegistry.class); + + /** + * The associated syncManager + */ + private final SyncManager syncManager; + + /** + * A data source suitable for use in persistent stores + */ + private ConnectionPoolDataSource persistentDataSource = + JavaDBStorageEngine.getDataSource(false); + + /** + * The storage engines that contain the locally-stored data + */ + private HashMap<String,SynchronizingStorageEngine> localStores = + new HashMap<String, SynchronizingStorageEngine>(); + + /** + * Undelivered hints associated with the stores + */ + private InMemoryStorageEngine<HintKey,byte[]> hints; + + /** + * A queue containing pending hints. + */ + private ArrayDeque<HintKey> hintQueue = new ArrayDeque<HintKey>(); + private Lock hintLock = new ReentrantLock(); + private Condition hintsAvailable = hintLock.newCondition(); + + /** + * Construct a new {@link StoreRegistry} + * @param syncManager The associated syncManager + */ + public StoreRegistry(SyncManager syncManager) { + super(); + this.syncManager = syncManager; + hints = new InMemoryStorageEngine<HintKey, byte[]>("system-hints"); + } + + // ************** + // public methods + // ************** + + /** + * Get the store associated with the given name, or null if there is no + * such store + * @param storeName + * @return a {@link SynchronizingStorageEngine} + */ + public SynchronizingStorageEngine get(String storeName) { + return localStores.get(storeName); + } + + /** + * Register a new store with the given name, scope and persistence + * @param storeName the name of the store + * @param scope the scope for the store + * @param persistent whether the store should be persistent + * @return the newly-allocated store + * @throws PersistException + */ + public synchronized SynchronizingStorageEngine register(String storeName, + Scope scope, + boolean persistent) + throws PersistException { + SynchronizingStorageEngine store = + localStores.get(storeName); + if (store != null) { + return store; + } + + IStorageEngine<ByteArray, byte[]> dstore; + if (persistent) { + dstore = new JavaDBStorageEngine(storeName, persistentDataSource); + } else { + dstore = new InMemoryStorageEngine<ByteArray, byte[]>(storeName); + } + store = new SynchronizingStorageEngine(dstore, syncManager, + syncManager.debugCounter, + scope); + localStores.put(storeName, store); + return store; + } + + /** + * Get a collection containing all the currently-registered stores + * @return the {@link Collection<SynchronizingStorageEngine>} + */ + public Collection<SynchronizingStorageEngine> values() { + return localStores.values(); + } + + /** + * Add a key/value to the hint store for the given store + * @param storeName the name of the store for the keyed value + * @param key the key + * @param value the value + */ + @LogMessageDoc(level="ERROR", + message="Failed to queue hint for store {storeName}", + explanation="There was an error synchronizing data to " + + "remote nodes", + recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) + public void queueHint(String storeName, + ByteArray key, Versioned<byte[]> value) { + try { + HintKey hk = new HintKey(storeName,key); + hintLock.lock(); + try { + boolean needed = !hints.containsKey(hk); + needed &= hints.doput(hk, value); + if (needed) { + hintQueue.add(hk); + hintsAvailable.signal(); + } + } finally { + hintLock.unlock(); + } + } catch (SyncException e) { + logger.error("Failed to queue hint for store " + storeName, e); + } + } + + /** + * Drain up to the given number of hints to the provided collection. + * This method will block until at least one hint is available + * @param c the collection to which the hints should be copied + * @param maxElements the maximum number of hints to drain + * @throws InterruptedException + */ + public void takeHints(Collection<Hint> c, int maxElements) + throws InterruptedException { + int count = 0; + try { + while (count == 0) { + hintLock.lock(); + while (hintQueue.isEmpty()) { + hintsAvailable.await(); + } + while (count < maxElements && !hintQueue.isEmpty()) { + HintKey hintKey = hintQueue.pollFirst(); + if (hintKey != null) { + List<Versioned<byte[]>> values = hints.remove(hintKey); + if (values == null) { + continue; + } + c.add(new Hint(hintKey, values)); + count += 1; + } + } + } + } finally { + hintLock.unlock(); + } + } + + public void shutdown() { + hintQueue.clear(); + hints.close(); + } + + /** + * A key in the hint store + * @author readams + */ + public static class HintKey { + private final String storeName; + private final ByteArray key; + private final short nodeId; + + public HintKey(String storeName, + ByteArray key, + short nodeId) { + super(); + this.storeName = storeName; + this.key = key; + this.nodeId = nodeId; + } + + public HintKey(String storeName, + ByteArray key) { + super(); + this.storeName = storeName; + this.key = key; + this.nodeId = -1; + } + + public String getStoreName() { + return storeName; + } + public ByteArray getKey() { + return key; + } + public short getNodeId() { + return nodeId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + nodeId; + result = prime * result + + ((storeName == null) ? 0 : storeName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + HintKey other = (HintKey) obj; + if (key == null) { + if (other.key != null) return false; + } else if (!key.equals(other.key)) return false; + if (nodeId != other.nodeId) return false; + if (storeName == null) { + if (other.storeName != null) return false; + } else if (!storeName.equals(other.storeName)) return false; + return true; + } + } + + /** + * A hint representing a hint key and a value + * @author readams + */ + public static class Hint { + private HintKey hintKey; + private List<Versioned<byte[]>> values; + public Hint(HintKey hintKey, List<Versioned<byte[]>> values) { + super(); + this.hintKey = hintKey; + this.values = values; + } + public HintKey getHintKey() { + return hintKey; + } + public List<Versioned<byte[]>> getValues() { + return values; + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/SyncManager.java b/src/main/java/org/sdnplatform/sync/internal/SyncManager.java new file mode 100644 index 0000000000000000000000000000000000000000..50098da72c37898d499bb164ed353df9c6dbc4c7 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/SyncManager.java @@ -0,0 +1,807 @@ +package org.sdnplatform.sync.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.IVersion.Occurred; +import org.sdnplatform.sync.error.PersistException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.SyncRuntimeException; +import org.sdnplatform.sync.error.UnknownStoreException; +import org.sdnplatform.sync.internal.StoreRegistry.Hint; +import org.sdnplatform.sync.internal.config.ClusterConfig; +import org.sdnplatform.sync.internal.config.DelegatingCCProvider; +import org.sdnplatform.sync.internal.config.FallbackCCProvider; +import org.sdnplatform.sync.internal.config.IClusterConfigProvider; +import org.sdnplatform.sync.internal.config.Node; +import org.sdnplatform.sync.internal.config.PropertyCCProvider; +import org.sdnplatform.sync.internal.config.StorageCCProvider; +import org.sdnplatform.sync.internal.rpc.RPCService; +import org.sdnplatform.sync.internal.rpc.TProtocolUtil; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.MappingStoreListener; +import org.sdnplatform.sync.internal.store.SynchronizingStorageEngine; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.version.VectorClock; +import org.sdnplatform.sync.thrift.SyncMessage; +import org.sdnplatform.sync.thrift.KeyedValues; +import org.sdnplatform.sync.thrift.KeyedVersions; +import org.sdnplatform.sync.thrift.SyncOfferMessage; +import org.sdnplatform.sync.thrift.SyncValueMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.floodlightcontroller.core.annotations.LogMessageCategory; +import net.floodlightcontroller.core.annotations.LogMessageDoc; +import net.floodlightcontroller.core.annotations.LogMessageDocs; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightService; +import net.floodlightcontroller.core.util.SingletonTask; +import net.floodlightcontroller.debugcounter.IDebugCounterService; +import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType; +import net.floodlightcontroller.storage.IStorageSourceService; +import net.floodlightcontroller.threadpool.IThreadPoolService; + + +/** + * Implementation for {@link ISyncService} that keeps local copies of the data + * and will synchronize it to other nodes in the cluster + * @author readams + * @see ISyncService + */ +@LogMessageCategory("State Synchronization") +public class SyncManager extends AbstractSyncManager { + protected static final Logger logger = + LoggerFactory.getLogger(SyncManager.class.getName()); + + protected IThreadPoolService threadPool; + protected IDebugCounterService debugCounter; + + /** + * The store registry holds the storage engines that provide + * access to the data + */ + private StoreRegistry storeRegistry = new StoreRegistry(this); + + private IClusterConfigProvider clusterConfigProvider; + private ClusterConfig clusterConfig = new ClusterConfig(); + + protected RPCService rpcService = null; + + /** + * Interval between cleanup tasks in seconds + */ + private static final int CLEANUP_INTERVAL = 60 * 60; + + /** + * Interval between antientropy tasks in seconds + */ + private static final int ANTIENTROPY_INTERVAL = 5 * 60; + + /** + * Interval between configuration rescans + */ + private static final int CONFIG_RESCAN_INTERVAL = 10; + + /** + * Task for performing periodic maintenance/cleanup on local stores + */ + private SingletonTask cleanupTask; + + /** + * Task for periodic antientropy between nodes + */ + private SingletonTask antientropyTask; + + /** + * Task to periodically rescan configuration + */ + private SingletonTask updateConfigTask; + + /** + * Number of {@link HintWorker} workers used to drain the queue of writes + * that need to be sent to the connected nodes + */ + private static final int SYNC_WORKER_POOL = 2; + + /** + * A thread pool for the {@link HintWorker} threads. + */ + private ExecutorService hintThreadPool; + + /** + * Random number generator + */ + private Random random = new Random(); + + /** + * A map of the currently-allocated cursors + */ + private Map<Integer, Cursor> cursorMap = + new ConcurrentHashMap<Integer, Cursor>(); + + private static final String PACKAGE = + ISyncService.class.getPackage().getName(); + public static final String COUNTER_HINTS = PACKAGE + "-hints"; + public static final String COUNTER_SENT_VALUES = PACKAGE + "-sent_values"; + public static final String COUNTER_RECEIVED_VALUES = + PACKAGE + "-received_values"; + public static final String COUNTER_PUTS = PACKAGE + "-puts"; + public static final String COUNTER_GETS = PACKAGE + "-gets"; + public static final String COUNTER_ITERATORS = PACKAGE + "-iterators"; + + // ************ + // ISyncService + // ************ + + @Override + public void registerStore(String storeName, Scope scope) { + try { + storeRegistry.register(storeName, scope, false); + } catch (PersistException e) { + // not possible + throw new SyncRuntimeException(e); + } + } + + @Override + public void registerPersistentStore(String storeName, Scope scope) + throws PersistException { + storeRegistry.register(storeName, scope, true); + } + + // ************************** + // SyncManager public methods + // ************************** + + /** + * Get the cluster configuration object + * @return the {@link ClusterConfig} object + * @see ClusterConfig + */ + public ClusterConfig getClusterConfig() { + return clusterConfig; + } + + /** + * Perform periodic scheduled cleanup. Note that this will be called + * automatically and you shouldn't generally call it directly except for + * testing + * @throws SyncException + */ + public void cleanup() throws SyncException { + for (SynchronizingStorageEngine store : storeRegistry.values()) { + store.cleanupTask(); + } + } + + /** + * Perform a synchronization with the node specified + */ + @LogMessageDoc(level="INFO", + message="[{id}->{id}] Synchronizing local state to remote node", + explanation="Normal state resynchronization is occurring") + public void antientropy(Node node) { + if (!rpcService.isConnected(node.getNodeId())) return; + + logger.info("[{}->{}] Synchronizing local state to remote node", + getLocalNodeId(), node.getNodeId()); + + for (SynchronizingStorageEngine store : storeRegistry.values()) { + if (Scope.LOCAL.equals(store.getScope())) { + if (node.getDomainId() != + getClusterConfig().getNode().getDomainId()) + continue; + } + + IClosableIterator<Entry<ByteArray, + List<Versioned<byte[]>>>> entries = + store.entries(); + try { + SyncMessage bsm = + TProtocolUtil.getTSyncOfferMessage(store.getName(), + store.getScope(), + store.isPersistent()); + int count = 0; + while (entries.hasNext()) { + if (!rpcService.isConnected(node.getNodeId())) return; + + Entry<ByteArray, List<Versioned<byte[]>>> pair = + entries.next(); + KeyedVersions kv = + TProtocolUtil.getTKeyedVersions(pair.getKey(), + pair.getValue()); + bsm.getSyncOffer().addToVersions(kv); + count += 1; + if (count >= 50) { + sendSyncOffer(node.getNodeId(), bsm); + bsm.getSyncOffer().unsetVersions(); + count = 0; + } + } + sendSyncOffer(node.getNodeId(), bsm); + } catch (InterruptedException e) { + // This can't really happen + throw new RuntimeException(e); + } finally { + entries.close(); + } + } + } + + /** + * Communicate with a random node and do a full synchronization of the + * all the stores on each node that have the appropriate scope. + */ + public void antientropy() { + ArrayList<Node> candidates = new ArrayList<Node>(); + for (Node n : clusterConfig.getNodes()) + if (rpcService.isConnected(n.getNodeId())) + candidates.add(n); + + int numNodes = candidates.size(); + if (numNodes == 0) return; + Node[] nodes = candidates.toArray(new Node[numNodes]); + int rn = random.nextInt(numNodes); + antientropy(nodes[rn]); + } + + /** + * Write a value synchronized from another node, bypassing some of the + * usual logic when a client writes data. If the store is not known, + * this will automatically register it + * @param storeName the store name + * @param scope the scope for the store + * @param persist TODO + * @param key the key to write + * @param values a list of versions for the key to write + * @throws PersistException + */ + public void writeSyncValue(String storeName, Scope scope, + boolean persist, + byte[] key, Iterable<Versioned<byte[]>> values) + throws PersistException { + SynchronizingStorageEngine store = storeRegistry.get(storeName); + if (store == null) { + store = storeRegistry.register(storeName, scope, persist); + } + store.writeSyncValue(new ByteArray(key), values); + } + + /** + * Check whether any of the specified versions for the key are not older + * than the versions we already have + * @param storeName the store to check + * @param key the key to check + * @param versions an iterable over the versions + * @return true if we'd like a copy of the data indicated + * @throws SyncException + */ + public boolean handleSyncOffer(String storeName, + byte[] key, + Iterable<VectorClock> versions) + throws SyncException { + SynchronizingStorageEngine store = storeRegistry.get(storeName); + if (store == null) return true; + + List<Versioned<byte[]>> values = store.get(new ByteArray(key)); + if (values == null || values.size() == 0) return true; + + // check whether any of the versions are not older than what we have + for (VectorClock vc : versions) { + for (Versioned<byte[]> value : values) { + VectorClock existingVc = (VectorClock)value.getVersion(); + if (!vc.compare(existingVc).equals(Occurred.BEFORE)) + return true; + } + } + + return false; + } + + /** + * Get access to the raw storage engine. This is useful for some + * on-the-wire communication + * @param storeName the store name to get + * @return the {@link IStorageEngine} + * @throws UnknownStoreException + */ + public IStorageEngine<ByteArray, byte[]> getRawStore(String storeName) + throws UnknownStoreException { + return getStoreInternal(storeName); + } + + /** + * Return the threadpool + * @return the {@link IThreadPoolService} + */ + public IThreadPoolService getThreadPool() { + return threadPool; + } + + /** + * Queue a synchronization of the specified {@link KeyedValues} to all nodes + * assocatiated with the storage engine specified + * @param e the storage engine for the values + * @param kv the values to synchronize + */ + @LogMessageDoc(level="WARN", + message="Sync task queue full and not emptying", + explanation="The synchronization service is overloaded", + recommendation=LogMessageDoc.CHECK_CONTROLLER) + public void queueSyncTask(SynchronizingStorageEngine e, + ByteArray key, Versioned<byte[]> value) { + storeRegistry.queueHint(e.getName(), key, value); + } + + @Override + public void addListener(String storeName, MappingStoreListener listener) + throws UnknownStoreException { + SynchronizingStorageEngine store = getStoreInternal(storeName); + store.addListener(listener); + } + + /** + * Update the node configuration to add or remove nodes + * @throws FloodlightModuleException + */ + @LogMessageDocs({ + @LogMessageDoc(level="INFO", + message="Updating sync configuration {config}", + explanation="The sync service cluster configuration has been updated"), + @LogMessageDoc(level="INFO", + message="Local node configuration changed; restarting sync" + + "service", + explanation="The sync service must be restarted to update its configuration") + }) + public void updateConfiguration() + throws FloodlightModuleException { + + try { + ClusterConfig oldConfig = clusterConfig; + clusterConfig = clusterConfigProvider.getConfig(); + if (clusterConfig.equals(oldConfig)) return; + + logger.info("Updating sync configuration {}", clusterConfig); + if (oldConfig.getNode() != null && + !clusterConfig.getNode().equals(oldConfig.getNode())) { + logger.info("Local node configuration changed; restarting sync" + + "service"); + shutdown(); + startUp(null); + } + + for (Node n : clusterConfig.getNodes()) { + Node existing = oldConfig.getNode(n.getNodeId()); + if (existing != null && !n.equals(existing)) { + // we already had this node's configuration, but it's + // changed. Disconnect from the node and let it + // reinitialize + logger.debug("[{}->{}] Configuration for node has changed", + getLocalNodeId(), n.getNodeId()); + rpcService.disconnectNode(n.getNodeId()); + } + } + for (Node n : oldConfig.getNodes()) { + Node nn = clusterConfig.getNode(n.getNodeId()); + if (nn == null) { + // n is a node that doesn't appear in the new config + logger.debug("[{}->{}] Disconnecting deconfigured node", + getLocalNodeId(), n.getNodeId()); + rpcService.disconnectNode(n.getNodeId()); + } + } + } catch (Exception e) { + throw new FloodlightModuleException("Could not update " + + "configuration", e); + } + } + + /** + * Retrieve the cursor, if any, for the given cursor ID + * @param cursorId the cursor ID + * @return the {@link Cursor} + */ + public Cursor getCursor(int cursorId) { + return cursorMap.get(Integer.valueOf(cursorId)); + } + + /** + * Allocate a new cursor for the given store name + * @param storeName the store name + * @return the {@link Cursor} + * @throws SyncException + */ + public Cursor newCursor(String storeName) throws UnknownStoreException { + IStore<ByteArray, byte[]> store = getStore(storeName); + int cursorId = rpcService.getTransactionId(); + Cursor cursor = new Cursor(cursorId, store.entries()); + cursorMap.put(Integer.valueOf(cursorId), cursor); + return cursor; + } + + /** + * Close the given cursor and remove it from the map + * @param cursor the cursor to close + */ + public void closeCursor(Cursor cursor) { + cursor.close(); + cursorMap.remove(Integer.valueOf(cursor.getCursorId())); + } + + // ******************* + // AbstractSyncManager + // ******************* + + @Override + public IStore<ByteArray,byte[]> getStore(String storeName) + throws UnknownStoreException { + return getRawStore(storeName); + } + + @Override + public short getLocalNodeId() { + return clusterConfig.getNode().getNodeId(); + } + + @Override + public void shutdown() { + logger.debug("Shutting down Sync Manager: {} {}", + clusterConfig.getNode().getHostname(), + clusterConfig.getNode().getPort()); + + if (rpcService != null) { + rpcService.shutdown(); + } + if (hintThreadPool != null) { + hintThreadPool.shutdown(); + } + if (storeRegistry != null) { + storeRegistry.shutdown(); + } + hintThreadPool = null; + rpcService = null; + } + + // ***************** + // IFloodlightModule + // ***************** + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + threadPool = context.getServiceImpl(IThreadPoolService.class); + debugCounter = context.getServiceImpl(IDebugCounterService.class); + Map<String, String> config = context.getConfigParams(this); + + String[] configProviders = + {StorageCCProvider.class.getName(), + PropertyCCProvider.class.getName(), + FallbackCCProvider.class.getName()}; + try { + + if (config.containsKey("configProviders")) { + configProviders = config.get("configProviders").split(","); + } + DelegatingCCProvider dprovider = new DelegatingCCProvider(); + for (String configProvider : configProviders) { + Class<?> cClass = Class.forName(configProvider); + IClusterConfigProvider provider = + (IClusterConfigProvider) cClass.newInstance(); + dprovider.addProvider(provider); + } + dprovider.init(this, context); + clusterConfigProvider = dprovider; + } catch (Exception e) { + throw new FloodlightModuleException("Could not instantiate config" + + "providers " + Arrays.toString(configProviders), e); + } + + String manualStoreString = config.get("manualStores"); + if (manualStoreString != null) { + List<String> manualStores = null; + try { + manualStores = + (new ObjectMapper()).readValue(manualStoreString, + new TypeReference<List<String>>() {}); + } catch (Exception e) { + throw new FloodlightModuleException("Failed to parse sync " + + "manager manual stores: " + manualStoreString, e); + } + for (String s : manualStores) { + registerStore(s, Scope.GLOBAL); + } + } + } + + @Override + public void startUp(FloodlightModuleContext context) + throws FloodlightModuleException { + debugCounter.registerCounter(COUNTER_HINTS, + "Queued sync events processed", + CounterType.ALWAYS_COUNT); + debugCounter.registerCounter(COUNTER_SENT_VALUES, + "Values synced to remote node", + CounterType.ALWAYS_COUNT); + debugCounter.registerCounter(COUNTER_RECEIVED_VALUES, + "Values received from remote node", + CounterType.ALWAYS_COUNT); + debugCounter.registerCounter(COUNTER_PUTS, + "Local puts to store", + CounterType.ALWAYS_COUNT); + debugCounter.registerCounter(COUNTER_GETS, + "Local gets from store", + CounterType.ALWAYS_COUNT); + debugCounter.registerCounter(COUNTER_ITERATORS, + "Local iterators created over store", + CounterType.ALWAYS_COUNT); + + updateConfiguration(); + rpcService = new RPCService(this, debugCounter); + rpcService.run(); + + cleanupTask = new SingletonTask(threadPool.getScheduledExecutor(), + new CleanupTask()); + cleanupTask.reschedule(CLEANUP_INTERVAL + + random.nextInt(30), TimeUnit.SECONDS); + + antientropyTask = new SingletonTask(threadPool.getScheduledExecutor(), + new AntientropyTask()); + antientropyTask.reschedule(ANTIENTROPY_INTERVAL + + random.nextInt(30), TimeUnit.SECONDS); + + updateConfigTask = + new SingletonTask(threadPool.getScheduledExecutor(), + new UpdateConfigTask()); + updateConfigTask.reschedule(CONFIG_RESCAN_INTERVAL, TimeUnit.SECONDS); + + final ThreadGroup tg = new ThreadGroup("Hint Workers"); + tg.setMaxPriority(Thread.NORM_PRIORITY - 2); + ThreadFactory f = new ThreadFactory() { + AtomicInteger id = new AtomicInteger(); + + @Override + public Thread newThread(Runnable runnable) { + return new Thread(tg, runnable, + "HintWorker-" + id.getAndIncrement()); + } + }; + hintThreadPool = Executors.newCachedThreadPool(f); + for (int i = 0; i < SYNC_WORKER_POOL; i++) { + hintThreadPool.execute(new HintWorker()); + } + } + + @Override + public Collection<Class<? extends IFloodlightService>> + getModuleDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IThreadPoolService.class); + l.add(IStorageSourceService.class); + l.add(IDebugCounterService.class); + return l; + } + + // *************** + // Local methods + // *************** + + protected SynchronizingStorageEngine getStoreInternal(String storeName) + throws UnknownStoreException { + SynchronizingStorageEngine store = storeRegistry.get(storeName); + if (store == null) { + throw new UnknownStoreException("Store " + storeName + + " has not been registered"); + } + return store; + } + + private void sendSyncOffer(short nodeId, SyncMessage bsm) + throws InterruptedException { + SyncOfferMessage som = bsm.getSyncOffer(); + if (!som.isSetVersions()) return; + if (logger.isTraceEnabled()) { + logger.trace("[{}->{}] Sending SyncOffer with {} elements", + new Object[]{getLocalNodeId(), nodeId, + som.getVersionsSize()}); + } + + som.getHeader().setTransactionId(rpcService.getTransactionId()); + rpcService.writeToNode(nodeId, bsm); + } + + /** + * Periodically perform cleanup + * @author readams + */ + @LogMessageDoc(level="ERROR", + message="Cleanup task failed", + explanation="Failed to clean up deleted data in the store", + recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) + protected class CleanupTask implements Runnable { + @Override + public void run() { + try { + if (rpcService != null) + cleanup(); + } catch (Exception e) { + logger.error("Cleanup task failed", e); + } + + if (rpcService != null) { + cleanupTask.reschedule(CLEANUP_INTERVAL + + random.nextInt(30), TimeUnit.SECONDS); + } + } + } + + /** + * Periodically perform antientropy + * @author readams + */ + @LogMessageDoc(level="ERROR", + message="Antientropy task failed", + explanation="Failed to synchronize state between two nodes", + recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) + protected class AntientropyTask implements Runnable { + @Override + public void run() { + try { + if (rpcService != null) + antientropy(); + } catch (Exception e) { + logger.error("Antientropy task failed", e); + } + + if (rpcService != null) { + antientropyTask.reschedule(ANTIENTROPY_INTERVAL + + random.nextInt(30), + TimeUnit.SECONDS); + } + } + } + + /** + * Worker task to periodically rescan the configuration + * @author readams + */ + @LogMessageDoc(level="ERROR", + message="Failed to update configuration", + explanation="An error occured while updating sync service configuration", + recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) + protected class UpdateConfigTask implements Runnable { + @Override + public void run() { + try { + if (rpcService != null) + updateConfiguration(); + } catch (Exception e) { + logger.error("Failed to update configuration", e); + } + if (rpcService != null) { + updateConfigTask.reschedule(CONFIG_RESCAN_INTERVAL, + TimeUnit.SECONDS); + } + } + } + + /** + * Worker thread that will drain the sync item queue and write the + * appropriate messages to the node I/O channels + * @author readams + */ + @LogMessageDoc(level="ERROR", + message="Error occured in synchronization worker", + explanation="Failed to synchronize state to remote node", + recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) + protected class HintWorker implements Runnable { + ArrayList<Hint> tasks = new ArrayList<Hint>(50); + protected HashMap<String, SyncMessage> messages = + new HashMap<String, SyncMessage>(); + + @Override + public void run() { + while (rpcService != null) { + try { + // Batch up sync tasks so we use fewer, larger messages + // XXX - todo - handle hints targeted to specific nodes + storeRegistry.takeHints(tasks, 50); + for (Hint task : tasks) { + debugCounter.updateCounter(COUNTER_HINTS); + SynchronizingStorageEngine store = + storeRegistry.get(task.getHintKey(). + getStoreName()); + SyncMessage bsm = getMessage(store); + KeyedValues kv = + TProtocolUtil. + getTKeyedValues(task.getHintKey().getKey(), + task.getValues()); + bsm.getSyncValue().addToValues(kv); + } + + Iterable<Node> nodes = getClusterConfig().getNodes(); + short localDomainId = + getClusterConfig().getNode().getDomainId(); + short localNodeId = + getClusterConfig().getNode().getNodeId(); + for (Node n : nodes) { + if (localNodeId == n.getNodeId()) + continue; + for (SyncMessage bsm : messages.values()) { + SyncValueMessage svm = bsm.getSyncValue(); + if (svm.getStore().getScope(). + equals(org.sdnplatform.sync.thrift. + Scope.LOCAL) && + n.getDomainId() != localDomainId) { + // This message is only for local domain + continue; + } + + svm.getHeader(). + setTransactionId(rpcService. + getTransactionId()); + debugCounter.updateCounter(COUNTER_SENT_VALUES, + bsm.getSyncValue(). + getValuesSize()); + rpcService.writeToNode(n.getNodeId(), bsm); + } + } + debugCounter.flushCounters(); + tasks.clear(); + clearMessages(); + + } catch (Exception e) { + logger.error("Error occured in synchronization worker", e); + } + } + } + + /** + * Clear the current list of pending messages + */ + private void clearMessages() { + for (SyncMessage bsm : messages.values()) { + bsm.getSyncValue().unsetValues(); + } + } + + /** + * Allocate a partially-initialized {@link SyncMessage} object for + * the given store + * @param store the store + * @return the {@link SyncMessage} object + */ + private SyncMessage getMessage(SynchronizingStorageEngine store) { + String storeName = store.getName(); + SyncMessage bsm = messages.get(storeName); + if (bsm == null) { + bsm = TProtocolUtil.getTSyncValueMessage(storeName, + store.getScope(), + store.isPersistent()); + messages.put(storeName, bsm); + } + return bsm; + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/SyncTorture.java b/src/main/java/org/sdnplatform/sync/internal/SyncTorture.java new file mode 100644 index 0000000000000000000000000000000000000000..74e4ae96648089a28dd38758b817886a01f57f63 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/SyncTorture.java @@ -0,0 +1,196 @@ +package org.sdnplatform.sync.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.sdnplatform.sync.IStoreClient; +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.error.SyncException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; +import net.floodlightcontroller.core.module.IFloodlightService; +import net.floodlightcontroller.debugcounter.IDebugCounterService; + +/** + * A floodlight module that will start up and start doing horrible, + * horrible things to the sync service. + * @author readams + */ +public class SyncTorture implements IFloodlightModule { + protected static final Logger logger = + LoggerFactory.getLogger(SyncTorture.class); + + private static final String SYNC_STORE_NAME = + SyncTorture.class.getCanonicalName() + ".torture"; + + ISyncService syncService; + IDebugCounterService debugCounter; + + int numWorkers = 2; + int keysPerWorker = 1024*1024; + int iterations = 0; + int delay = 0; + + @Override + public Collection<Class<? extends IFloodlightService>> + getModuleServices() { + return null; + } + + @Override + public Map<Class<? extends IFloodlightService>, IFloodlightService> + getServiceImpls() { + return null; + } + + @Override + public Collection<Class<? extends IFloodlightService>> + getModuleDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(ISyncService.class); + l.add(IDebugCounterService.class); + + return l; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + syncService = context.getServiceImpl(ISyncService.class); + debugCounter = context.getServiceImpl(IDebugCounterService.class); + + try { + syncService.registerStore(SYNC_STORE_NAME, Scope.GLOBAL); + } catch (SyncException e) { + throw new FloodlightModuleException(e); + } + + Map<String,String> config = context.getConfigParams(this); + if (config.containsKey("numWorkers")) { + numWorkers = Integer.parseInt(config.get("numWorkers")); + } + if (config.containsKey("keysPerWorker")) { + keysPerWorker = Integer.parseInt(config.get("keysPerWorker")); + } + if (config.containsKey("iterations")) { + iterations = Integer.parseInt(config.get("iterations")); + } + if (config.containsKey("delay")) { + delay = Integer.parseInt(config.get("delay")); + } + } + + @Override + public void startUp(FloodlightModuleContext context) + throws FloodlightModuleException { + try { + final IStoreClient<String, TortureValue> storeClient = + syncService.getStoreClient(SYNC_STORE_NAME, + String.class, + TortureValue.class); + for (int i = 0; i < numWorkers; i++) { + Thread thread = new Thread(new TortureWorker(storeClient, i), + "Torture-" + i); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + } + } catch (Exception e) { + throw new FloodlightModuleException(e); + } + } + + protected static class TortureValue { + private String string; + private int integer; + private boolean bool; + + public TortureValue() { + super(); + } + + public TortureValue(String string, int integer, boolean bool) { + super(); + this.string = string; + this.integer = integer; + this.bool = bool; + } + + public String getString() { + return string; + } + public void setString(String string) { + this.string = string; + } + public int getInteger() { + return integer; + } + public void setInteger(int integer) { + this.integer = integer; + } + public boolean isBool() { + return bool; + } + public void setBool(boolean bool) { + this.bool = bool; + } + } + + protected class TortureWorker implements Runnable { + final IStoreClient<String, TortureValue> storeClient; + final int workerId; + final List<TortureValue> values; + + public TortureWorker(IStoreClient<String, TortureValue> storeClient, + int workerId) { + super(); + this.storeClient = storeClient; + this.workerId = workerId; + values = new ArrayList<TortureValue>(); + for (int i = 0; i < keysPerWorker; i++) { + values.add(new TortureValue(workerId+":"+i, 0, true)); + } + } + + @Override + public void run() { + if (delay > 0) { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { } + } + int i = 0; + while (iterations == 0 || i++ < iterations) { + long start = System.currentTimeMillis(); + try { + for (TortureValue v : values) { + Versioned<TortureValue> vv = + storeClient.get(v.getString()); + v.setInteger(v.getInteger() + 1); + v.setBool(!v.isBool()); + vv.setValue(v); + storeClient.put(v.getString(), vv); + } + } catch (Exception e) { + logger.error("Error in worker: ", e); + } + long iterend = System.currentTimeMillis(); + debugCounter.flushCounters(); + logger.info("Completed iteration of {} values in {}ms" + + " ({}/s)", + new Object[]{values.size(), (iterend-start), + 1000*values.size()/(iterend-start)}); + } + + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/ClusterConfig.java b/src/main/java/org/sdnplatform/sync/internal/config/ClusterConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..23b64f8428eb69e27518d42590d5a48f226101c7 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/ClusterConfig.java @@ -0,0 +1,174 @@ +package org.sdnplatform.sync.internal.config; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import org.sdnplatform.sync.error.SyncException; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; + + +/** + * Represent the configuration of a cluster in the sync manager + * @author readams + */ +public class ClusterConfig { + private HashMap<Short, Node> allNodes = + new HashMap<Short, Node>(); + private HashMap<Short, List<Node>> localDomains = + new HashMap<Short, List<Node>>(); + private Node thisNode; + + public ClusterConfig() { + super(); + } + + /** + * Initialize a cluster config object using a JSON string containing + * the nodes + * @param nodeConfig the JSON-formatted cluster configurations + * @param thisNodeId the node ID for the current node + * @throws SyncException + */ + public ClusterConfig(String nodeConfig, + short thisNodeId) throws SyncException { + super(); + ObjectMapper mapper = new ObjectMapper(); + List<Node> nodes; + try { + nodes = mapper.readValue(nodeConfig, + new TypeReference<List<Node>>() { }); + } catch (Exception e) { + throw new SyncException("Failed to initialize sync manager", e); + } + init(nodes, thisNodeId); + } + + /** + * Initialize a cluster config using a list of nodes + * @param nodes the nodes to use + * @param thisNodeId the node ID for the current node + * @throws SyncException + */ + public ClusterConfig(List<Node> nodes, short thisNodeId) + throws SyncException { + init(nodes, thisNodeId); + } + + /** + * Get a collection containing all configured nodes + * @return the collection of nodes + */ + public Collection<Node> getNodes() { + return Collections.unmodifiableCollection(allNodes.values()); + } + + /** + * A collection of the nodes in the local domain for the current node + * @return the list of nodes + */ + public Collection<Node> getDomainNodes() { + return getDomainNodes(thisNode.getDomainId()); + } + + /** + * A collection of the nodes in the local domain specified + * @param domainId the domain ID + * @return the list of nodes + */ + public Collection<Node> getDomainNodes(short domainId) { + List<Node> r = localDomains.get(domainId); + return Collections.unmodifiableCollection(r); + } + + /** + * Get the {@link Node} object for the current node + */ + public Node getNode() { + return thisNode; + } + + /** + * The a list of the nodes in the local domain specified + * @param nodeId the node ID to retrieve + * @return the node (or null if there is no such node + */ + public Node getNode(short nodeId) { + return allNodes.get(nodeId); + } + + /** + * Add a new node to the cluster + * @param node the {@link Node} to add + * @throws SyncException if the node already exists + */ + private void addNode(Node node) throws SyncException { + Short nodeId = node.getNodeId(); + if (allNodes.get(nodeId) != null) { + throw new SyncException("Error adding node " + node + + ": a node with that ID already exists"); + } + allNodes.put(nodeId, node); + + Short domainId = node.getDomainId(); + List<Node> localDomain = localDomains.get(domainId); + if (localDomain == null) { + localDomains.put(domainId, + localDomain = new ArrayList<Node>()); + } + localDomain.add(node); + } + + private void init(List<Node> nodes, short thisNodeId) + throws SyncException { + for (Node n : nodes) { + addNode(n); + } + thisNode = getNode(thisNodeId); + if (thisNode == null) { + throw new SyncException("Cannot set thisNode " + + "node: No node with ID " + thisNodeId); + } + } + + @Override + public String toString() { + return "ClusterConfig [allNodes=" + allNodes + ", thisNode=" + + thisNode.getNodeId() + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((allNodes == null) ? 0 : allNodes.hashCode()); + result = prime * result + + ((localDomains == null) ? 0 : localDomains.hashCode()); + result = prime * result + + ((thisNode == null) ? 0 : thisNode.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + ClusterConfig other = (ClusterConfig) obj; + if (allNodes == null) { + if (other.allNodes != null) return false; + } else if (!allNodes.equals(other.allNodes)) return false; + if (localDomains == null) { + if (other.localDomains != null) return false; + } else if (!localDomains.equals(other.localDomains)) return false; + if (thisNode == null) { + if (other.thisNode != null) return false; + } else if (!thisNode.equals(other.thisNode)) return false; + return true; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/DelegatingCCProvider.java b/src/main/java/org/sdnplatform/sync/internal/config/DelegatingCCProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..2e793b7f68194385b46694ee9cbedefdbe28a1e4 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/DelegatingCCProvider.java @@ -0,0 +1,49 @@ +package org.sdnplatform.sync.internal.config; + +import java.util.ArrayList; +import java.util.List; + +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; + + +/** + * Delegate cluster configuration to a list of providers + * @author readams + */ +public class DelegatingCCProvider implements IClusterConfigProvider { + protected static final Logger logger = + LoggerFactory.getLogger(DelegatingCCProvider.class.getName()); + + List<IClusterConfigProvider> providers = + new ArrayList<IClusterConfigProvider>(); + + public void addProvider(IClusterConfigProvider provider) { + this.providers.add(provider); + } + + @Override + public void init(SyncManager syncManager, + FloodlightModuleContext context) { + for (IClusterConfigProvider provider : providers) + provider.init(syncManager, context); + } + + @Override + public ClusterConfig getConfig() throws SyncException { + for (IClusterConfigProvider provider : providers) { + try { + return provider.getConfig(); + } catch (Exception e) { + logger.debug("ClusterConfig provider {} failed: {}", + provider.getClass().getSimpleName(), + e.getMessage()); + } + } + throw new SyncException("All cluster config providers failed"); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/FallbackCCProvider.java b/src/main/java/org/sdnplatform/sync/internal/config/FallbackCCProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..4fc891902deaa95ceef5ba9390074eae66f25b17 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/FallbackCCProvider.java @@ -0,0 +1,43 @@ +package org.sdnplatform.sync.internal.config; + +import java.util.Collections; + +import net.floodlightcontroller.core.annotations.LogMessageCategory; +import net.floodlightcontroller.core.annotations.LogMessageDoc; + +import org.sdnplatform.sync.error.SyncException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Provide a fallback local configuration + * @author readams + */ +@LogMessageCategory("State Synchronization") +public class FallbackCCProvider extends StaticCCProvider { + protected static final Logger logger = + LoggerFactory.getLogger(FallbackCCProvider.class.getName()); + protected volatile boolean warned = false; + + public FallbackCCProvider() throws SyncException { + super(new ClusterConfig(Collections. + singletonList(new Node("localhost", + 6642, + Short.MAX_VALUE, + Short.MAX_VALUE)), + Short.MAX_VALUE)); + } + + @Override + @LogMessageDoc(level="WARN", + message="Using fallback local configuration", + explanation="No other nodes are known") + public ClusterConfig getConfig() throws SyncException { + if (!warned) { + logger.warn("Using fallback local configuration"); + warned = true; + } + return super.getConfig(); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/IClusterConfigProvider.java b/src/main/java/org/sdnplatform/sync/internal/config/IClusterConfigProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..355d3df31cd6e47c3b52dbb9cee0d24d7aafcde6 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/IClusterConfigProvider.java @@ -0,0 +1,27 @@ +package org.sdnplatform.sync.internal.config; + +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; + +/** + * Provides configuration for the sync service + * @author readams + */ +public interface IClusterConfigProvider { + /** + * Initialize the provider with the configuration parameters from the + * Floodlight module context. + * @param config + */ + public void init(SyncManager syncManager, + FloodlightModuleContext context); + + /** + * Get the {@link ClusterConfig} that represents the current cluster + * @return the {@link ClusterConfig} object + * @throws SyncException + */ + public ClusterConfig getConfig() throws SyncException; +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/Node.java b/src/main/java/org/sdnplatform/sync/internal/config/Node.java new file mode 100644 index 0000000000000000000000000000000000000000..5893355ef17f54c03e433ad5b371f503e7063663 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/Node.java @@ -0,0 +1,95 @@ +package org.sdnplatform.sync.internal.config; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represent a node in the synchronization system + * @author readams + */ +public class Node { + /** + * The host name to use for contacting this node from the + * other nodes + */ + private String hostname; + + /** + * The TCP port to use for contacting this node from the + * other nodes + */ + private int port; + + /** + * The node ID for this node + */ + private short nodeId; + + /** + * The ID for the local cluster domain. Data with a local scope will + * be shared only among nodes that share the same domain ID. + */ + private short domainId; + + @JsonCreator + public Node(@JsonProperty("hostname") String hostname, + @JsonProperty("port") int port, + @JsonProperty("nodeId") short nodeId, + @JsonProperty("domainId") short domainId) { + super(); + this.hostname = hostname; + this.port = port; + this.nodeId = nodeId; + this.domainId = domainId; + } + + public String getHostname() { + return hostname; + } + + public int getPort() { + return port; + } + + public short getNodeId() { + return nodeId; + } + + public short getDomainId() { + return domainId; + } + + @Override + public String toString() { + return "Node [hostname=" + hostname + ", port=" + port + ", nodeId=" + + nodeId + ", domainId=" + domainId + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + domainId; + result = + prime * result + + ((hostname == null) ? 0 : hostname.hashCode()); + result = prime * result + nodeId; + result = prime * result + port; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Node other = (Node) obj; + if (domainId != other.domainId) return false; + if (hostname == null) { + if (other.hostname != null) return false; + } else if (!hostname.equals(other.hostname)) return false; + if (nodeId != other.nodeId) return false; + if (port != other.port) return false; + return true; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/PropertyCCProvider.java b/src/main/java/org/sdnplatform/sync/internal/config/PropertyCCProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..1732a3b9468d9024e36655ff0e65b70a6e266eb0 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/PropertyCCProvider.java @@ -0,0 +1,44 @@ +package org.sdnplatform.sync.internal.config; + +import java.util.Map; + +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; + +public class PropertyCCProvider implements IClusterConfigProvider { + protected static Logger logger = + LoggerFactory.getLogger(PropertyCCProvider.class.getName()); + + private Map<String, String> config; + + @Override + public ClusterConfig getConfig() throws SyncException { + if (!config.containsKey("nodes") || !config.containsKey("thisNode")) + throw new SyncException("Configuration properties nodes or " + + "thisNode not set"); + + Short thisNodeId; + try { + thisNodeId = Short.parseShort(config.get("thisNode")); + } catch (NumberFormatException e) { + throw new SyncException("Failed to parse thisNode " + + "node ID: " + config.get("thisNode"), e); + } + try { + return new ClusterConfig(config.get("nodes"), thisNodeId); + } catch (Exception e) { + throw new SyncException("Could not update " + + "configuration", e); + } + } + + @Override + public void init(SyncManager syncManager, + FloodlightModuleContext context) { + this.config = context.getConfigParams(syncManager); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/StaticCCProvider.java b/src/main/java/org/sdnplatform/sync/internal/config/StaticCCProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..0028d9e0339abb0fa9903bf720b6cfdac4118a63 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/StaticCCProvider.java @@ -0,0 +1,26 @@ +package org.sdnplatform.sync.internal.config; + +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; + +public class StaticCCProvider implements IClusterConfigProvider { + public final ClusterConfig config; + + public StaticCCProvider(ClusterConfig config) { + super(); + this.config = config; + } + + @Override + public void init(SyncManager syncManager, + FloodlightModuleContext context) { + + } + + @Override + public ClusterConfig getConfig() throws SyncException { + return config; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/config/StorageCCProvider.java b/src/main/java/org/sdnplatform/sync/internal/config/StorageCCProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..22be6e03c7260a29c1a3a48d4fc2e96b5d062adc --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/config/StorageCCProvider.java @@ -0,0 +1,163 @@ +package org.sdnplatform.sync.internal.config; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.floodlightcontroller.core.FloodlightProvider; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.storage.IResultSet; +import net.floodlightcontroller.storage.IStorageSourceService; + +public class StorageCCProvider + implements IClusterConfigProvider { + protected static final Logger logger = + LoggerFactory.getLogger(StorageCCProvider.class.getName()); + + private IStorageSourceService storageSource; + + String thisControllerID; + + protected static final String CONTROLLER_TABLE_NAME = "controller_controller"; + protected static final String CONTROLLER_ID = "id"; + protected static final String CONTROLLER_SYNC_ID = "sync_id"; + protected static final String CONTROLLER_SYNC_DOMAIN_ID = "sync_domain_id"; + protected static final String CONTROLLER_SYNC_PORT = "sync_port"; + + protected static final String CONTROLLER_INTERFACE_TABLE_NAME = "controller_controllerinterface"; + protected static final String CONTROLLER_INTERFACE_CONTROLLER_ID = "controller_id"; + protected static final String CONTROLLER_INTERFACE_DISCOVERED_IP = "discovered_ip"; + protected static final String CONTROLLER_INTERFACE_TYPE = "type"; + protected static final String CONTROLLER_INTERFACE_NUMBER = "number"; + + protected static final String BOOT_CONFIG = + "/opt/bigswitch/run/boot-config"; + + // ********************** + // IClusterConfigProvider + // ********************** + + @Override + public void init(SyncManager syncManager, + FloodlightModuleContext context) { + storageSource = context.getServiceImpl(IStorageSourceService.class); + + // storageSource.addListener(CONTROLLER_TABLE_NAME, this); + + Map<String, String> config = + context.getConfigParams(FloodlightProvider.class); + thisControllerID = config.get("controllerid"); + } + + @Override + public ClusterConfig getConfig() throws SyncException { + if (thisControllerID == null) { + Properties bootConfig = new Properties(); + FileInputStream is = null; + try { + is = new FileInputStream(BOOT_CONFIG); + bootConfig.load(is); + thisControllerID = bootConfig.getProperty("controller-id"); + } catch (Exception e) { + throw new SyncException("No controller ID configured and " + + "could not read " + BOOT_CONFIG); + } finally { + if (is != null) try { + is.close(); + } catch (IOException e) { + throw new SyncException(e); + } + } + } + if (thisControllerID == null) { + throw new SyncException("No controller ID configured"); + } + logger.debug("Using controller ID: {}", thisControllerID); + + List<Node> nodes = new ArrayList<Node>(); + short thisNodeId = -1; + + String[] cols = {CONTROLLER_ID, + CONTROLLER_SYNC_ID, + CONTROLLER_SYNC_DOMAIN_ID, + CONTROLLER_SYNC_PORT}; + IResultSet res = null; + try { + res = storageSource.executeQuery(CONTROLLER_TABLE_NAME, + cols, null, null); + while (res.next()) { + String controllerId = res.getString(CONTROLLER_ID); + if (!res.containsColumn(CONTROLLER_SYNC_ID) || + !res.containsColumn(CONTROLLER_SYNC_DOMAIN_ID) || + !res.containsColumn(CONTROLLER_SYNC_PORT)) { + logger.debug("No sync data found for {}", controllerId); + continue; + } + + short nodeId = res.getShort(CONTROLLER_SYNC_ID); + short domainId = res.getShort(CONTROLLER_SYNC_DOMAIN_ID); + int port = res.getInt(CONTROLLER_SYNC_PORT); + String syncIp = getNodeIP(controllerId); + if (syncIp == null) { + logger.debug("No sync IP found for {}", controllerId); + continue; + } + Node node = new Node(syncIp, port, nodeId, domainId); + nodes.add(node); + + if (thisControllerID.equals(controllerId)) + thisNodeId = nodeId; + } + } finally { + if (res != null) res.close(); + } + + if (nodes.size() == 0) + throw new SyncException("No valid nodes found"); + if (thisNodeId < 0) + throw new SyncException("Could not find a node for the local node"); + + return new ClusterConfig(nodes, thisNodeId); + } + + // ************* + // Local methods + // ************* + + private String getNodeIP(String controllerID) { + + String[] cols = {CONTROLLER_INTERFACE_CONTROLLER_ID, + CONTROLLER_INTERFACE_TYPE, + CONTROLLER_INTERFACE_NUMBER, + CONTROLLER_INTERFACE_DISCOVERED_IP}; + IResultSet res = null; + try { + res = storageSource.executeQuery(CONTROLLER_INTERFACE_TABLE_NAME, + cols, null, null); + while (res.next()) { + logger.debug("{} {} {} {}", + new Object[] {res.getString(CONTROLLER_INTERFACE_CONTROLLER_ID), + res.getString(CONTROLLER_INTERFACE_TYPE), + res.getIntegerObject(CONTROLLER_INTERFACE_NUMBER), + res.getString(CONTROLLER_INTERFACE_DISCOVERED_IP)}); + if ("Ethernet".equals(res.getString(CONTROLLER_INTERFACE_TYPE)) && + Integer.valueOf(0).equals(res.getIntegerObject(CONTROLLER_INTERFACE_NUMBER)) && + controllerID.equals(res.getString(CONTROLLER_INTERFACE_CONTROLLER_ID))) + return res.getString(CONTROLLER_INTERFACE_DISCOVERED_IP); + } + return null; + + } finally { + if (res != null) res.close(); + } + + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/remote/RemoteStore.java b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteStore.java new file mode 100644 index 0000000000000000000000000000000000000000..ce19253f47118622019ee6bf7f0580329d48d942 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteStore.java @@ -0,0 +1,234 @@ +package org.sdnplatform.sync.internal.remote; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.RemoteStoreException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.SyncRuntimeException; +import org.sdnplatform.sync.internal.rpc.TProtocolUtil; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.StoreUtils; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.util.Pair; +import org.sdnplatform.sync.thrift.AsyncMessageHeader; +import org.sdnplatform.sync.thrift.SyncMessage; +import org.sdnplatform.sync.thrift.CursorRequestMessage; +import org.sdnplatform.sync.thrift.GetRequestMessage; +import org.sdnplatform.sync.thrift.KeyedValues; +import org.sdnplatform.sync.thrift.MessageType; +import org.sdnplatform.sync.thrift.PutRequestMessage; + + +/** + * A store implementation that will connect to a remote sync instance + * @author readams + */ +public class RemoteStore implements IStore<ByteArray, byte[]> { + + private String storeName; + private RemoteSyncManager syncManager; + + public RemoteStore(String storeName, RemoteSyncManager syncManager) { + super(); + this.storeName = storeName; + this.syncManager = syncManager; + } + + // ************************* + // IStore<ByteArray, byte[]> + // ************************* + + @Override + public List<Versioned<byte[]>> get(ByteArray key) throws SyncException { + StoreUtils.assertValidKey(key); + GetRequestMessage grm = new GetRequestMessage(); + + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(syncManager.getTransactionId()); + grm.setHeader(header); + + grm.setKey(key.get()); + grm.setStoreName(storeName); + + SyncMessage bsm = new SyncMessage(MessageType.GET_REQUEST); + bsm.setGetRequest(grm); + + SyncReply reply = getReply(header.getTransactionId(), bsm); + + return reply.getValues(); + } + + @Override + public IClosableIterator<Entry<ByteArray, List<Versioned<byte[]>>>> + entries() { + return new RemoteIterator(); + } + + @Override + public void put(ByteArray key, Versioned<byte[]> value) + throws SyncException { + StoreUtils.assertValidKey(key); + PutRequestMessage prm = new PutRequestMessage(); + + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(syncManager.getTransactionId()); + prm.setHeader(header); + prm.setVersionedValue(TProtocolUtil.getTVersionedValue(value)); + prm.setKey(key.get()); + prm.setStoreName(storeName); + + SyncMessage bsm = new SyncMessage(MessageType.PUT_REQUEST); + bsm.setPutRequest(prm); + + getReply(header.getTransactionId(), bsm); + } + + @Override + public List<IVersion> getVersions(ByteArray key) throws SyncException { + List<Versioned<byte[]>> values = get(key); + ArrayList<IVersion> versions = new ArrayList<IVersion>(); + for (Versioned<byte[]> v : values) { + versions.add(v.getVersion()); + } + return versions; + } + + @Override + public String getName() { + return storeName; + } + + @Override + public void close() throws SyncException { + + } + + // ************* + // Local methods + // ************* + + private SyncReply getReply(int xid, + SyncMessage bsm) + throws SyncException { + SyncReply reply = null; + try { + Future<SyncReply> future = + syncManager.sendRequest(xid, bsm); + reply = future.get(5, TimeUnit.SECONDS); + + } catch (Exception e) { + throw new RemoteStoreException("Error while waiting for reply", e); + } + + if (reply.getError() != null) + throw reply.getError(); + + return reply; + } + + private class RemoteIterator + implements IClosableIterator<Entry<ByteArray, + List<Versioned<byte[]>>>> { + + private final int cursorId; + Iterator<KeyedValues> currentChunk; + + public RemoteIterator() { + CursorRequestMessage crm = getCRM(); + crm.setStoreName(storeName); + SyncMessage bsm = new SyncMessage(MessageType.CURSOR_REQUEST); + bsm.setCursorRequest(crm); + SyncReply reply; + try { + reply = getReply(crm.getHeader().getTransactionId(), + bsm); + } catch (SyncException e) { + throw new SyncRuntimeException(e); + } + this.cursorId = reply.getIntValue(); + if (reply.getKeyedValues() != null) + currentChunk = reply.getKeyedValues().iterator(); + } + + @Override + public boolean hasNext() { + if (currentChunk != null) { + if (currentChunk.hasNext()) + return true; + } + Iterator<KeyedValues> nextChunk = getChunk(); + if (nextChunk != null) { + currentChunk = nextChunk; + return nextChunk.hasNext(); + } + return false; + } + + @Override + public Entry<ByteArray, List<Versioned<byte[]>>> next() { + if (!hasNext()) throw new NoSuchElementException(); + KeyedValues kv = currentChunk.next(); + + ByteArray k = new ByteArray(kv.getKey()); + List<Versioned<byte[]>> v = + TProtocolUtil.getVersionedList(kv.getValues()); + return new Pair<ByteArray, List<Versioned<byte[]>>>(k, v); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + CursorRequestMessage crm = getCRM(); + crm.setCursorId(cursorId); + crm.setClose(true); + SyncMessage bsm = new SyncMessage(MessageType.CURSOR_REQUEST); + bsm.setCursorRequest(crm); + try { + getReply(crm.getHeader().getTransactionId(), + bsm); + } catch (SyncException e) { + throw new SyncRuntimeException(e); + } + } + + private Iterator<KeyedValues> getChunk() { + CursorRequestMessage crm = getCRM(); + crm.setCursorId(cursorId); + SyncMessage bsm = new SyncMessage(MessageType.CURSOR_REQUEST); + bsm.setCursorRequest(crm); + + SyncReply reply; + try { + reply = getReply(crm.getHeader().getTransactionId(), + bsm); + } catch (SyncException e) { + throw new SyncRuntimeException(e); + } + if (reply.getKeyedValues() == null || + reply.getKeyedValues().size() == 0) return null; + + return reply.getKeyedValues().iterator(); + } + + private CursorRequestMessage getCRM() { + CursorRequestMessage crm = new CursorRequestMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(syncManager.getTransactionId()); + crm.setHeader(header); + return crm; + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncChannelHandler.java b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncChannelHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..4c215f93a89d75a8c6efc54683b76e9489a8ea12 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncChannelHandler.java @@ -0,0 +1,149 @@ +package org.sdnplatform.sync.internal.remote; + +import java.util.List; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.SyncException.ErrorType; +import org.sdnplatform.sync.internal.rpc.AbstractRPCChannelHandler; +import org.sdnplatform.sync.internal.rpc.TProtocolUtil; +import org.sdnplatform.sync.thrift.CursorResponseMessage; +import org.sdnplatform.sync.thrift.DeleteResponseMessage; +import org.sdnplatform.sync.thrift.ErrorMessage; +import org.sdnplatform.sync.thrift.GetResponseMessage; +import org.sdnplatform.sync.thrift.HelloMessage; +import org.sdnplatform.sync.thrift.PutResponseMessage; +import org.sdnplatform.sync.thrift.RegisterResponseMessage; + + +/** + * Implement the client side of the RPC service for the + * {@link RemoteSyncManager} + * @see RemoteSyncManager + * @author readams + */ +public class RemoteSyncChannelHandler extends AbstractRPCChannelHandler { + + RemoteSyncManager syncManager; + + public RemoteSyncChannelHandler(RemoteSyncManager syncManager) { + super(); + this.syncManager = syncManager; + } + + // **************************** + // IdleStateAwareChannelHandler + // **************************** + + @Override + public void channelOpen(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + syncManager.cg.add(ctx.getChannel()); + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + this.syncManager.channel = null; + } + + // ****************************************** + // AbstractRPCChannelHandler message handlers + // ****************************************** + + @Override + protected void handleHello(HelloMessage hello, Channel channel) { + syncManager.remoteNodeId = hello.getNodeId(); + } + + @Override + protected void handleGetResponse(GetResponseMessage response, + Channel channel) { + List<Versioned<byte[]>> values = + TProtocolUtil.getVersionedList(response.getValues()); + SyncReply reply = new SyncReply(values, null, true, null, 0); + syncManager.dispatchReply(response.getHeader().getTransactionId(), + reply); + } + + @Override + protected void handlePutResponse(PutResponseMessage response, + Channel channel) { + SyncReply reply = new SyncReply(null, null, true, null, 0); + syncManager.dispatchReply(response.getHeader().getTransactionId(), + reply); + + } + + @Override + protected void handleDeleteResponse(DeleteResponseMessage response, + Channel channel) { + SyncReply reply = new SyncReply(null, null, + response.isDeleted(), null, 0); + syncManager.dispatchReply(response.getHeader().getTransactionId(), + reply); + } + + @Override + protected void handleCursorResponse(CursorResponseMessage response, + Channel channel) { + SyncReply reply = new SyncReply(null, response.getValues(), true, + null, response.getCursorId()); + syncManager.dispatchReply(response.getHeader().getTransactionId(), + reply); + } + + @Override + protected void handleRegisterResponse(RegisterResponseMessage response, + Channel channel) { + SyncReply reply = new SyncReply(null, null, + true, null, 0); + syncManager.dispatchReply(response.getHeader().getTransactionId(), + reply); + } + + @Override + protected void handleError(ErrorMessage error, Channel channel) { + ErrorType errType = ErrorType.GENERIC; + for (ErrorType e : ErrorType.values()) { + if (e.getValue() == error.getError().getErrorCode()) { + errType = e; + break; + } + } + SyncException ex = + SyncException.newInstance(errType, + error.getError().getMessage(), + null); + SyncReply reply = new SyncReply(null, null, false, ex, 0); + syncManager.dispatchReply(error.getHeader().getTransactionId(), + reply); + } + + // ************************* + // AbstractRPCChannelHandler + // ************************* + + @Override + protected Short getRemoteNodeId() { + return syncManager.remoteNodeId; + } + + @Override + protected Short getLocalNodeId() { + return null; + } + + @Override + protected String getLocalNodeIdString() { + return "client"; + } + + @Override + protected int getTransactionId() { + return syncManager.getTransactionId(); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncFuture.java b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncFuture.java new file mode 100644 index 0000000000000000000000000000000000000000..6e2088d093b4cb805b9990a4a142d7a7469655b1 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncFuture.java @@ -0,0 +1,84 @@ +package org.sdnplatform.sync.internal.remote; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class RemoteSyncFuture implements Future<SyncReply> { + + private final int xid; + private volatile SyncReply reply = null; + private Object notify = new Object(); + + public RemoteSyncFuture(int xid) { + super(); + this.xid = xid; + } + + // ********************** + // Future<SyncReply> + // ********************** + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public SyncReply get() throws InterruptedException, + ExecutionException { + if (reply != null) return reply; + synchronized (notify) { + while (reply == null) + notify.wait(); + } + return reply; + } + + @Override + public SyncReply + get(long timeout, TimeUnit unit) throws InterruptedException, + ExecutionException, + TimeoutException { + if (reply != null) return reply; + synchronized (notify) { + notify.wait(TimeUnit.MILLISECONDS.convert(timeout, unit)); + } + if (reply == null) throw new TimeoutException(); + return reply; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return (reply != null); + } + + // **************** + // RemoteSyncFuture + // **************** + + /** + * Get the xid for this message + * @return + */ + public int getXid() { + return xid; + } + + /** + * Set the reply message + * @param reply + */ + public void setReply(SyncReply reply) { + synchronized (notify) { + this.reply = reply; + notify.notifyAll(); + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncManager.java b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncManager.java new file mode 100644 index 0000000000000000000000000000000000000000..bae0019d7d0a13f1da91eab551fc9ed3cc971701 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncManager.java @@ -0,0 +1,316 @@ +package org.sdnplatform.sync.internal.remote; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jboss.netty.bootstrap.ClientBootstrap; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.group.ChannelGroup; +import org.jboss.netty.channel.group.DefaultChannelGroup; +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; +import org.sdnplatform.sync.error.RemoteStoreException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.SyncRuntimeException; +import org.sdnplatform.sync.error.UnknownStoreException; +import org.sdnplatform.sync.internal.AbstractSyncManager; +import org.sdnplatform.sync.internal.rpc.RPCService; +import org.sdnplatform.sync.internal.rpc.TProtocolUtil; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.MappingStoreListener; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.thrift.AsyncMessageHeader; +import org.sdnplatform.sync.thrift.SyncMessage; +import org.sdnplatform.sync.thrift.MessageType; +import org.sdnplatform.sync.thrift.RegisterRequestMessage; +import org.sdnplatform.sync.thrift.Store; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.floodlightcontroller.core.annotations.LogMessageCategory; +import net.floodlightcontroller.core.annotations.LogMessageDoc; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightService; + +/** + * Implementation of a sync service that passes its functionality off to a + * remote sync manager over a TCP connection + * @author readams + */ +@LogMessageCategory("State Synchronization") +public class RemoteSyncManager extends AbstractSyncManager { + protected static final Logger logger = + LoggerFactory.getLogger(RemoteSyncManager.class.getName()); + + /** + * Channel group that will hold all our channels + */ + final ChannelGroup cg = new DefaultChannelGroup("Internal RPC"); + + /** + * Active connection to server + */ + protected volatile Channel channel; + + /** + * The remote node ID of the node we're connected to + */ + protected Short remoteNodeId; + + /** + * Client bootstrap + */ + protected ClientBootstrap clientBootstrap; + + /** + * Transaction ID used in message headers in the RPC protocol + */ + private AtomicInteger transactionId = new AtomicInteger(); + + /** + * The hostname of the server to connect to + */ + protected String hostname = "localhost"; + + /** + * Port to connect to + */ + protected int port = 6642; + + private ConcurrentHashMap<Integer, RemoteSyncFuture> futureMap = + new ConcurrentHashMap<Integer, RemoteSyncFuture>(); + private Object futureNotify = new Object(); + private static int MAX_PENDING_REQUESTS = 1000; + + // ************ + // ISyncService + // ************ + + public RemoteSyncManager() { + } + + @Override + public void registerStore(String storeName, Scope scope) + throws SyncException { + doRegisterStore(storeName, scope, false); + } + + @Override + public void registerPersistentStore(String storeName, Scope scope) + throws SyncException { + doRegisterStore(storeName, scope, true); + } + + // ******************* + // AbstractSyncManager + // ******************* + + @Override + public void addListener(String storeName, + MappingStoreListener listener) + throws UnknownStoreException { + ensureConnected(); + } + + @Override + public IStore<ByteArray, byte[]> + getStore(String storeName) throws UnknownStoreException { + ensureConnected(); + return new RemoteStore(storeName, this); + } + + @Override + public short getLocalNodeId() { + ensureConnected(); + return remoteNodeId; + } + + @Override + public void shutdown() { + logger.debug("Shutting down Remote Sync Manager"); + try { + if (!cg.close().await(5, TimeUnit.SECONDS)) { + logger.debug("Failed to cleanly shut down remote sync"); + } + clientBootstrap.releaseExternalResources(); + } catch (InterruptedException e) { + logger.debug("Interrupted while shutting down remote sync"); + } + } + + // ***************** + // IFloodlightModule + // ***************** + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + Map<String, String> config = context.getConfigParams(this); + if (null != config.get("hostname")) + hostname = config.get("hostname"); + if (null != config.get("port")) + port = Integer.parseInt(config.get("port")); + } + + @Override + public void startUp(FloodlightModuleContext context) + throws FloodlightModuleException { + Executor bossExecutor = Executors.newCachedThreadPool(); + Executor workerExecutor = Executors.newCachedThreadPool(); + + final ClientBootstrap bootstrap = + new ClientBootstrap( + new NioClientSocketChannelFactory(bossExecutor, + workerExecutor)); + bootstrap.setOption("child.reuseAddr", true); + bootstrap.setOption("child.keepAlive", true); + bootstrap.setOption("child.tcpNoDelay", true); + bootstrap.setOption("child.sendBufferSize", + RPCService.SEND_BUFFER_SIZE); + bootstrap.setOption("child.receiveBufferSize", + RPCService.SEND_BUFFER_SIZE); + bootstrap.setOption("child.connectTimeoutMillis", + RPCService.CONNECT_TIMEOUT); + bootstrap.setPipelineFactory(new RemoteSyncPipelineFactory(this)); + clientBootstrap = bootstrap; + } + + @Override + public Collection<Class<? extends IFloodlightService>> + getModuleDependencies() { + return null; + } + + // ***************** + // RemoteSyncManager + // ***************** + + /** + * Get a suitable transaction ID for sending a message + * @return the unique transaction iD + */ + public int getTransactionId() { + return transactionId.getAndIncrement(); + } + + /** + * Send a request to the server and generate a future for the + * eventual reply. Note that this call can block if there is no active + * connection while a new connection is re-established or if the maximum + * number of requests is already pending + * @param xid the transaction ID for the request + * @param request the actual request to send + * @return A {@link Future} for the reply message + * @throws InterruptedException + */ + public Future<SyncReply> sendRequest(int xid, + SyncMessage request) + throws RemoteStoreException { + ensureConnected(); + RemoteSyncFuture future = new RemoteSyncFuture(xid); + futureMap.put(Integer.valueOf(xid), future); + + if (futureMap.size() > MAX_PENDING_REQUESTS) { + synchronized (futureNotify) { + while (futureMap.size() > MAX_PENDING_REQUESTS) { + try { + futureNotify.wait(); + } catch (InterruptedException e) { + throw new RemoteStoreException("Could not send request", + e); + } + } + } + } + channel.write(request); + return future; + } + + @LogMessageDoc(level="WARN", + message="Unexpected sync message reply type={type} id={id}", + explanation="An error occurred in the sync protocol", + recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG) + public void dispatchReply(int xid, + SyncReply reply) { + RemoteSyncFuture future = futureMap.get(Integer.valueOf(xid)); + if (future == null) { + logger.warn("Unexpected sync message replyid={}", xid); + return; + } + futureMap.remove(Integer.valueOf(xid)); + future.setReply(reply); + synchronized (futureNotify) { + futureNotify.notify(); + } + } + + // *************** + // Local methods + // *************** + + protected void ensureConnected() { + if (channel == null || !channel.isConnected()) { + for (int i = 0; i < 25; i++) { + synchronized (this) { + if (connect(hostname, port)) + return; + } + try { + Thread.sleep(1000); + } catch (Exception e) {} + } + if (channel == null) + throw new SyncRuntimeException(new SyncException("Failed to establish connection")); + } + } + + protected boolean connect(String hostname, int port) { + SocketAddress sa = + new InetSocketAddress(hostname, port); + ChannelFuture future = clientBootstrap.connect(sa); + future.awaitUninterruptibly(); + if (!future.isSuccess()) { + logger.error("Could not connect to " + hostname + + ":" + port, future.getCause()); + return false; + } + channel = future.getChannel(); + logger.debug("Connected to " + hostname + ":" + port); + return true; + } + + private void doRegisterStore(String storeName, Scope scope, boolean b) + throws SyncException{ + + ensureConnected(); + RegisterRequestMessage rrm = new RegisterRequestMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(getTransactionId()); + rrm.setHeader(header); + + Store store = new Store(storeName); + store.setScope(TProtocolUtil.getTScope(scope)); + store.setPersist(false); + rrm.setStore(store); + + SyncMessage bsm = new SyncMessage(MessageType.REGISTER_REQUEST); + bsm.setRegisterRequest(rrm); + Future<SyncReply> future = + sendRequest(header.getTransactionId(), bsm); + try { + future.get(2, TimeUnit.SECONDS); + } catch (Exception e) { + throw new RemoteStoreException("Error while waiting for reply", e); + } + } + +} diff --git a/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncPipelineFactory.java b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncPipelineFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..812781f52c85a51fbd75fc69e2fb04e7c851d412 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/remote/RemoteSyncPipelineFactory.java @@ -0,0 +1,38 @@ +package org.sdnplatform.sync.internal.remote; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.sdnplatform.sync.internal.rpc.ThriftFrameDecoder; +import org.sdnplatform.sync.internal.rpc.ThriftFrameEncoder; + +/** + * Pipeline factory for the remote sync service + * @author readams + */ +public class RemoteSyncPipelineFactory implements ChannelPipelineFactory { + + protected RemoteSyncManager syncManager; + + private static final int maxFrameSize = 1024 * 1024 * 10; + + public RemoteSyncPipelineFactory(RemoteSyncManager syncManager) { + super(); + this.syncManager = syncManager; + } + + @Override + public ChannelPipeline getPipeline() throws Exception { + RemoteSyncChannelHandler channelHandler = + new RemoteSyncChannelHandler(syncManager); + ChannelPipeline pipeline = Channels.pipeline(); + + pipeline.addLast("frameDecoder", + new ThriftFrameDecoder(maxFrameSize)); + pipeline.addLast("frameEncoder", + new ThriftFrameEncoder()); + + pipeline.addLast("handler", channelHandler); + return pipeline; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/remote/SyncReply.java b/src/main/java/org/sdnplatform/sync/internal/remote/SyncReply.java new file mode 100644 index 0000000000000000000000000000000000000000..1c114a3e6ab48040c5905f32f2e279ec2647a51b --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/remote/SyncReply.java @@ -0,0 +1,46 @@ +package org.sdnplatform.sync.internal.remote; + +import java.util.List; + +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.thrift.KeyedValues; + + +/* + * Represent a reply to a remote message + */ +public class SyncReply { + private List<KeyedValues> keyedValues; + private List<Versioned<byte[]>> values; + private boolean success; + private SyncException error; + private int intValue; + + public SyncReply(List<Versioned<byte[]>> values, + List<KeyedValues> keyedValues, + boolean success, SyncException error, int intValue) { + super(); + this.values = values; + this.keyedValues = keyedValues; + this.success = success; + this.error = error; + this.intValue = intValue; + } + + public int getIntValue() { + return intValue; + } + public List<KeyedValues> getKeyedValues() { + return keyedValues; + } + public List<Versioned<byte[]>> getValues() { + return values; + } + public SyncException getError() { + return error; + } + public boolean isSuccess() { + return success; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/AbstractRPCChannelHandler.java b/src/main/java/org/sdnplatform/sync/internal/rpc/AbstractRPCChannelHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..23aeab647a76e6690c6cd261d71371010bd034fa --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/AbstractRPCChannelHandler.java @@ -0,0 +1,439 @@ +package org.sdnplatform.sync.internal.rpc; + +import java.io.IOException; +import java.net.ConnectException; +import java.util.List; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; +import org.jboss.netty.handler.timeout.IdleStateEvent; +import org.jboss.netty.handler.timeout.ReadTimeoutException; +import org.sdnplatform.sync.error.HandshakeTimeoutException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.thrift.AsyncMessageHeader; +import org.sdnplatform.sync.thrift.SyncError; +import org.sdnplatform.sync.thrift.SyncMessage; +import org.sdnplatform.sync.thrift.CursorRequestMessage; +import org.sdnplatform.sync.thrift.CursorResponseMessage; +import org.sdnplatform.sync.thrift.DeleteRequestMessage; +import org.sdnplatform.sync.thrift.DeleteResponseMessage; +import org.sdnplatform.sync.thrift.EchoReplyMessage; +import org.sdnplatform.sync.thrift.EchoRequestMessage; +import org.sdnplatform.sync.thrift.ErrorMessage; +import org.sdnplatform.sync.thrift.FullSyncRequestMessage; +import org.sdnplatform.sync.thrift.GetRequestMessage; +import org.sdnplatform.sync.thrift.GetResponseMessage; +import org.sdnplatform.sync.thrift.HelloMessage; +import org.sdnplatform.sync.thrift.MessageType; +import org.sdnplatform.sync.thrift.PutRequestMessage; +import org.sdnplatform.sync.thrift.PutResponseMessage; +import org.sdnplatform.sync.thrift.RegisterRequestMessage; +import org.sdnplatform.sync.thrift.RegisterResponseMessage; +import org.sdnplatform.sync.thrift.SyncOfferMessage; +import org.sdnplatform.sync.thrift.SyncRequestMessage; +import org.sdnplatform.sync.thrift.SyncValueMessage; +import org.sdnplatform.sync.thrift.SyncValueResponseMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Abstract base class for implementing the RPC protocol. The protocol is + * defined by a thrift specification; all protocol messages are delivered in + * a {@link SyncMessage} which will provide specific type information. + * @author readams + */ +public abstract class AbstractRPCChannelHandler + extends IdleStateAwareChannelHandler { + protected static final Logger logger = + LoggerFactory.getLogger(AbstractRPCChannelHandler.class); + + public AbstractRPCChannelHandler() { + super(); + } + + // **************************** + // IdleStateAwareChannelHandler + // **************************** + + @Override + public void channelConnected(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + HelloMessage m = new HelloMessage(); + if (getLocalNodeId() != null) + m.setNodeId(getLocalNodeId()); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(getTransactionId()); + m.setHeader(header); + SyncMessage bsm = new SyncMessage(MessageType.HELLO); + bsm.setHello(m); + ctx.getChannel().write(bsm); + } + + @Override + public void channelIdle(ChannelHandlerContext ctx, + IdleStateEvent e) throws Exception { + // send an echo request + EchoRequestMessage m = new EchoRequestMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(getTransactionId()); + m.setHeader(header); + SyncMessage bsm = new SyncMessage(MessageType.ECHO_REQUEST); + bsm.setEchoRequest(m); + ctx.getChannel().write(bsm); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, + ExceptionEvent e) throws Exception { + if (e.getCause() instanceof ReadTimeoutException) { + // read timeout + logger.error("[{}->{}] Disconnecting RPC node due to read timeout", + getLocalNodeIdString(), getRemoteNodeIdString()); + ctx.getChannel().close(); + } else if (e.getCause() instanceof HandshakeTimeoutException) { + // read timeout + logger.error("[{}->{}] Disconnecting RPC node due to " + + "handshake timeout", + getLocalNodeIdString(), getRemoteNodeIdString()); + ctx.getChannel().close(); + } else if (e.getCause() instanceof ConnectException || + e.getCause() instanceof IOException) { + logger.debug("[{}->{}] {}: {}", + new Object[] {getLocalNodeIdString(), + getRemoteNodeIdString(), + e.getCause().getClass().getName(), + e.getCause().getMessage()}); + } else { + logger.error("[{}->{}] An error occurred on RPC channel", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + e.getCause()}); + ctx.getChannel().close(); + } + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, + MessageEvent e) throws Exception { + Object message = e.getMessage(); + if (message instanceof SyncMessage) { + handleSyncMessage((SyncMessage)message, ctx.getChannel()); + } else if (message instanceof List) { + for (Object i : (List<?>)message) { + if (i instanceof SyncMessage) { + try { + handleSyncMessage((SyncMessage)i, + ctx.getChannel()); + } catch (Exception ex) { + logger.error("Error processing message", ex); + Channels.fireExceptionCaught(ctx, ex); + } + } + } + } else { + handleUnknownMessage(ctx, message); + } + } + + // **************** + // Message Handlers + // **************** + + /** + * A handler for messages on the channel that are not of type + * {@link SyncMessage} + * @param ctx the context + * @param message the message object + */ + protected void handleUnknownMessage(ChannelHandlerContext ctx, + Object message) { + logger.warn("[{}->{}] Unhandled message: {}", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + message.getClass().getCanonicalName()}); + } + + /** + * Handle a generic {@link SyncMessage} and dispatch to an appropriate + * handler + * @param bsm the message + * @param channel the channel on which the message arrived + */ + protected void handleSyncMessage(SyncMessage bsm, Channel channel) { + switch (bsm.getType()) { + case HELLO: + handleHello(bsm.getHello(), channel); + break; + case ECHO_REQUEST: + handleEchoRequest(bsm.getEchoRequest(), channel); + break; + case GET_REQUEST: + handleGetRequest(bsm.getGetRequest(), channel); + break; + case GET_RESPONSE: + handleGetResponse(bsm.getGetResponse(), channel); + break; + case PUT_REQUEST: + handlePutRequest(bsm.getPutRequest(), channel); + break; + case PUT_RESPONSE: + handlePutResponse(bsm.getPutResponse(), channel); + break; + case DELETE_REQUEST: + handleDeleteRequest(bsm.getDeleteRequest(), channel); + break; + case DELETE_RESPONSE: + handleDeleteResponse(bsm.getDeleteResponse(), channel); + break; + case SYNC_VALUE_RESPONSE: + handleSyncValueResponse(bsm.getSyncValueResponse(), channel); + break; + case SYNC_VALUE: + handleSyncValue(bsm.getSyncValue(), channel); + break; + case SYNC_OFFER: + handleSyncOffer(bsm.getSyncOffer(), channel); + break; + case FULL_SYNC_REQUEST: + handleFullSyncRequest(bsm.getFullSyncRequest(), channel); + break; + case SYNC_REQUEST: + handleSyncRequest(bsm.getSyncRequest(), channel); + break; + case CURSOR_REQUEST: + handleCursorRequest(bsm.getCursorRequest(), channel); + break; + case CURSOR_RESPONSE: + handleCursorResponse(bsm.getCursorResponse(), channel); + break; + case REGISTER_REQUEST: + handleRegisterRequest(bsm.getRegisterRequest(), channel); + break; + case REGISTER_RESPONSE: + handleRegisterResponse(bsm.getRegisterResponse(), channel); + break; + case ERROR: + handleError(bsm.getError(), channel); + break; + case ECHO_REPLY: + // do nothing; just the read will have reset our read timeout + // handler + break; + default: + logger.warn("[{}->{}] Unhandled message: {}", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + bsm.getType()}); + break; + } + + } + + protected void handleHello(HelloMessage request, Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.HELLO, channel); + } + + protected void handleEchoRequest(EchoRequestMessage request, + Channel channel) { + EchoReplyMessage m = new EchoReplyMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + SyncMessage bsm = new SyncMessage(MessageType.ECHO_REPLY); + bsm.setEchoReply(m); + channel.write(bsm); + } + + protected void handleGetRequest(GetRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.GET_REQUEST, channel); + } + + protected void handleGetResponse(GetResponseMessage response, + Channel channel) { + unexpectedMessage(response.getHeader().getTransactionId(), + MessageType.GET_RESPONSE, channel); + } + + protected void handlePutRequest(PutRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.PUT_REQUEST, channel); + } + + protected void handlePutResponse(PutResponseMessage response, + Channel channel) { + unexpectedMessage(response.getHeader().getTransactionId(), + MessageType.PUT_RESPONSE, channel); + } + + protected void handleDeleteRequest(DeleteRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.DELETE_REQUEST, channel); + } + + protected void handleDeleteResponse(DeleteResponseMessage response, + Channel channel) { + unexpectedMessage(response.getHeader().getTransactionId(), + MessageType.PUT_RESPONSE, channel); + } + + protected void handleSyncValue(SyncValueMessage message, + Channel channel) { + unexpectedMessage(message.getHeader().getTransactionId(), + MessageType.SYNC_VALUE, channel); + } + + protected void handleSyncValueResponse(SyncValueResponseMessage message, + Channel channel) { + unexpectedMessage(message.getHeader().getTransactionId(), + MessageType.SYNC_VALUE_RESPONSE, channel); + } + + protected void handleSyncOffer(SyncOfferMessage message, + Channel channel) { + unexpectedMessage(message.getHeader().getTransactionId(), + MessageType.SYNC_OFFER, channel); + } + + protected void handleSyncRequest(SyncRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.SYNC_REQUEST, channel); + } + + protected void handleFullSyncRequest(FullSyncRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.FULL_SYNC_REQUEST, channel); + } + + protected void handleCursorRequest(CursorRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.CURSOR_REQUEST, channel); + } + + protected void handleCursorResponse(CursorResponseMessage response, + Channel channel) { + unexpectedMessage(response.getHeader().getTransactionId(), + MessageType.CURSOR_RESPONSE, channel); + } + + protected void handleRegisterRequest(RegisterRequestMessage request, + Channel channel) { + unexpectedMessage(request.getHeader().getTransactionId(), + MessageType.REGISTER_REQUEST, channel); + } + + protected void handleRegisterResponse(RegisterResponseMessage response, + Channel channel) { + unexpectedMessage(response.getHeader().getTransactionId(), + MessageType.REGISTER_RESPONSE, channel); + } + + protected void handleError(ErrorMessage error, Channel channel) { + logger.error("[{}->{}] Error for message {}: {}", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + error.getHeader().getTransactionId(), + error.getError().getMessage()}); + } + + // ***************** + // Utility functions + // ***************** + + /** + * Generate an error message from the provided transaction ID and + * exception + * @param transactionId the transaction Id + * @param error the exception + * @param type the type of the message that generated the error + * @return the {@link SyncError} message + */ + protected SyncMessage getError(int transactionId, Exception error, + MessageType type) { + int ec = SyncException.ErrorType.GENERIC.getValue(); + if (error instanceof SyncException) { + ec = ((SyncException)error).getErrorCode().getValue(); + } + SyncError m = new SyncError(); + m.setErrorCode(ec); + m.setMessage(error.getMessage()); + ErrorMessage em = new ErrorMessage(); + em.setError(m); + em.setType(type); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(transactionId); + em.setHeader(header); + SyncMessage bsm = new SyncMessage(MessageType.ERROR); + bsm.setError(em); + return bsm; + } + + /** + * Send an error to the channel indicating that we got an unexpected + * message for this type of RPC client + * @param transactionId the transaction ID for the message that generated + * the error + * @param type The type of the message that generated the error + * @param channel the channel to write the error + */ + protected void unexpectedMessage(int transactionId, + MessageType type, + Channel channel) { + String message = "Received unexpected message: " + type; + logger.warn("[{}->{}] {}", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + message}); + channel.write(getError(transactionId, + new SyncException(message), type)); + } + + /** + * Get a transaction ID suitable for sending an async message + * @return the unique transaction ID + */ + protected abstract int getTransactionId(); + + /** + * Get the node ID for the remote node if its connected + * @return the node ID + */ + protected abstract Short getRemoteNodeId(); + + /** + * Get the node ID for the remote node if its connected as a string + * for use output + * @return the node ID + */ + protected String getRemoteNodeIdString() { + return ""+getRemoteNodeId(); + } + + /** + * Get the node ID for the local node if appropriate + * @return the node ID. Null if this is a client + */ + protected abstract Short getLocalNodeId(); + + /** + * Get the node ID for the local node as a string for use output + * @return the node ID + */ + protected String getLocalNodeIdString() { + return ""+getLocalNodeId(); + } + +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/HandshakeTimeoutHandler.java b/src/main/java/org/sdnplatform/sync/internal/rpc/HandshakeTimeoutHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..2ba0e4bb9be944b6729ee23cf0bf31b70040e4d0 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/HandshakeTimeoutHandler.java @@ -0,0 +1,105 @@ +/** +* Copyright 2011, Big Switch Networks, Inc. +* Originally created by David Erickson, Stanford University +* +* 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 org.sdnplatform.sync.internal.rpc; + +import java.util.concurrent.TimeUnit; + +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.util.ExternalResourceReleasable; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.Timer; +import org.jboss.netty.util.TimerTask; +import org.sdnplatform.sync.error.HandshakeTimeoutException; + + +/** + * Trigger a timeout if a switch fails to complete handshake soon enough + */ +public class HandshakeTimeoutHandler + extends SimpleChannelUpstreamHandler + implements ExternalResourceReleasable { + static final HandshakeTimeoutException EXCEPTION = + new HandshakeTimeoutException(); + + final RPCChannelHandler handler; + final Timer timer; + final long timeoutNanos; + volatile Timeout timeout; + + public HandshakeTimeoutHandler(RPCChannelHandler handler, + Timer timer, + long timeoutSeconds) { + super(); + this.handler = handler; + this.timer = timer; + this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds); + + } + + @Override + public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) + throws Exception { + if (timeoutNanos > 0) { + timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx), + timeoutNanos, TimeUnit.NANOSECONDS); + } + ctx.sendUpstream(e); + } + + @Override + public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) + throws Exception { + if (timeout != null) { + timeout.cancel(); + timeout = null; + } + } + + @Override + public void releaseExternalResources() { + timer.stop(); + } + + private final class HandshakeTimeoutTask implements TimerTask { + + private final ChannelHandlerContext ctx; + + HandshakeTimeoutTask(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + @Override + public void run(Timeout timeout) throws Exception { + if (timeout.isCancelled()) { + return; + } + + if (!ctx.getChannel().isOpen()) { + return; + } + if (!handler.isClientConnection && + ((handler.remoteNode == null || + !handler.rpcService.isConnected(handler.remoteNode. + getNodeId())))) + Channels.fireExceptionCaught(ctx, EXCEPTION); + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/RPCChannelHandler.java b/src/main/java/org/sdnplatform/sync/internal/rpc/RPCChannelHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..b46ddcc37ef630364ace3f468e7657c3b47619e8 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/RPCChannelHandler.java @@ -0,0 +1,559 @@ +package org.sdnplatform.sync.internal.rpc; + +import java.nio.ByteBuffer; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import net.floodlightcontroller.core.annotations.LogMessageCategory; +import net.floodlightcontroller.core.annotations.LogMessageDoc; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.MessageEvent; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.Cursor; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.config.Node; +import org.sdnplatform.sync.internal.rpc.RPCService.NodeMessage; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.version.VectorClock; +import org.sdnplatform.sync.thrift.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Channel handler for the RPC service + * @author readams + */ +@LogMessageCategory("State Synchronization") +public class RPCChannelHandler extends AbstractRPCChannelHandler { + protected static final Logger logger = + LoggerFactory.getLogger(RPCChannelHandler.class); + + protected SyncManager syncManager; + protected RPCService rpcService; + protected Node remoteNode; + protected boolean isClientConnection = false; + + public RPCChannelHandler(SyncManager syncManager, + RPCService rpcService) { + super(); + this.syncManager = syncManager; + this.rpcService = rpcService; + } + + // **************************** + // IdleStateAwareChannelHandler + // **************************** + + @Override + public void channelOpen(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + rpcService.cg.add(ctx.getChannel()); + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + if (remoteNode != null) { + rpcService.disconnectNode(remoteNode.getNodeId()); + } + } + + // ****************************************** + // AbstractRPCChannelHandler message handlers + // ****************************************** + + @Override + public void messageReceived(ChannelHandlerContext ctx, + MessageEvent e) throws Exception { + super.messageReceived(ctx, e); + rpcService.debugCounter.flushCounters(); + } + + @Override + @LogMessageDoc(level="ERROR", + message="[{id}->{id}] Attempted connection from unrecognized " + + "floodlight node {id}; disconnecting", + explanation="A unknown node connected. This can happen " + + "transiently if new nodes join the cluster.", + recommendation="If the problem persists, verify your cluster" + + "configuration and that you don't have unauthorized agents " + + "in your network.") + protected void handleHello(HelloMessage hello, Channel channel) { + if (!hello.isSetNodeId()) { + // this is a client connection. Don't set this up as a node + // connection + isClientConnection = true; + return; + } + remoteNode = syncManager.getClusterConfig().getNode(hello.getNodeId()); + if (remoteNode == null) { + logger.error("[{}->{}] Attempted connection from unrecognized " + + "floodlight node {}; disconnecting", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + hello.getNodeId()}); + channel.close(); + return; + } + rpcService.nodeConnected(remoteNode.getNodeId(), channel); + + FullSyncRequestMessage srm = new FullSyncRequestMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(getTransactionId()); + srm.setHeader(header); + SyncMessage bsm = new SyncMessage(MessageType.FULL_SYNC_REQUEST); + channel.write(bsm); + + // XXX - TODO - if last connection was longer ago than the tombstone + // timeout, then we need to do a complete flush and reload of our + // state. This is complex though since this applies across entire + // partitions and not just single nodes. We'd need to identify the + // partition and nuke the smaller half (or lower priority in the case + // of an even split). Downstream listeners would need to be able to + // handle a state nuke as well. A simple way to nuke would be to ensure + // floodlight is restarted in the smaller partition. + } + + @Override + protected void handleGetRequest(GetRequestMessage request, + Channel channel) { + String storeName = request.getStoreName(); + try { + IStorageEngine<ByteArray, byte[]> store = + syncManager.getRawStore(storeName); + + GetResponseMessage m = new GetResponseMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + + List<Versioned<byte[]>> values = + store.get(new ByteArray(request.getKey())); + for (Versioned<byte[]> value : values) { + m.addToValues(TProtocolUtil.getTVersionedValue(value)); + } + + SyncMessage bsm = new SyncMessage(MessageType.GET_RESPONSE); + bsm.setGetResponse(m); + channel.write(bsm); + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), e, + MessageType.GET_REQUEST)); + } + } + + @Override + protected void handlePutRequest(PutRequestMessage request, + Channel channel) { + String storeName = request.getStoreName(); + try { + IStorageEngine<ByteArray, byte[]> store = + syncManager.getRawStore(storeName); + + ByteArray key = new ByteArray(request.getKey()); + Versioned<byte[]> value = null; + if (request.isSetVersionedValue()) { + value = TProtocolUtil. + getVersionedValued(request.getVersionedValue()); + value.increment(syncManager.getLocalNodeId(), + System.currentTimeMillis()); + } else if (request.isSetValue()) { + byte[] rvalue = request.getValue(); + List<IVersion> versions = store.getVersions(key); + VectorClock newclock = new VectorClock(); + for (IVersion v : versions) { + newclock = newclock.merge((VectorClock)v); + } + newclock = newclock.incremented(syncManager.getLocalNodeId(), + System.currentTimeMillis()); + value = Versioned.value(rvalue, newclock); + } else { + throw new SyncException("No value specified for put"); + } + + store.put(key, value); + + PutResponseMessage m = new PutResponseMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + + SyncMessage bsm = new SyncMessage(MessageType.PUT_RESPONSE); + bsm.setPutResponse(m); + channel.write(bsm); + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), e, + MessageType.PUT_REQUEST)); + } + } + + @Override + protected void handleDeleteRequest(DeleteRequestMessage request, + Channel channel) { + try { + String storeName = request.getStoreName(); + IStorageEngine<ByteArray, byte[]> store = + syncManager.getRawStore(storeName); + ByteArray key = new ByteArray(request.getKey()); + VectorClock newclock; + if (request.isSetVersion()) { + newclock = TProtocolUtil.getVersion(request.getVersion()); + } else { + newclock = new VectorClock(); + List<IVersion> versions = store.getVersions(key); + for (IVersion v : versions) { + newclock = newclock.merge((VectorClock)v); + } + } + newclock = + newclock.incremented(rpcService.syncManager.getLocalNodeId(), + System.currentTimeMillis()); + Versioned<byte[]> value = Versioned.value(null, newclock); + store.put(key, value); + + DeleteResponseMessage m = new DeleteResponseMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + + SyncMessage bsm = + new SyncMessage(MessageType.DELETE_RESPONSE); + bsm.setDeleteResponse(m); + channel.write(bsm); + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), e, + MessageType.DELETE_REQUEST)); + } + } + + @Override + protected void handleSyncValue(SyncValueMessage request, + Channel channel) { + if (request.isSetResponseTo()) + rpcService.messageAcked(MessageType.SYNC_REQUEST, + getRemoteNodeId()); + try { + if (logger.isTraceEnabled()) { + logger.trace("[{}->{}] Got syncvalue {}", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + request}); + } + + Scope scope = TProtocolUtil.getScope(request.getStore().getScope()); + for (KeyedValues kv : request.getValues()) { + Iterable<VersionedValue> tvvi = kv.getValues(); + Iterable<Versioned<byte[]>> vs = new TVersionedValueIterable(tvvi); + syncManager.writeSyncValue(request.getStore().getStoreName(), + scope, + request.getStore().isPersist(), + kv.getKey(), vs); + } + + SyncValueResponseMessage m = new SyncValueResponseMessage(); + m.setCount(request.getValuesSize()); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + SyncMessage bsm = + new SyncMessage(MessageType.SYNC_VALUE_RESPONSE); + bsm.setSyncValueResponse(m); + + updateCounter(SyncManager.COUNTER_RECEIVED_VALUES, + request.getValuesSize()); + channel.write(bsm); + } catch (Exception e) { + + channel.write(getError(request.getHeader().getTransactionId(), e, + MessageType.SYNC_VALUE)); + } + } + + protected void handleSyncValueResponse(SyncValueResponseMessage message, + Channel channel) { + rpcService.messageAcked(MessageType.SYNC_VALUE, getRemoteNodeId()); + } + + @Override + protected void handleSyncOffer(SyncOfferMessage request, + Channel channel) { + try { + String storeName = request.getStore().getStoreName(); + + SyncRequestMessage srm = new SyncRequestMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + srm.setHeader(header); + srm.setStore(request.getStore()); + + for (KeyedVersions kv : request.getVersions()) { + Iterable<org.sdnplatform.sync.thrift.VectorClock> tvci = + kv.getVersions(); + Iterable<VectorClock> vci = new TVersionIterable(tvci); + + boolean wantKey = syncManager.handleSyncOffer(storeName, + kv.getKey(), vci); + if (wantKey) + srm.addToKeys(kv.bufferForKey()); + } + + SyncMessage bsm = + new SyncMessage(MessageType.SYNC_REQUEST); + bsm.setSyncRequest(srm); + if (logger.isTraceEnabled()) { + logger.trace("[{}->{}] Sending SyncRequest with {} elements", + new Object[]{getLocalNodeIdString(), + getRemoteNodeIdString(), + srm.getKeysSize()}); + } + channel.write(bsm); + + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), + e, MessageType.SYNC_OFFER)); + } + } + + @Override + protected void handleSyncRequest(SyncRequestMessage request, + Channel channel) { + rpcService.messageAcked(MessageType.SYNC_OFFER, getRemoteNodeId()); + if (!request.isSetKeys()) return; + + String storeName = request.getStore().getStoreName(); + try { + IStorageEngine<ByteArray, byte[]> store = + syncManager.getRawStore(storeName); + + SyncMessage bsm = + TProtocolUtil.getTSyncValueMessage(request.getStore()); + SyncValueMessage svm = bsm.getSyncValue(); + svm.setResponseTo(request.getHeader().getTransactionId()); + svm.getHeader().setTransactionId(rpcService.getTransactionId()); + + for (ByteBuffer key : request.getKeys()) { + ByteArray keyArray = new ByteArray(key.array()); + List<Versioned<byte[]>> values = + store.get(keyArray); + if (values == null || values.size() == 0) continue; + KeyedValues kv = + TProtocolUtil.getTKeyedValues(keyArray, values); + svm.addToValues(kv); + } + + if (svm.isSetValues()) { + updateCounter(SyncManager.COUNTER_SENT_VALUES, + svm.getValuesSize()); + rpcService.syncQueue.add(new NodeMessage(getRemoteNodeId(), + bsm)); + } + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), e, + MessageType.SYNC_REQUEST)); + } + } + + @Override + protected void handleFullSyncRequest(FullSyncRequestMessage request, + Channel channel) { + startAntientropy(); + } + + protected void handleCursorRequest(CursorRequestMessage request, + Channel channel) { + try { + Cursor c = null; + if (request.isSetCursorId()) { + c = syncManager.getCursor(request.getCursorId()); + } else { + c = syncManager.newCursor(request.getStoreName()); + } + if (c == null) { + throw new SyncException("Unrecognized cursor"); + } + + CursorResponseMessage m = new CursorResponseMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + m.setCursorId(c.getCursorId()); + + if (request.isClose()) { + syncManager.closeCursor(c); + } else { + int i = 0; + while (i < 50 && c.hasNext()) { + Entry<ByteArray, List<Versioned<byte[]>>> e = c.next(); + + m.addToValues(TProtocolUtil.getTKeyedValues(e.getKey(), + e.getValue())); + i += 1; + } + } + + SyncMessage bsm = + new SyncMessage(MessageType.CURSOR_RESPONSE); + bsm.setCursorResponse(m); + channel.write(bsm); + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), + e, MessageType.CURSOR_REQUEST)); + } + } + + @Override + protected void handleRegisterRequest(RegisterRequestMessage request, + Channel channel) { + try { + Scope scope = TProtocolUtil.getScope(request.store.getScope()); + if (request.store.isPersist()) + syncManager.registerPersistentStore(request.store.storeName, + scope); + else + syncManager.registerStore(request.store.storeName, scope); + RegisterResponseMessage m = new RegisterResponseMessage(); + AsyncMessageHeader header = new AsyncMessageHeader(); + header.setTransactionId(request.getHeader().getTransactionId()); + m.setHeader(header); + SyncMessage bsm = + new SyncMessage(MessageType.REGISTER_RESPONSE); + bsm.setRegisterResponse(m); + channel.write(bsm); + } catch (Exception e) { + channel.write(getError(request.getHeader().getTransactionId(), e, + MessageType.REGISTER_REQUEST)); + } + } + + @Override + protected void handleError(ErrorMessage error, Channel channel) { + rpcService.messageAcked(error.getType(), getRemoteNodeId()); + super.handleError(error, channel); + } + + // ************************* + // AbstractRPCChannelHandler + // ************************* + + @Override + protected Short getLocalNodeId() { + return syncManager.getLocalNodeId(); + } + + @Override + protected Short getRemoteNodeId() { + if (remoteNode != null) + return remoteNode.getNodeId(); + return null; + } + + @Override + protected String getLocalNodeIdString() { + return ""+getLocalNodeId(); + } + + @Override + protected String getRemoteNodeIdString() { + return ""+getRemoteNodeId(); + } + + @Override + protected int getTransactionId() { + return rpcService.getTransactionId(); + } + + // ***************** + // Utility functions + // ***************** + + protected void updateCounter(String counter, int incr) { + rpcService.debugCounter.updateCounter(counter, incr); + } + + protected void startAntientropy() { + // Run antientropy in a background task so we don't use up an I/O + // thread. Note that this task will result in lots of traffic + // that will use I/O threads but each of those will be in manageable + // chunks + Runnable arTask = new Runnable() { + @Override + public void run() { + syncManager.antientropy(remoteNode); + } + }; + syncManager.getThreadPool().getScheduledExecutor().execute(arTask); + } + + + protected static class TVersionedValueIterable + implements Iterable<Versioned<byte[]>> { + final Iterable<VersionedValue> tvvi; + + public TVersionedValueIterable(Iterable<VersionedValue> tvvi) { + this.tvvi = tvvi; + } + + @Override + public Iterator<Versioned<byte[]>> iterator() { + final Iterator<VersionedValue> vs = tvvi.iterator(); + return new Iterator<Versioned<byte[]>>() { + + @Override + public boolean hasNext() { + return vs.hasNext(); + } + + @Override + public Versioned<byte[]> next() { + return TProtocolUtil.getVersionedValued(vs.next()); + } + + @Override + public void remove() { + vs.remove(); + } + }; + } + } + + protected static class TVersionIterable + implements Iterable<VectorClock> { + final Iterable<org.sdnplatform.sync.thrift.VectorClock> tcvi; + + public TVersionIterable(Iterable<org.sdnplatform.sync.thrift.VectorClock> tcvi) { + this.tcvi = tcvi; + } + + @Override + public Iterator<VectorClock> iterator() { + final Iterator<org.sdnplatform.sync.thrift.VectorClock> tcs = + tcvi.iterator(); + return new Iterator<VectorClock>() { + + @Override + public boolean hasNext() { + return tcs.hasNext(); + } + + @Override + public VectorClock next() { + return TProtocolUtil.getVersion(tcs.next()); + } + + @Override + public void remove() { + tcs.remove(); + } + }; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/RPCPipelineFactory.java b/src/main/java/org/sdnplatform/sync/internal/rpc/RPCPipelineFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..888314ddf3ec845f1da2d1c14e4a87efecc3c78f --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/RPCPipelineFactory.java @@ -0,0 +1,60 @@ +package org.sdnplatform.sync.internal.rpc; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.handler.timeout.IdleStateHandler; +import org.jboss.netty.handler.timeout.ReadTimeoutHandler; +import org.jboss.netty.util.HashedWheelTimer; +import org.jboss.netty.util.Timer; +import org.sdnplatform.sync.internal.SyncManager; + + +/** + * Pipeline factory for the sync service. + * @see SyncManager + * @author readams + */ +public class RPCPipelineFactory implements ChannelPipelineFactory { + + protected SyncManager syncManager; + protected RPCService rpcService; + protected Timer timer; + + private static final int maxFrameSize = 512 * 1024; + + public RPCPipelineFactory(SyncManager syncManager, + RPCService rpcService) { + super(); + this.syncManager = syncManager; + this.rpcService = rpcService; + + this.timer = new HashedWheelTimer(); + } + + @Override + public ChannelPipeline getPipeline() throws Exception { + RPCChannelHandler channelHandler = + new RPCChannelHandler(syncManager, rpcService); + + IdleStateHandler idleHandler = + new IdleStateHandler(timer, 5, 10, 0); + ReadTimeoutHandler readTimeoutHandler = + new ReadTimeoutHandler(timer, 30); + + ChannelPipeline pipeline = Channels.pipeline(); + pipeline.addLast("idle", idleHandler); + pipeline.addLast("timeout", readTimeoutHandler); + pipeline.addLast("handshaketimeout", + new HandshakeTimeoutHandler(channelHandler, timer, 10)); + + pipeline.addLast("frameDecoder", + new ThriftFrameDecoder(maxFrameSize)); + pipeline.addLast("frameEncoder", + new ThriftFrameEncoder()); + + pipeline.addLast("handler", channelHandler); + return pipeline; + } + +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/RPCService.java b/src/main/java/org/sdnplatform/sync/internal/rpc/RPCService.java new file mode 100644 index 0000000000000000000000000000000000000000..f68687062df31c1ae59d465155439ab637be614d --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/RPCService.java @@ -0,0 +1,664 @@ +package org.sdnplatform.sync.internal.rpc; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import net.floodlightcontroller.core.annotations.LogMessageCategory; +import net.floodlightcontroller.core.annotations.LogMessageDoc; +import net.floodlightcontroller.core.annotations.LogMessageDocs; +import net.floodlightcontroller.core.util.SingletonTask; +import net.floodlightcontroller.debugcounter.IDebugCounterService; + +import org.jboss.netty.bootstrap.ClientBootstrap; +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.channel.group.ChannelGroup; +import org.jboss.netty.channel.group.DefaultChannelGroup; +import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; +import org.jboss.netty.util.internal.LinkedTransferQueue; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.config.Node; +import org.sdnplatform.sync.internal.util.Pair; +import org.sdnplatform.sync.thrift.SyncMessage; +import org.sdnplatform.sync.thrift.MessageType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + + +/** + * A lightweight RPC mechanism built on netty. + * @author readams + */ +@LogMessageCategory("State Synchronization") +public class RPCService { + protected static final Logger logger = + LoggerFactory.getLogger(RPCService.class); + + /** + * Sync manager associated with this RPC service + */ + protected SyncManager syncManager; + + /** + * Debug counter service + */ + protected IDebugCounterService debugCounter; + + /** + * Channel group that will hold all our channels + */ + final ChannelGroup cg = new DefaultChannelGroup("Internal RPC"); + + /** + * {@link Executor} used for netty boss threads + */ + protected Executor bossExecutor; + + /** + * {@link Executor} used for netty worker threads + */ + protected Executor workerExecutor; + + /** + * Netty {@link ClientBootstrap} used for creating client connections + */ + protected ClientBootstrap clientBootstrap; + + /** + * Netty {@link ServerBootstrap} used for creating server connections + */ + protected ServerBootstrap serverBootstrap; + + /** + * Node connections + */ + protected HashMap<Short, NodeConnection> connections = + new HashMap<Short, NodeConnection>(); + + /** + * Transaction ID used in message headers in the RPC protocol + */ + protected AtomicInteger transactionId = new AtomicInteger(); + + /** + * Buffer size for sockets + */ + public static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; + + /** + * Connect timeout for client connections + */ + public static final int CONNECT_TIMEOUT = 500; + + /** + * True after the {@link RPCService#run()} method is called + */ + protected boolean started = false; + + /** + * true after the {@link RPCService#shutdown()} method + * is called. + */ + protected volatile boolean shutDown = false; + + /** + * Task to periodically ensure that connections are active + */ + protected SingletonTask reconnectTask; + + /** + * If we want to rate-limit certain types of messages, we can do + * so by limiting the overall number of outstanding messages. + * The number of such messages will be stored in the + * {@link MessageWindow} + */ + protected ConcurrentHashMap<Short, MessageWindow> messageWindows; + protected static final EnumSet<MessageType> windowedTypes = + EnumSet.of(MessageType.SYNC_VALUE, + MessageType.SYNC_OFFER); + + /** + * A thread pool for handling sync messages. These messages require + * a separate pool since writing to the node can be a blocking operation + * while waiting for window capacity, and blocking the I/O threads could + * lead to deadlock + * @see SyncMessageWorker + */ + protected ExecutorService syncExecutor; + + /** + * A queue for holding sync messages that are awaiting being written + * to the channel. + * @see SyncMessageWorker + */ + protected LinkedTransferQueue<NodeMessage> syncQueue = + new LinkedTransferQueue<NodeMessage>(); + + /** + * Number of workers in the sync message thread pool + */ + protected static final int SYNC_MESSAGE_POOL = 2; + + /** + * The maximum number of outstanding pending messages for messages + * that use message windows + */ + protected static final int MAX_PENDING_MESSAGES = 500; + + public RPCService(SyncManager syncManager, + IDebugCounterService debugCounter) { + super(); + this.syncManager = syncManager; + this.debugCounter = debugCounter; + + messageWindows = new ConcurrentHashMap<Short, MessageWindow>(); + } + + // ************* + // public methods + // ************* + + /** + * Start the RPC service + */ + public void run() { + started = true; + + final ThreadGroup tg1 = new ThreadGroup("Sync Message Handlers"); + tg1.setMaxPriority(Thread.NORM_PRIORITY - 3); + ThreadFactory f1 = new ThreadFactory() { + AtomicInteger id = new AtomicInteger(); + + @Override + public Thread newThread(Runnable runnable) { + return new Thread(tg1, runnable, + "SyncMessage-" + id.getAndIncrement()); + } + }; + syncExecutor = Executors.newCachedThreadPool(f1); + for (int i = 0; i < SYNC_MESSAGE_POOL; i++) { + syncExecutor.execute(new SyncMessageWorker()); + } + + final ThreadGroup tg2 = new ThreadGroup("Sync I/O Threads"); + tg2.setMaxPriority(Thread.NORM_PRIORITY - 1); + ThreadFactory f2 = new ThreadFactory() { + @Override + public Thread newThread(Runnable runnable) { + return new Thread(tg2, runnable); + } + }; + + bossExecutor = Executors.newCachedThreadPool(f2); + workerExecutor = Executors.newCachedThreadPool(f2); + + ChannelPipelineFactory pipelineFactory = + new RPCPipelineFactory(syncManager, this); + + startServer(pipelineFactory); + startClients(pipelineFactory); + } + + /** + * Stop the RPC service + */ + @LogMessageDocs({ + @LogMessageDoc(level="WARN", + message="Failed to cleanly shut down RPC server", + explanation="Could not close all open sockets cleanly"), + @LogMessageDoc(level="WARN", + message="Interrupted while shutting down RPC server", + explanation="Could not close all open sockets cleanly") + }) + public void shutdown() { + shutDown = true; + try { + if (!cg.close().await(5, TimeUnit.SECONDS)) { + logger.warn("Failed to cleanly shut down RPC server"); + } + clientBootstrap.releaseExternalResources(); + serverBootstrap.releaseExternalResources(); + } catch (InterruptedException e) { + logger.warn("Interrupted while shutting down RPC server"); + } + logger.debug("Internal floodlight RPC shut down"); + } + + /** + * Get a suitable transaction ID for sending a message + * @return the unique transaction iD + */ + public int getTransactionId() { + return transactionId.getAndIncrement(); + } + + /** + * Write a message to the node specified + * @param nodeId the node ID + * @param bsm the message to write + * @return <code>true</code> if the message was actually written to + * the channel. Note this is not the same as having been sent to the + * other node. + * @throws InterruptedException + */ + public boolean writeToNode(Short nodeId, SyncMessage bsm) + throws InterruptedException { + if (nodeId == null) return false; + NodeConnection nc = connections.get(nodeId); + if (nc != null && nc.state == NodeConnectionState.CONNECTED) { + waitForMessageWindow(bsm.getType(), nodeId, 0); + nc.nodeChannel.write(bsm); + return true; + } + return false; + } + + /** + * Remove the connection from the connection registry and clean up + * any remaining shrapnel + * @param nodeId + */ + public void disconnectNode(short nodeId) { + synchronized (connections) { + Short n = Short.valueOf(nodeId); + MessageWindow mw = messageWindows.get(n); + if (mw != null) { + mw.lock.lock(); + mw.disconnected = true; + try { + mw.full.signalAll(); + messageWindows.remove(n); + } finally { + mw.lock.unlock(); + } + } + + NodeConnection nc = connections.get(nodeId); + if (nc != null) { + nc.nuke(); + } + connections.remove(nodeId); + } + } + + /** + * Check whether all links are established + * @return + */ + public boolean isFullyConnected() { + for (Node n : syncManager.getClusterConfig().getNodes()) { + if (n.getNodeId() != syncManager.getLocalNodeId() && + !isConnected(n.getNodeId())) { + if (logger.isTraceEnabled()) { + logger.trace("[{}->{}] missing connection", + syncManager.getLocalNodeId(), + n.getNodeId()); + } + return false; + } + } + return true; + } + + /** + * Find out if a particular node is connected + * @param nodeId + * @return true if the node is connected + */ + public boolean isConnected(short nodeId) { + NodeConnection nc = connections.get(nodeId); + return (nc != null && nc.state == NodeConnectionState.CONNECTED); + } + + /** + * Called when a message is acknowledged by a remote node + * @param type the message type + * @param nodeId the remote node + */ + public void messageAcked(MessageType type, Short nodeId) { + if (nodeId == null) return; + if (!windowedTypes.contains(type)) return; + + MessageWindow mw = messageWindows.get(nodeId); + if (mw == null) return; + + int pending = mw.pending.decrementAndGet(); + if (pending < MAX_PENDING_MESSAGES) { + mw.lock.lock(); + try { + mw.full.signalAll(); + } finally { + mw.lock.unlock(); + } + } + } + + // ************* + // Local methods + // ************* + + /** + * Get the appropriate {@link MessageWindow} object for the given node. + * @param nodeId the remote node + * @return a {@link MessageWindow} object + */ + private MessageWindow getMW(short nodeId) { + + if (!isConnected(nodeId)) return null; + + Short n = Short.valueOf(nodeId); + MessageWindow mw = messageWindows.get(n); + if (mw == null) { + mw = new MessageWindow(); + MessageWindow old = messageWindows.putIfAbsent(n, mw); + if (old != null) mw = old; + } + + return mw; + } + + /** + * Wait for a message window slow to be available for the given node and + * message type + * @param type the type of the message + * @param nodeId the node Id + * @param maxWait the maximum time to wait in milliseconds + * @throws InterruptedException + * @return <code>true</code> if the message can be safely written + */ + private boolean waitForMessageWindow(MessageType type, short nodeId, + long maxWait) + throws InterruptedException { + if (!windowedTypes.contains(type)) return true; + + long start = System.nanoTime(); + + // note that this can allow slightly more than the maximum number + // of messages. This is fine. + MessageWindow mw = getMW(nodeId); + if (!mw.disconnected && + mw.pending.get() >= MAX_PENDING_MESSAGES) { + mw.lock.lock(); + try { + while (!mw.disconnected && + mw.pending.get() >= MAX_PENDING_MESSAGES) { + long now = System.nanoTime(); + if (maxWait > 0 && + (now - start) > maxWait * 1000) return false; + mw.full.awaitNanos(now - start); + } + } finally { + mw.lock.unlock(); + } + } + mw = getMW(nodeId); + if (mw != null) + mw.pending.getAndIncrement(); + + return true; + } + + /** + * Start listening sockets + */ + @LogMessageDoc(level="INFO", + message="Listening for internal floodlight RPC on {port}", + explanation="The internal RPC service is ready for connections") + protected void startServer(ChannelPipelineFactory pipelineFactory) { + final ServerBootstrap bootstrap = + new ServerBootstrap( + new NioServerSocketChannelFactory(bossExecutor, + workerExecutor)); + bootstrap.setOption("reuseAddr", true); + bootstrap.setOption("child.keepAlive", true); + bootstrap.setOption("child.tcpNoDelay", true); + bootstrap.setOption("child.sendBufferSize", SEND_BUFFER_SIZE); + bootstrap.setOption("child.receiveBufferSize", SEND_BUFFER_SIZE); + + bootstrap.setPipelineFactory(pipelineFactory); + serverBootstrap = bootstrap; + + int port = syncManager.getClusterConfig().getNode().getPort(); + InetSocketAddress sa = new InetSocketAddress(port); + cg.add(bootstrap.bind(sa)); + + logger.info("Listening for internal floodlight RPC on {}", sa); + } + + /** + * Wait for the client connection + * @author readams + */ + protected class ConnectCFListener implements ChannelFutureListener { + protected Node node; + + public ConnectCFListener(Node node) { + super(); + this.node = node; + } + + @Override + public void operationComplete(ChannelFuture cf) throws Exception { + if (!cf.isSuccess()) { + synchronized (connections) { + NodeConnection c = connections.remove(node.getNodeId()); + if (c != null) c.nuke(); + cf.getChannel().close(); + } + + String message = "[unknown error]"; + if (cf.isCancelled()) message = "Timed out on connect"; + if (cf.getCause() != null) message = cf.getCause().getMessage(); + logger.debug("[{}->{}] Could not connect to RPC " + + "node: {}", + new Object[]{syncManager.getLocalNodeId(), + node.getNodeId(), + message}); + } else { + logger.trace("[{}->{}] Channel future successful", + syncManager.getLocalNodeId(), + node.getNodeId()); + } + } + } + + /** + * Add the node connection to the node connection map + * @param nodeId the node ID for the channel + * @param channel the new channel + */ + protected void nodeConnected(short nodeId, Channel channel) { + logger.debug("[{}->{}] Connection established", + syncManager.getLocalNodeId(), + nodeId); + synchronized (connections) { + NodeConnection c = connections.get(nodeId); + if (c == null) { + connections.put(nodeId, c = new NodeConnection()); + } + c.nodeChannel = channel; + c.state = NodeConnectionState.CONNECTED; + } + } + + /** + * Connect to remote servers. We'll initiate the connection to + * any nodes with a lower ID so that there will be a single connection + * between each pair of nodes which we'll use symmetrically + */ + protected void startClients(ChannelPipelineFactory pipelineFactory) { + final ClientBootstrap bootstrap = + new ClientBootstrap( + new NioClientSocketChannelFactory(bossExecutor, + workerExecutor)); + bootstrap.setOption("child.reuseAddr", true); + bootstrap.setOption("child.keepAlive", true); + bootstrap.setOption("child.tcpNoDelay", true); + bootstrap.setOption("child.sendBufferSize", SEND_BUFFER_SIZE); + bootstrap.setOption("child.connectTimeoutMillis", CONNECT_TIMEOUT); + bootstrap.setPipelineFactory(pipelineFactory); + clientBootstrap = bootstrap; + + ScheduledExecutorService ses = + syncManager.getThreadPool().getScheduledExecutor(); + reconnectTask = new SingletonTask(ses, new ConnectTask()); + reconnectTask.reschedule(0, TimeUnit.SECONDS); + } + + /** + * Connect to a remote node if appropriate + * @param bootstrap the client bootstrap object + * @param n the node to connect to + */ + protected void doNodeConnect(Node n) { + if (!shutDown && n.getNodeId() < syncManager.getLocalNodeId()) { + Short nodeId = n.getNodeId(); + + synchronized (connections) { + NodeConnection c = connections.get(n.getNodeId()); + if (c == null) { + connections.put(nodeId, c = new NodeConnection()); + } + + if (logger.isTraceEnabled()) { + logger.trace("[{}->{}] Connection state: {}", + new Object[]{syncManager.getLocalNodeId(), + nodeId, c.state}); + } + if (c.state.equals(NodeConnectionState.NONE)) { + if (logger.isDebugEnabled()) { + logger.debug("[{}->{}] Attempting connection {} {}", + new Object[]{syncManager.getLocalNodeId(), + nodeId, + n.getHostname(), + n.getPort()}); + } + SocketAddress sa = + new InetSocketAddress(n.getHostname(), n.getPort()); + c.pendingFuture = clientBootstrap.connect(sa); + c.pendingFuture.addListener(new ConnectCFListener(n)); + c.state = NodeConnectionState.PENDING; + } + } + } + } + + /** + * Ensure that all client connections are active + */ + protected void startClientConnections() { + for (Node n : syncManager.getClusterConfig().getNodes()) { + doNodeConnect(n); + } + } + + /** + * Periodically ensure that all the node connections are alive + * @author readams + */ + protected class ConnectTask implements Runnable { + @Override + public void run() { + try { + if (!shutDown) + startClientConnections(); + } catch (Exception e) { + logger.error("Error in reconnect task", e); + } + if (!shutDown) { + reconnectTask.reschedule(500, TimeUnit.MILLISECONDS); + } + } + } + + /** + * Various states for connections + * @author readams + */ + protected enum NodeConnectionState { + NONE, + PENDING, + CONNECTED + } + + /** + * Connection state wrapper for node connections + * @author readams + */ + protected static class NodeConnection { + volatile NodeConnectionState state = NodeConnectionState.NONE; + protected ChannelFuture pendingFuture; + protected Channel nodeChannel; + + protected void nuke() { + state = NodeConnectionState.NONE; + if (pendingFuture != null) pendingFuture.cancel(); + if (nodeChannel != null) nodeChannel.close(); + pendingFuture = null; + nodeChannel = null; + } + } + + /** + * Maintain state for the pending message window for a given message type + * @author readams + */ + protected static class MessageWindow { + AtomicInteger pending = new AtomicInteger(); + volatile boolean disconnected = false; + Lock lock = new ReentrantLock(); + Condition full = lock.newCondition(); + } + + /** + * A pending message to be sent to a particular mode. + * @author readams + */ + protected static class NodeMessage extends Pair<Short,SyncMessage> { + private static final long serialVersionUID = -3443080461324647922L; + + public NodeMessage(Short first, SyncMessage second) { + super(first, second); + } + } + + /** + * A worker thread responsible for reading sync messages off the queue + * and writing them to the appropriate node's channel. Because calls + * {@link RPCService#writeToNode(Short, SyncMessage)} can block while + * waiting for available slots in the message window, we do this in a + * separate thread. + * @author readams + */ + protected class SyncMessageWorker implements Runnable { + @Override + public void run() { + while (true) { + try { + NodeMessage m = syncQueue.take(); + writeToNode(m.getFirst(), m.getSecond()); + } catch (Exception e) { + logger.error("Error while dispatching message", e); + } + } + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/TProtocolUtil.java b/src/main/java/org/sdnplatform/sync/internal/rpc/TProtocolUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..184482d794cc2b3aebb2d9ba7b1199c8de5b3506 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/TProtocolUtil.java @@ -0,0 +1,293 @@ +package org.sdnplatform.sync.internal.rpc; + +import java.util.ArrayList; +import java.util.List; + +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.version.ClockEntry; +import org.sdnplatform.sync.internal.version.VectorClock; +import org.sdnplatform.sync.thrift.AsyncMessageHeader; +import org.sdnplatform.sync.thrift.SyncMessage; +import org.sdnplatform.sync.thrift.KeyedValues; +import org.sdnplatform.sync.thrift.KeyedVersions; +import org.sdnplatform.sync.thrift.MessageType; +import org.sdnplatform.sync.thrift.Store; +import org.sdnplatform.sync.thrift.SyncOfferMessage; +import org.sdnplatform.sync.thrift.SyncValueMessage; +import org.sdnplatform.sync.thrift.VersionedValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Some utility methods for constructing Thrift messages + * @author readams + */ +public class TProtocolUtil { + protected static Logger logger = + LoggerFactory.getLogger(TProtocolUtil.class.getName()); + + /** + * Convert a {@link VectorClock} into a + * {@link org.sdnplatform.sync.thrift.VectorClock} + * @param vc the input clock + * @return the output thrift object + */ + public static org.sdnplatform.sync.thrift.VectorClock + getTVectorClock(VectorClock vc) { + org.sdnplatform.sync.thrift.VectorClock tvc = + new org.sdnplatform.sync.thrift.VectorClock(); + tvc.setTimestamp(vc.getTimestamp()); + for (ClockEntry ce : vc.getEntries()) { + org.sdnplatform.sync.thrift.ClockEntry tce = + new org.sdnplatform.sync.thrift.ClockEntry(); + tce.setNodeId(ce.getNodeId()); + tce.setVersion(ce.getVersion()); + tvc.addToVersions(tce); + } + + return tvc; + } + + /** + * Allocate a thrift {@link org.sdnplatform.sync.thrift.VersionedValue} + * object wrapping a {@link Versioned} object + * @param value the value to wrap + * @return the thrift object + */ + public static org.sdnplatform.sync.thrift.VersionedValue + getTVersionedValue(Versioned<byte[]> value) { + + org.sdnplatform.sync.thrift.VersionedValue tvv = + new org.sdnplatform.sync.thrift.VersionedValue(); + org.sdnplatform.sync.thrift.VectorClock tvc = + getTVectorClock((VectorClock)value.getVersion()); + + tvv.setVersion(tvc); + tvv.setValue(value.getValue()); + + return tvv; + } + + /** + * Construct a thrift {@link org.sdnplatform.sync.thrift.KeyedValues} + * @param key the key + * @param value the versioned values + * @return the thrift object + */ + public static KeyedValues getTKeyedValues(ByteArray key, + Versioned<byte[]>... value) { + KeyedValues kv = new KeyedValues(); + kv.setKey(key.get()); + for (Versioned<byte[]> v : value) { + kv.addToValues(getTVersionedValue(v)); + } + return kv; + } + + /** + * Construct a thrift {@link org.sdnplatform.sync.thrift.KeyedValues} + * @param key the key + * @param values the versioned values + * @return the thrift object + */ + public static KeyedValues + getTKeyedValues(ByteArray key, + Iterable<Versioned<byte[]>> values) { + KeyedValues kv = new KeyedValues(); + kv.setKey(key.get()); + for (Versioned<byte[]> v : values) { + kv.addToValues(getTVersionedValue(v)); + } + return kv; + } + + /** + * Construct a thrift {@link org.sdnplatform.sync.thrift.KeyedValues} + * @param key the key + * @param value the versioned values + * @return the thrift object + */ + public static KeyedVersions + getTKeyedVersions(ByteArray key, List<Versioned<byte[]>> values) { + KeyedVersions kv = new KeyedVersions(); + kv.setKey(key.get()); + for (Versioned<byte[]> v : values) { + kv.addToVersions(getTVectorClock((VectorClock)v.getVersion())); + } + return kv; + } + + /** + * Allocate a thrift {@link org.sdnplatform.sync.thrift.Store} object + * for the current store + * @param storeName the name of the store + * @param scope the scope of the store + * @param persist whether the store is persistent + * @return the object + */ + public static org.sdnplatform.sync.thrift.Store getTStore(String storeName, + Scope scope, + boolean persist) { + return getTStore(storeName, getTScope(scope), persist); + } + + /** + * Allocate a thrift {@link org.sdnplatform.sync.thrift.Store} object + * for the current store + * @param storeName the name of the store + * @param scope the scope of the store + * @param persist whether the store is persistent + * @return the object + */ + public static org.sdnplatform.sync.thrift.Store + getTStore(String storeName, + org.sdnplatform.sync.thrift.Scope scope, + boolean persist) { + org.sdnplatform.sync.thrift.Store store = + new org.sdnplatform.sync.thrift.Store(); + store.setScope(scope); + store.setStoreName(storeName); + store.setPersist(persist); + return store; + } + + /** + * Convert a {@link org.sdnplatform.sync.thrift.Scope} into a + * {@link Scope} + * @param tScope the {@link org.sdnplatform.sync.thrift.Scope} to convert + * @return the resulting {@link Scope} + */ + public static Scope getScope(org.sdnplatform.sync.thrift.Scope tScope) { + switch (tScope) { + case LOCAL: + return Scope.LOCAL; + case GLOBAL: + default: + return Scope.GLOBAL; + } + } + + /** + * Convert a {@link Scope} into a + * {@link org.sdnplatform.sync.thrift.Scope} + * @param tScope the {@link Scope} to convert + * @return the resulting {@link org.sdnplatform.sync.thrift.Scope} + */ + public static org.sdnplatform.sync.thrift.Scope getTScope(Scope Scope) { + switch (Scope) { + case LOCAL: + return org.sdnplatform.sync.thrift.Scope.LOCAL; + case GLOBAL: + default: + return org.sdnplatform.sync.thrift.Scope.GLOBAL; + } + } + + /** + * Get a partially-initialized {@link SyncValueMessage} wrapped with a + * {@link SyncMessage}. The values will not be set in the + * {@link SyncValueMessage}, and the transaction ID will not be set in + * the {@link AsyncMessageHeader}. + * @param storeName the store name + * @param scope the scope + * @param persist whether the store is persistent + * @return the {@link SyncMessage} + */ + public static SyncMessage getTSyncValueMessage(String storeName, + Scope scope, + boolean persist) { + return getTSyncValueMessage(getTStore(storeName, scope, persist)); + } + + /** + * Get a partially-initialized {@link SyncValueMessage} wrapped with a + * {@link SyncMessage}. The values will not be set in the + * {@link SyncValueMessage}, and the transaction ID will not be set in + * the {@link AsyncMessageHeader}. + * @param store the {@link Store} associated with the message + * @return the {@link SyncMessage} + */ + public static SyncMessage getTSyncValueMessage(Store store) { + SyncMessage bsm = + new SyncMessage(MessageType.SYNC_VALUE); + AsyncMessageHeader header = new AsyncMessageHeader(); + SyncValueMessage svm = new SyncValueMessage(); + svm.setHeader(header); + svm.setStore(store); + + bsm.setSyncValue(svm); + return bsm; + } + + /** + * Get a partially-initialized {@link SyncOfferMessage} wrapped with a + * {@link SyncMessage}. + * @param storeName the name of the store associated with the message + * @param scope the {@link Scope} for the store + * @param persist the scope for the store + * @return the {@link SyncMessage} + */ + public static SyncMessage getTSyncOfferMessage(String storeName, + Scope scope, + boolean persist) { + SyncMessage bsm = new SyncMessage(MessageType.SYNC_OFFER); + AsyncMessageHeader header = new AsyncMessageHeader(); + SyncOfferMessage som = new SyncOfferMessage(); + som.setHeader(header); + som.setStore(getTStore(storeName, scope, persist)); + + bsm.setSyncOffer(som); + return bsm; + } + + /** + * Convert a thrift {@link org.sdnplatform.sync.thrift.VectorClock} into + * a {@link VectorClock}. + * @param tvc the {@link org.sdnplatform.sync.thrift.VectorClock} + * @param the {@link VectorClock} + */ + public static VectorClock getVersion(org.sdnplatform.sync.thrift.VectorClock tvc) { + ArrayList<ClockEntry> entries = + new ArrayList<ClockEntry>(); + if (tvc.getVersions() != null) { + for (org.sdnplatform.sync.thrift.ClockEntry ce : + tvc.getVersions()) { + entries.add(new ClockEntry(ce.getNodeId(), ce.getVersion())); + } + } + return new VectorClock(entries, tvc.getTimestamp()); + } + + /** + * Convert a thrift {@link VersionedValue} into a {@link Versioned}. + * @param tvv the {@link VersionedValue} + * @return the {@link Versioned} + */ + public static Versioned<byte[]> + getVersionedValued(VersionedValue tvv) { + Versioned<byte[]> vv = + new Versioned<byte[]>(tvv.getValue(), + getVersion(tvv.getVersion())); + return vv; + } + + /** + * Convert from a list of {@link VersionedValue} to a list + * of {@link Versioned<byte[]>} + * @param tvv the list of versioned values + * @return the list of versioned + */ + public static List<Versioned<byte[]>> getVersionedList(List<VersionedValue> tvv) { + ArrayList<Versioned<byte[]>> values = + new ArrayList<Versioned<byte[]>>(); + if (tvv != null) { + for (VersionedValue v : tvv) { + values.add(TProtocolUtil.getVersionedValued(v)); + } + } + return values; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/ThriftFrameDecoder.java b/src/main/java/org/sdnplatform/sync/internal/rpc/ThriftFrameDecoder.java new file mode 100644 index 0000000000000000000000000000000000000000..50ec9d0f81f6613ba33555ed7366634baac2f759 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/ThriftFrameDecoder.java @@ -0,0 +1,49 @@ +package org.sdnplatform.sync.internal.rpc; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.transport.TIOStreamTransport; +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBufferInputStream; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.sdnplatform.sync.thrift.SyncMessage; + +/** + * Decode a {@link SyncMessage} from the channel + * @author readams + */ +public class ThriftFrameDecoder extends LengthFieldBasedFrameDecoder { + + public ThriftFrameDecoder(int maxSize) { + super(maxSize, 0, 4, 0, 4); + } + + @Override + protected Object decode(ChannelHandlerContext ctx, + Channel channel, + ChannelBuffer buffer) throws Exception { + List<SyncMessage> ms = null; + ChannelBuffer frame = null; + while (null != (frame = (ChannelBuffer) super.decode(ctx, channel, + buffer))) { + if (ms == null) ms = new ArrayList<SyncMessage>(); + ChannelBufferInputStream is = new ChannelBufferInputStream(frame); + TCompactProtocol thriftProtocol = + new TCompactProtocol(new TIOStreamTransport(is)); + SyncMessage bsm = new SyncMessage(); + bsm.read(thriftProtocol); + ms.add(bsm); + } + return ms; + } + + @Override + protected ChannelBuffer extractFrame(ChannelBuffer buffer, + int index, int length) { + return buffer.slice(index, length); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/rpc/ThriftFrameEncoder.java b/src/main/java/org/sdnplatform/sync/internal/rpc/ThriftFrameEncoder.java new file mode 100644 index 0000000000000000000000000000000000000000..d71e8d2de8e51dd0285fa55b85c3d6e6c75bcc4e --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/rpc/ThriftFrameEncoder.java @@ -0,0 +1,39 @@ +package org.sdnplatform.sync.internal.rpc; + +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.transport.TIOStreamTransport; +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBufferOutputStream; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.buffer.DynamicChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; +import org.sdnplatform.sync.thrift.SyncMessage; + + +/** + * Encode a {@link SyncMessage} into the channel + * @author readams + * + */ +public class ThriftFrameEncoder extends OneToOneEncoder { + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object message) throws Exception { + if (message instanceof SyncMessage) { + ChannelBuffer buf = new DynamicChannelBuffer(512); + ChannelBufferOutputStream os = new ChannelBufferOutputStream(buf); + TCompactProtocol thriftProtocol = + new TCompactProtocol(new TIOStreamTransport(os)); + ((SyncMessage) message).write(thriftProtocol); + + ChannelBuffer len = ChannelBuffers.buffer(4); + len.writeInt(buf.readableBytes()); + return ChannelBuffers.wrappedBuffer(len, buf); + } + return message; + } + +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/DerbySlf4jBridge.java b/src/main/java/org/sdnplatform/sync/internal/store/DerbySlf4jBridge.java new file mode 100644 index 0000000000000000000000000000000000000000..43484289fe6eb664294d250c595bb64a18d105e8 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/DerbySlf4jBridge.java @@ -0,0 +1,60 @@ +package org.sdnplatform.sync.internal.store; + +import java.io.Writer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Funnels Derby log outputs into an SLF4J logger. + */ +public final class DerbySlf4jBridge +{ + + private static final Logger logger = + LoggerFactory.getLogger(DerbySlf4jBridge.class); + + private DerbySlf4jBridge() + { + } + + /** + * A basic adapter that funnels Derby's logs through an SLF4J logger. + */ + public static final class LoggingWriter extends Writer + { + @Override + public void write(final char[] cbuf, final int off, final int len) + { + if (!logger.isDebugEnabled()) return; + + // Don't bother with empty lines. + if (len > 1) + { + logger.debug(new String(cbuf, off, len)); + } + } + + @Override + public void flush() + { + // noop. + } + + @Override + public void close() + { + // noop. + } + } + + public static String getBridgeMethod() { + return DerbySlf4jBridge.class.getCanonicalName() + + ".bridge"; + } + + public static Writer bridge() + { + return new LoggingWriter(); + } +} \ No newline at end of file diff --git a/src/main/java/org/sdnplatform/sync/internal/store/IStorageEngine.java b/src/main/java/org/sdnplatform/sync/internal/store/IStorageEngine.java new file mode 100644 index 0000000000000000000000000000000000000000..4e1515f9164697449fe4b308519fe2bcc70afa10 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/IStorageEngine.java @@ -0,0 +1,108 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.store; + +import java.util.List; +import java.util.Map.Entry; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SyncException; + + +/** + * A base storage class which is actually responsible for data persistence. This + * interface implies all the usual responsibilities of a Store implementation, + * and in addition + * <ol> + * <li>The implementation MUST throw an ObsoleteVersionException if the user + * attempts to put a version which is strictly before an existing version + * (concurrent is okay)</li> + * <li>The implementation MUST increment this version number when the value is + * stored.</li> + * <li>The implementation MUST contain an ID identifying it as part of the + * cluster</li> + * </ol> + * + * A hash value can be produced for known subtrees of a StorageEngine + * + * + * @param <K> The type of the key being stored + * @param <V> The type of the value being stored + * @param <T> The type of the transforms + * + */ +public interface IStorageEngine<K, V> extends IStore<K, V> { + + /** + * Get an iterator over pairs of entries in the store. The key is the first + * element in the pair and the versioned value is the second element. + * + * Note that the iterator need not be threadsafe, and that it must be + * manually closed after use. + * + * @return An iterator over the entries in this StorageEngine. + */ + public IClosableIterator<Entry<K,List<Versioned<V>>>> entries(); + + /** + * Get an iterator over keys in the store. + * + * Note that the iterator need not be threadsafe, and that it must be + * manually closed after use. + * + * @return An iterator over the keys in this StorageEngine. + */ + public IClosableIterator<K> keys(); + + /** + * Truncate all entries in the store. Note that this is a purely local + * operation and all the data will sync back over of it's connected + * @throws SyncException + */ + public void truncate() throws SyncException; + + /** + * Write the given versioned values into the given key. + * @param key the key + * @param values the list of versions for that key + * @return true if any of the values were new and not obsolete + * @throws SyncException + */ + public boolean writeSyncValue(K key, Iterable<Versioned<V>> values); + + /** + * Perform any periodic cleanup tasks that might need to be performed. + * This method will be called periodically by the sync manager + * @throws SyncException + */ + public void cleanupTask() throws SyncException; + + /** + * Returns true if the underlying data store is persistent + * @return whether the store is persistent + */ + public boolean isPersistent(); + + /** + * Set the interval after which tombstones will be cleaned up. This + * imposes an upper bound on the amount of time that two partitions can + * be separate before reaching consistency for any given key. + * @param interval the interval in milliseconds + */ + void setTombstoneInterval(int interval); +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/IStore.java b/src/main/java/org/sdnplatform/sync/internal/store/IStore.java new file mode 100644 index 0000000000000000000000000000000000000000..8c97966252028736416f10f246c68683167dfc88 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/IStore.java @@ -0,0 +1,89 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.internal.store; + +import java.util.List; +import java.util.Map.Entry; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SyncException; + + +/** + * The basic interface used for storage and storage decorators. Allows the usual + * crud operations. + * + * Note that certain operations rely on the correct implementation of equals and + * hashCode for the key. As such, arrays as keys should be avoided. + * + * + */ +public interface IStore<K, V> { + + /** + * Get the value associated with the given key + * + * @param key The key to check for + * @return The value associated with the key or an empty list if no values + * are found. + * @throws SyncException + */ + public List<Versioned<V>> get(K key) throws SyncException; + + /** + * Get an iterator over pairs of entries in the store. The key is the first + * element in the pair and the versioned value is the second element. + * + * Note that the iterator need not be threadsafe, and that it must be + * manually closed after use. + * + * @return An iterator over the entries in this StorageEngine. + */ + public IClosableIterator<Entry<K,List<Versioned<V>>>> entries(); + + /** + * Associate the value with the key and version in this store + * + * @param key The key to use + * @param value The value to store and its version. + */ + public void put(K key, Versioned<V> value) + throws SyncException; + + /** + * Get a list of the versions associated with the given key + * @param key the key + * @return the list of {@link IVersion} objects + * @throws SyncException + */ + public List<IVersion> getVersions(K key) throws SyncException; + + /** + * @return The name of the store. + */ + public String getName(); + + /** + * Close the store. + * + * @throws SyncException If closing fails. + */ + public void close() throws SyncException; +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/InMemoryStorageEngine.java b/src/main/java/org/sdnplatform/sync/internal/store/InMemoryStorageEngine.java new file mode 100644 index 0000000000000000000000000000000000000000..fc04ac5686c1fbe5c16e3241e64eff21c3c61ea0 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/InMemoryStorageEngine.java @@ -0,0 +1,289 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.IVersion.Occurred; +import org.sdnplatform.sync.error.ObsoleteVersionException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.util.Pair; + + +/** + * A simple non-persistent, in-memory store. + */ +public class InMemoryStorageEngine<K, V> implements IStorageEngine<K, V> { + + private final ConcurrentMap<K, List<Versioned<V>>> map; + private final String name; + + /** + * Interval in milliseconds before tombstones will be cleared. + */ + protected int tombstoneDeletion = 24 * 60 * 60 * 1000; + + public InMemoryStorageEngine(String name) { + this.name = name; + this.map = new ConcurrentHashMap<K, List<Versioned<V>>>(); + } + + public InMemoryStorageEngine(String name, + ConcurrentMap<K, List<Versioned<V>>> map) { + this.name = name; + this.map = map; + } + + // ****************** + // StorageEngine<K,V> + // ****************** + + @Override + public void close() {} + + @Override + public List<IVersion> getVersions(K key) throws SyncException { + return StoreUtils.getVersions(get(key)); + } + + @Override + public List<Versioned<V>> get(K key) throws SyncException { + StoreUtils.assertValidKey(key); + List<Versioned<V>> results = map.get(key); + if(results == null) { + return new ArrayList<Versioned<V>>(0); + } + synchronized(results) { + return new ArrayList<Versioned<V>>(results); + } + } + + @Override + public void put(K key, Versioned<V> value) throws SyncException { + if (!doput(key, value)) + throw new ObsoleteVersionException(); + } + + public boolean doput(K key, Versioned<V> value) throws SyncException { + StoreUtils.assertValidKey(key); + + IVersion version = value.getVersion(); + + while(true) { + List<Versioned<V>> items = map.get(key); + // If we have no value, optimistically try to add one + if(items == null) { + items = new ArrayList<Versioned<V>>(); + items.add(new Versioned<V>(value.getValue(), version)); + if (map.putIfAbsent(key, items) != null) + continue; + return true; + } else { + synchronized(items) { + // if this check fails, items has been removed from the map + // by delete, so we try again. + if(map.get(key) != items) + continue; + + // Check for existing versions - remember which items to + // remove in case of success + List<Versioned<V>> itemsToRemove = new ArrayList<Versioned<V>>(items.size()); + for(Versioned<V> versioned: items) { + Occurred occurred = value.getVersion().compare(versioned.getVersion()); + if(occurred == Occurred.BEFORE) { + return false; + } else if(occurred == Occurred.AFTER) { + itemsToRemove.add(versioned); + } + } + items.removeAll(itemsToRemove); + items.add(value); + } + return true; + } + } + } + + @Override + public IClosableIterator<Entry<K,List<Versioned<V>>>> entries() { + return new InMemoryIterator<K, V>(map); + } + + @Override + public IClosableIterator<K> keys() { + // TODO Implement more efficient version. + return StoreUtils.keys(entries()); + } + + @Override + public void truncate() { + map.clear(); + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean writeSyncValue(K key, Iterable<Versioned<V>> values) { + boolean success = false; + for (Versioned<V> value : values) { + try { + put (key, value); + success = true; + } catch (SyncException e) { + // ignore + } + } + return success; + } + + @Override + public void cleanupTask() { + // Remove tombstones that are older than the tombstone deletion + // threshold. If a value is deleted and the tombstone has been + // cleaned up before the cluster is fully synchronized, then there + // is a chance that deleted values could be resurrected + Iterator<Entry<K, List<Versioned<V>>>> iter = map.entrySet().iterator(); + while (iter.hasNext()) { + Entry<K, List<Versioned<V>>> e = iter.next(); + List<Versioned<V>> items = e.getValue(); + + synchronized (items) { + if (StoreUtils.canDelete(items, tombstoneDeletion)) + iter.remove(); + } + } + } + + @Override + public boolean isPersistent() { + return false; + } + + @Override + public void setTombstoneInterval(int interval) { + this.tombstoneDeletion = interval; + } + + // ********************* + // InMemoryStorageEngine + // ********************* + + /** + * Get the number of keys currently in the store + * @return + */ + public int size() { + return map.size(); + } + + /** + * Atomically remove the key and return the value that was mapped to it, + * if any + * @param key the key to remove + * @return the mapped values + */ + public List<Versioned<V>> remove(K key) { + while (true) { + List<Versioned<V>> items = map.get(key); + synchronized (items) { + if (map.remove(key, items)) + return items; + } + } + } + + /** + * Check whether the given key is present in the store + * @param key the key + * @return <code>true</code> if the key is present + */ + public boolean containsKey(K key) { + return map.containsKey(key); + } + + // ****** + // Object + // ****** + + @Override + public String toString() { + return toString(15); + } + + // ************* + // Local methods + // ************* + + protected String toString(int size) { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + int count = 0; + for(Entry<K, List<Versioned<V>>> entry: map.entrySet()) { + if(count > size) { + builder.append("..."); + break; + } + builder.append(entry.getKey()); + builder.append(':'); + builder.append(entry.getValue()); + builder.append(','); + } + builder.append('}'); + return builder.toString(); + } + + private static class InMemoryIterator<K, V> implements + IClosableIterator<Entry<K, List<Versioned<V>>>> { + + private final Iterator<Entry<K, List<Versioned<V>>>> iterator; + + public InMemoryIterator(ConcurrentMap<K, List<Versioned<V>>> map) { + this.iterator = map.entrySet().iterator(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public Pair<K, List<Versioned<V>>> next() { + Entry<K, List<Versioned<V>>> entry = iterator.next(); + return new Pair<K, List<Versioned<V>>>(entry.getKey(), + entry.getValue()); + } + + public void remove() { + throw new UnsupportedOperationException("No removal y'all."); + } + + @Override + public void close() { + // nothing to do + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/JacksonStore.java b/src/main/java/org/sdnplatform/sync/internal/store/JacksonStore.java new file mode 100644 index 0000000000000000000000000000000000000000..a4cd6e251d7d0b41bae9d93db28bd640e90ccea7 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/JacksonStore.java @@ -0,0 +1,240 @@ +package org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.smile.SmileFactory; + +import com.fasterxml.jackson.core.type.TypeReference; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SerializationException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.SyncRuntimeException; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * A store that will serialize and deserialize objects to JSON using Jackson + */ +public class JacksonStore<K, V> implements IStore<K, V> { + protected static Logger logger = + LoggerFactory.getLogger(JacksonStore.class); + + protected static final ObjectMapper mapper = + new ObjectMapper(new SmileFactory()); + static { + mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, + true); + } + + private final IStore<ByteArray, byte[]> delegate; + + private final ObjectWriter keyWriter; + private final ObjectWriter valueWriter; + private final ObjectReader keyReader; + private final ObjectReader valueReader; + + private final boolean keyAsTree; + private final boolean valueAsTree; + + public JacksonStore(IStore<ByteArray, byte[]> delegate, + Class<K> keyClass, + Class<V> valueClass) { + super(); + this.delegate = delegate; + if (keyClass.isAssignableFrom(JsonNode.class)) { + keyAsTree = true; + this.keyWriter = null; + this.keyReader = null; + } else { + keyAsTree = false; + this.keyWriter = mapper.writerWithType(keyClass); + this.keyReader = mapper.reader(keyClass); + } + if (valueClass.isAssignableFrom(JsonNode.class)) { + valueAsTree = true; + this.valueWriter = null; + this.valueReader = null; + } else { + valueAsTree = false; + this.valueWriter = mapper.writerWithType(valueClass); + this.valueReader = mapper.reader(valueClass); + } + } + + public JacksonStore(IStore<ByteArray, byte[]> delegate, + TypeReference<K> keyType, + TypeReference<V> valueType) { + super(); + this.delegate = delegate; + keyAsTree = false; + valueAsTree = false; + this.keyWriter = mapper.writerWithType(keyType); + this.keyReader = mapper.reader(keyType); + this.valueWriter = mapper.writerWithType(valueType); + this.valueReader = mapper.reader(valueType); + } + + // ************ + // Store<K,V,T> + // ************ + @Override + public List<Versioned<V>> get(K key) throws SyncException { + ByteArray keybytes = getKeyBytes(key); + List<Versioned<byte[]>> values = delegate.get(keybytes); + return convertValues(values); + } + + @Override + public IClosableIterator<Entry<K, List<Versioned<V>>>> entries() { + return new JacksonIterator(delegate.entries()); + } + + @Override + public void put(K key, Versioned<V> value) + throws SyncException { + ByteArray keybytes = getKeyBytes(key); + byte[] valuebytes = value.getValue() != null + ? getValueBytes(value.getValue()) + : null; + delegate.put(keybytes, + new Versioned<byte[]>(valuebytes, value.getVersion())); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public void close() throws SyncException { + delegate.close(); + } + + @Override + public List<IVersion> getVersions(K key) throws SyncException { + ByteArray keybytes = getKeyBytes(key); + return delegate.getVersions(keybytes); + } + + // ************* + // Local methods + // ************* + + private ByteArray getKeyBytes(K key) + throws SyncException { + if (key == null) + throw new IllegalArgumentException("Cannot get null key"); + + try { + if (keyAsTree) + return new ByteArray(mapper.writeValueAsBytes(key)); + else + return new ByteArray(keyWriter.writeValueAsBytes(key)); + } catch (Exception e) { + throw new SerializationException(e); + } + } + + private byte[] getValueBytes(V value) throws SyncException { + try { + if (valueAsTree) + return mapper.writeValueAsBytes(value); + else + return valueWriter.writeValueAsBytes(value); + } catch (Exception e) { + throw new SerializationException(e); + } + } + + @SuppressWarnings("unchecked") + private V getValueObject(byte[] value) throws SyncException { + try { + if (value == null) return null; + if (valueAsTree) + return (V)mapper.readTree(value); + else + return valueReader.readValue(value); + } catch (Exception e) { + throw new SerializationException(e); + } + } + + @SuppressWarnings("unchecked") + private K getKeyObject(ByteArray key) throws SyncException { + try { + if (keyAsTree) + return (K)mapper.readTree(key.get()); + else + return keyReader.readValue(key.get()); + } catch (Exception e) { + throw new SerializationException(e); + } + } + + private List<Versioned<V>> convertValues(List<Versioned<byte[]>> values) + throws SyncException { + if (values != null) { + List<Versioned<V>> objectvalues = + new ArrayList<Versioned<V>>(values.size()); + for (Versioned<byte[]> vb : values) { + objectvalues.add(new Versioned<V>(getValueObject(vb.getValue()), + vb.getVersion())); + } + return objectvalues; + } + return null; + } + + private class JacksonIterator implements + IClosableIterator<Entry<K, List<Versioned<V>>>> { + + IClosableIterator<Entry<ByteArray, List<Versioned<byte[]>>>> delegate; + + public JacksonIterator(IClosableIterator<Entry<ByteArray, + List<Versioned<byte[]>>>> delegate) { + super(); + this.delegate = delegate; + } + + @Override + public boolean hasNext() { + return delegate.hasNext(); + } + + @Override + public Entry<K, List<Versioned<V>>> next() { + Entry<ByteArray, List<Versioned<byte[]>>> n = delegate.next(); + try { + return new Pair<K, List<Versioned<V>>>(getKeyObject(n.getKey()), + convertValues(n.getValue())); + } catch (SyncException e) { + throw new SyncRuntimeException("Failed to construct next value", + e); + } + } + + @Override + public void remove() { + delegate.remove(); + } + + @Override + public void close() { + delegate.close(); + } + + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/JavaDBStorageEngine.java b/src/main/java/org/sdnplatform/sync/internal/store/JavaDBStorageEngine.java new file mode 100644 index 0000000000000000000000000000000000000000..d05393406aebcb106854c863200a99966011397e --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/JavaDBStorageEngine.java @@ -0,0 +1,505 @@ +package org.sdnplatform.sync.internal.store; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +import javax.sql.ConnectionPoolDataSource; +import org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource40; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.IVersion.Occurred; +import org.sdnplatform.sync.error.ObsoleteVersionException; +import org.sdnplatform.sync.error.PersistException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.SyncRuntimeException; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.util.EmptyClosableIterator; +import org.sdnplatform.sync.internal.util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.smile.SmileFactory; + +/** + * Persistent storage engine that keeps its data in a JDB database + * @author readams + */ +public class JavaDBStorageEngine implements IStorageEngine<ByteArray, byte[]> { + protected static final Logger logger = + LoggerFactory.getLogger(JavaDBStorageEngine.class.getName()); + + private static String CREATE_DATA_TABLE = + " (datakey varchar(4096) primary key," + + "datavalue blob)"; + private static String SELECT_ALL = + "select * from <tbl>"; + private static String SELECT_KEY = + "select * from <tbl> where datakey = ?"; + private static String INSERT_KEY = + "insert into <tbl> values (?, ?)"; + private static String UPDATE_KEY = + "update <tbl> set datavalue = ? where datakey = ?"; + private static String DELETE_KEY = + "delete from <tbl> where datakey = ?"; + private static String TRUNCATE = + "delete from <tbl>"; + + private String name; + + private ConnectionPoolDataSource dataSource; + + /** + * Interval in milliseconds before tombstones will be cleared. + */ + private int tombstoneDeletion = 24 * 60 * 60 * 1000; + + private static final ObjectMapper mapper = + new ObjectMapper(new SmileFactory()); + { + System.setProperty("derby.stream.error.method", + DerbySlf4jBridge.getBridgeMethod()); + } + + /** + * Construct a new storage engine that will use the provided engine + * as a delegate and provide persistence for its data. Note that + * the delegate engine must be empty when this object is constructed + * @param delegate the delegate engine to persist + * @throws SyncException + */ + public JavaDBStorageEngine(String name, + ConnectionPoolDataSource dataSource) + throws PersistException { + super(); + + this.name = name; + this.dataSource = dataSource; + + try { + initTable(); + } catch (SQLException sqle) { + throw new PersistException("Could not initialize persistent storage", + sqle); + } + } + + // ******************************* + // StorageEngine<ByteArray,byte[]> + // ******************************* + + @Override + public List<Versioned<byte[]>> get(ByteArray key) throws SyncException { + StoreUtils.assertValidKey(key); + Connection dbConnection = null; + PreparedStatement stmt = null; + try { + dbConnection = getConnection(); + stmt = dbConnection.prepareStatement(getSql(SELECT_KEY)); + return doSelect(stmt, getKeyAsString(key)); + + } catch (Exception e) { + throw new PersistException("Could not retrieve key" + + " from database", + e); + } finally { + cleanupSQL(dbConnection, stmt); + } + } + + @Override + public IClosableIterator<Entry<ByteArray, List<Versioned<byte[]>>>> + entries() { + PreparedStatement stmt = null; + Connection dbConnection = null; + try { + // we never close this connection unless there's an error; + // it must be closed by the DbIterator + dbConnection = getConnection(); + stmt = dbConnection.prepareStatement(getSql(SELECT_ALL)); + ResultSet rs = stmt.executeQuery(); + return new DbIterator(dbConnection, stmt, rs); + } catch (Exception e) { + logger.error("Could not create iterator on data", e); + try { + cleanupSQL(dbConnection, stmt); + } catch (Exception e2) { + logger.error("Failed to clean up after error", e2); + } + return new EmptyClosableIterator<Entry<ByteArray,List<Versioned<byte[]>>>>(); + } + } + + @Override + public void put(ByteArray key, Versioned<byte[]> value) + throws SyncException { + StoreUtils.assertValidKey(key); + Connection dbConnection = null; + try { + PreparedStatement stmt = null; + PreparedStatement update = null; + try { + String keyStr = getKeyAsString(key); + dbConnection = getConnection(); + dbConnection.setAutoCommit(false); + stmt = dbConnection.prepareStatement(getSql(SELECT_KEY)); + List<Versioned<byte[]>> values = doSelect(stmt, keyStr); + + int vindex; + if (values.size() > 0) { + update = dbConnection.prepareStatement(getSql(UPDATE_KEY)); + update.setString(2, keyStr); + vindex = 1; + } else { + update = dbConnection.prepareStatement(getSql(INSERT_KEY)); + update.setString(1, keyStr); + vindex = 2; + } + + List<Versioned<byte[]>> itemsToRemove = + new ArrayList<Versioned<byte[]>>(values.size()); + for(Versioned<byte[]> versioned: values) { + Occurred occurred = value.getVersion().compare(versioned.getVersion()); + if(occurred == Occurred.BEFORE) { + throw new ObsoleteVersionException("Obsolete version for key '" + key + + "': " + value.getVersion()); + } else if(occurred == Occurred.AFTER) { + itemsToRemove.add(versioned); + } + } + values.removeAll(itemsToRemove); + values.add(value); + + ByteArrayInputStream is = + new ByteArrayInputStream(mapper.writeValueAsBytes(values)); + update.setBinaryStream(vindex, is); + update.execute(); + dbConnection.commit(); + } catch (SyncException e) { + dbConnection.rollback(); + throw e; + } catch (Exception e) { + dbConnection.rollback(); + throw new PersistException("Could not retrieve key from database", + e); + } finally { + cleanupSQL(dbConnection, stmt, update); + } + } catch (SQLException e) { + cleanupSQL(dbConnection); + throw new PersistException("Could not clean up", e); + } + } + + @Override + public IClosableIterator<ByteArray> keys() { + return StoreUtils.keys(entries()); + } + + @Override + public void truncate() throws SyncException { + Connection dbConnection = null; + PreparedStatement update = null; + try { + dbConnection = getConnection(); + update = dbConnection.prepareStatement(getSql(TRUNCATE)); + update.execute(); + } catch (Exception e) { + logger.error("Failed to truncate store " + getName(), e); + } finally { + cleanupSQL(dbConnection, update); + } + } + + @Override + public String getName() { + return name; + } + + @Override + public void close() throws SyncException { + + } + + @Override + public boolean writeSyncValue(ByteArray key, + Iterable<Versioned<byte[]>> values) { + boolean success = false; + for (Versioned<byte[]> value : values) { + try { + put (key, value); + success = true; + } catch (PersistException e) { + logger.error("Failed to sync value because of " + + "persistence exception", e); + } catch (SyncException e) { + // ignore obsolete version exception + } + } + return success; + } + + @Override + public List<IVersion> getVersions(ByteArray key) throws SyncException { + return StoreUtils.getVersions(get(key)); + } + + @Override + public void cleanupTask() throws SyncException { + Connection dbConnection = null; + PreparedStatement stmt = null; + try { + dbConnection = getConnection(); + dbConnection.setAutoCommit(true); + stmt = dbConnection.prepareStatement(getSql(SELECT_ALL)); + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + List<Versioned<byte[]>> items = getVersionedList(rs); + if (StoreUtils.canDelete(items, tombstoneDeletion)) { + doClearTombstone(rs.getString("datakey")); + } + } + } catch (Exception e) { + logger.error("Failed to delete key", e); + } finally { + cleanupSQL(dbConnection, stmt); + } + } + + @Override + public boolean isPersistent() { + return true; + } + + @Override + public void setTombstoneInterval(int interval) { + this.tombstoneDeletion = interval; + } + + // ******************* + // JavaDBStorageEngine + // ******************* + + /** + * Get a connection pool data source for use by Java DB storage engines + * @param memory whether to actually use a memory database + * @return the {@link ConnectionPoolDataSource} + */ + public static ConnectionPoolDataSource getDataSource(boolean memory) { + + EmbeddedConnectionPoolDataSource40 ds = + new EmbeddedConnectionPoolDataSource40(); + if (memory) { + ds.setDatabaseName("memory:SyncDB"); + } else { + ds.setDatabaseName("SyncDB"); + } + ds.setCreateDatabase("create"); + ds.setUser("floodlight"); + ds.setPassword("floodlight"); + return ds; + } + + // ************* + // Local methods + // ************* + + private static void cleanupSQL(Connection dbConnection) + throws SyncException { + cleanupSQL(dbConnection, (PreparedStatement[])null); + } + + private static void cleanupSQL(Connection dbConnection, + PreparedStatement... stmts) + throws SyncException { + try { + if (stmts != null) { + for (PreparedStatement stmt : stmts) { + if (stmt != null) + stmt.close(); + } + } + } catch (SQLException e) { + throw new PersistException("Could not close statement", e); + } finally { + try { + if (dbConnection != null && !dbConnection.isClosed()) + dbConnection.close(); + } catch (SQLException e) { + throw new PersistException("Could not close connection", e); + } + } + } + + private Connection getConnection() throws SQLException { + Connection conn = dataSource.getPooledConnection().getConnection(); + conn.setTransactionIsolation(Connection. + TRANSACTION_READ_COMMITTED); + return conn; + } + + private void initTable() throws SQLException { + Connection dbConnection = getConnection(); + Statement statement = null; + statement = dbConnection.createStatement(); + try { + statement.execute("CREATE TABLE " + getName() + + CREATE_DATA_TABLE); + } catch (SQLException e) { + // eat table already exists exception + if (!"X0Y32".equals(e.getSQLState())) + throw e; + } finally { + if (statement != null) statement.close(); + dbConnection.close(); + } + } + + private String getKeyAsString(ByteArray key) + throws UnsupportedEncodingException { + return new String(key.get(), "UTF8"); + } + + private static ByteArray getStringAsKey(String keyStr) + throws UnsupportedEncodingException { + return new ByteArray(keyStr.getBytes("UTF8")); + } + + private String getSql(String sql) { + return sql.replace("<tbl>", getName()); + } + + private static List<Versioned<byte[]>> getVersionedList(ResultSet rs) + throws SQLException, JsonParseException, + JsonMappingException, IOException { + InputStream is = rs.getBinaryStream("datavalue"); + return mapper.readValue(is, + new TypeReference<List<VCVersioned<byte[]>>>() {}); + } + + private List<Versioned<byte[]>> doSelect(PreparedStatement stmt, + String key) + throws SQLException, JsonParseException, + JsonMappingException, IOException { + stmt.setString(1, key); + ResultSet rs = stmt.executeQuery(); + + if (rs.next()) { + return getVersionedList(rs); + } else { + return new ArrayList<Versioned<byte[]>>(0); + } + } + + private void doClearTombstone(String keyStr) throws SyncException { + Connection dbConnection = null; + try { + PreparedStatement stmt = null; + PreparedStatement update = null; + try { + dbConnection = getConnection(); + dbConnection.setAutoCommit(false); + stmt = dbConnection.prepareStatement(getSql(SELECT_KEY)); + List<Versioned<byte[]>> items = doSelect(stmt, keyStr); + if (StoreUtils.canDelete(items, tombstoneDeletion)) { + update = dbConnection.prepareStatement(getSql(DELETE_KEY)); + update.setString(1, keyStr); + update.execute(); + } + dbConnection.commit(); + + } catch (Exception e) { + if (dbConnection != null) + dbConnection.rollback(); + logger.error("Failed to delete key", e); + } finally { + cleanupSQL(dbConnection, stmt, update); + } + } catch (SQLException e) { + logger.error("Failed to clean up after error", e); + cleanupSQL(dbConnection); + } + } + + private static class DbIterator implements + IClosableIterator<Entry<ByteArray,List<Versioned<byte[]>>>> { + + private final Connection dbConnection; + private final PreparedStatement stmt; + private final ResultSet rs; + private boolean hasNext = false; + private boolean hasNextSet = false; + + public DbIterator(Connection dbConnection, + PreparedStatement stmt, + ResultSet rs) { + super(); + this.dbConnection = dbConnection; + this.stmt = stmt; + this.rs = rs; + } + + @Override + public boolean hasNext() { + try { + if (hasNextSet) return hasNext; + hasNextSet = true; + hasNext = rs.next(); + } catch (Exception e) { + logger.error("Error in DB Iterator", e); + hasNextSet = true; + hasNext = false; + } + return hasNext; + } + + @Override + public Pair<ByteArray, List<Versioned<byte[]>>> next() { + if (hasNext()) { + try { + ByteArray key = getStringAsKey(rs.getString("datakey")); + List<Versioned<byte[]>> vlist = getVersionedList(rs); + hasNextSet = false; + return new Pair<ByteArray, + List<Versioned<byte[]>>>(key, vlist); + } catch (Exception e) { + throw new SyncRuntimeException("Error in DB Iterator", + new PersistException(e)); + } + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + try { + cleanupSQL(dbConnection, stmt); + } catch (SyncException e) { + logger.error("Could not close DB iterator", e); + } + } + + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/ListenerStorageEngine.java b/src/main/java/org/sdnplatform/sync/internal/store/ListenerStorageEngine.java new file mode 100644 index 0000000000000000000000000000000000000000..56ced90b80300c668e2bc40114ac64722f5b2062 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/ListenerStorageEngine.java @@ -0,0 +1,151 @@ +package org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import net.floodlightcontroller.debugcounter.IDebugCounterService; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.IStoreListener.UpdateType; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.util.ByteArray; + + +/** + * A storage engine that proxies to another storage engine and notifies + * registered listeners of changes + * @author readams + */ +public class ListenerStorageEngine + implements IStorageEngine<ByteArray, byte[]> { + + /** + * Listeners for this store + */ + protected List<MappingStoreListener> listeners = + new ArrayList<MappingStoreListener>(); + + /** + * The local storage for this storage engine + */ + protected IStorageEngine<ByteArray, byte[]> localStorage; + + /** + * Debug counter service + */ + protected IDebugCounterService debugCounter; + + /** + * Allocate new {@link ListenerStorageEngine} + * @param localStorage the delegate store + * @param debugCounter debug counter service + */ + public ListenerStorageEngine(IStorageEngine<ByteArray, + byte[]> localStorage, + IDebugCounterService debugCounter) { + this.localStorage = localStorage; + this.debugCounter = debugCounter; + } + + // ************************* + // StorageEngine<Key,byte[]> + // ************************* + + @Override + public List<Versioned<byte[]>> get(ByteArray key) throws SyncException { + updateCounter(SyncManager.COUNTER_GETS); + return localStorage.get(key); + } + + @Override + public IClosableIterator<Entry<ByteArray,List<Versioned<byte[]>>>> entries() { + updateCounter(SyncManager.COUNTER_ITERATORS); + return localStorage.entries(); + } + + @Override + public void put(ByteArray key, Versioned<byte[]> value) + throws SyncException { + updateCounter(SyncManager.COUNTER_PUTS); + localStorage.put(key, value); + notifyListeners(key, UpdateType.LOCAL); + } + + @Override + public IClosableIterator<ByteArray> keys() { + return localStorage.keys(); + } + + @Override + public void truncate() throws SyncException { + localStorage.truncate(); + } + + @Override + public String getName() { + return localStorage.getName(); + } + + @Override + public void close() throws SyncException { + localStorage.close(); + } + + @Override + public List<IVersion> getVersions(ByteArray key) throws SyncException { + return localStorage.getVersions(key); + } + + @Override + public boolean writeSyncValue(ByteArray key, + Iterable<Versioned<byte[]>> values) { + boolean r = localStorage.writeSyncValue(key, values); + if (r) notifyListeners(key, UpdateType.REMOTE); + return r; + } + + @Override + public void cleanupTask() throws SyncException { + localStorage.cleanupTask(); + } + + @Override + public boolean isPersistent() { + return localStorage.isPersistent(); + } + + @Override + public void setTombstoneInterval(int interval) { + localStorage.setTombstoneInterval(interval); + } + + // ********************* + // ListenerStorageEngine + // ********************* + + public void addListener(MappingStoreListener listener) { + listeners.add(listener); + } + + protected void notifyListeners(ByteArray key, UpdateType type) { + notifyListeners(Collections.singleton(key).iterator(), type); + } + + protected void notifyListeners(Iterator<ByteArray> keys, UpdateType type) { + for (MappingStoreListener msl : listeners) { + msl.notify(keys, type); + } + } + + protected void updateCounter(String counterName) { + if (debugCounter != null) { + debugCounter.updateCounter(counterName); + } + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/MappingStoreListener.java b/src/main/java/org/sdnplatform/sync/internal/store/MappingStoreListener.java new file mode 100644 index 0000000000000000000000000000000000000000..920c60f421e783689d6424e699bbef8d4f68ff3b --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/MappingStoreListener.java @@ -0,0 +1,90 @@ +package org.sdnplatform.sync.internal.store; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.sdnplatform.sync.IStoreListener; +import org.sdnplatform.sync.IStoreListener.UpdateType; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; + +/** + * A class that will map from the raw serialized keys to the appropriate key + * type for a store listener + * @author readams + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class MappingStoreListener { + protected static Logger logger = + LoggerFactory.getLogger(MappingStoreListener.class); + + TypeReference typeRef; + Class keyClass; + IStoreListener listener; + + public MappingStoreListener(TypeReference typeRef, Class keyClass, + IStoreListener listener) { + super(); + this.typeRef = typeRef; + this.keyClass = keyClass; + this.listener = listener; + } + + public void notify(Iterator<ByteArray> keys, UpdateType type) { + listener.keysModified(new MappingIterator(keys), type); + } + + class MappingIterator implements Iterator { + Iterator<ByteArray> keys; + protected Object next; + + public MappingIterator(Iterator<ByteArray> keys) { + super(); + this.keys = keys; + } + + private Object map() { + try { + ByteArray ka = keys.next(); + Object key = null; + if (typeRef != null) + key = JacksonStore.mapper.readValue(ka.get(), typeRef); + else if (keyClass != null) + key = JacksonStore.mapper.readValue(ka.get(), keyClass); + + return key; + } catch (Exception e) { + return null; + } + } + + @Override + public boolean hasNext() { + if (next != null) return true; + while (keys.hasNext()) { + next = map(); + if (next != null) return true; + } + return false; + } + + @Override + public Object next() { + if (hasNext()) { + Object cur = next; + next = null; + return cur; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/StoreUtils.java b/src/main/java/org/sdnplatform/sync/internal/store/StoreUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..7b92dade96666ff6ae0b145eaf41d5b36d34c043 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/StoreUtils.java @@ -0,0 +1,177 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.store; + +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.IVersion.Occurred; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.version.VectorClock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +/** + * Group of store utilities + * + */ +public class StoreUtils { + protected static final Logger logger = + LoggerFactory.getLogger(StoreUtils.class); + + public static void assertValidKeys(Iterable<?> keys) { + if(keys == null) + throw new IllegalArgumentException("Keys cannot be null."); + for(Object key: keys) + assertValidKey(key); + } + + public static <K> void assertValidKey(K key) { + if(key == null) + throw new IllegalArgumentException("Key cannot be null."); + } + + /** + * Implements getAll by delegating to get. + * @throws SyncException + */ + public static <K, V> Map<K, List<Versioned<V>>> + getAll(IStore<K, V> storageEngine, + Iterable<K> keys) throws SyncException { + Map<K, List<Versioned<V>>> result = newEmptyHashMap(keys); + for(K key: keys) { + List<Versioned<V>> value = + storageEngine.get(key); + if(!value.isEmpty()) + result.put(key, value); + } + return result; + } + + /** + * Returns an empty map with expected size matching the iterable size if + * it's of type Collection. Otherwise, an empty map with the default size is + * returned. + */ + public static <K, V> HashMap<K, V> newEmptyHashMap(Iterable<?> iterable) { + if(iterable instanceof Collection<?>) + return Maps.newHashMapWithExpectedSize(((Collection<?>) iterable).size()); + return Maps.newHashMap(); + } + + /** + * Closes a Closeable and logs a potential error instead of re-throwing the + * exception. If {@code null} is passed, this method is a no-op. + * + * This is typically used in finally blocks to prevent an exception thrown + * during close from hiding an exception thrown inside the try. + * + * @param c The Closeable to close, may be null. + */ + public static void close(Closeable c) { + if(c != null) { + try { + c.close(); + } catch(IOException e) { + logger.error("Error closing stream", e); + } + } + } + + + public static <V> List<IVersion> getVersions(List<Versioned<V>> versioneds) { + List<IVersion> versions = Lists.newArrayListWithCapacity(versioneds.size()); + for(Versioned<?> versioned: versioneds) + versions.add(versioned.getVersion()); + return versions; + } + + public static <K, V> IClosableIterator<K> + keys(final IClosableIterator<Entry<K, V>> values) { + return new IClosableIterator<K>() { + + public void close() { + values.close(); + } + + public boolean hasNext() { + return values.hasNext(); + } + + public K next() { + Entry<K, V> value = values.next(); + if(value == null) + return null; + return value.getKey(); + } + + public void remove() { + values.remove(); + } + + }; + } + + public static <V> boolean canDelete(List<Versioned<V>> items, + long tombstoneDeletion) { + List<VectorClock> tombstones = new ArrayList<VectorClock>(); + long now = System.currentTimeMillis(); + // make two passes; first we find tombstones that are old enough. + for (Versioned<V> v : items) { + if (v.getValue() == null) { + VectorClock vc = (VectorClock)v.getVersion(); + if ((vc.getTimestamp() + tombstoneDeletion) < now) + tombstones.add(vc); + } + } + + // second, if we find a tombstone which is later than every + // non-tombstone value, then we can delete the key. + for (VectorClock vc : tombstones) { + boolean later = true; + for (Versioned<V> v : items) { + if (v.getValue() != null) { + VectorClock curvc = (VectorClock)v.getVersion(); + if (!Occurred.AFTER.equals(vc.compare(curvc))) { + later = false; + break; + } + } + } + if (later) { + // we found a tombstone that's old enough and + // logically later than all non-tombstones. We can + // remove the value from the map. + return true; + } + } + + return false; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/SynchronizingStorageEngine.java b/src/main/java/org/sdnplatform/sync/internal/store/SynchronizingStorageEngine.java new file mode 100644 index 0000000000000000000000000000000000000000..689911e547b05df925bfef804ddb15c506532333 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/SynchronizingStorageEngine.java @@ -0,0 +1,75 @@ +package org.sdnplatform.sync.internal.store; + +import net.floodlightcontroller.debugcounter.IDebugCounterService; + +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * This storage engine will asynchronously replicate its data to the other + * nodes in the cluster based on the scope of the s + */ +public class SynchronizingStorageEngine extends ListenerStorageEngine { + + protected static Logger logger = + LoggerFactory.getLogger(SynchronizingStorageEngine.class); + + /** + * The synchronization manager + */ + protected SyncManager syncManager; + + /** + * The scope of distribution for data in this store + */ + protected Scope scope; + + /** + * Allocate a synchronizing storage engine + * @param localStorage the local storage + * @param syncManager the sync manager + * @param debugCounter the debug counter service + * @param scope the scope for this store + * @param rpcService the RPC service + * @param storeName the name of the store + */ + public SynchronizingStorageEngine(IStorageEngine<ByteArray, + byte[]> localStorage, + SyncManager syncManager, + IDebugCounterService debugCounter, + Scope scope) { + super(localStorage, debugCounter); + this.localStorage = localStorage; + this.syncManager = syncManager; + this.scope = scope; + } + + // ************************* + // StorageEngine<Key,byte[]> + // ************************* + + @Override + public void put(ByteArray key, Versioned<byte[]> value) + throws SyncException { + super.put(key, value); + syncManager.queueSyncTask(this, key, value); + } + + // ************** + // Public methods + // ************** + + /** + * Get the scope for this store + * @return + */ + public Scope getScope() { + return scope; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/store/VCVersioned.java b/src/main/java/org/sdnplatform/sync/internal/store/VCVersioned.java new file mode 100644 index 0000000000000000000000000000000000000000..4861892bc7004416a5384eca71f74fc8dbc05e43 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/store/VCVersioned.java @@ -0,0 +1,23 @@ +package org.sdnplatform.sync.internal.store; + +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.internal.version.VectorClock; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + + +public final class VCVersioned<T> extends Versioned<T> { + + private static final long serialVersionUID = 8038484251323965062L; + + public VCVersioned(T object) { + super(object); + } + + @JsonCreator + public VCVersioned(@JsonProperty("object") T object, + @JsonProperty("version") VectorClock version) { + super(object, version); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/util/ByteArray.java b/src/main/java/org/sdnplatform/sync/internal/util/ByteArray.java new file mode 100644 index 0000000000000000000000000000000000000000..5a9473562e4d226fb7e8f5f22e805074bcd90129 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/util/ByteArray.java @@ -0,0 +1,65 @@ +package org.sdnplatform.sync.internal.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; + +import org.openflow.util.HexString; + +/** + * A byte array container that provides an equals and hashCode pair based on the + * contents of the byte array. This is useful as a key for Maps. + */ +public final class ByteArray implements Serializable { + + private static final long serialVersionUID = 1L; + + public static final ByteArray EMPTY = new ByteArray(); + + private final byte[] underlying; + + public ByteArray(byte... underlying) { + this.underlying = underlying; + } + + public byte[] get() { + return underlying; + } + + @Override + public int hashCode() { + return Arrays.hashCode(underlying); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) + return true; + if(!(obj instanceof ByteArray)) + return false; + ByteArray other = (ByteArray) obj; + return Arrays.equals(underlying, other.underlying); + } + + @Override + public String toString() { + return Arrays.toString(underlying); + } + + /** + * Translate the each ByteArray in an iterable into a hexidecimal string + * + * @param arrays The array of bytes to translate + * @return An iterable of converted strings + */ + public static Iterable<String> toHexStrings(Iterable<ByteArray> arrays) { + ArrayList<String> ret = new ArrayList<String>(); + for(ByteArray array: arrays) + ret.add(HexString.toHexString(array.get())); + return ret; + } + + public int length() { + return underlying.length; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/util/EmptyClosableIterator.java b/src/main/java/org/sdnplatform/sync/internal/util/EmptyClosableIterator.java new file mode 100644 index 0000000000000000000000000000000000000000..55554db9297d60bb3aec00bedd9b86218cce6bcd --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/util/EmptyClosableIterator.java @@ -0,0 +1,26 @@ +package org.sdnplatform.sync.internal.util; + +import java.util.NoSuchElementException; + +import org.sdnplatform.sync.IClosableIterator; + + +public class EmptyClosableIterator<T> implements IClosableIterator<T> { + + public boolean hasNext() { + return false; + } + + public T next() { + throw new NoSuchElementException(); + } + + public void remove() { + throw new NoSuchElementException(); + } + + @Override + public void close() { + // no-op + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/util/Pair.java b/src/main/java/org/sdnplatform/sync/internal/util/Pair.java new file mode 100644 index 0000000000000000000000000000000000000000..db78f6dc4812b98715a864102d14760c54b63dde --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/util/Pair.java @@ -0,0 +1,113 @@ +package org.sdnplatform.sync.internal.util; + +import java.io.Serializable; +import java.util.Map.Entry; + +import com.google.common.base.Function; +import com.google.common.base.Objects; + +/** + * Represents a pair of items. + */ +public class Pair<F, S> implements Serializable, Function<F, S>, + Entry<F, S> { + + private static final long serialVersionUID = 1L; + + private final F first; + + private final S second; + + /** + * Static factory method that, unlike the constructor, performs generic + * inference saving some typing. Use in the following way (for a pair of + * Strings): + * + * <p> + * <code> + * Pair<String, String> pair = Pair.create("first", "second"); + * </code> + * </p> + * + * @param <F> The type of the first thing. + * @param <S> The type of the second thing + * @param first The first thing + * @param second The second thing + * @return The pair (first,second) + */ + public static final <F, S> Pair<F, S> create(F first, S second) { + return new Pair<F, S>(first, second); + } + + /** + * Use the static factory method {@link #create(Object, Object)} instead of + * this where possible. + * + * @param first + * @param second + */ + public Pair(F first, S second) { + this.first = first; + this.second = second; + } + + public S apply(F from) { + if(from == null ? first == null : from.equals(first)) + return second; + return null; + } + + public final F getFirst() { + return first; + } + + public final S getSecond() { + return second; + } + + @Override + public final int hashCode() { + final int PRIME = 31; + int result = 1; + result = PRIME * result + ((first == null) ? 0 : first.hashCode()); + result = PRIME * result + ((second == null) ? 0 : second.hashCode()); + return result; + } + + @Override + public final boolean equals(Object obj) { + if(this == obj) + return true; + if(!(obj instanceof Pair<?, ?>)) + return false; + + final Pair<?, ?> other = (Pair<?, ?>) (obj); + return Objects.equal(first, other.first) && Objects.equal(second, other.second); + } + + @Override + public final String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("[ " + first + ", " + second + " ]"); + return builder.toString(); + } + + // ***** + // Entry + // ***** + + @Override + public F getKey() { + return getFirst(); + } + + @Override + public S getValue() { + return getSecond(); + } + + @Override + public S setValue(S value) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/version/ChainedResolver.java b/src/main/java/org/sdnplatform/sync/internal/version/ChainedResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..a3b98d93fe197f842a6988ccd09497eac9d9df2f --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/version/ChainedResolver.java @@ -0,0 +1,73 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.version; + +import java.util.ArrayList; +import java.util.List; + +import org.sdnplatform.sync.IInconsistencyResolver; + + +/** + * Apply the given inconsistency resolvers in order until there are 1 or fewer + * items left. + * + * + */ +public class ChainedResolver<T> implements IInconsistencyResolver<T> { + + private List<IInconsistencyResolver<T>> resolvers; + + public ChainedResolver(IInconsistencyResolver<T>... resolvers) { + this.resolvers = new ArrayList<IInconsistencyResolver<T>>(resolvers.length); + for(IInconsistencyResolver<T> resolver: resolvers) + this.resolvers.add(resolver); + } + + public List<T> resolveConflicts(List<T> items) { + for(IInconsistencyResolver<T> resolver: resolvers) { + if(items.size() <= 1) + return items; + else + items = resolver.resolveConflicts(items); + } + + return items; + } + + @Override + public boolean equals(Object o) { + if(this == o) + return true; + if(o == null || getClass() != o.getClass()) + return false; + + ChainedResolver<?> that = (ChainedResolver<?>) o; + + if(resolvers != null + ? !resolvers.equals(that.resolvers) + : that.resolvers != null) + return false; + + return true; + } + + @Override + public int hashCode() { + return resolvers != null ? resolvers.hashCode() : 0; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/version/ClockEntry.java b/src/main/java/org/sdnplatform/sync/internal/version/ClockEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..058a1cacd7658aa26f0f9ee486188790e1205c64 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/version/ClockEntry.java @@ -0,0 +1,105 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.internal.version; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * An entry element for a vector clock versioning scheme This assigns the + * version from a specific machine, the VectorClock keeps track of the complete + * system version, which will consist of many individual Version objects. + * + * + */ +public final class ClockEntry + implements Cloneable, Serializable { + + private static final long serialVersionUID = -759862327985468981L; + + private final short nodeId; + private final long version; + + /** + * Create a new Version from constituate parts + * + * @param nodeId The node id + * @param version The current version + */ + @JsonCreator + public ClockEntry(@JsonProperty("nodeId") short nodeId, + @JsonProperty("version") long version) { + if(nodeId < 0) + throw new IllegalArgumentException("Node id " + nodeId + " is not in the range (0, " + + Short.MAX_VALUE + ")."); + if(version < 1) + throw new IllegalArgumentException("Version " + version + " is not in the range (1, " + + Short.MAX_VALUE + ")."); + this.nodeId = nodeId; + this.version = version; + } + + @Override + public ClockEntry clone() { + try { + return (ClockEntry) super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + public short getNodeId() { + return nodeId; + } + + public long getVersion() { + return version; + } + + public ClockEntry incremented() { + return new ClockEntry(nodeId, version + 1); + } + + @Override + public int hashCode() { + return nodeId + (((int) version) << 16); + } + + @Override + public boolean equals(Object o) { + if(this == o) + return true; + + if(o == null) + return false; + + if(o.getClass().equals(ClockEntry.class)) { + ClockEntry v = (ClockEntry) o; + return v.getNodeId() == getNodeId() && v.getVersion() == getVersion(); + } else { + return false; + } + } + + @Override + public String toString() { + return nodeId + ":" + version; + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/version/TimeBasedInconsistencyResolver.java b/src/main/java/org/sdnplatform/sync/internal/version/TimeBasedInconsistencyResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..75b0c80530dc8d242eb3c76dba7fab9bf39391f3 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/version/TimeBasedInconsistencyResolver.java @@ -0,0 +1,68 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.internal.version; + +import java.util.Collections; +import java.util.List; + +import org.sdnplatform.sync.IInconsistencyResolver; +import org.sdnplatform.sync.Versioned; + + +/** + * Resolve inconsistencies based on timestamp in the vector clock + * @param <T> The type f the versioned object + */ +public class TimeBasedInconsistencyResolver<T> + implements IInconsistencyResolver<Versioned<T>> { + + public List<Versioned<T>> resolveConflicts(List<Versioned<T>> items) { + if(items.size() <= 1) { + return items; + } else { + Versioned<T> max = items.get(0); + long maxTime = + ((VectorClock) items.get(0).getVersion()).getTimestamp(); + VectorClock maxClock = ((VectorClock) items.get(0).getVersion()); + for(Versioned<T> versioned: items) { + VectorClock clock = (VectorClock) versioned.getVersion(); + if(clock.getTimestamp() > maxTime) { + max = versioned; + maxTime = ((VectorClock) versioned.getVersion()). + getTimestamp(); + } + maxClock = maxClock.merge(clock); + } + Versioned<T> maxTimeClockVersioned = + new Versioned<T>(max.getValue(), maxClock); + return Collections.singletonList(maxTimeClockVersioned); + } + } + + @Override + public boolean equals(Object o) { + if(this == o) + return true; + return (o != null && getClass() == o.getClass()); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/version/VectorClock.java b/src/main/java/org/sdnplatform/sync/internal/version/VectorClock.java new file mode 100644 index 0000000000000000000000000000000000000000..7ad1b5bf3dff01fb03d8f75d9fe6a2373185fcf2 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/version/VectorClock.java @@ -0,0 +1,278 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.internal.version; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.sdnplatform.sync.IVersion; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +import com.google.common.collect.Lists; + +/** + * A vector of the number of writes mastered by each node. The vector is stored + * sparely, since, in general, writes will be mastered by only one node. This + * means implicitly all the versions are at zero, but we only actually store + * those greater than zero. + */ +public class VectorClock implements IVersion, Serializable, Cloneable { + + private static final long serialVersionUID = 7663945747147638702L; + + private static final int MAX_NUMBER_OF_VERSIONS = Short.MAX_VALUE; + + /* A sorted list of live versions ordered from least to greatest */ + private final List<ClockEntry> versions; + + /* + * The time of the last update on the server on which the update was + * performed + */ + private final long timestamp; + + /** + * Construct an empty VectorClock + */ + public VectorClock() { + this(new ArrayList<ClockEntry>(0), System.currentTimeMillis()); + } + + public VectorClock(long timestamp) { + this(new ArrayList<ClockEntry>(0), timestamp); + } + + /** + * Create a VectorClock with the given version and timestamp + * + * @param versions The version to prepopulate + * @param timestamp The timestamp to prepopulate + */ + @JsonCreator + public VectorClock(@JsonProperty("entries") List<ClockEntry> versions, + @JsonProperty("timestamp") long timestamp) { + this.versions = versions; + this.timestamp = timestamp; + } + + /** + * Get new vector clock based on this clock but incremented on index nodeId + * + * @param nodeId The id of the node to increment + * @return A vector clock equal on each element execept that indexed by + * nodeId + */ + public VectorClock incremented(int nodeId, long time) { + if(nodeId < 0 || nodeId > Short.MAX_VALUE) + throw new IllegalArgumentException(nodeId + + " is outside the acceptable range of node ids."); + + // stop on the index greater or equal to the node + List<ClockEntry> newversions = Lists.newArrayList(versions); + boolean found = false; + int index = 0; + for(; index < newversions.size(); index++) { + if(newversions.get(index).getNodeId() == nodeId) { + found = true; + break; + } else if(newversions.get(index).getNodeId() > nodeId) { + found = false; + break; + } + } + + if(found) { + newversions.set(index, newversions.get(index).incremented()); + } else if(index < newversions.size() - 1) { + newversions.add(index, new ClockEntry((short) nodeId, 1)); + } else { + // we don't already have a version for this, so add it + if(newversions.size() > MAX_NUMBER_OF_VERSIONS) + throw new IllegalStateException("Vector clock is full!"); + newversions.add(index, new ClockEntry((short) nodeId, 1)); + } + + return new VectorClock(newversions, time); + } + + @Override + public VectorClock clone() { + return new VectorClock(Lists.newArrayList(versions), this.timestamp); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (timestamp ^ (timestamp >>> 32)); + result = prime * result + + ((versions == null) ? 0 : versions.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + VectorClock other = (VectorClock) obj; + if (timestamp != other.timestamp) return false; + if (versions == null) { + if (other.versions != null) return false; + } else if (!versions.equals(other.versions)) return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("version("); + if(this.versions.size() > 0) { + for(int i = 0; i < this.versions.size() - 1; i++) { + builder.append(this.versions.get(i)); + builder.append(", "); + } + builder.append(this.versions.get(this.versions.size() - 1)); + } + builder.append(")"); + builder.append(" ts:" + timestamp); + return builder.toString(); + } + + @JsonIgnore + public long getMaxVersion() { + long max = -1; + for(ClockEntry entry: versions) + max = Math.max(entry.getVersion(), max); + return max; + } + + public VectorClock merge(VectorClock clock) { + VectorClock newClock = new VectorClock(); + int i = 0; + int j = 0; + while(i < this.versions.size() && j < clock.versions.size()) { + ClockEntry v1 = this.versions.get(i); + ClockEntry v2 = clock.versions.get(j); + if(v1.getNodeId() == v2.getNodeId()) { + newClock.versions.add(new ClockEntry(v1.getNodeId(), Math.max(v1.getVersion(), + v2.getVersion()))); + i++; + j++; + } else if(v1.getNodeId() < v2.getNodeId()) { + newClock.versions.add(v1.clone()); + i++; + } else { + newClock.versions.add(v2.clone()); + j++; + } + } + + // Okay now there may be leftovers on one or the other list remaining + for(int k = i; k < this.versions.size(); k++) + newClock.versions.add(this.versions.get(k).clone()); + for(int k = j; k < clock.versions.size(); k++) + newClock.versions.add(clock.versions.get(k).clone()); + + return newClock; + } + + @Override + public Occurred compare(IVersion v) { + if(!(v instanceof VectorClock)) + throw new IllegalArgumentException("Cannot compare Versions of different types."); + + return compare(this, (VectorClock) v); + } + + /** + * Is this Reflexive, AntiSymetic, and Transitive? Compare two VectorClocks, + * the outcomes will be one of the following: -- Clock 1 is BEFORE clock 2 + * if there exists an i such that c1(i) <= c(2) and there does not exist a j + * such that c1(j) > c2(j). -- Clock 1 is CONCURRENT to clock 2 if there + * exists an i, j such that c1(i) < c2(i) and c1(j) > c2(j) -- Clock 1 is + * AFTER clock 2 otherwise + * + * @param v1 The first VectorClock + * @param v2 The second VectorClock + */ + public static Occurred compare(VectorClock v1, VectorClock v2) { + if(v1 == null || v2 == null) + throw new IllegalArgumentException("Can't compare null vector clocks!"); + // We do two checks: v1 <= v2 and v2 <= v1 if both are true then + boolean v1Bigger = false; + boolean v2Bigger = false; + int p1 = 0; + int p2 = 0; + + while(p1 < v1.versions.size() && p2 < v2.versions.size()) { + ClockEntry ver1 = v1.versions.get(p1); + ClockEntry ver2 = v2.versions.get(p2); + if(ver1.getNodeId() == ver2.getNodeId()) { + if(ver1.getVersion() > ver2.getVersion()) + v1Bigger = true; + else if(ver2.getVersion() > ver1.getVersion()) + v2Bigger = true; + p1++; + p2++; + } else if(ver1.getNodeId() > ver2.getNodeId()) { + // since ver1 is bigger that means it is missing a version that + // ver2 has + v2Bigger = true; + p2++; + } else { + // this means ver2 is bigger which means it is missing a version + // ver1 has + v1Bigger = true; + p1++; + } + } + + /* Okay, now check for left overs */ + if(p1 < v1.versions.size()) + v1Bigger = true; + else if(p2 < v2.versions.size()) + v2Bigger = true; + + /* This is the case where they are equal, return BEFORE arbitrarily */ + if(!v1Bigger && !v2Bigger) + return Occurred.BEFORE; + /* This is the case where v1 is a successor clock to v2 */ + else if(v1Bigger && !v2Bigger) + return Occurred.AFTER; + /* This is the case where v2 is a successor clock to v1 */ + else if(!v1Bigger && v2Bigger) + return Occurred.BEFORE; + /* This is the case where both clocks are parallel to one another */ + else + return Occurred.CONCURRENTLY; + } + + public long getTimestamp() { + return this.timestamp; + } + + public List<ClockEntry> getEntries() { + return Collections.unmodifiableList(this.versions); + } +} diff --git a/src/main/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolver.java b/src/main/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..a50779bb27e78e2346a8bdb916412acfc139b979 --- /dev/null +++ b/src/main/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolver.java @@ -0,0 +1,74 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.version; + +import java.util.List; +import java.util.ListIterator; + +import org.sdnplatform.sync.IInconsistencyResolver; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.IVersion.Occurred; + +import com.google.common.collect.Lists; + +/** + * An inconsistency resolver that uses the object VectorClocks leaving only a + * set of concurrent versions remaining. + * + * + */ +public class VectorClockInconsistencyResolver<T> + implements IInconsistencyResolver<Versioned<T>> { + + public List<Versioned<T>> resolveConflicts(List<Versioned<T>> items) { + int size = items.size(); + if(size <= 1) + return items; + + List<Versioned<T>> newItems = Lists.newArrayList(); + for(Versioned<T> v1: items) { + boolean found = false; + for(ListIterator<Versioned<T>> it2 = + newItems.listIterator(); it2.hasNext();) { + Versioned<T> v2 = it2.next(); + Occurred compare = v1.getVersion().compare(v2.getVersion()); + if(compare == Occurred.AFTER) { + if(found) + it2.remove(); + else + it2.set(v1); + } + if(compare != Occurred.CONCURRENTLY) + found = true; + } + if(!found) + newItems.add(v1); + } + return newItems; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + return (o != null && getClass() == o.getClass()); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule index dc38c05b97eed015c76e1f6ea56ae3b1099130be..4f2f68440b700de96a3c5690f857a13dc560b6a4 100644 --- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule +++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule @@ -26,4 +26,6 @@ net.floodlightcontroller.devicemanager.test.MockDeviceManager net.floodlightcontroller.core.test.MockFloodlightProvider net.floodlightcontroller.core.test.MockThreadPoolService net.floodlightcontroller.firewall.Firewall -net.floodlightcontroller.loadbalancer.LoadBalancer \ No newline at end of file +net.floodlightcontroller.loadbalancer.LoadBalancer +org.sdnplatform.sync.internal.SyncManager +org.sdnplatform.sync.internal.SyncTorture diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties index 2d384d3a1b6e39accfcd56839588cbfc1fb9bdbe..620471ab9fb0491700e9980e7f98675942dcd00d 100644 --- a/src/main/resources/floodlightdefault.properties +++ b/src/main/resources/floodlightdefault.properties @@ -15,7 +15,8 @@ net.floodlightcontroller.counter.CounterStore,\ net.floodlightcontroller.debugcounter.DebugCounter,\ net.floodlightcontroller.perfmon.PktInProcessingTime,\ net.floodlightcontroller.ui.web.StaticWebRoutable,\ -net.floodlightcontroller.loadbalancer.LoadBalancer +net.floodlightcontroller.loadbalancer.LoadBalancer,\ +org.sdnplatform.sync.internal.SyncManager net.floodlightcontroller.restserver.RestApiServer.port = 8080 net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633 net.floodlightcontroller.jython.JythonDebugInterface.port = 6655 diff --git a/src/main/thrift/sync.thrift b/src/main/thrift/sync.thrift new file mode 100644 index 0000000000000000000000000000000000000000..f7f766520e772232a7f3debde07f2b1afc4b6153 --- /dev/null +++ b/src/main/thrift/sync.thrift @@ -0,0 +1,218 @@ +# +# Interface definition for sync +# + +namespace java org.sdnplatform.sync.thrift +namespace cpp org.sdnplatform.sync.thrift +namespace py sync +namespace php sync +namespace perl sync + +const string VERSION = "1.0.0" + +# +# data structures +# + +struct ClockEntry { + 1: required i16 nodeId, + 2: required i64 version +} + +struct VectorClock { + 1: optional list<ClockEntry> versions, + 2: optional i64 timestamp +} + +struct VersionedValue { + 1: optional binary value, + 2: required VectorClock version +} + +struct SyncError { + 1: i32 errorCode, + 2: string message +} + +struct KeyedValues { + 1: required binary key, + 2: required list<VersionedValue> values +} + +struct KeyedVersions { + 1: required binary key, + 2: required list<VectorClock> versions +} + +struct AsyncMessageHeader { + 1: optional i32 transactionId, +} + +enum Scope { + GLOBAL = 0 + LOCAL = 1, +} + +struct Store { + 1: required string storeName, + 2: optional Scope scope, + 3: optional bool persist +} + +# +# Protocol messages +# + +enum MessageType { + HELLO = 1, + ERROR = 2, + ECHO_REQUEST = 3, + ECHO_REPLY = 4, + GET_REQUEST = 5, + GET_RESPONSE = 6, + PUT_REQUEST = 7, + PUT_RESPONSE = 8, + DELETE_REQUEST = 9, + DELETE_RESPONSE = 10, + SYNC_VALUE = 11, + SYNC_VALUE_RESPONSE = 12, + SYNC_OFFER = 13, + SYNC_REQUEST = 14, + FULL_SYNC_REQUEST = 15, + CURSOR_REQUEST = 16, + CURSOR_RESPONSE = 17, + REGISTER_REQUEST = 18, + REGISTER_RESPONSE = 19, +} + +struct HelloMessage { + 1: required AsyncMessageHeader header, + 2: optional i16 nodeId, +} + +struct ErrorMessage { + 1: required AsyncMessageHeader header, + 2: optional SyncError error, + 3: optional MessageType type +} + +struct EchoRequestMessage { + 1: required AsyncMessageHeader header +} + +struct EchoReplyMessage { + 1: required AsyncMessageHeader header +} + +struct GetRequestMessage { + 1: required AsyncMessageHeader header + 2: required string storeName, + 3: required binary key +} + +struct GetResponseMessage { + 1: required AsyncMessageHeader header + 2: list<VersionedValue> values, + 3: optional SyncError error +} + +struct PutRequestMessage { + 1: required AsyncMessageHeader header + 2: required string storeName, + 3: required binary key, + 4: optional VersionedValue versionedValue, + 5: optional binary value, +} + +struct PutResponseMessage { + 1: required AsyncMessageHeader header +} + +struct DeleteRequestMessage { + 1: required AsyncMessageHeader header + 2: required string storeName, + 3: required binary key, + 4: optional VectorClock version +} + +struct DeleteResponseMessage { + 1: optional AsyncMessageHeader header, + 2: optional bool deleted +} + +struct SyncValueMessage { + 1: required AsyncMessageHeader header, + 2: required Store store, + 3: list<KeyedValues> values, + 4: optional i32 responseTo +} + +struct SyncValueResponseMessage { + 1: required AsyncMessageHeader header, + 2: optional i32 count +} + +struct SyncOfferMessage { + 1: required AsyncMessageHeader header, + 2: required Store store, + 3: list<KeyedVersions> versions +} + +struct SyncRequestMessage { + 1: required AsyncMessageHeader header, + 2: required Store store, + 3: optional list<binary> keys +} + +struct FullSyncRequestMessage { + 1: required AsyncMessageHeader header, +} + +struct CursorRequestMessage { + 1: required AsyncMessageHeader header, + 2: optional string storeName, + 3: optional i32 cursorId, + 4: optional bool close +} + +struct CursorResponseMessage { + 1: required AsyncMessageHeader header, + 2: required i32 cursorId, + 3: list<KeyedValues> values +} + +struct RegisterRequestMessage { + 1: required AsyncMessageHeader header, + 2: required Store store +} + +struct RegisterResponseMessage { + 1: required AsyncMessageHeader header, +} + +# +# Message wrapper +# + +struct SyncMessage { + 1: required MessageType type, + 2: optional HelloMessage hello, + 3: optional ErrorMessage error, + 4: optional EchoRequestMessage echoRequest, + 5: optional EchoReplyMessage echoReply, + 6: optional GetRequestMessage getRequest, + 7: optional GetResponseMessage getResponse, + 8: optional PutRequestMessage putRequest, + 9: optional PutResponseMessage putResponse, + 10: optional DeleteRequestMessage deleteRequest, + 11: optional DeleteResponseMessage deleteResponse, + 12: optional SyncValueMessage syncValue, + 13: optional SyncValueResponseMessage syncValueResponse, + 14: optional SyncOfferMessage syncOffer, + 15: optional SyncRequestMessage syncRequest, + 16: optional FullSyncRequestMessage fullSyncRequest, + 17: optional CursorRequestMessage cursorRequest, + 18: optional CursorResponseMessage cursorResponse, + 19: optional RegisterRequestMessage registerRequest, + 20: optional RegisterResponseMessage registerResponse +} \ No newline at end of file diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java index e21239ab92dfe01a36bcf349a620ae10a97cec56..e25ba585f9b4281452f3a956d50fbabeb1ef53c7 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java @@ -217,7 +217,7 @@ public class ControllerTest extends FloodlightTestCase byte[] testPacketSerialized = testPacket.serialize(); // Build the PacketIn - OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN)) + OFPacketIn pi = ((OFPacketIn) BasicFactory.getInstance().getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(testPacketSerialized) @@ -425,7 +425,7 @@ public class ControllerTest extends FloodlightTestCase byte[] testPacketSerialized = testPacket.serialize(); // Build the PacketIn - OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN)) + OFPacketIn pi = ((OFPacketIn) BasicFactory.getInstance().getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(testPacketSerialized) @@ -1467,7 +1467,7 @@ public class ControllerTest extends FloodlightTestCase byte[] testPacketSerialized = testPacket.serialize(); // Build the PacketIn - OFPacketIn pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN)) + OFPacketIn pi = ((OFPacketIn) BasicFactory.getInstance().getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(testPacketSerialized) @@ -1662,7 +1662,7 @@ public class ControllerTest extends FloodlightTestCase byte[] testPacketSerialized = testPacket.serialize(); // Build the PacketIn - pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN)) + pi = ((OFPacketIn) BasicFactory.getInstance().getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(testPacketSerialized) diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java index 40d1f7b59671e132d390d36a67979b6142100c6e..7148b472fa58c81cb03f26c22883ed6407dbe31b 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java @@ -62,7 +62,7 @@ public class RoleChangerTest { public void setUp() throws Exception { controller = createMock(Controller.class); roleChanger = new RoleChanger(controller); - BasicFactory factory = new BasicFactory(); + BasicFactory factory = BasicFactory.getInstance(); expect(controller.getOFMessageFactory()).andReturn(factory).anyTimes(); } diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java index 7b5cd6293c1888250299c6352918c610df70733c..78139acfba14f6d2fb61ec8092332be3dfe0ed0c 100644 --- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java +++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java @@ -77,7 +77,7 @@ public class MockFloodlightProvider implements IFloodlightModule, IFloodlightPro switches = new ConcurrentHashMap<Long, IOFSwitch>(); switchListeners = new CopyOnWriteArrayList<IOFSwitchListener>(); haListeners = new CopyOnWriteArrayList<IHAListener>(); - factory = new BasicFactory(); + factory = BasicFactory.getInstance(); } @Override diff --git a/src/test/java/net/floodlightcontroller/core/test/PacketFactory.java b/src/test/java/net/floodlightcontroller/core/test/PacketFactory.java index 99b1ecf2537ccdc80ab2f6caf622d68222dfbb56..07f8c3dd5295233dde8e5405816df12cc17bc031 100644 --- a/src/test/java/net/floodlightcontroller/core/test/PacketFactory.java +++ b/src/test/java/net/floodlightcontroller/core/test/PacketFactory.java @@ -41,7 +41,7 @@ import org.openflow.protocol.factory.BasicFactory; public class PacketFactory { public static String broadcastMac = "ff:ff:ff:ff:ff:ff"; public static String broadcastIp = "255.255.255.255"; - protected static BasicFactory OFMessageFactory = new BasicFactory(); + protected static BasicFactory OFMessageFactory = BasicFactory.getInstance(); /** * Generates a DHCP request OFPacketIn. diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java index b9397b603b2585af1adcb9bcf51ef9db38958f14..566493a7075a5c921c664a819ca776b1fc0f6614 100644 --- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java +++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java @@ -111,6 +111,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase { return mockSwitch; } + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -525,7 +526,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase { byte[] testPacketSerialized = testPacket.serialize(); OFPacketIn pi; // build out input packet - pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN)) + pi = ((OFPacketIn) BasicFactory.getInstance().getMessage(OFType.PACKET_IN)) .setBufferId(-1) .setInPort((short) 1) .setPacketData(testPacketSerialized) diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java index 27c6c4444645a60698ef2aa76b548848f70a61d3..84db817f747542c1d5b5ef3f04e2d0061657dd5f 100644 --- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java +++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperTest.java @@ -50,7 +50,7 @@ public class OFMessageDamperTest { @Before public void setUp() throws IOException { - factory = new BasicFactory(); + factory = BasicFactory.getInstance(); cntx = new FloodlightContext(); sw1 = new OFMessageDamperMockSwitch(); diff --git a/src/test/java/org/openflow/protocol/BasicFactoryTest.java b/src/test/java/org/openflow/protocol/BasicFactoryTest.java index 312fcd3f57d616c6716e7f702e56a086a44609d0..350d4be39c3f1148c7a6c4191085bbe8bb9132a5 100644 --- a/src/test/java/org/openflow/protocol/BasicFactoryTest.java +++ b/src/test/java/org/openflow/protocol/BasicFactoryTest.java @@ -37,7 +37,7 @@ import org.openflow.util.U16; public class BasicFactoryTest extends TestCase { public void testCreateAndParse() throws MessageParseException { - BasicFactory factory = new BasicFactory(); + BasicFactory factory = BasicFactory.getInstance(); OFMessage m = factory.getMessage(OFType.HELLO); m.setVersion((byte) 1); m.setType(OFType.ECHO_REQUEST); @@ -56,7 +56,7 @@ public class BasicFactoryTest extends TestCase { } public void testInvalidMsgParse() throws MessageParseException { - BasicFactory factory = new BasicFactory(); + BasicFactory factory = BasicFactory.getInstance(); OFMessage m = factory.getMessage(OFType.HELLO); m.setVersion((byte) 1); m.setType(OFType.ECHO_REQUEST); @@ -69,7 +69,7 @@ public class BasicFactoryTest extends TestCase { } public void testCurrouptedMsgParse() throws MessageParseException { - BasicFactory factory = new BasicFactory(); + BasicFactory factory = BasicFactory.getInstance(); OFMessage m = factory.getMessage(OFType.HELLO); m.setVersion((byte) 1); m.setType(OFType.ERROR); @@ -86,7 +86,7 @@ public class BasicFactoryTest extends TestCase { } public void testCustomVendorAction() throws MessageParseException { - BasicFactory factory = new BasicFactory(); + BasicFactory factory = BasicFactory.getInstance(); OFVendorActionRegistry.getInstance().register( MockVendorAction.VENDOR_ID, new MockVendorActionFactory()); @@ -119,7 +119,7 @@ public class BasicFactoryTest extends TestCase { 0x05, 0x06, 0x07, 0x08 // pad }; - BasicFactory factory = new BasicFactory(); + BasicFactory factory = BasicFactory.getInstance(); OFVendorActionRegistry.getInstance().register( MockVendorAction.VENDOR_ID, new MockVendorActionFactory()); diff --git a/src/test/java/org/openflow/protocol/OFErrorTest.java b/src/test/java/org/openflow/protocol/OFErrorTest.java index 45d52576e75c2760d1499497964258f42457564c..f4a57269826d81cf17b47b547e4b7588afeb873f 100644 --- a/src/test/java/org/openflow/protocol/OFErrorTest.java +++ b/src/test/java/org/openflow/protocol/OFErrorTest.java @@ -34,14 +34,14 @@ public class OFErrorTest extends OFTestCase { public void testWriteRead() throws Exception { OFError msg = (OFError) messageFactory.getMessage(OFType.ERROR); msg.setMessageFactory(messageFactory); - msg.setErrorType((short) OFErrorType.OFPET_HELLO_FAILED.getValue()); + msg.setErrorType(OFErrorType.OFPET_HELLO_FAILED.getValue()); msg.setErrorCode((short) OFHelloFailedCode.OFPHFC_INCOMPATIBLE .ordinal()); ChannelBuffer bb = ChannelBuffers.dynamicBuffer(); bb.clear(); msg.writeTo(bb); msg.readFrom(bb); - TestCase.assertEquals((short) OFErrorType.OFPET_HELLO_FAILED.getValue(), + TestCase.assertEquals(OFErrorType.OFPET_HELLO_FAILED.getValue(), msg.getErrorType()); TestCase.assertEquals((short) OFHelloFailedCode.OFPHFC_INCOMPATIBLE .ordinal(), msg.getErrorType()); @@ -51,7 +51,7 @@ public class OFErrorTest extends OFTestCase { bb.clear(); msg.writeTo(bb); msg.readFrom(bb); - TestCase.assertEquals((short) OFErrorType.OFPET_HELLO_FAILED.getValue(), + TestCase.assertEquals(OFErrorType.OFPET_HELLO_FAILED.getValue(), msg.getErrorType()); TestCase.assertEquals((short) OFHelloFailedCode.OFPHFC_INCOMPATIBLE .ordinal(), msg.getErrorType()); @@ -74,7 +74,7 @@ public class OFErrorTest extends OFTestCase { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - OFMessageFactory factory = new BasicFactory(); + OFMessageFactory factory = BasicFactory.getInstance(); ChannelBuffer oferrorBuf = ChannelBuffers.wrappedBuffer(oferrorRaw); List<OFMessage> msg = factory.parseMessage(oferrorBuf); diff --git a/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java b/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java index 50bac8f711131923bd4f0ff27488d23f71b1b2e3..1885cae7b3d4731ccae5bfbe4fdb295951b1a760 100644 --- a/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java +++ b/src/test/java/org/openflow/protocol/OFStatisticsReplyTest.java @@ -64,7 +64,7 @@ public class OFStatisticsReplyTest extends OFTestCase { 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xc4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00 }; - OFMessageFactory factory = new BasicFactory(); + OFMessageFactory factory = BasicFactory.getInstance(); ChannelBuffer packetBuf = ChannelBuffers.wrappedBuffer(packet); List<OFMessage> msg = factory.parseMessage(packetBuf); TestCase.assertNotNull(msg); diff --git a/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java b/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java index 74af6f41d213593a746639132a320b1b9e81f1c6..fceb8955eb755a12bb03c68bd1102513874b06ab 100644 --- a/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java +++ b/src/test/java/org/openflow/protocol/OFStatisticsRequestTest.java @@ -40,7 +40,7 @@ public class OFStatisticsRequestTest extends OFTestCase { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xff, 0x00, (byte) 0xff, (byte) 0xff }; - OFMessageFactory factory = new BasicFactory(); + OFMessageFactory factory = BasicFactory.getInstance(); ChannelBuffer packetBuf = ChannelBuffers.wrappedBuffer(packet); List<OFMessage> msg = factory.parseMessage(packetBuf); TestCase.assertNotNull(msg); @@ -64,7 +64,7 @@ public class OFStatisticsRequestTest extends OFTestCase { 0x00, 0x00, 0x00, 0x00, (byte) 0xff, 0x00, 0x00, 0x00, (byte) 0xff, (byte) 0xff, 0x4e, 0x20 }; - OFMessageFactory factory = new BasicFactory(); + OFMessageFactory factory = BasicFactory.getInstance(); ChannelBuffer packetBuf = ChannelBuffers.wrappedBuffer(packet); List<OFMessage> msg = factory.parseMessage(packetBuf); TestCase.assertNotNull(msg); diff --git a/src/test/java/org/openflow/protocol/OFVendorTest.java b/src/test/java/org/openflow/protocol/OFVendorTest.java index b85a915a9f76898d4bfcdd3f06e0607aa926ed1d..c0385f4415824d1c79408e93ac31de4be40f3e52 100644 --- a/src/test/java/org/openflow/protocol/OFVendorTest.java +++ b/src/test/java/org/openflow/protocol/OFVendorTest.java @@ -38,14 +38,17 @@ public class OFVendorTest extends OFTestCase { static class AcmeVendorData implements OFVendorData { protected int dataType; + @Override public int getLength() { return 4; } + @Override public void readFrom(ChannelBuffer data, int length) { dataType = data.readInt(); } + @Override public void writeTo(ChannelBuffer data) { data.writeInt(dataType); } @@ -74,16 +77,19 @@ public class OFVendorTest extends OFTestCase { return value; } + @Override public int getLength() { return 8; } + @Override public void readFrom(ChannelBuffer data, int length) { super.readFrom(data, length); flags = data.readShort(); value = data.readShort(); } + @Override public void writeTo(ChannelBuffer data) { super.writeTo(data); data.writeShort(flags); @@ -92,6 +98,7 @@ public class OFVendorTest extends OFTestCase { public static Instantiable<OFVendorData> getInstantiable() { return new Instantiable<OFVendorData>() { + @Override public OFVendorData instantiate() { return new AcmeVendorData1(); } @@ -122,16 +129,19 @@ public class OFVendorTest extends OFTestCase { return subtype; } + @Override public int getLength() { return 12; } + @Override public void readFrom(ChannelBuffer data, int length) { super.readFrom(data, length); type = data.readShort(); subtype = data.readShort(); } + @Override public void writeTo(ChannelBuffer data) { super.writeTo(data); data.writeShort(type); @@ -140,6 +150,7 @@ public class OFVendorTest extends OFTestCase { public static Instantiable<OFVendorData> getInstantiable() { return new Instantiable<OFVendorData>() { + @Override public OFVendorData instantiate() { return new AcmeVendorData2(); } @@ -160,7 +171,7 @@ public class OFVendorTest extends OFTestCase { private OFVendor makeVendorMessage(int vendor) { OFVendor msg = (OFVendor) messageFactory.getMessage(OFType.VENDOR); - msg.setVendorDataFactory(new BasicFactory()); + msg.setVendorDataFactory(BasicFactory.getInstance()); msg.setVendor(vendor); return msg; } diff --git a/src/test/java/org/openflow/util/OFTestCase.java b/src/test/java/org/openflow/util/OFTestCase.java index 5132c2c7007e1dbc6c86e0adf77afedcc28c5a12..07bee2d589a1901ad1f77afc3a2ee262a48be429 100644 --- a/src/test/java/org/openflow/util/OFTestCase.java +++ b/src/test/java/org/openflow/util/OFTestCase.java @@ -28,7 +28,7 @@ public class OFTestCase extends TestCase { @Override protected void setUp() throws Exception { super.setUp(); - messageFactory = new BasicFactory(); + messageFactory = BasicFactory.getInstance(); } public void test() throws Exception { diff --git a/src/test/java/org/sdnplatform/sync/VersionedTest.java b/src/test/java/org/sdnplatform/sync/VersionedTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7c2c4433db1330a03af7363ec52beef714bddeb4 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/VersionedTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.internal.TUtils; + + +public class VersionedTest { + + private Versioned<Integer> getVersioned(Integer value, int... versionIncrements) { + return new Versioned<Integer>(value, TUtils.getClock(versionIncrements)); + } + + public void mustHaveVersion() { + try { + new Versioned<Integer>(1, null); + fail("Successfully created Versioned with null version."); + } catch(NullPointerException e) { + // this is good + } + } + + @Test + public void testEquals() { + assertEquals("Null versioneds not equal.", getVersioned(null), getVersioned(null)); + assertEquals("equal versioneds not equal.", getVersioned(1), getVersioned(1)); + assertEquals("equal versioneds not equal.", getVersioned(1, 1, 2), getVersioned(1, 1, 2)); + + assertTrue("Equals values with different version are equal!", + !getVersioned(1, 1, 2).equals(getVersioned(1, 1, 2, 2))); + assertTrue("Different values with same version are equal!", + !getVersioned(1, 1, 2).equals(getVersioned(2, 1, 2))); + assertTrue("Different values with different version are equal!", + !getVersioned(1, 1, 2).equals(getVersioned(2, 1, 1, 2))); + + // Should work for array types too! + assertEquals("Equal arrays are not equal!", + new Versioned<byte[]>(new byte[] { 1 }), + new Versioned<byte[]>(new byte[] { 1 })); + } + + @Test + public void testClone() { + Versioned<Integer> v1 = getVersioned(2, 1, 2, 3); + Versioned<Integer> v2 = v1.cloneVersioned(); + assertEquals(v1, v2); + assertTrue(v1 != v2); + assertTrue(v1.getVersion() != v2.getVersion()); + v2.increment(1, System.currentTimeMillis()); + assertTrue(!v1.equals(v2)); + } + +} diff --git a/src/test/java/org/sdnplatform/sync/client/ClientTest.java b/src/test/java/org/sdnplatform/sync/client/ClientTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ec677fc7e498ef1422d9ed97c8464fa5941fe3db --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/client/ClientTest.java @@ -0,0 +1,152 @@ +package org.sdnplatform.sync.client; + +import static org.junit.Assert.*; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.debugcounter.IDebugCounterService; +import net.floodlightcontroller.debugcounter.NullDebugCounter; +import net.floodlightcontroller.threadpool.IThreadPoolService; +import net.floodlightcontroller.threadpool.ThreadPool; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.client.SyncClient; +import org.sdnplatform.sync.client.SyncClient.SyncClientSettings; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.config.Node; + + +public class ClientTest { + protected SyncManager syncManager; + protected final static ObjectMapper mapper = new ObjectMapper(); + protected String nodeString; + ArrayList<Node> nodes; + ThreadPool tp; + + @Before + public void setUp() throws Exception { + nodes = new ArrayList<Node>(); + nodes.add(new Node("localhost", 40101, (short)1, (short)1)); + nodeString = mapper.writeValueAsString(nodes); + + tp = new ThreadPool(); + syncManager = new SyncManager(); + + FloodlightModuleContext fmc = new FloodlightModuleContext(); + fmc.addService(IThreadPoolService.class, tp); + fmc.addService(IDebugCounterService.class, new NullDebugCounter()); + + fmc.addConfigParam(syncManager, "nodes", nodeString); + fmc.addConfigParam(syncManager, "thisNode", ""+1); + syncManager.registerStore("global", Scope.GLOBAL); + tp.init(fmc); + syncManager.init(fmc); + tp.startUp(fmc); + syncManager.startUp(fmc); + } + + @After + public void tearDown() { + if (null != tp) + tp.getScheduledExecutor().shutdownNow(); + tp = null; + + if (null != syncManager) + syncManager.shutdown(); + syncManager = null; + } + + @Test + public void testClientBasic() throws Exception { + SyncClientSettings scs = new SyncClientSettings(); + scs.hostname = "localhost"; + scs.port = 40101; + scs.storeName = "global"; + scs.debug = true; + SyncClient client = new SyncClient(scs); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + client.out = new PrintStream(out); + ByteArrayOutputStream err = new ByteArrayOutputStream(); + client.err = new PrintStream(err); + client.connect(); + client.executeCommandLine("get \"key\""); + assertEquals("", err.toString()); + assertEquals("Connected to localhost:40101\n" + + "Getting Key:\n" + + "\"key\"\n\n" + + "Not found\n", + out.toString()); + + out = new ByteArrayOutputStream(); + err = new ByteArrayOutputStream(); + client.out = new PrintStream(out); + client.err = new PrintStream(err); + client.executeCommandLine("put \"key\" {\"field1\": \"value1\", \"field2\": \"value2\"}"); + assertEquals("", err.toString()); + assertEquals("Putting Key:\n" + + "\"key\"\n\n" + + "Value:\n" + + "{\n" + + " \"field1\" : \"value1\",\n" + + " \"field2\" : \"value2\"\n" + + "}\n" + + "Success\n", + out.toString()); + + out = new ByteArrayOutputStream(); + err = new ByteArrayOutputStream(); + client.out = new PrintStream(out); + client.err = new PrintStream(err); + client.executeCommandLine("get \"key\""); + assertEquals("", err.toString()); + assertEquals("Getting Key:\n" + + "\"key\"\n\n" + + "Value:\n" + + "{\n" + + " \"field1\" : \"value1\",\n" + + " \"field2\" : \"value2\"\n" + + "}\n", + out.toString()); + + out = new ByteArrayOutputStream(); + err = new ByteArrayOutputStream(); + client.out = new PrintStream(out); + client.err = new PrintStream(err); + client.executeCommandLine("delete \"key\""); + assertEquals("", err.toString()); + assertEquals("Deleting Key:\n" + + "\"key\"\n\n" + + "Success\n", + out.toString()); + + out = new ByteArrayOutputStream(); + err = new ByteArrayOutputStream(); + client.out = new PrintStream(out); + client.err = new PrintStream(err); + client.executeCommandLine("get \"key\""); + assertEquals("", err.toString()); + assertEquals("Getting Key:\n" + + "\"key\"\n\n" + + "Not found\n", + out.toString()); + + out = new ByteArrayOutputStream(); + err = new ByteArrayOutputStream(); + client.out = new PrintStream(out); + client.err = new PrintStream(err); + client.executeCommandLine("quit"); + assertEquals("", err.toString()); + assertEquals("", + out.toString()); + + client.executeCommandLine("help"); + assert(!"".equals(out.toString())); + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java b/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9f0a56bdf100f398c8ab44526006a7f83f1b028b --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/SyncManagerTest.java @@ -0,0 +1,702 @@ +package org.sdnplatform.sync.internal; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.debugcounter.IDebugCounterService; +import net.floodlightcontroller.debugcounter.NullDebugCounter; +import net.floodlightcontroller.threadpool.IThreadPoolService; +import net.floodlightcontroller.threadpool.ThreadPool; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IInconsistencyResolver; +import org.sdnplatform.sync.IStoreClient; +import org.sdnplatform.sync.IStoreListener; +import org.sdnplatform.sync.IStoreListener.UpdateType; +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.error.ObsoleteVersionException; +import org.sdnplatform.sync.internal.AbstractSyncManager; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.SyncTorture; +import org.sdnplatform.sync.internal.config.Node; +import org.sdnplatform.sync.internal.config.PropertyCCProvider; +import org.sdnplatform.sync.internal.store.Key; +import org.sdnplatform.sync.internal.store.TBean; +import org.sdnplatform.sync.internal.version.VectorClock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class SyncManagerTest { + protected static Logger logger = + LoggerFactory.getLogger(SyncManagerTest.class); + + protected FloodlightModuleContext[] moduleContexts; + protected SyncManager[] syncManagers; + protected final static ObjectMapper mapper = new ObjectMapper(); + protected String nodeString; + ArrayList<Node> nodes; + + ThreadPool tp; + + protected void setupSyncManager(FloodlightModuleContext fmc, + SyncManager syncManager, Node thisNode) + throws FloodlightModuleException { + fmc.addService(IThreadPoolService.class, tp); + fmc.addService(IDebugCounterService.class, new NullDebugCounter()); + fmc.addConfigParam(syncManager, "configProviders", + PropertyCCProvider.class.getName()); + fmc.addConfigParam(syncManager, "nodes", nodeString); + fmc.addConfigParam(syncManager, "thisNode", ""+thisNode.getNodeId()); + syncManager.registerStore("global", Scope.GLOBAL); + syncManager.registerStore("local", Scope.LOCAL); + tp.init(fmc); + syncManager.init(fmc); + tp.startUp(fmc); + syncManager.startUp(fmc); + } + + @Before + public void setUp() throws Exception { + tp = new ThreadPool(); + + syncManagers = new SyncManager[4]; + moduleContexts = new FloodlightModuleContext[4]; + + nodes = new ArrayList<Node>(); + nodes.add(new Node("localhost", 40101, (short)1, (short)1)); + nodes.add(new Node("localhost", 40102, (short)2, (short)2)); + nodes.add(new Node("localhost", 40103, (short)3, (short)1)); + nodes.add(new Node("localhost", 40104, (short)4, (short)2)); + nodeString = mapper.writeValueAsString(nodes); + + for(int i = 0; i < 4; i++) { + moduleContexts[i] = new FloodlightModuleContext(); + syncManagers[i] = new SyncManager(); + setupSyncManager(moduleContexts[i], syncManagers[i], nodes.get(i)); + } + } + + @After + public void tearDown() { + tp.getScheduledExecutor().shutdownNow(); + tp = null; + + if (syncManagers != null) { + for(int i = 0; i < syncManagers.length; i++) { + if (null != syncManagers[i]) + syncManagers[i].shutdown(); + } + } + syncManagers = null; + } + + @Test + public void testBasicOneNode() throws Exception { + AbstractSyncManager sync = syncManagers[0]; + IStoreClient<Key, TBean> testClient = + sync.getStoreClient("global", Key.class, TBean.class); + Key k = new Key("com.bigswitch.bigsync.internal", "test"); + TBean tb = new TBean("hello", 42); + TBean tb2 = new TBean("hello", 84); + TBean tb3 = new TBean("hello", 126); + + assertNotNull(testClient.get(k)); + assertNull(testClient.get(k).getValue()); + + testClient.put(k, tb); + Versioned<TBean> result = testClient.get(k); + assertEquals(result.getValue(), tb); + + result.setValue(tb2); + testClient.put(k, result); + + try { + result.setValue(tb3); + testClient.put(k, result); + fail("Should get ObsoleteVersionException"); + } catch (ObsoleteVersionException e) { + // happy town + } + + result = testClient.get(k); + assertEquals(tb2, result.getValue()); + + } + + @Test + public void testIterator() throws Exception { + AbstractSyncManager sync = syncManagers[0]; + IStoreClient<Key, TBean> testClient = + sync.getStoreClient("local", Key.class, TBean.class); + + HashMap<Key, TBean> testMap = new HashMap<Key, TBean>(); + for (int i = 0; i < 100; i++) { + Key k = new Key("com.bigswitch.bigsync.internal", "test" + i); + TBean tb = new TBean("value", i); + testMap.put(k, tb); + testClient.put(k, tb); + } + + IClosableIterator<Entry<Key, Versioned<TBean>>> iter = + testClient.entries(); + int size = 0; + try { + while (iter.hasNext()) { + Entry<Key, Versioned<TBean>> e = iter.next(); + assertEquals(testMap.get(e.getKey()), e.getValue().getValue()); + size += 1; + } + } finally { + iter.close(); + } + assertEquals(testMap.size(), size); + } + + private <K, V> Versioned<V> waitForValue(IStoreClient<K, V> client, + K key, V value, + int maxTime, + String clientName) + throws Exception { + Versioned<V> v = null; + long then = System.currentTimeMillis(); + while (true) { + v = client.get(key); + if (value != null) { + if (v.getValue() != null && v.getValue().equals(value)) break; + } else { + if (v.getValue() != null) break; + } + if (v.getValue() != null) + logger.info("{}: Value for key {} not yet right: " + + "expected: {}; actual: {}", + new Object[]{clientName, key, value, v.getValue()}); + else + logger.info("{}: Value for key {} is null: expected {}", + new Object[]{clientName, key, value}); + + + Thread.sleep(100); + assertTrue(then + maxTime > System.currentTimeMillis()); + } + return v; + } + + private void waitForFullMesh(int maxTime) throws Exception { + long then = System.currentTimeMillis(); + + while (true) { + boolean full = true; + for(int i = 0; i < syncManagers.length; i++) { + if (!syncManagers[i].rpcService.isFullyConnected()) + full = false; + } + if (full) break; + Thread.sleep(100); + assertTrue(then + maxTime > System.currentTimeMillis()); + } + } + + private void waitForConnection(SyncManager sm, + short nodeId, + boolean connected, + int maxTime) throws Exception { + long then = System.currentTimeMillis(); + + while (true) { + if (connected == sm.rpcService.isConnected(nodeId)) break; + Thread.sleep(100); + assertTrue(then + maxTime > System.currentTimeMillis()); + } + } + + @Test + public void testBasicGlobalSync() throws Exception { + waitForFullMesh(2000); + + ArrayList<IStoreClient<String, String>> clients = + new ArrayList<IStoreClient<String, String>>(syncManagers.length); + // write one value to each node's local interface + for (int i = 0; i < syncManagers.length; i++) { + IStoreClient<String, String> client = + syncManagers[i].getStoreClient("global", + String.class, String.class); + clients.add(client); + client.put("key" + i, ""+i); + } + + // verify that we see all the values everywhere + for (int j = 0; j < clients.size(); j++) { + for (int i = 0; i < syncManagers.length; i++) { + waitForValue(clients.get(j), "key" + i, ""+i, 2000, "client"+j); + } + } + } + + @Test + public void testBasicLocalSync() throws Exception { + waitForFullMesh(2000); + + ArrayList<IStoreClient<String, String>> clients = + new ArrayList<IStoreClient<String, String>>(syncManagers.length); + // write one value to each node's local interface + for (int i = 0; i < syncManagers.length; i++) { + IStoreClient<String, String> client = + syncManagers[i].getStoreClient("local", + String.class, String.class); + clients.add(client); + client.put("key" + i, ""+i); + } + + // verify that we see all the values from each local group at all the + // nodes of that local group + for (int j = 0; j < clients.size(); j++) { + IStoreClient<String, String> client = clients.get(j); + for (int i = 0; i < syncManagers.length; i++) { + if (i % 2 == j % 2) + waitForValue(client, "key" + i, ""+i, 2000, "client"+j); + else { + Versioned<String> v = client.get("key" + i); + if (v.getValue() != null) { + fail("Node " + j + " reading key" + i + + ": " + v.getValue()); + } + } + } + } + } + + @Test + public void testConcurrentWrite() throws Exception { + waitForFullMesh(2000); + + // Here we generate concurrent writes and then resolve them using + // a custom inconsistency resolver + IInconsistencyResolver<Versioned<List<String>>> ir = + new IInconsistencyResolver<Versioned<List<String>>>() { + @Override + public List<Versioned<List<String>>> + resolveConflicts(List<Versioned<List<String>>> items) { + VectorClock vc = null; + List<String> strings = new ArrayList<String>(); + for (Versioned<List<String>> item : items) { + if (vc == null) + vc = (VectorClock)item.getVersion(); + else + vc = vc.merge((VectorClock)item.getVersion()); + + strings.addAll(item.getValue()); + } + Versioned<List<String>> v = + new Versioned<List<String>>(strings, vc); + return Collections.singletonList(v); + } + }; + + TypeReference<List<String>> tr = new TypeReference<List<String>>() {}; + TypeReference<String> ktr = new TypeReference<String>() {}; + IStoreClient<String, List<String>> client0 = + syncManagers[0].getStoreClient("local", ktr, tr, ir); + IStoreClient<String, List<String>> client2 = + syncManagers[2].getStoreClient("local", ktr, tr, ir); + + client0.put("key", Collections.singletonList("value")); + Versioned<List<String>> v = client0.get("key"); + assertNotNull(v); + + // now we generate two writes that are concurrent to each other + // but are both locally after the first write. The result should be + // two non-obsolete lists each containing a single element. + // The inconsistency resolver above will resolve these by merging + // the lists + List<String> comp = new ArrayList<String>(); + v.setValue(Collections.singletonList("newvalue0")); + comp.add("newvalue0"); + client0.put("key", v); + v.setValue(Collections.singletonList("newvalue1")); + comp.add("newvalue1"); + client2.put("key", v); + + v = waitForValue(client0, "key", comp, 1000, "client0"); + + // add one more value to the array. Now there will be exactly one + // non-obsolete value + List<String> newlist = new ArrayList<String>(v.getValue()); + assertEquals(2, newlist.size()); + newlist.add("finalvalue"); + v.setValue(newlist); + client0.put("key", v); + + v = waitForValue(client2, "key", newlist, 2000, "client2"); + assertEquals(3, newlist.size()); + + } + + @Test + public void testReconnect() throws Exception { + IStoreClient<String, String> client0 = + syncManagers[0].getStoreClient("global", + String.class, + String.class); + IStoreClient<String, String> client1 = + syncManagers[1].getStoreClient("global", + String.class, String.class); + IStoreClient<String, String> client2 = + syncManagers[2].getStoreClient("global", + String.class, String.class); + + client0.put("key0", "value0"); + waitForValue(client2, "key0", "value0", 1000, "client0"); + + logger.info("Shutting down server ID 1"); + syncManagers[0].shutdown(); + + client1.put("newkey1", "newvalue1"); + client2.put("newkey2", "newvalue2"); + client1.put("key0", "newvalue0"); + client2.put("key2", "newvalue2"); + + for (int i = 0; i < 500; i++) { + client2.put("largetest" + i, "largetestvalue"); + } + + logger.info("Initializing server ID 1"); + syncManagers[0] = new SyncManager(); + setupSyncManager(moduleContexts[0], syncManagers[0], nodes.get(0)); + + waitForFullMesh(2000); + + client0 = syncManagers[0].getStoreClient("global", + String.class, String.class); + waitForValue(client0, "newkey1", "newvalue1", 1000, "client0"); + waitForValue(client0, "newkey2", "newvalue2", 1000, "client0"); + waitForValue(client0, "key0", "newvalue0", 1000, "client0"); + waitForValue(client0, "key2", "newvalue2", 1000, "client0"); + + for (int i = 0; i < 500; i++) { + waitForValue(client0, "largetest" + i, + "largetestvalue", 1000, "client0"); + } + } + + protected class Update { + String key; + UpdateType type; + + public Update(String key, UpdateType type) { + super(); + this.key = key; + this.type = type; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getOuterType().hashCode(); + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Update other = (Update) obj; + if (!getOuterType().equals(other.getOuterType())) return false; + if (key == null) { + if (other.key != null) return false; + } else if (!key.equals(other.key)) return false; + if (type != other.type) return false; + return true; + } + + private SyncManagerTest getOuterType() { + return SyncManagerTest.this; + } + } + + protected class TestListener implements IStoreListener<String> { + HashSet<Update> notified = new HashSet<Update>(); + + @Override + public void keysModified(Iterator<String> keys, + UpdateType type) { + while (keys.hasNext()) + notified.add(new Update(keys.next(), type)); + } + + } + + @SuppressWarnings("rawtypes") + private void waitForNotify(TestListener tl, + HashSet comp, + int maxTime) throws Exception { + long then = System.currentTimeMillis(); + + while (true) { + if (tl.notified.containsAll(comp)) break; + Thread.sleep(100); + assertTrue(then + maxTime > System.currentTimeMillis()); + } + } + + @Test + public void testNotify() throws Exception { + IStoreClient<String, String> client0 = + syncManagers[0].getStoreClient("local", + String.class, String.class); + IStoreClient<String, String> client2 = + syncManagers[2].getStoreClient("local", + new TypeReference<String>() {}, + new TypeReference<String>() {}); + + TestListener t0 = new TestListener(); + TestListener t2 = new TestListener(); + client0.addStoreListener(t0); + client2.addStoreListener(t2); + + client0.put("test0", "value"); + client2.put("test2", "value"); + + HashSet<Update> c0 = new HashSet<Update>(); + c0.add(new Update("test0", UpdateType.LOCAL)); + c0.add(new Update("test2", UpdateType.REMOTE)); + HashSet<Update> c2 = new HashSet<Update>(); + c2.add(new Update("test0", UpdateType.REMOTE)); + c2.add(new Update("test2", UpdateType.LOCAL)); + + waitForNotify(t0, c0, 2000); + waitForNotify(t2, c2, 2000); + assertEquals(2, t0.notified.size()); + assertEquals(2, t2.notified.size()); + + t0.notified.clear(); + t2.notified.clear(); + + Versioned<String> v0 = client0.get("test0"); + v0.setValue("newvalue"); + client0.put("test0", v0); + + Versioned<String> v2 = client0.get("test2"); + v2.setValue("newvalue"); + client2.put("test2", v2); + + waitForNotify(t0, c0, 2000); + waitForNotify(t2, c2, 2000); + assertEquals(2, t0.notified.size()); + assertEquals(2, t2.notified.size()); + + t0.notified.clear(); + t2.notified.clear(); + + client0.delete("test0"); + client2.delete("test2"); + + waitForNotify(t0, c0, 2000); + waitForNotify(t2, c2, 2000); + assertEquals(2, t0.notified.size()); + assertEquals(2, t2.notified.size()); + } + + @Test + public void testAddNode() throws Exception { + waitForFullMesh(2000); + IStoreClient<String, String> client0 = + syncManagers[0].getStoreClient("global", + String.class, String.class); + IStoreClient<String, String> client1 = + syncManagers[1].getStoreClient("global", + String.class, String.class); + client0.put("key", "value"); + waitForValue(client1, "key", "value", 2000, "client1"); + + nodes.add(new Node("localhost", 40105, (short)5, (short)5)); + SyncManager[] sms = Arrays.copyOf(syncManagers, + syncManagers.length + 1); + FloodlightModuleContext[] fmcs = + Arrays.copyOf(moduleContexts, + moduleContexts.length + 1); + sms[syncManagers.length] = new SyncManager(); + fmcs[moduleContexts.length] = new FloodlightModuleContext(); + nodeString = mapper.writeValueAsString(nodes); + + setupSyncManager(fmcs[moduleContexts.length], + sms[syncManagers.length], + nodes.get(syncManagers.length)); + syncManagers = sms; + moduleContexts = fmcs; + + for(int i = 0; i < 4; i++) { + moduleContexts[i].addConfigParam(syncManagers[i], + "nodes", nodeString); + syncManagers[i].updateConfiguration(); + } + waitForFullMesh(2000); + + IStoreClient<String, String> client4 = + syncManagers[4].getStoreClient("global", + String.class, String.class); + client4.put("newkey", "newvalue"); + waitForValue(client4, "key", "value", 2000, "client4"); + waitForValue(client0, "newkey", "newvalue", 2000, "client0"); + } + + @Test + public void testRemoveNode() throws Exception { + waitForFullMesh(2000); + IStoreClient<String, String> client0 = + syncManagers[0].getStoreClient("global", + String.class, String.class); + IStoreClient<String, String> client1 = + syncManagers[1].getStoreClient("global", + String.class, String.class); + IStoreClient<String, String> client2 = + syncManagers[2].getStoreClient("global", + String.class, String.class); + + client0.put("key", "value"); + waitForValue(client1, "key", "value", 2000, "client1"); + + nodes.remove(0); + nodeString = mapper.writeValueAsString(nodes); + + SyncManager oldNode = syncManagers[0]; + syncManagers = Arrays.copyOfRange(syncManagers, 1, 4); + moduleContexts = Arrays.copyOfRange(moduleContexts, 1, 4); + + try { + for(int i = 0; i < syncManagers.length; i++) { + moduleContexts[i].addConfigParam(syncManagers[i], + "nodes", nodeString); + syncManagers[i].updateConfiguration(); + waitForConnection(syncManagers[i], (short)1, false, 2000); + } + } finally { + oldNode.shutdown(); + } + waitForFullMesh(2000); + + client1.put("newkey", "newvalue"); + waitForValue(client2, "key", "value", 2000, "client4"); + waitForValue(client2, "newkey", "newvalue", 2000, "client0"); + } + + @Test + public void testChangeNode() throws Exception { + waitForFullMesh(2000); + IStoreClient<String, String> client0 = + syncManagers[0].getStoreClient("global", + String.class, String.class); + IStoreClient<String, String> client2 = + syncManagers[2].getStoreClient("global", + String.class, String.class); + client0.put("key", "value"); + waitForValue(client2, "key", "value", 2000, "client2"); + + nodes.set(2, new Node("localhost", 50103, (short)3, (short)1)); + nodeString = mapper.writeValueAsString(nodes); + + for(int i = 0; i < syncManagers.length; i++) { + moduleContexts[i].addConfigParam(syncManagers[i], + "nodes", nodeString); + syncManagers[i].updateConfiguration(); + } + waitForFullMesh(2000); + + waitForValue(client2, "key", "value", 2000, "client2"); + client2 = syncManagers[2].getStoreClient("global", + String.class, String.class); + client0.put("key", "newvalue"); + waitForValue(client2, "key", "newvalue", 2000, "client2"); + } + + /** + * Do a brain-dead performance test with one thread writing and waiting + * for the values on the other node. The result get printed to the log + */ + public void testSimpleWritePerformance(String store) throws Exception { + waitForFullMesh(5000); + + final int count = 1000000; + + IStoreClient<String, String> client0 = + syncManagers[0].getStoreClient(store, + String.class, String.class); + IStoreClient<String, String> client2 = + syncManagers[2].getStoreClient(store, + String.class, String.class); + + long then = System.currentTimeMillis(); + + for (int i = 1; i <= count; i++) { + client0.put(""+i, ""+i); + } + + long donewriting = System.currentTimeMillis(); + + waitForValue(client2, ""+count, null, count, "client2"); + + long now = System.currentTimeMillis(); + + logger.info("Simple write ({}): {} values in {}+/-100 " + + "millis ({} synced writes/s) ({} local writes/s)", + new Object[]{store, count, (now-then), + 1000.0*count/(now-then), + 1000.0*count/(donewriting-then)}); + + } + + @Test + @Ignore // ignored just to speed up routine tests + public void testPerfSimpleWriteLocal() throws Exception { + testSimpleWritePerformance("local"); + } + + @Test + @Ignore // ignored just to speed up routine tests + public void testPerfSimpleWriteGlobal() throws Exception { + testSimpleWritePerformance("global"); + } + + @Test + @Ignore + public void testPerfOneNode() throws Exception { + tearDown(); + tp = new ThreadPool(); + tp.init(null); + tp.startUp(null); + nodes = new ArrayList<Node>(); + nodes.add(new Node("localhost", 40101, (short)1, (short)1)); + nodeString = mapper.writeValueAsString(nodes); + SyncManager sm = new SyncManager(); + FloodlightModuleContext fmc = new FloodlightModuleContext(); + setupSyncManager(fmc, sm, nodes.get(0)); + fmc.addService(ISyncService.class, sm); + SyncTorture st = new SyncTorture(); + //fmc.addConfigParam(st, "iterations", "1"); + st.init(fmc); + st.startUp(fmc); + Thread.sleep(10000); + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/TUtils.java b/src/test/java/org/sdnplatform/sync/internal/TUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..249a414d889c3a33c654be29ebb3838351430922 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/TUtils.java @@ -0,0 +1,315 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * Copyright (c) 2013 Big Switch Networks, Inc. + * + * 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 org.sdnplatform.sync.internal; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Random; + +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.version.VectorClock; + + +/** + * Helper utilities for tests + * + * + */ +public class TUtils { + + public static final String DIGITS = "0123456789"; + public static final String LETTERS = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"; + public static final String CHARACTERS = LETTERS + DIGITS + "~!@#$%^&*()____+-=[];',,,./>?:{}"; + public static final Random SEEDED_RANDOM = new Random(19873482374L); + public static final Random UNSEEDED_RANDOM = new Random(); + + /** + * Get a vector clock with events on the sequence of nodes given So + * getClock(1,1,2,2,2) means a clock that has two writes on node 1 and 3 + * writes on node 2. The timestamp will be the current time + * + * @param nodes The sequence of nodes + * @return A VectorClock initialized with the given sequence of events + */ + public static VectorClock getClock(int... nodes) { + VectorClock clock = new VectorClock(); + return increment(clock, nodes); + } + + /** + * Get a vector clock with a the given timestamp and events on the + * sequence of nodes given So getClock(1,1,2,2,2) means a clock that has + * two writes on node 1 and 3 writes on node 2. + * + * @param nodes The sequence of nodes + * @return A VectorClock initialized with the given sequence of events + */ + public static VectorClock getClockT(long timestamp, int... nodes) { + VectorClock clock = new VectorClock(timestamp); + return increment(clock, nodes); + } + + /** + * Record events for the given sequence of nodes + * + * @param clock The VectorClock to record the events on + * @param nodes The sequences of node events + */ + public static VectorClock increment(VectorClock clock, int... nodes) { + for(int n: nodes) + clock = clock.incremented((short) n, System.currentTimeMillis()); + return clock; + } + + /** + * Test two byte arrays for (deep) equality. I think this exists in java 6 + * but not java 5 + * + * @param a1 Array 1 + * @param a2 Array 2 + * @return True iff a1.length == a2.length and a1[i] == a2[i] for 0 <= i < + * a1.length + */ + public static boolean bytesEqual(byte[] a1, byte[] a2) { + if(a1 == a2) { + return true; + } else if(a1 == null || a2 == null) { + return false; + } else if(a1.length != a2.length) { + return false; + } else { + for(int i = 0; i < a1.length; i++) + if(a1[i] != a2[i]) + return false; + } + + return true; + } + + /** + * Create a string with some random letters + * + * @param length The length of the string to create + * @return The string + */ + public static String randomLetters(int length) { + return randomString(LETTERS, length); + } + + /** + * Create a string that is a random sample (with replacement) from the given + * string + * + * @param sampler The string to sample from + * @param length The length of the string to create + * @return The created string + */ + public static String randomString(String sampler, int length) { + StringBuilder builder = new StringBuilder(length); + for(int i = 0; i < length; i++) + builder.append(sampler.charAt(SEEDED_RANDOM.nextInt(sampler.length()))); + return builder.toString(); + } + + /** + * Generate an array of random bytes + * + * @param length + * @return + */ + public static byte[] randomBytes(int length) { + byte[] bytes = new byte[length]; + SEEDED_RANDOM.nextBytes(bytes); + return bytes; + } + + /** + * Return an array of length count containing random integers in the range + * (0, max) generated off the test rng. + * + * @param max The bound on the random number size + * @param count The number of integers to generate + * @return The array of integers + */ + public static int[] randomInts(int max, int count) { + int[] vals = new int[count]; + for(int i = 0; i < count; i++) + vals[i] = SEEDED_RANDOM.nextInt(max); + return vals; + } + + /** + * Weirdly java doesn't seem to have Arrays.shuffle(), this terrible hack + * does that. + * + * @return A shuffled copy of the input + */ + public static int[] shuffle(int[] input) { + List<Integer> vals = new ArrayList<Integer>(input.length); + for(int i = 0; i < input.length; i++) + vals.add(input[i]); + Collections.shuffle(vals, SEEDED_RANDOM); + int[] copy = new int[input.length]; + for(int i = 0; i < input.length; i++) + copy[i] = vals.get(i); + return copy; + } + + /** + * Compute the requested quantile of the given array + * + * @param values The array of values + * @param quantile The quantile requested (must be between 0.0 and 1.0 + * inclusive) + * @return The quantile + */ + public static long quantile(long[] values, double quantile) { + if(values == null) + throw new IllegalArgumentException("Values cannot be null."); + if(quantile < 0.0 || quantile > 1.0) + throw new IllegalArgumentException("Quantile must be between 0.0 and 1.0"); + + long[] copy = new long[values.length]; + System.arraycopy(values, 0, copy, 0, copy.length); + Arrays.sort(copy); + int index = (int) (copy.length * quantile); + return copy[index]; + } + + /** + * Compute the mean of the given values + * + * @param values The values + * @return The mean + */ + public static double mean(long[] values) { + double total = 0.0; + for(int i = 0; i < values.length; i++) + total += values[i]; + return total / values.length; + } + + /** + * Create a temporary directory in the directory given by java.io.tmpdir + * + * @return The directory created. + */ + public static File createTempDir() { + return createTempDir(new File(System.getProperty("java.io.tmpdir"))); + } + + /** + * Create a temporary directory that is a child of the given directory + * + * @param parent The parent directory + * @return The temporary directory + */ + public static File createTempDir(File parent) { + File temp = new File(parent, + Integer.toString(Math.abs(UNSEEDED_RANDOM.nextInt()) % 1000000)); + temp.delete(); + temp.mkdir(); + temp.deleteOnExit(); + return temp; + } + + /** + * Wrap the given string in quotation marks. This is slightly more readable + * then the java inline quotes that require escaping. + * + * @param s The string to wrap in quotes + * @return The string + */ + public static String quote(String s) { + return "\"" + s + "\""; + } + + /** + * Always uses UTF-8. + */ + public static ByteArray toByteArray(String s) { + try { + return new ByteArray(s.getBytes("UTF-8")); + } catch(UnsupportedEncodingException e) { + /* Should not happen */ + throw new IllegalStateException(e); + } + } +/* + public static void assertWithBackoff(long timeout, Attempt attempt) throws Exception { + assertWithBackoff(30, timeout, attempt); + } + + public static void assertWithBackoff(long initialDelay, long timeout, Attempt attempt) + throws Exception { + long delay = initialDelay; + long finishBy = System.currentTimeMillis() + timeout; + + while(true) { + try { + attempt.checkCondition(); + return; + } catch(AssertionError e) { + if(System.currentTimeMillis() < finishBy) { + Thread.sleep(delay); + delay *= 2; + } else { + throw e; + } + } + } + } +*/ + /** + * Because java.beans.ReflectionUtils isn't public... + */ + + @SuppressWarnings("unchecked") + public static <T> T getPrivateValue(Object instance, String fieldName) throws Exception { + Field eventDataQueueField = instance.getClass().getDeclaredField(fieldName); + eventDataQueueField.setAccessible(true); + return (T) eventDataQueueField.get(instance); + } + + /** + * Constructs a calendar object representing the given time + */ + public static GregorianCalendar getCalendar(int year, + int month, + int day, + int hour, + int mins, + int secs) { + GregorianCalendar cal = new GregorianCalendar(); + cal.set(Calendar.YEAR, year); + cal.set(Calendar.MONTH, month); + cal.set(Calendar.DATE, day); + cal.set(Calendar.HOUR_OF_DAY, hour); + cal.set(Calendar.MINUTE, mins); + cal.set(Calendar.SECOND, secs); + cal.set(Calendar.MILLISECOND, 0); + return cal; + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/AbstractByteArrayStoreT.java b/src/test/java/org/sdnplatform/sync/internal/store/AbstractByteArrayStoreT.java new file mode 100644 index 0000000000000000000000000000000000000000..2c7ce1ee00fb500941f87633f986ee7c162875f5 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/AbstractByteArrayStoreT.java @@ -0,0 +1,65 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.store; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.junit.Test; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.internal.TUtils; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.util.ByteArray; + +import com.google.common.collect.Lists; + +/** + * + */ +public abstract class AbstractByteArrayStoreT extends + AbstractStoreT<ByteArray, byte[]> { + + @Override + public List<ByteArray> getKeys(int numValues) { + List<ByteArray> keys = Lists.newArrayList(); + for(byte[] array: this.getByteValues(numValues, 8)) + keys.add(new ByteArray(array)); + return keys; + } + + @Override + public List<byte[]> getValues(int numValues) { + return this.getByteValues(numValues, 10); + } + + @Override + protected boolean valuesEqual(byte[] t1, byte[] t2) { + return TUtils.bytesEqual(t1, t2); + } + + @Test + public void testEmptyByteArray() throws Exception { + IStore<ByteArray, byte[]> store = getStore(); + Versioned<byte[]> bytes = new Versioned<byte[]>(new byte[0]); + store.put(new ByteArray(new byte[0]), bytes); + List<Versioned<byte[]>> found = store.get(new ByteArray(new byte[0])); + assertEquals("Incorrect number of results.", 1, found.size()); + bassertEquals("Get doesn't equal put.", bytes, found.get(0)); + } + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/AbstractStorageEngineT.java b/src/test/java/org/sdnplatform/sync/internal/store/AbstractStorageEngineT.java new file mode 100644 index 0000000000000000000000000000000000000000..aaae98011f36478c4f4596580bde59fee4d41cc4 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/AbstractStorageEngineT.java @@ -0,0 +1,191 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.store; + +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import org.junit.Test; +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.TUtils; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.util.ByteArray; + +import static org.junit.Assert.*; + + +public abstract class AbstractStorageEngineT extends AbstractByteArrayStoreT { + + @Override + public IStore<ByteArray, byte[]> getStore() { + return getStorageEngine(); + } + + public abstract IStorageEngine<ByteArray, byte[]> getStorageEngine(); + + public void testGetNoEntries() { + IClosableIterator<Entry<ByteArray, List<Versioned<byte[]>>>> it = null; + try { + IStorageEngine<ByteArray, byte[]> engine = getStorageEngine(); + it = engine.entries(); + while(it.hasNext()) + fail("There shouldn't be any entries in this store."); + } finally { + if(it != null) + it.close(); + } + } + + @Test + public void testGetNoKeys() { + IClosableIterator<ByteArray> it = null; + try { + IStorageEngine<ByteArray, byte[]> engine = getStorageEngine(); + it = engine.keys(); + while(it.hasNext()) + fail("There shouldn't be any entries in this store."); + } finally { + if(it != null) + it.close(); + } + } + + @Test + public void testPruneOnWrite() throws SyncException { + IStorageEngine<ByteArray, byte[]> engine = getStorageEngine(); + Versioned<byte[]> v1 = new Versioned<byte[]>(new byte[] { 1 }, TUtils.getClock(1)); + Versioned<byte[]> v2 = new Versioned<byte[]>(new byte[] { 2 }, TUtils.getClock(2)); + Versioned<byte[]> v3 = new Versioned<byte[]>(new byte[] { 3 }, TUtils.getClock(1, 2)); + ByteArray key = new ByteArray((byte) 3); + engine.put(key, v1); + engine.put(key, v2); + assertEquals(2, engine.get(key).size()); + engine.put(key, v3); + assertEquals(1, engine.get(key).size()); + } + + @Test + public void testTruncate() throws Exception { + IStorageEngine<ByteArray, byte[]> engine = getStorageEngine(); + Versioned<byte[]> v1 = new Versioned<byte[]>(new byte[] { 1 }); + Versioned<byte[]> v2 = new Versioned<byte[]>(new byte[] { 2 }); + Versioned<byte[]> v3 = new Versioned<byte[]>(new byte[] { 3 }); + ByteArray key1 = new ByteArray((byte) 3); + ByteArray key2 = new ByteArray((byte) 4); + ByteArray key3 = new ByteArray((byte) 5); + + engine.put(key1, v1); + engine.put(key2, v2); + engine.put(key3, v3); + engine.truncate(); + + IClosableIterator<Entry<ByteArray, List<Versioned<byte[]>>>> it = null; + try { + it = engine.entries(); + while(it.hasNext()) { + fail("There shouldn't be any entries in this store."); + } + } finally { + if(it != null) { + it.close(); + } + } + } + + @Test + public void testCleanupTask() throws Exception { + IStorageEngine<ByteArray, byte[]> engine = getStorageEngine(); + engine.setTombstoneInterval(500); + + Versioned<byte[]> v1_1 = new Versioned<byte[]>(new byte[] { 1 }, TUtils.getClock(1)); + Versioned<byte[]> v1_2 = new Versioned<byte[]>(null, TUtils.getClock(1, 1)); + + // add, update, delete + Versioned<byte[]> v2_1 = new Versioned<byte[]>(new byte[] { 1 }, TUtils.getClock(1)); + Versioned<byte[]> v2_2 = new Versioned<byte[]>(new byte[] { 2 }, TUtils.getClock(1, 2)); + Versioned<byte[]> v2_3 = new Versioned<byte[]>(null, TUtils.getClock(1, 2, 1)); + + // delete then add again + Versioned<byte[]> v3_1 = new Versioned<byte[]>(new byte[] { 1 }, TUtils.getClock(1)); + Versioned<byte[]> v3_2 = new Versioned<byte[]>(null, TUtils.getClock(1, 2)); + Versioned<byte[]> v3_3 = new Versioned<byte[]>(new byte[] { 2 }, TUtils.getClock(1, 2, 1)); + + // delete concurrent to update + Versioned<byte[]> v4_1 = new Versioned<byte[]>(new byte[] { 1 }, TUtils.getClock(1)); + Versioned<byte[]> v4_2 = new Versioned<byte[]>(new byte[] { 2 }, TUtils.getClock(1, 2)); + Versioned<byte[]> v4_3 = new Versioned<byte[]>(null, TUtils.getClock(1, 1)); + + ByteArray key1 = new ByteArray((byte) 3); + ByteArray key2 = new ByteArray((byte) 4); + ByteArray key3 = new ByteArray((byte) 5); + ByteArray key4 = new ByteArray((byte) 6); + + engine.put(key1, v1_1); + assertEquals(1, engine.get(key1).size()); + + engine.put(key1, v1_2); + List<Versioned<byte[]>> r = engine.get(key1); + assertEquals(1, r.size()); + assertNull(r.get(0).getValue()); + + engine.put(key2, v2_1); + engine.put(key2, v2_2); + engine.put(key2, v2_3); + engine.put(key3, v3_1); + engine.put(key3, v3_2); + engine.put(key4, v4_1); + engine.put(key4, v4_2); + engine.put(key4, v4_3); + + engine.cleanupTask(); + r = engine.get(key1); + assertEquals(1, r.size()); + assertNull(r.get(0).getValue()); + + engine.put(key3, v3_3); + + Thread.sleep(501); + engine.cleanupTask(); + r = engine.get(key1); + assertEquals(0, r.size()); + r = engine.get(key2); + assertEquals(0, r.size()); + r = engine.get(key3); + assertEquals(1, r.size()); + r = engine.get(key4); + assertEquals(2, r.size()); + + } + + @SuppressWarnings("unused") + private boolean remove(List<byte[]> list, byte[] item) { + Iterator<byte[]> it = list.iterator(); + boolean removedSomething = false; + while(it.hasNext()) { + if(TUtils.bytesEqual(item, it.next())) { + it.remove(); + removedSomething = true; + } + } + return removedSomething; + } + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/AbstractStoreT.java b/src/test/java/org/sdnplatform/sync/internal/store/AbstractStoreT.java new file mode 100644 index 0000000000000000000000000000000000000000..9f8f22edec20172399954a919d3d3276dc51fcda --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/AbstractStoreT.java @@ -0,0 +1,286 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import org.junit.Test; +import org.sdnplatform.sync.IClosableIterator; +import org.sdnplatform.sync.IVersion; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.error.ObsoleteVersionException; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.internal.TUtils; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.version.VectorClock; + + +import static org.junit.Assert.*; +import static org.sdnplatform.sync.internal.TUtils.*; + +import com.google.common.base.Objects; + +public abstract class AbstractStoreT<K, V> { + + public abstract IStore<K, V> getStore() throws Exception; + + public abstract List<V> getValues(int numValues); + + public abstract List<K> getKeys(int numKeys); + + public List<String> getStrings(int numKeys, int size) { + List<String> ts = new ArrayList<String>(numKeys); + for(int i = 0; i < numKeys; i++) + ts.add(randomLetters(size)); + return ts; + } + + public List<byte[]> getByteValues(int numValues, int size) { + List<byte[]> values = new ArrayList<byte[]>(); + for(int i = 0; i < numValues; i++) + values.add(TUtils.randomBytes(size)); + return values; + } + + public List<ByteArray> getByteArrayValues(int numValues, int size) { + List<ByteArray> values = new ArrayList<ByteArray>(); + for(int i = 0; i < numValues; i++) + values.add(new ByteArray(TUtils.randomBytes(size))); + return values; + } + + public K getKey() { + return getKeys(1).get(0); + } + + public V getValue() { + return getValues(1).get(0); + } + + public IVersion getExpectedVersionAfterPut(IVersion version) { + return version; + } + + protected boolean valuesEqual(V t1, V t2) { + if (t1 instanceof byte[]) return Arrays.equals((byte[])t1, (byte[])t2); + return Objects.equal(t1, t2); + } + + protected void bassertEquals(String message, Versioned<V> v1, Versioned<V> v2) { + String assertTrueMessage = v1 + " != " + v2 + "."; + if(message != null) + assertTrueMessage += message; + assertTrue(assertTrueMessage, valuesEqual(v1.getValue(), v2.getValue())); + assertEquals(message, v1.getVersion(), v2.getVersion()); + } + + protected void bassertEquals(Versioned<V> v1, Versioned<V> v2) { + bassertEquals(null, v1, v2); + } + + public void assertContains(Collection<Versioned<V>> collection, Versioned<V> value) { + boolean found = false; + for(Versioned<V> t: collection) + if(valuesEqual(t.getValue(), value.getValue())) + found = true; + assertTrue(collection + " does not contain " + value + ".", found); + } + + @Test + public void testNullKeys() throws Exception { + IStore<K, V> store = getStore(); + try { + store.put(null, new Versioned<V>(getValue())); + fail("Store should not put null keys!"); + } catch(IllegalArgumentException e) { + // this is good + } + try { + store.get(null); + fail("Store should not get null keys!"); + } catch(IllegalArgumentException e) { + // this is good + } + } + + @Test + public void testPutNullValue() throws Exception { + IStore<K,V> store = getStore(); + K key = getKey(); + store.put(key, new Versioned<V>(null)); + List<Versioned<V>> found = store.get(key); + assertEquals("Wrong number of values.", 1, found.size()); + assertEquals("Returned non-null value.", null, + found.get(0).getValue()); + } + + @Test + public void testGetAndDeleteNonExistentKey() throws Exception { + K key = getKey(); + IStore<K, V> store = getStore(); + List<Versioned<V>> found = store.get(key); + assertEquals("Found non-existent key: " + found, 0, found.size()); + } + + private void testObsoletePutFails(String message, + IStore<K, V> store, + K key, + Versioned<V> versioned) throws SyncException { + VectorClock clock = (VectorClock) versioned.getVersion(); + clock = clock.clone(); + try { + store.put(key, versioned); + fail(message); + } catch(ObsoleteVersionException e) { + // this is good, but check that we didn't fuck with the version + assertEquals(clock, versioned.getVersion()); + } + } + + @Test + public void testFetchedEqualsPut() throws Exception { + K key = getKey(); + IStore<K, V> store = getStore(); + VectorClock clock = getClock(1, 1, 2, 3, 3, 4); + V value = getValue(); + assertEquals("Store not empty at start!", 0, store.get(key).size()); + Versioned<V> versioned = new Versioned<V>(value, clock); + store.put(key, versioned); + List<Versioned<V>> found = store.get(key); + assertEquals("Should only be one version stored.", 1, found.size()); + assertTrue("Values not equal!", valuesEqual(versioned.getValue(), found.get(0).getValue())); + } + + @Test + public void testVersionedPut() throws Exception { + K key = getKey(); + IStore<K, V> store = getStore(); + VectorClock clock = getClock(1, 1); + VectorClock clockCopy = clock.clone(); + V value = getValue(); + assertEquals("Store not empty at start!", 0, store.get(key).size()); + Versioned<V> versioned = new Versioned<V>(value, clock); + + // put initial version + store.put(key, versioned); + assertContains(store.get(key), versioned); + + // test that putting obsolete versions fails + testObsoletePutFails("Put of identical version/value succeeded.", + store, + key, + new Versioned<V>(value, clockCopy)); + testObsoletePutFails("Put of identical version succeeded.", + store, + key, + new Versioned<V>(getValue(), clockCopy)); + testObsoletePutFails("Put of obsolete version succeeded.", + store, + key, + new Versioned<V>(getValue(), getClock(1))); + assertEquals("Should still only be one version in store.", store.get(key).size(), 1); + assertContains(store.get(key), versioned); + + // test that putting a concurrent version succeeds + if(allowConcurrentOperations()) { + store.put(key, new Versioned<V>(getValue(), getClock(1, 2))); + assertEquals(2, store.get(key).size()); + } else { + try { + store.put(key, new Versioned<V>(getValue(), getClock(1, 2))); + fail(); + } catch(ObsoleteVersionException e) { + // expected + } + } + + // test that putting an incremented version succeeds + Versioned<V> newest = new Versioned<V>(getValue(), getClock(1, 1, 2, 2)); + store.put(key, newest); + assertContains(store.get(key), newest); + } + + @Test + public void testGetVersions() throws Exception { + List<K> keys = getKeys(2); + K key = keys.get(0); + V value = getValue(); + IStore<K, V> store = getStore(); + store.put(key, Versioned.value(value)); + List<Versioned<V>> versioneds = store.get(key); + List<IVersion> versions = store.getVersions(key); + assertEquals(1, versioneds.size()); + assertTrue(versions.size() > 0); + for(int i = 0; i < versions.size(); i++) + assertEquals(versioneds.get(0).getVersion(), versions.get(i)); + + assertEquals(0, store.getVersions(keys.get(1)).size()); + } + + @Test + public void testCloseIsIdempotent() throws Exception { + IStore<K, V> store = getStore(); + store.close(); + // second close is okay, should not throw an exception + store.close(); + } + + @Test + public void testEntries() throws Exception { + IStore<K, V> store = getStore(); + int putCount = 537; + List<K> keys = getKeys(putCount); + List<V> values = getValues(putCount); + assertEquals(putCount, values.size()); + for(int i = 0; i < putCount; i++) + store.put(keys.get(i), new Versioned<V>(values.get(i))); + + HashMap<K, V> map = new HashMap<K, V>(); + for (int i = 0; i < keys.size(); i++) { + map.put(keys.get(i), values.get(i)); + } + + IClosableIterator<Entry<K, List<Versioned<V>>>> iter = store.entries(); + int size = 0; + try { + while (iter.hasNext()) { + Entry<K, List<Versioned<V>>> e = iter.next(); + size += 1; + assertGetAllValues(map.get(e.getKey()), e.getValue()); + + } + } finally { + iter.close(); + } + assertEquals("Number of entries", keys.size(), size); + } + + protected void assertGetAllValues(V expectedValue, List<Versioned<V>> versioneds) { + assertEquals(1, versioneds.size()); + valuesEqual(expectedValue, versioneds.get(0).getValue()); + } + + protected boolean allowConcurrentOperations() { + return true; + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/InMemoryStorageEngineTest.java b/src/test/java/org/sdnplatform/sync/internal/store/InMemoryStorageEngineTest.java new file mode 100644 index 0000000000000000000000000000000000000000..84bf376136d0cf3141abf7216ce6eb53b8f77047 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/InMemoryStorageEngineTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.sdnplatform.sync.internal.TUtils; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.store.InMemoryStorageEngine; +import org.sdnplatform.sync.internal.util.ByteArray; + + +public class InMemoryStorageEngineTest extends AbstractStorageEngineT { + + private IStorageEngine<ByteArray, byte[]> store; + + @Override + public IStorageEngine<ByteArray, byte[]> getStorageEngine() { + return store; + } + + @Before + public void setUp() throws Exception { + this.store = new InMemoryStorageEngine<ByteArray, byte[]>("test"); + } + + @Override + public List<ByteArray> getKeys(int numKeys) { + List<ByteArray> keys = new ArrayList<ByteArray>(numKeys); + for(int i = 0; i < numKeys; i++) + keys.add(new ByteArray(TUtils.randomBytes(10))); + return keys; + } + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/JacksonStoreTest.java b/src/test/java/org/sdnplatform/sync/internal/store/JacksonStoreTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0846cf40c73bf5e1af7842a316fd3b9929b3b8d0 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/JacksonStoreTest.java @@ -0,0 +1,46 @@ +package org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.List; + +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.InMemoryStorageEngine; +import org.sdnplatform.sync.internal.store.JacksonStore; +import org.sdnplatform.sync.internal.util.ByteArray; + + +public class JacksonStoreTest extends AbstractStoreT<Key, TBean> { + + @Override + public IStore<Key, TBean> getStore() throws Exception { + IStore<ByteArray,byte[]> ims = + new InMemoryStorageEngine<ByteArray,byte[]>("test"); + IStore<Key,TBean> js = + new JacksonStore<Key, TBean>(ims, Key.class, TBean.class); + return js; + } + + @Override + public List<TBean> getValues(int numValues) { + List<TBean> v = new ArrayList<TBean>(numValues); + for (int i = 0; i < numValues; i++) { + TBean tb = new TBean(); + tb.setI(i); + tb.setS("" + i); + v.add(tb); + } + return v; + } + + @Override + public List<Key> getKeys(int numKeys) { + List<Key> k = new ArrayList<Key>(numKeys); + for (int i = 0; i < numKeys; i++) { + Key tk = new Key("com.bigswitch.bigsync.internal.store", "" + i); + k.add(tk); + } + return k; + } + + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/JavaDBStorageEngineTest.java b/src/test/java/org/sdnplatform/sync/internal/store/JavaDBStorageEngineTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2f01246aef8f66b5287ddc77ac4d749b229644a4 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/JavaDBStorageEngineTest.java @@ -0,0 +1,64 @@ +package org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.List; + +import javax.sql.ConnectionPoolDataSource; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.type.TypeReference; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sdnplatform.sync.internal.TUtils; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.store.JavaDBStorageEngine; +import org.sdnplatform.sync.internal.util.ByteArray; +import org.sdnplatform.sync.internal.version.VectorClock; + +import static org.junit.Assert.*; +import static org.sdnplatform.sync.internal.TUtils.*; + + +public class JavaDBStorageEngineTest extends AbstractStorageEngineT { + + private IStorageEngine<ByteArray, byte[]> store; + + @Before + public void setUp() throws Exception { + ConnectionPoolDataSource dataSource = + JavaDBStorageEngine.getDataSource(true); + this.store = new JavaDBStorageEngine("test", dataSource); + } + + @After + public void tearDown() throws Exception { + this.store.truncate(); + this.store.close(); + this.store = null; + } + + @Override + public IStorageEngine<ByteArray, byte[]> getStorageEngine() { + return store; + } + + @Override + public List<ByteArray> getKeys(int numKeys) { + List<ByteArray> keys = new ArrayList<ByteArray>(numKeys); + for(int i = 0; i < numKeys; i++) + keys.add(new ByteArray(TUtils.randomBytes(10))); + return keys; + } + + @Test + public void testSerialization() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + VectorClock clock = getClock(1,2); + String cs = mapper.writeValueAsString(clock); + VectorClock reconstructed = + mapper.readValue(cs, new TypeReference<VectorClock>() {}); + assertEquals(clock, reconstructed); + } + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/Key.java b/src/test/java/org/sdnplatform/sync/internal/store/Key.java new file mode 100644 index 0000000000000000000000000000000000000000..4f290fb377244d11e07f31ad74c168acb45bc853 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/Key.java @@ -0,0 +1,67 @@ +package org.sdnplatform.sync.internal.store; + +import java.io.Serializable; + +/** + * Represent a key in the sync system. Keys consist of a namespace and a + * key name. Namespaces should be dot-separated such as "com.bigswitch.device" + * @author readams + * + */ +public class Key implements Serializable { + + private static final long serialVersionUID = -3998115385199627376L; + + private String namespace; + private String key; + + public Key() { + super(); + } + + public Key(String namespace, String key) { + super(); + this.namespace = namespace; + this.key = key; + } + + public String getNamespace() { + return namespace; + } + public void setNamespace(String namespace) { + this.namespace = namespace; + } + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = + prime * result + + ((namespace == null) ? 0 : namespace.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Key other = (Key) obj; + if (key == null) { + if (other.key != null) return false; + } else if (!key.equals(other.key)) return false; + if (namespace == null) { + if (other.namespace != null) return false; + } else if (!namespace.equals(other.namespace)) return false; + return true; + } + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java b/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4794abec08601a7494093ad50315804bbf939316 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/RemoteStoreTest.java @@ -0,0 +1,79 @@ +package org.sdnplatform.sync.internal.store; + +import java.util.ArrayList; +import java.util.List; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.debugcounter.IDebugCounterService; +import net.floodlightcontroller.debugcounter.NullDebugCounter; +import net.floodlightcontroller.threadpool.IThreadPoolService; +import net.floodlightcontroller.threadpool.ThreadPool; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.After; +import org.junit.Before; +import org.sdnplatform.sync.ISyncService.Scope; +import org.sdnplatform.sync.internal.SyncManager; +import org.sdnplatform.sync.internal.remote.RemoteSyncManager; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.util.ByteArray; + + +public class RemoteStoreTest extends AbstractStoreT<ByteArray,byte[]> { + ThreadPool tp; + SyncManager syncManager; + protected final static ObjectMapper mapper = new ObjectMapper(); + + RemoteSyncManager remoteSyncManager; + + @Before + public void setUp() throws Exception { + FloodlightModuleContext fmc = new FloodlightModuleContext(); + tp = new ThreadPool(); + + fmc.addService(IThreadPoolService.class, tp); + fmc.addService(IDebugCounterService.class, new NullDebugCounter()); + syncManager = new SyncManager(); + syncManager.registerStore("local", Scope.LOCAL); + + remoteSyncManager = new RemoteSyncManager(); + + tp.init(fmc); + syncManager.init(fmc); + remoteSyncManager.init(fmc); + tp.startUp(fmc); + syncManager.startUp(fmc); + remoteSyncManager.startUp(fmc); + } + + @After + public void tearDown() { + tp.getScheduledExecutor().shutdownNow(); + tp = null; + syncManager.shutdown(); + remoteSyncManager.shutdown(); + } + + @Override + public IStore<ByteArray, byte[]> getStore() throws Exception { + return remoteSyncManager.getStore("local"); + } + + @Override + public List<byte[]> getValues(int numValues) { + ArrayList<byte[]> r = new ArrayList<byte[]>(); + for (int i = 0; i < numValues; i++) { + r.add(Integer.toString(i).getBytes()); + } + return r; + } + + @Override + public List<ByteArray> getKeys(int numKeys) { + ArrayList<ByteArray> r = new ArrayList<ByteArray>(); + for (int i = 0; i < numKeys; i++) { + r.add(new ByteArray(Integer.toString(i).getBytes())); + } + return r; + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/store/TBean.java b/src/test/java/org/sdnplatform/sync/internal/store/TBean.java new file mode 100644 index 0000000000000000000000000000000000000000..5a720438335d420a466f32c4392a3096e515c9dc --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/store/TBean.java @@ -0,0 +1,51 @@ +package org.sdnplatform.sync.internal.store; + +public class TBean { + String s; + int i; + + public TBean(String s, int i) { + super(); + this.s = s; + this.i = i; + } + public TBean() { + super(); + } + public String getS() { + return s; + } + public void setS(String s) { + this.s = s; + } + public int getI() { + return i; + } + public void setI(int i) { + this.i = i; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + i; + result = prime * result + ((s == null) ? 0 : s.hashCode()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + TBean other = (TBean) obj; + if (i != other.i) return false; + if (s == null) { + if (other.s != null) return false; + } else if (!s.equals(other.s)) return false; + return true; + } + @Override + public String toString() { + return "TestBean [s=" + s + ", i=" + i + "]"; + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/version/ClockEntryTest.java b/src/test/java/org/sdnplatform/sync/internal/version/ClockEntryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..46ae2cddd49e6a1ed2a1096a7d2445c1050d8c46 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/version/ClockEntryTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.version; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.sdnplatform.sync.internal.version.ClockEntry; + + +/** + * + */ +public class ClockEntryTest { + + @Test + public void testEquality() { + ClockEntry v1 = new ClockEntry((short) 0, 1); + ClockEntry v2 = new ClockEntry((short) 0, 1); + assertTrue(v1.equals(v1)); + assertTrue(!v1.equals(null)); + assertEquals(v1, v2); + + v1 = new ClockEntry((short) 0, 1); + v2 = new ClockEntry((short) 0, 2); + assertTrue(!v1.equals(v2)); + + v1 = new ClockEntry(Short.MAX_VALUE, 256); + v2 = new ClockEntry(Short.MAX_VALUE, 256); + assertEquals(v1, v2); + } + + @Test + public void testIncrement() { + ClockEntry v = new ClockEntry((short) 0, 1); + assertEquals(v.getNodeId(), 0); + assertEquals(v.getVersion(), 1); + ClockEntry v2 = v.incremented(); + assertEquals(v.getVersion(), 1); + assertEquals(v2.getVersion(), 2); + } + +} diff --git a/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java b/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1ad45ec9cd15400658c48085d8003a82415ce0fd --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/version/VectorClockInconsistencyResolverTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.version; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.sdnplatform.sync.IInconsistencyResolver; +import org.sdnplatform.sync.Versioned; +import org.sdnplatform.sync.internal.TUtils; +import org.sdnplatform.sync.internal.version.VectorClockInconsistencyResolver; + + +public class VectorClockInconsistencyResolverTest { + + private IInconsistencyResolver<Versioned<String>> resolver; + private Versioned<String> later; + private Versioned<String> prior; + private Versioned<String> current; + private Versioned<String> concurrent; + private Versioned<String> concurrent2; + + @Before + public void setUp() { + resolver = new VectorClockInconsistencyResolver<String>(); + current = getVersioned(1, 1, 2, 3); + prior = getVersioned(1, 2, 3); + concurrent = getVersioned(1, 2, 3, 3); + concurrent2 = getVersioned(1, 2, 3, 4); + later = getVersioned(1, 1, 2, 2, 3); + } + + private Versioned<String> getVersioned(int... nodes) { + return new Versioned<String>("my-value", TUtils.getClock(nodes)); + } + + @Test + public void testEmptyList() { + assertEquals(0, resolver.resolveConflicts(new ArrayList<Versioned<String>>()).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void testDuplicatesResolve() { + assertEquals(2, resolver.resolveConflicts(Arrays.asList(concurrent, + current, + current, + concurrent, + current)).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void testResolveNormal() { + assertEquals(later, resolver.resolveConflicts(Arrays.asList(current, prior, later)).get(0)); + assertEquals(later, resolver.resolveConflicts(Arrays.asList(prior, current, later)).get(0)); + assertEquals(later, resolver.resolveConflicts(Arrays.asList(later, current, prior)).get(0)); + } + + @SuppressWarnings("unchecked") + @Test + public void testResolveConcurrent() { + List<Versioned<String>> resolved = resolver.resolveConflicts(Arrays.asList(current, + concurrent, + prior)); + assertEquals(2, resolved.size()); + assertTrue("Version not found", resolved.contains(current)); + assertTrue("Version not found", resolved.contains(concurrent)); + } + + @SuppressWarnings("unchecked") + @Test + public void testResolveLargerConcurrent() { + assertEquals(3, resolver.resolveConflicts(Arrays.asList(concurrent, + concurrent2, + current, + concurrent2, + current, + concurrent, + current)).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void testResolveConcurrentPairWithLater() { + Versioned<String> later2 = getVersioned(1, 2, 3, 3, 4, 4); + List<Versioned<String>> resolved = resolver.resolveConflicts(Arrays.asList(concurrent, + concurrent2, + later2)); + assertEquals(1, resolved.size()); + assertEquals(later2, resolved.get(0)); + } +} diff --git a/src/test/java/org/sdnplatform/sync/internal/version/VectorClockTest.java b/src/test/java/org/sdnplatform/sync/internal/version/VectorClockTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a15c77b4df99b8b5d0e07f79d954bfb9baf58e04 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/internal/version/VectorClockTest.java @@ -0,0 +1,131 @@ +/* + * Copyright 2008-2009 LinkedIn, Inc + * + * 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 org.sdnplatform.sync.internal.version; + +import static org.junit.Assert.*; +import static org.sdnplatform.sync.internal.TUtils.getClockT; + +import org.junit.Test; +import org.sdnplatform.sync.IVersion.Occurred; +import static org.sdnplatform.sync.internal.TUtils.*; + +import org.sdnplatform.sync.internal.version.ClockEntry; +import org.sdnplatform.sync.internal.version.VectorClock; + +import com.google.common.collect.Lists; + +/** + * VectorClock tests + * + * + */ + +public class VectorClockTest { + @Test + public void testEqualsAndHashcode() { + long now = 5555555555L; + VectorClock one = getClockT(now, 1, 2); + VectorClock other = getClockT(now, 1, 2); + assertEquals(one, other); + assertEquals(one.hashCode(), other.hashCode()); + } + + @Test + public void testComparisons() { + assertTrue("The empty clock should not happen before itself.", + getClock().compare(getClock()) != Occurred.CONCURRENTLY); + assertTrue("A clock should not happen before an identical clock.", + getClock(1, 1, 2).compare(getClock(1, 1, 2)) != Occurred.CONCURRENTLY); + assertTrue(" A clock should happen before an identical clock with a single additional event.", + getClock(1, 1, 2).compare(getClock(1, 1, 2, 3)) == Occurred.BEFORE); + assertTrue("Clocks with different events should be concurrent.", + getClock(1).compare(getClock(2)) == Occurred.CONCURRENTLY); + assertTrue("Clocks with different events should be concurrent.", + getClock(1, 1, 2).compare(getClock(1, 1, 3)) == Occurred.CONCURRENTLY); + assertTrue(getClock(2, 2).compare(getClock(1, 2, 2, 3)) == Occurred.BEFORE + && getClock(1, 2, 2, 3).compare(getClock(2, 2)) == Occurred.AFTER); + } + + @Test + public void testMerge() { + // merging two clocks should create a clock contain the element-wise + // maximums + + assertEquals("Two empty clocks merge to an empty clock.", + getClock().merge(getClock()).getEntries(), + getClock().getEntries()); + assertEquals("Merge of a clock with itself does nothing", + getClock(1).merge(getClock(1)).getEntries(), + getClock(1).getEntries()); + assertEquals(getClock(1).merge(getClock(2)).getEntries(), getClock(1, 2).getEntries()); + assertEquals(getClock(1).merge(getClock(1, 2)).getEntries(), getClock(1, 2).getEntries()); + assertEquals(getClock(1, 2).merge(getClock(1)).getEntries(), getClock(1, 2).getEntries()); + assertEquals("Two-way merge fails.", + getClock(1, 1, 1, 2, 3, 5).merge(getClock(1, 2, 2, 4)).getEntries(), + getClock(1, 1, 1, 2, 2, 3, 4, 5).getEntries()); + assertEquals(getClock(2, 3, 5).merge(getClock(1, 2, 2, 4, 7)).getEntries(), + getClock(1, 2, 2, 3, 4, 5, 7).getEntries()); + } + + /** + * See gihub issue #25: Incorrect coersion of version to short before + * passing to ClockEntry constructor + */ + @Test + public void testMergeWithLargeVersion() { + VectorClock clock1 = getClock(1); + VectorClock clock2 = new VectorClock(Lists.newArrayList(new ClockEntry((short) 1, + Short.MAX_VALUE + 1)), + System.currentTimeMillis()); + VectorClock mergedClock = clock1.merge(clock2); + assertEquals(mergedClock.getMaxVersion(), Short.MAX_VALUE + 1); + } + + @Test + public void testIncrementOrderDoesntMatter() { + // Clocks should have the property that no matter what order the + // increment operations are done in the resulting clocks are equal + int numTests = 10; + int numNodes = 10; + int numValues = 100; + VectorClock[] clocks = new VectorClock[numNodes]; + for(int t = 0; t < numTests; t++) { + int[] test = randomInts(numNodes, numValues); + for(int n = 0; n < numNodes; n++) + clocks[n] = getClock(shuffle(test)); + // test all are equal + for(int n = 0; n < numNodes - 1; n++) + assertEquals("Clock " + n + " and " + (n + 1) + " are not equal.", + clocks[n].getEntries(), + clocks[n + 1].getEntries()); + } + } +/* + public void testIncrementAndSerialize() { + int node = 1; + VectorClock vc = getClock(node); + assertEquals(node, vc.getMaxVersion()); + int increments = 3000; + for(int i = 0; i < increments; i++) { + vc.incrementVersion(node, 45); + // serialize + vc = new VectorClock(vc.toBytes()); + } + assertEquals(increments + 1, vc.getMaxVersion()); + } */ + +} diff --git a/src/test/java/org/sdnplatform/sync/test/MockSyncService.java b/src/test/java/org/sdnplatform/sync/test/MockSyncService.java new file mode 100644 index 0000000000000000000000000000000000000000..e4f1c63261b897bc55875d5db0c8bdfb4a51c5e9 --- /dev/null +++ b/src/test/java/org/sdnplatform/sync/test/MockSyncService.java @@ -0,0 +1,122 @@ +package org.sdnplatform.sync.test; + +import java.util.Collection; +import java.util.HashMap; + +import org.sdnplatform.sync.ISyncService; +import org.sdnplatform.sync.error.SyncException; +import org.sdnplatform.sync.error.UnknownStoreException; +import org.sdnplatform.sync.internal.AbstractSyncManager; +import org.sdnplatform.sync.internal.store.IStorageEngine; +import org.sdnplatform.sync.internal.store.IStore; +import org.sdnplatform.sync.internal.store.InMemoryStorageEngine; +import org.sdnplatform.sync.internal.store.ListenerStorageEngine; +import org.sdnplatform.sync.internal.store.MappingStoreListener; +import org.sdnplatform.sync.internal.util.ByteArray; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightService; + + +/** + * Mock sync service useful for testing + * @author readams + */ +public class MockSyncService extends AbstractSyncManager { + /** + * The storage engines that contain the locally-stored data + */ + private HashMap<String,ListenerStorageEngine> localStores = + new HashMap<String, ListenerStorageEngine>(); + + + // ************ + // ISyncService + // ************ + + @Override + public void registerStore(String storeName, Scope scope) + throws SyncException { + ListenerStorageEngine store = localStores.get(storeName); + if (store != null) return; + IStorageEngine<ByteArray, byte[]> memstore = + new InMemoryStorageEngine<ByteArray, byte[]>(storeName); + store = new ListenerStorageEngine(memstore, null); + localStores.put(storeName, store); + } + + /** + * Persistent stores are not actually persistent in the mock sync service + * @see ISyncService#registerPersistentStore(String, + * org.sdnplatform.sync.ISyncService.Scope) + */ + @Override + public void registerPersistentStore(String storeName, Scope scope) + throws SyncException { + registerStore(storeName, scope); + } + + // ***************** + // IFloodlightModule + // ***************** + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + + } + + @Override + public void startUp(FloodlightModuleContext context) + throws FloodlightModuleException { + + } + + @Override + public Collection<Class<? extends IFloodlightService>> + getModuleDependencies() { + return null; + } + + // ******************* + // AbstractSyncManager + // ******************* + + @Override + public IStore<ByteArray, byte[]> + getStore(String storeName) throws UnknownStoreException { + return localStores.get(storeName); + } + + @Override + public short getLocalNodeId() { + return Short.MAX_VALUE; + } + + @Override + public void addListener(String storeName, MappingStoreListener listener) + throws UnknownStoreException { + ListenerStorageEngine store = localStores.get(storeName); + if (store == null) + throw new UnknownStoreException("Store " + storeName + + " has not been registered"); + store.addListener(listener); + } + + @Override + public void shutdown() { + + } + + // *************** + // MockSyncService + // *************** + + /** + * Reset to pristine condition + */ + public void reset() { + localStores = new HashMap<String, ListenerStorageEngine>(); + } +}