Initially working on flatbuffers backend
diff --git a/FbsKerbydata.mon b/FbsKerbydata.mon
new file mode 100644
index 0000000..355dd76
--- /dev/null
+++ b/FbsKerbydata.mon
Binary files differ
diff --git a/kerby-backend/flatbuffers-backend/CodeGen.sh b/kerby-backend/flatbuffers-backend/CodeGen.sh
new file mode 100644
index 0000000..aa4ece6
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/CodeGen.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+# To be refined, considering license headers, formats and etc.
+flatc -j --gen-mutable -o src/main/java src/schema/kerby.fbs
\ No newline at end of file
diff --git a/kerby-backend/flatbuffers-backend/pom.xml b/kerby-backend/flatbuffers-backend/pom.xml
new file mode 100644
index 0000000..772a831
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerby-backend</artifactId>
+ <version>1.0.0-RC2-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>flatbuffers-backend</artifactId>
+
+ <name>Flatbuffers identity backend</name>
+ <description>Flatbuffers identity backend</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerby-config</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-identity</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kerby</groupId>
+ <artifactId>kerb-identity-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.3.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Constants.java b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Constants.java
new file mode 100644
index 0000000..67585d7
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Constants.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+// Class that holds shared constants.
+
+public class Constants {
+ // Java doesn't seem to have these.
+ static final int SIZEOF_SHORT = 2;
+ static final int SIZEOF_INT = 4;
+ static final int FILE_IDENTIFIER_LENGTH = 4;
+}
+
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/FlatBufferBuilder.java b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/FlatBufferBuilder.java
new file mode 100644
index 0000000..368be2f
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/FlatBufferBuilder.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.util.Arrays;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Class that helps you build a FlatBuffer. See the section
+ * <a href="http://google.github.io/flatbuffers/md__java_usage.html">"Use in Java"</a> in the
+ * main FlatBuffers documentation.
+ */
+public class FlatBufferBuilder {
+ ByteBuffer bb; // Where we construct the FlatBuffer.
+ int space; // Remaining space in the ByteBuffer.
+ static final Charset utf8charset = Charset.forName("UTF-8");
+ int minalign = 1; // Minimum alignment encountered so far.
+ int[] vtable = null; // The vtable for the current table.
+ int vtable_in_use = 0; // The amount of fields we're actually using.
+ boolean nested = false; // Whether we are currently serializing a table.
+ int object_start; // Starting offset of the current struct/table.
+ int[] vtables = new int[16]; // List of offsets of all vtables.
+ int num_vtables = 0; // Number of entries in `vtables` in use.
+ int vector_num_elems = 0; // For the current vector being built.
+ boolean force_defaults = false; // False omits default values from the serialized data
+
+ /**
+ * Start with a buffer of size {@code initial_size}, then grow as required.
+ *
+ * @param initial_size The initial size of the internal buffer to use
+ */
+ public FlatBufferBuilder(int initial_size) {
+ if (initial_size <= 0) initial_size = 1;
+ space = initial_size;
+ bb = newByteBuffer(initial_size);
+ }
+
+ /**
+ * Start with a buffer of 1KiB, then grow as required.
+ */
+ public FlatBufferBuilder() {
+ this(1024);
+ }
+
+ /**
+ * Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
+ * can still grow the buffer as necessary. User classes should make sure
+ * to call {@link #dataBuffer()} to obtain the resulting encoded message
+ *
+ * @param existing_bb The byte buffer to reuse
+ */
+ public FlatBufferBuilder(ByteBuffer existing_bb) {
+ init(existing_bb);
+ }
+
+ /**
+ * Alternative initializer that allows reusing this object on an existing
+ * ByteBuffer. This method resets the builder's internal state, but keeps
+ * objects that have been allocated for temporary storage.
+ *
+ * @param existing_bb The byte buffer to reuse
+ * @return this
+ */
+ public FlatBufferBuilder init(ByteBuffer existing_bb){
+ bb = existing_bb;
+ bb.clear();
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+ minalign = 1;
+ space = bb.capacity();
+ vtable_in_use = 0;
+ nested = false;
+ object_start = 0;
+ num_vtables = 0;
+ vector_num_elems = 0;
+ return this;
+ }
+
+ static ByteBuffer newByteBuffer(int capacity) {
+ ByteBuffer newbb = ByteBuffer.allocate(capacity);
+ newbb.order(ByteOrder.LITTLE_ENDIAN);
+ return newbb;
+ }
+
+ /**
+ * Doubles the size of the backing {link ByteBuffer} and copies the old data towards the
+ * end of the new buffer (since we build the buffer backwards).
+ *
+ * @param bb The current buffer with the existing data
+ * @return A new byte buffer with the old data copied copied to it. The data is
+ * located at the end of the buffer.
+ */
+ static ByteBuffer growByteBuffer(ByteBuffer bb) {
+ int old_buf_size = bb.capacity();
+ if ((old_buf_size & 0xC0000000) != 0) // Ensure we don't grow beyond what fits in an int.
+ throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
+ int new_buf_size = old_buf_size << 1;
+ bb.position(0);
+ ByteBuffer nbb = newByteBuffer(new_buf_size);
+ nbb.position(new_buf_size - old_buf_size);
+ nbb.put(bb);
+ return nbb;
+ }
+
+ /**
+ * Offset relative to the end of the buffer.
+ *
+ * @return Offset relative to the end of the buffer.
+ */
+ public int offset() {
+ return bb.capacity() - space;
+ }
+
+ /**
+ * Add zero valued bytes to prepare a new entry to be added
+ *
+ * @param byte_size Number of bytes to add.
+ */
+ public void pad(int byte_size) {
+ for (int i = 0; i < byte_size; i++) bb.put(--space, (byte)0);
+ }
+
+ /**
+ * Prepare to write an element of {@code size} after {@code additional_bytes}
+ * have been written, e.g. if you write a string, you need to align such
+ * the int length field is aligned to {@link com.google.flatbuffers.Constants#SIZEOF_INT}, and
+ * the string data follows it directly. If all you need to do is alignment, {@code additional_bytes}
+ * will be 0.
+ *
+ * @param size This is the of the new element to write
+ * @param additional_bytes The padding size
+ */
+ public void prep(int size, int additional_bytes) {
+ // Track the biggest thing we've ever aligned to.
+ if (size > minalign) minalign = size;
+ // Find the amount of alignment needed such that `size` is properly
+ // aligned after `additional_bytes`
+ int align_size = ((~(bb.capacity() - space + additional_bytes)) + 1) & (size - 1);
+ // Reallocate the buffer if needed.
+ while (space < align_size + size + additional_bytes) {
+ int old_buf_size = bb.capacity();
+ bb = growByteBuffer(bb);
+ space += bb.capacity() - old_buf_size;
+ }
+ pad(align_size);
+ }
+
+ // Add a scalar to the buffer, backwards from the current location.
+ // Doesn't align nor check for space.
+ public void putBoolean(boolean x) { bb.put (space -= 1, (byte)(x ? 1 : 0)); }
+ public void putByte (byte x) { bb.put (space -= 1, x); }
+ public void putShort (short x) { bb.putShort (space -= 2, x); }
+ public void putInt (int x) { bb.putInt (space -= 4, x); }
+ public void putLong (long x) { bb.putLong (space -= 8, x); }
+ public void putFloat (float x) { bb.putFloat (space -= 4, x); }
+ public void putDouble (double x) { bb.putDouble(space -= 8, x); }
+
+ // Adds a scalar to the buffer, properly aligned, and the buffer grown
+ // if needed.
+ public void addBoolean(boolean x) { prep(1, 0); putBoolean(x); }
+ public void addByte (byte x) { prep(1, 0); putByte (x); }
+ public void addShort (short x) { prep(2, 0); putShort (x); }
+ public void addInt (int x) { prep(4, 0); putInt (x); }
+ public void addLong (long x) { prep(8, 0); putLong (x); }
+ public void addFloat (float x) { prep(4, 0); putFloat (x); }
+ public void addDouble (double x) { prep(8, 0); putDouble (x); }
+
+ /**
+ * Adds on offset, relative to where it will be written.
+ *
+ * @param off The offset to add
+ */
+ public void addOffset(int off) {
+ prep(SIZEOF_INT, 0); // Ensure alignment is already done.
+ assert off <= offset();
+ off = offset() - off + SIZEOF_INT;
+ putInt(off);
+ }
+
+ /**
+ * Start a new array/vector of objects. Users usually will not call
+ * this directly. The {@code FlatBuffers} compiler will create a start/end
+ * method for vector types in generated code.
+ * <p>
+ * The expected sequence of calls is:
+ * <ol>
+ * <li>Start the array using this method.</li>
+ * <li>Call {@link #addOffset(int)} {@code num_elems} number of times to set
+ * the offset of each element in the array.</li>
+ * <li>Call {@link #endVector()} to retrieve the offset of the array.</li>
+ * </ol>
+ * <p>
+ * For example, to create an array of strings, do:
+ * <pre>{@code
+ * // Need 10 strings
+ * FlatBufferBuilder builder = new FlatBufferBuilder(existingBuffer);
+ * int[] offsets = new int[10];
+ *
+ * for (int i = 0; i < 10; i++) {
+ * offsets[i] = fbb.createString(" " + i);
+ * }
+ *
+ * // Have the strings in the buffer, but don't have a vector.
+ * // Add a vector that references the newly created strings:
+ * builder.startVector(4, offsets.length, 4);
+ *
+ * // Add each string to the newly created vector
+ * // The strings are added in reverse order since the buffer
+ * // is filled in back to front
+ * for (int i = offsets.length - 1; i >= 0; i--) {
+ * builder.addOffset(offsets[i]);
+ * }
+ *
+ * // Finish off the vector
+ * int offsetOfTheVector = fbb.endVector();
+ * }</pre>
+ *
+ * @param elem_size The size of each element in the array
+ * @param num_elems The number of elements in the array
+ * @param alignment The alignment of the array
+ */
+ public void startVector(int elem_size, int num_elems, int alignment) {
+ notNested();
+ vector_num_elems = num_elems;
+ prep(SIZEOF_INT, elem_size * num_elems);
+ prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+ }
+
+ /**
+ * Finish off the creation of an array and all its elements. The array
+ * must be created with {@link #startVector(int, int, int)}.
+ *
+ * @return The offset at which the newly created array starts.
+ * @see #startVector(int, int, int)
+ */
+ public int endVector() {
+ putInt(vector_num_elems);
+ return offset();
+ }
+
+ /**
+ * Encode the string {@code s} in the buffer using UTF-8.
+ *
+ * @param s The string to encode
+ * @return The offset in the buffer where the encoded string starts
+ */
+ public int createString(String s) {
+ byte[] utf8 = s.getBytes(utf8charset);
+ addByte((byte)0);
+ startVector(1, utf8.length, 1);
+ bb.position(space -= utf8.length);
+ bb.put(utf8, 0, utf8.length);
+ return endVector();
+ }
+
+ /**
+ * Encode the string {@code s} in the buffer using UTF-8.
+ *
+ * @param s An already encoded UTF-8 string
+ * @return The offset in the buffer where the encoded string starts
+ */
+ public int createString(ByteBuffer s) {
+ int length = s.remaining();
+ addByte((byte)0);
+ startVector(1, length, 1);
+ bb.position(space -= length);
+ bb.put(s);
+ return endVector();
+ }
+
+ /**
+ * Should not be creating any other object, string or vector
+ * while an object is being constructed
+ */
+ public void notNested() {
+ if (nested)
+ throw new AssertionError("FlatBuffers: object serialization must not be nested.");
+ }
+
+ /**
+ * Structures are always stored inline, they need to be created right
+ * where they're used. You'll get this assertion failure if you
+ * created it elsewhere.
+ *
+ * @param obj The offset of the created object
+ */
+ public void Nested(int obj) {
+ if (obj != offset())
+ throw new AssertionError("FlatBuffers: struct must be serialized inline.");
+ }
+
+ /**
+ * Start encoding a new object in the buffer. Users will not usually need to
+ * call this directly. The {@code FlatBuffers} compiler will generate helper methods
+ * that call this method internally.
+ * <p>
+ * For example, using the "Monster" code found on the
+ * <a href="http://google.github.io/flatbuffers/md__java_usage.html">landing page</a>. An
+ * object of type {@code Monster} can be created using the following code:
+ *
+ * <pre>{@code
+ * int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
+ * fbb.createString("test1"),
+ * fbb.createString("test2")
+ * });
+ *
+ * Monster.startMonster(fbb);
+ * Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+ * Color.Green, (short)5, (byte)6));
+ * Monster.addHp(fbb, (short)80);
+ * Monster.addName(fbb, str);
+ * Monster.addInventory(fbb, inv);
+ * Monster.addTestType(fbb, (byte)Any.Monster);
+ * Monster.addTest(fbb, mon2);
+ * Monster.addTest4(fbb, test4);
+ * Monster.addTestarrayofstring(fbb, testArrayOfString);
+ * int mon = Monster.endMonster(fbb);
+ * }</pre>
+ * <p>
+ * Here:
+ * <ul>
+ * <li>The call to {@code Monster#startMonster(FlatBufferBuilder)} will call this
+ * method with the right number of fields set.</li>
+ * <li>{@code Monster#endMonster(FlatBufferBuilder)} will ensure {@link #endObject()} is called.</li>
+ * </ul>
+ * <p>
+ * It's not recommended to call this method directly. If it's called manually, you must ensure
+ * to audit all calls to it whenever fields are added or removed from your schema. This is
+ * automatically done by the code generated by the {@code FlatBuffers} compiler.
+ *
+ * @param numfields The number of fields found in this object.
+ */
+ public void startObject(int numfields) {
+ notNested();
+ if (vtable == null || vtable.length < numfields) vtable = new int[numfields];
+ vtable_in_use = numfields;
+ Arrays.fill(vtable, 0, vtable_in_use, 0);
+ nested = true;
+ object_start = offset();
+ }
+
+ // Add a scalar to a table at `o` into its vtable, with value `x` and default `d`
+ public void addBoolean(int o, boolean x, boolean d) { if(force_defaults || x != d) { addBoolean(x); slot(o); } }
+ public void addByte (int o, byte x, int d) { if(force_defaults || x != d) { addByte (x); slot(o); } }
+ public void addShort (int o, short x, int d) { if(force_defaults || x != d) { addShort (x); slot(o); } }
+ public void addInt (int o, int x, int d) { if(force_defaults || x != d) { addInt (x); slot(o); } }
+ public void addLong (int o, long x, long d) { if(force_defaults || x != d) { addLong (x); slot(o); } }
+ public void addFloat (int o, float x, double d) { if(force_defaults || x != d) { addFloat (x); slot(o); } }
+ public void addDouble (int o, double x, double d) { if(force_defaults || x != d) { addDouble (x); slot(o); } }
+ public void addOffset (int o, int x, int d) { if(force_defaults || x != d) { addOffset (x); slot(o); } }
+
+ // Structs are stored inline, so nothing additional is being added. `d` is always 0.
+ public void addStruct(int voffset, int x, int d) {
+ if(x != d) {
+ Nested(x);
+ slot(voffset);
+ }
+ }
+
+ // Set the current vtable at `voffset` to the current location in the buffer.
+ public void slot(int voffset) {
+ vtable[voffset] = offset();
+ }
+
+ /**
+ * Finish off writing the object that is under construction.
+ *
+ * @return The offset to the object inside {@link #dataBuffer()}
+ * @see #startObject(int)
+ */
+ public int endObject() {
+ if (vtable == null || !nested)
+ throw new AssertionError("FlatBuffers: endObject called without startObject");
+ addInt(0);
+ int vtableloc = offset();
+ // Write out the current vtable.
+ for (int i = vtable_in_use - 1; i >= 0 ; i--) {
+ // Offset relative to the start of the table.
+ short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0);
+ addShort(off);
+ }
+
+ final int standard_fields = 2; // The fields below:
+ addShort((short)(vtableloc - object_start));
+ addShort((short)((vtable_in_use + standard_fields) * SIZEOF_SHORT));
+
+ // Search for an existing vtable that matches the current one.
+ int existing_vtable = 0;
+ outer_loop:
+ for (int i = 0; i < num_vtables; i++) {
+ int vt1 = bb.capacity() - vtables[i];
+ int vt2 = space;
+ short len = bb.getShort(vt1);
+ if (len == bb.getShort(vt2)) {
+ for (int j = SIZEOF_SHORT; j < len; j += SIZEOF_SHORT) {
+ if (bb.getShort(vt1 + j) != bb.getShort(vt2 + j)) {
+ continue outer_loop;
+ }
+ }
+ existing_vtable = vtables[i];
+ break outer_loop;
+ }
+ }
+
+ if (existing_vtable != 0) {
+ // Found a match:
+ // Remove the current vtable.
+ space = bb.capacity() - vtableloc;
+ // Point table to existing vtable.
+ bb.putInt(space, existing_vtable - vtableloc);
+ } else {
+ // No match:
+ // Add the location of the current vtable to the list of vtables.
+ if (num_vtables == vtables.length) vtables = Arrays.copyOf(vtables, num_vtables * 2);
+ vtables[num_vtables++] = offset();
+ // Point table to current vtable.
+ bb.putInt(bb.capacity() - vtableloc, offset() - vtableloc);
+ }
+
+ nested = false;
+ return vtableloc;
+ }
+
+ // This checks a required field has been set in a given table that has
+ // just been constructed.
+ public void required(int table, int field) {
+ int table_start = bb.capacity() - table;
+ int vtable_start = table_start - bb.getInt(table_start);
+ boolean ok = bb.getShort(vtable_start + field) != 0;
+ // If this fails, the caller will show what field needs to be set.
+ if (!ok)
+ throw new AssertionError("FlatBuffers: field " + field + " must be set");
+ }
+
+ public void finish(int root_table) {
+ prep(minalign, SIZEOF_INT);
+ addOffset(root_table);
+ bb.position(space);
+ }
+
+ public void finish(int root_table, String file_identifier) {
+ prep(minalign, SIZEOF_INT + FILE_IDENTIFIER_LENGTH);
+ if (file_identifier.length() != FILE_IDENTIFIER_LENGTH)
+ throw new AssertionError("FlatBuffers: file identifier must be length " +
+ FILE_IDENTIFIER_LENGTH);
+ for (int i = FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+ addByte((byte)file_identifier.charAt(i));
+ }
+ finish(root_table);
+ }
+
+ /**
+ * In order to save space, fields that are set to their default value
+ * don't get serialized into the buffer. Forcing defaults provides a
+ * way to manually disable this optimization.
+ *
+ * @param forceDefaults true always serializes default values
+ * @return this
+ */
+ public FlatBufferBuilder forceDefaults(boolean forceDefaults){
+ this.force_defaults = forceDefaults;
+ return this;
+ }
+
+ // Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+ // called finish(). The actual data starts at the ByteBuffer's current position,
+ // not necessarily at 0.
+ public ByteBuffer dataBuffer() { return bb; }
+
+ /**
+ * The FlatBuffer data doesn't start at offset 0 in the {@link ByteBuffer}, but
+ * now the {@code ByteBuffer}'s position is set to that location upon {@link #finish(int)}.
+ *
+ * @return The {@link ByteBuffer#position() position} the data starts in {@link #dataBuffer()}
+ * @deprecated This method should not be needed anymore, but is left
+ * here for the moment to document this API change. It will be removed in the future.
+ */
+ @Deprecated
+ private int dataStart() {
+ return space;
+ }
+
+ /**
+ * Utility function for copying a byte array from {@code start} to
+ * {@code start} + {@code length}
+ *
+ * @param start Start copying at this offset
+ * @param length How many bytes to copy
+ * @return A range copy of the {@link #dataBuffer() data buffer}
+ * @throws IndexOutOfBoundsException If the range of bytes is ouf of bound
+ */
+ public byte[] sizedByteArray(int start, int length){
+ byte[] array = new byte[length];
+ bb.position(start);
+ bb.get(array);
+ return array;
+ }
+
+ /**
+ * Utility function for copying a byte array that starts at 0.
+ *
+ * @return A full copy of the {@link #dataBuffer() data buffer}
+ */
+ public byte[] sizedByteArray() {
+ return sizedByteArray(space, bb.capacity() - space);
+ }
+}
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Struct.java b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Struct.java
new file mode 100644
index 0000000..9e6fe4a
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Struct.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+
+// All structs in the generated code derive from this class, and add their own accessors.
+public class Struct {
+ protected int bb_pos;
+ protected ByteBuffer bb;
+}
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Table.java b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Table.java
new file mode 100644
index 0000000..c4a9375
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/com/google/flatbuffers/Table.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+// All tables in the generated code derive from this class, and add their own accessors.
+public class Table {
+ protected int bb_pos;
+ protected ByteBuffer bb;
+
+ public ByteBuffer getByteBuffer() { return bb; }
+
+ // Look up a field in the vtable, return an offset into the object, or 0 if the field is not
+ // present.
+ protected int __offset(int vtable_offset) {
+ int vtable = bb_pos - bb.getInt(bb_pos);
+ return vtable_offset < bb.getShort(vtable) ? bb.getShort(vtable + vtable_offset) : 0;
+ }
+
+ // Retrieve the relative offset stored at "offset"
+ protected int __indirect(int offset) {
+ return offset + bb.getInt(offset);
+ }
+
+ // Create a java String from UTF-8 data stored inside the flatbuffer.
+ // This allocates a new string and converts to wide chars upon each access,
+ // which is not very efficient. Instead, each FlatBuffer string also comes with an
+ // accessor based on __vector_as_bytebuffer below, which is much more efficient,
+ // assuming your Java program can handle UTF-8 data directly.
+ protected String __string(int offset) {
+ offset += bb.getInt(offset);
+ if (bb.hasArray()) {
+ return new String(bb.array(), bb.arrayOffset() + offset + SIZEOF_INT, bb.getInt(offset), FlatBufferBuilder.utf8charset);
+ } else {
+ // We can't access .array(), since the ByteBuffer is read-only,
+ // off-heap or a memory map
+ ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
+ // We're forced to make an extra copy:
+ byte[] copy = new byte[bb.getInt(offset)];
+ bb.position(offset + SIZEOF_INT);
+ bb.get(copy);
+ return new String(copy, 0, copy.length, FlatBufferBuilder.utf8charset);
+ }
+ }
+
+ // Get the length of a vector whose offset is stored at "offset" in this object.
+ protected int __vector_len(int offset) {
+ offset += bb_pos;
+ offset += bb.getInt(offset);
+ return bb.getInt(offset);
+ }
+
+ // Get the start of data of a vector whose offset is stored at "offset" in this object.
+ protected int __vector(int offset) {
+ offset += bb_pos;
+ return offset + bb.getInt(offset) + SIZEOF_INT; // data starts after the length
+ }
+
+ // Get a whole vector as a ByteBuffer. This is efficient, since it only allocates a new
+ // bytebuffer object, but does not actually copy the data, it still refers to the same
+ // bytes as the original ByteBuffer.
+ // Also useful with nested FlatBuffers etc.
+ protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
+ int o = __offset(vector_offset);
+ if (o == 0) return null;
+ ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
+ int vectorstart = __vector(o);
+ bb.position(vectorstart);
+ bb.limit(vectorstart + __vector_len(o) * elem_size);
+ return bb;
+ }
+
+ // Initialize any Table-derived type to point to the union at the given offset.
+ protected Table __union(Table t, int offset) {
+ offset += bb_pos;
+ t.bb_pos = offset + bb.getInt(offset);
+ t.bb = bb;
+ return t;
+ }
+
+ protected static boolean __has_identifier(ByteBuffer bb, String ident) {
+ if (ident.length() != FILE_IDENTIFIER_LENGTH)
+ throw new AssertionError("FlatBuffers: file identifier must be length " +
+ FILE_IDENTIFIER_LENGTH);
+ for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
+ if (ident.charAt(i) != (char)bb.get(bb.position() + SIZEOF_INT + i)) return false;
+ }
+ return true;
+ }
+}
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsEncryptionKey.java b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsEncryptionKey.java
new file mode 100644
index 0000000..3600666
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsEncryptionKey.java
@@ -0,0 +1,42 @@
+// automatically generated, do not modify
+
+package org.apache.kerby.kerberos.kdc.identitybackend;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class FbsEncryptionKey extends Table {
+ public static FbsEncryptionKey getRootAsFbsEncryptionKey(ByteBuffer _bb) { return getRootAsFbsEncryptionKey(_bb, new FbsEncryptionKey()); }
+ public static FbsEncryptionKey getRootAsFbsEncryptionKey(ByteBuffer _bb, FbsEncryptionKey obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public FbsEncryptionKey __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public int keyType() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+ public boolean mutateKeyType(int keyType) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, keyType); return true; } else { return false; } }
+ public byte keyValue(int j) { int o = __offset(6); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
+ public int keyValueLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }
+ public ByteBuffer keyValueAsByteBuffer() { return __vector_as_bytebuffer(6, 1); }
+ public boolean mutateKeyValue(int j, byte keyValue) { int o = __offset(6); if (o != 0) { bb.put(__vector(o) + j * 1, keyValue); return true; } else { return false; } }
+
+ public static int createFbsEncryptionKey(FlatBufferBuilder builder,
+ int keyType,
+ int keyValue) {
+ builder.startObject(2);
+ FbsEncryptionKey.addKeyValue(builder, keyValue);
+ FbsEncryptionKey.addKeyType(builder, keyType);
+ return FbsEncryptionKey.endFbsEncryptionKey(builder);
+ }
+
+ public static void startFbsEncryptionKey(FlatBufferBuilder builder) { builder.startObject(2); }
+ public static void addKeyType(FlatBufferBuilder builder, int keyType) { builder.addInt(0, keyType, 0); }
+ public static void addKeyValue(FlatBufferBuilder builder, int keyValueOffset) { builder.addOffset(1, keyValueOffset, 0); }
+ public static int createKeyValueVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+ public static void startKeyValueVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+ public static int endFbsEncryptionKey(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsKerby.java b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsKerby.java
new file mode 100644
index 0000000..21f8363
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsKerby.java
@@ -0,0 +1,42 @@
+// automatically generated, do not modify
+
+package org.apache.kerby.kerberos.kdc.identitybackend;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class FbsKerby extends Table {
+ public static FbsKerby getRootAsFbsKerby(ByteBuffer _bb) { return getRootAsFbsKerby(_bb, new FbsKerby()); }
+ public static FbsKerby getRootAsFbsKerby(ByteBuffer _bb, FbsKerby obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public FbsKerby __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
+ public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
+ public FbsKrbIdentity identities(int j) { return identities(new FbsKrbIdentity(), j); }
+ public FbsKrbIdentity identities(FbsKrbIdentity obj, int j) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
+ public int identitiesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }
+
+ public static int createFbsKerby(FlatBufferBuilder builder,
+ int name,
+ int identities) {
+ builder.startObject(2);
+ FbsKerby.addIdentities(builder, identities);
+ FbsKerby.addName(builder, name);
+ return FbsKerby.endFbsKerby(builder);
+ }
+
+ public static void startFbsKerby(FlatBufferBuilder builder) { builder.startObject(2); }
+ public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); }
+ public static void addIdentities(FlatBufferBuilder builder, int identitiesOffset) { builder.addOffset(1, identitiesOffset, 0); }
+ public static int createIdentitiesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+ public static void startIdentitiesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+ public static int endFbsKerby(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+ public static void finishFbsKerbyBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsKrbIdentity.java b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsKrbIdentity.java
new file mode 100644
index 0000000..13a1314
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsKrbIdentity.java
@@ -0,0 +1,56 @@
+// automatically generated, do not modify
+
+package org.apache.kerby.kerberos.kdc.identitybackend;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class FbsKrbIdentity extends Table {
+ public static FbsKrbIdentity getRootAsFbsKrbIdentity(ByteBuffer _bb) { return getRootAsFbsKrbIdentity(_bb, new FbsKrbIdentity()); }
+ public static FbsKrbIdentity getRootAsFbsKrbIdentity(ByteBuffer _bb, FbsKrbIdentity obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public FbsKrbIdentity __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public FbsPrincipalName principal() { return principal(new FbsPrincipalName()); }
+ public FbsPrincipalName principal(FbsPrincipalName obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+ public int keyVersion() { int o = __offset(6); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+ public boolean mutateKeyVersion(int keyVersion) { int o = __offset(6); if (o != 0) { bb.putInt(o + bb_pos, keyVersion); return true; } else { return false; } }
+ public int kdcFlags() { int o = __offset(8); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+ public boolean mutateKdcFlags(int kdcFlags) { int o = __offset(8); if (o != 0) { bb.putInt(o + bb_pos, kdcFlags); return true; } else { return false; } }
+ public boolean disabled() { int o = __offset(10); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
+ public boolean mutateDisabled(boolean disabled) { int o = __offset(10); if (o != 0) { bb.put(o + bb_pos, (byte)(disabled ? 1 : 0)); return true; } else { return false; } }
+ public FbsEncryptionKey keys(int j) { return keys(new FbsEncryptionKey(), j); }
+ public FbsEncryptionKey keys(FbsEncryptionKey obj, int j) { int o = __offset(12); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
+ public int keysLength() { int o = __offset(12); return o != 0 ? __vector_len(o) : 0; }
+
+ public static int createFbsKrbIdentity(FlatBufferBuilder builder,
+ int principal,
+ int keyVersion,
+ int kdcFlags,
+ boolean disabled,
+ int keys) {
+ builder.startObject(5);
+ FbsKrbIdentity.addKeys(builder, keys);
+ FbsKrbIdentity.addKdcFlags(builder, kdcFlags);
+ FbsKrbIdentity.addKeyVersion(builder, keyVersion);
+ FbsKrbIdentity.addPrincipal(builder, principal);
+ FbsKrbIdentity.addDisabled(builder, disabled);
+ return FbsKrbIdentity.endFbsKrbIdentity(builder);
+ }
+
+ public static void startFbsKrbIdentity(FlatBufferBuilder builder) { builder.startObject(5); }
+ public static void addPrincipal(FlatBufferBuilder builder, int principalOffset) { builder.addOffset(0, principalOffset, 0); }
+ public static void addKeyVersion(FlatBufferBuilder builder, int keyVersion) { builder.addInt(1, keyVersion, 0); }
+ public static void addKdcFlags(FlatBufferBuilder builder, int kdcFlags) { builder.addInt(2, kdcFlags, 0); }
+ public static void addDisabled(FlatBufferBuilder builder, boolean disabled) { builder.addBoolean(3, disabled, false); }
+ public static void addKeys(FlatBufferBuilder builder, int keysOffset) { builder.addOffset(4, keysOffset, 0); }
+ public static int createKeysVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+ public static void startKeysVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+ public static int endFbsKrbIdentity(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsPrincipalName.java b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsPrincipalName.java
new file mode 100644
index 0000000..baef55c
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FbsPrincipalName.java
@@ -0,0 +1,38 @@
+// automatically generated, do not modify
+
+package org.apache.kerby.kerberos.kdc.identitybackend;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class FbsPrincipalName extends Table {
+ public static FbsPrincipalName getRootAsFbsPrincipalName(ByteBuffer _bb) { return getRootAsFbsPrincipalName(_bb, new FbsPrincipalName()); }
+ public static FbsPrincipalName getRootAsFbsPrincipalName(ByteBuffer _bb, FbsPrincipalName obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public FbsPrincipalName __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public int nameType() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+ public boolean mutateNameType(int nameType) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, nameType); return true; } else { return false; } }
+ public String nameString() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; }
+ public ByteBuffer nameStringAsByteBuffer() { return __vector_as_bytebuffer(6, 1); }
+
+ public static int createFbsPrincipalName(FlatBufferBuilder builder,
+ int nameType,
+ int nameString) {
+ builder.startObject(2);
+ FbsPrincipalName.addNameString(builder, nameString);
+ FbsPrincipalName.addNameType(builder, nameType);
+ return FbsPrincipalName.endFbsPrincipalName(builder);
+ }
+
+ public static void startFbsPrincipalName(FlatBufferBuilder builder) { builder.startObject(2); }
+ public static void addNameType(FlatBufferBuilder builder, int nameType) { builder.addInt(0, nameType, 0); }
+ public static void addNameString(FlatBufferBuilder builder, int nameStringOffset) { builder.addOffset(1, nameStringOffset, 0); }
+ public static int endFbsPrincipalName(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FlatbuffersIdentityBackend.java b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FlatbuffersIdentityBackend.java
new file mode 100644
index 0000000..57c8bc4
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/FlatbuffersIdentityBackend.java
@@ -0,0 +1,197 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.kerby.kerberos.kdc.identitybackend;
+
+import com.google.flatbuffers.FlatBufferBuilder;
+import org.apache.kerby.config.Config;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
+import org.apache.kerby.kerberos.kerb.identity.backend.AbstractIdentityBackend;
+import org.apache.kerby.util.IOUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A Flatbuffers backed backend implementation.
+ *
+ */
+public class FlatbuffersIdentityBackend extends AbstractIdentityBackend {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(FlatbuffersIdentityBackend.class);
+ public static final String FBS_IDENTITY_BACKEND_DIR =
+ "backend.flatbuffers.dir";
+ private File fbsKdbFile;
+ private FlatBufferBuilder fbsBuilder;
+ private long kdbFileTimeStamp;
+
+ // Identities loaded from file
+ private final Map<String, KrbIdentity> identities =
+ new ConcurrentHashMap<>(new TreeMap<String, KrbIdentity>());
+
+ public FlatbuffersIdentityBackend() {
+
+ }
+
+ /**
+ * Constructing an instance using specified config that contains anything
+ * to be used to initialize the fbs format database.
+ * @param config The configuration for fbs identity backend
+ */
+ public FlatbuffersIdentityBackend(Config config) {
+ setConfig(config);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doInitialize() throws KrbException {
+ LOG.info("Initializing the Flatbuffers identity backend.");
+ createFbsBuilder();
+ load();
+ }
+
+ /**
+ * Load identities from file
+ */
+ private void load() throws KrbException {
+ LOG.info("Loading the identities from fbs file.");
+ String fbsFile = getConfig().getString(FBS_IDENTITY_BACKEND_DIR);
+ File fbsFileDir;
+ if (fbsFile == null || fbsFile.isEmpty()) {
+ fbsFileDir = getBackendConfig().getConfDir();
+ } else {
+ fbsFileDir = new File(fbsFile);
+ if (!fbsFileDir.exists() && !fbsFileDir.mkdirs()) {
+ throw new KrbException("could not create fbs file dir " + fbsFileDir);
+ }
+ }
+
+ fbsKdbFile = new File(fbsFileDir, "fbs-backend.bin");
+
+ if (!fbsKdbFile.exists()) {
+ try {
+ fbsKdbFile.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ checkAndLoad();
+ }
+
+ /**
+ * Check kdb file timestamp to see if it's changed or not. If
+ * necessary load the kdb again.
+ */
+ private synchronized void checkAndLoad() throws KrbException {
+ long nowTimeStamp = fbsKdbFile.lastModified();
+
+ if (kdbFileTimeStamp == 0 || nowTimeStamp != kdbFileTimeStamp) {
+ //load identities
+ String existsFbsFile = null;
+ try {
+ existsFbsFile = IOUtil.readFile(fbsKdbFile);
+ } catch (IOException e) {
+ throw new KrbException("Failed to read file", e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected KrbIdentity doGetIdentity(String principalName) throws KrbException {
+ checkAndLoad();
+ return identities.get(principalName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected KrbIdentity doAddIdentity(KrbIdentity identity) throws KrbException {
+ checkAndLoad();
+
+ identities.put(identity.getPrincipalName(), identity);
+ idsToFile(identities);
+
+ return doGetIdentity(identity.getPrincipalName());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected KrbIdentity doUpdateIdentity(KrbIdentity identity) throws KrbException {
+ checkAndLoad();
+ identities.put(identity.getPrincipalName(), identity);
+ idsToFile(identities);
+
+ return doGetIdentity(identity.getPrincipalName());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doDeleteIdentity(String principalName) throws KrbException {
+ checkAndLoad();
+ if (identities.containsKey(principalName)) {
+ identities.remove(principalName);
+ }
+ idsToFile(identities);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Iterable<String> doGetIdentities() throws KrbException {
+ List<String> principals = new ArrayList<>(identities.keySet());
+ Collections.sort(principals);
+
+ return principals;
+ }
+
+ private void createFbsBuilder() {
+ fbsBuilder = new FlatBufferBuilder();
+ }
+
+ /**
+ * Write identities into a file
+ * @param ids the identities to write into the fbs file
+ */
+ private synchronized void idsToFile(Map<String, KrbIdentity> ids) throws KrbException {
+ String newFbsFile = null;
+ try {
+ IOUtil.writeFile(newFbsFile, fbsKdbFile);
+ } catch (IOException e) {
+ LOG.error("Error occurred while writing identities to file: " + fbsKdbFile);
+ throw new KrbException("Failed to write file", e);
+ }
+ }
+}
diff --git a/kerby-backend/flatbuffers-backend/src/schema/include_test1.fbs b/kerby-backend/flatbuffers-backend/src/schema/include_test1.fbs
new file mode 100644
index 0000000..11aebe8
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/schema/include_test1.fbs
@@ -0,0 +1,5 @@
+include "include_test2.fbs";
+include "include_test2.fbs"; // should be skipped
+include "include_test1.fbs"; // should be skipped
+
+
diff --git a/kerby-backend/flatbuffers-backend/src/schema/include_test2.fbs b/kerby-backend/flatbuffers-backend/src/schema/include_test2.fbs
new file mode 100644
index 0000000..d22c0d9
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/schema/include_test2.fbs
@@ -0,0 +1,9 @@
+include "include_test2.fbs"; // should be skipped
+
+namespace MyGame.OtherNameSpace;
+
+enum FromInclude:long { IncludeVal }
+
+struct Unused {}
+
+
diff --git a/kerby-backend/flatbuffers-backend/src/schema/kerby.fbs b/kerby-backend/flatbuffers-backend/src/schema/kerby.fbs
new file mode 100644
index 0000000..a4eea19
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/schema/kerby.fbs
@@ -0,0 +1,28 @@
+// Kerby KDC backend schema file
+
+namespace org.apache.kerby.kerberos.kdc.identitybackend;
+
+table FbsPrincipalName {
+ nameType:int;
+ nameString:string;
+}
+
+table FbsEncryptionKey {
+ keyType:int;
+ keyValue:[byte];
+}
+
+table FbsKrbIdentity {
+ principal:FbsPrincipalName;
+ keyVersion:int;
+ kdcFlags:int;
+ disabled:bool;
+ keys:[FbsEncryptionKey];
+}
+
+table FbsKerby {
+ name:string;
+ identities:[FbsKrbIdentity];
+}
+
+root_type FbsKerby;
\ No newline at end of file
diff --git a/kerby-backend/flatbuffers-backend/src/schema/monster_test.fbs b/kerby-backend/flatbuffers-backend/src/schema/monster_test.fbs
new file mode 100644
index 0000000..b2b99bb
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/schema/monster_test.fbs
@@ -0,0 +1,66 @@
+// test schema file
+
+include "include_test1.fbs";
+
+namespace MyGame.Example;
+
+attribute "priority";
+
+enum Color:byte (bit_flags) { Red = 0, Green, Blue = 3, }
+
+union Any { Monster, TestSimpleTableWithEnum } // TODO: add more elements
+
+struct Test { a:short; b:byte; }
+
+table TestSimpleTableWithEnum {
+ color: Color = Green;
+}
+
+struct Vec3 (force_align: 16) {
+ x:float;
+ y:float;
+ z:float;
+ test1:double;
+ test2:Color;
+ test3:Test;
+}
+
+table Stat {
+ id:string;
+ val:long;
+ count:ushort;
+}
+
+table Monster {
+ pos:Vec3 (id: 0);
+ hp:short = 100 (id: 2);
+ mana:short = 150 (id: 1);
+ name:string (id: 3, required, key);
+ color:Color = Blue (id: 6);
+ inventory:[ubyte] (id: 5);
+ friendly:bool = false (deprecated, priority: 1, id: 4);
+ /// an example documentation comment: this will end up in the generated code
+ /// multiline too
+ testarrayoftables:[Monster] (id: 11);
+ testarrayofstring:[string] (id: 10);
+ testarrayofbools:[bool] (id: 24);
+ enemy:MyGame.Example.Monster (id:12); // Test referring by full namespace.
+ test:Any (id: 8);
+ test4:[Test] (id: 9);
+ testnestedflatbuffer:[ubyte] (id:13, nested_flatbuffer: "Monster");
+ testempty:Stat (id:14);
+ testbool:bool (id:15);
+ testhashs32_fnv1:int (id:16, hash:"fnv1_32");
+ testhashu32_fnv1:uint (id:17, hash:"fnv1_32");
+ testhashs64_fnv1:long (id:18, hash:"fnv1_64");
+ testhashu64_fnv1:ulong (id:19, hash:"fnv1_64");
+ testhashs32_fnv1a:int (id:20, hash:"fnv1a_32");
+ testhashu32_fnv1a:uint (id:21, hash:"fnv1a_32");
+ testhashs64_fnv1a:long (id:22, hash:"fnv1a_64");
+ testhashu64_fnv1a:ulong (id:23, hash:"fnv1a_64");
+}
+
+root_type Monster;
+
+file_identifier "MONS";
+file_extension "mon";
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/JavaTest.java b/kerby-backend/flatbuffers-backend/src/test/java/JavaTest.java
new file mode 100644
index 0000000..936bca5
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/JavaTest.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import MyGame.Example.*;
+import com.google.flatbuffers.FlatBufferBuilder;
+
+class JavaTest {
+ public static void main(String[] args) {
+
+ // First, let's test reading a FlatBuffer generated by C++ code:
+ // This file was generated from monsterdata_test.json
+
+ byte[] data = null;
+ File file = new File("C:\\work\\projects\\kerby\\kerby-backend\\flatbuffers-backend\\src\\test\\monsterdata_test.mon");
+ RandomAccessFile f = null;
+ try {
+ f = new RandomAccessFile(file, "r");
+ data = new byte[(int)f.length()];
+ f.readFully(data);
+ f.close();
+ } catch(IOException e) {
+ System.out.println("FlatBuffers test: couldn't read file");
+ return;
+ }
+
+ // Now test it:
+
+ ByteBuffer bb = ByteBuffer.wrap(data);
+ TestBuffer(bb);
+
+ FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+
+ // We set up the same values as monsterdata.json:
+
+ int str = fbb.createString("MyMonster");
+ // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+ // We use an initial size of 1 to exercise the reallocation algorithm,
+ // normally a size larger than the typical FlatBuffer you generate would be
+ // better for performance.
+
+ int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
+
+ int fred = fbb.createString("Fred");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, fred);
+ int mon2 = Monster.endMonster(fbb);
+
+ Monster.startTest4Vector(fbb, 2);
+ Test.createTest(fbb, (short)10, (byte)20);
+ Test.createTest(fbb, (short)30, (byte)40);
+ int test4 = fbb.endVector();
+
+ int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
+ fbb.createString("test1"),
+ fbb.createString("test2")
+ });
+
+ Monster.startMonster(fbb);
+ Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
+ Color.Green, (short)5, (byte)6));
+ Monster.addHp(fbb, (short)80);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, inv);
+ Monster.addTestType(fbb, (byte)Any.Monster);
+ Monster.addTest(fbb, mon2);
+ Monster.addTest4(fbb, test4);
+ Monster.addTestarrayofstring(fbb, testArrayOfString);
+ Monster.addTestbool(fbb, false);
+ Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
+ int mon = Monster.endMonster(fbb);
+
+ Monster.finishMonsterBuffer(fbb, mon);
+
+ // Write the result to a file for debugging purposes:
+ // Note that the binaries are not necessarily identical, since the JSON
+ // parser may serialize in a slightly different order than the above
+ // Java code. They are functionally equivalent though.
+
+ try {
+ DataOutputStream os = new DataOutputStream(new FileOutputStream(
+ "monsterdata_java_wire.mon"));
+ os.write(fbb.dataBuffer().array(), fbb.dataBuffer().position(), fbb.offset());
+ os.close();
+ } catch(IOException e) {
+ System.out.println("FlatBuffers test: couldn't write file");
+ return;
+ }
+
+ // Test it:
+ TestExtendedBuffer(fbb.dataBuffer());
+
+ // Make sure it also works with read only ByteBuffers. This is slower,
+ // since creating strings incurs an additional copy
+ // (see Table.__string).
+ TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
+
+ TestEnums();
+
+ //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+ // revert to original values after testing
+ Monster monster = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ // mana is optional and does not exist in the buffer so the mutation should fail
+ // the mana field should retain its default value
+ TestEq(monster.mutateMana((short)10), false);
+ TestEq(monster.mana(), (short)150);
+
+ // testType is an existing field and mutating it should succeed
+ TestEq(monster.testType(), (byte)Any.Monster);
+ TestEq(monster.mutateTestType(Any.NONE), true);
+ TestEq(monster.testType(), (byte)Any.NONE);
+ TestEq(monster.mutateTestType(Any.Monster), true);
+ TestEq(monster.testType(), (byte)Any.Monster);
+
+ //mutate the inventory vector
+ TestEq(monster.mutateInventory(0, 1), true);
+ TestEq(monster.mutateInventory(1, 2), true);
+ TestEq(monster.mutateInventory(2, 3), true);
+ TestEq(monster.mutateInventory(3, 4), true);
+ TestEq(monster.mutateInventory(4, 5), true);
+
+ for (int i = 0; i < monster.inventoryLength(); i++) {
+ TestEq(monster.inventory(i), i + 1);
+ }
+
+ //reverse mutation
+ TestEq(monster.mutateInventory(0, 0), true);
+ TestEq(monster.mutateInventory(1, 1), true);
+ TestEq(monster.mutateInventory(2, 2), true);
+ TestEq(monster.mutateInventory(3, 3), true);
+ TestEq(monster.mutateInventory(4, 4), true);
+
+ // get a struct field and edit one of its fields
+ Vec3 pos = monster.pos();
+ TestEq(pos.x(), 1.0f);
+ pos.mutateX(55.0f);
+ TestEq(pos.x(), 55.0f);
+ pos.mutateX(1.0f);
+ TestEq(pos.x(), 1.0f);
+
+ TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
+
+ System.out.println("FlatBuffers test: completed successfully");
+ }
+
+ static void TestEnums() {
+ TestEq(Color.name(Color.Red), "Red");
+ TestEq(Color.name(Color.Blue), "Blue");
+ TestEq(Any.name(Any.NONE), "NONE");
+ TestEq(Any.name(Any.Monster), "Monster");
+ }
+
+ static void TestBuffer(ByteBuffer bb) {
+ TestEq(Monster.MonsterBufferHasIdentifier(bb), true);
+
+ Monster monster = Monster.getRootAsMonster(bb);
+
+ TestEq(monster.hp(), (short)80);
+ TestEq(monster.mana(), (short)150); // default
+
+ TestEq(monster.name(), "MyMonster");
+ // monster.friendly() // can't access, deprecated
+
+ Vec3 pos = monster.pos();
+ TestEq(pos.x(), 1.0f);
+ TestEq(pos.y(), 2.0f);
+ TestEq(pos.z(), 3.0f);
+ TestEq(pos.test1(), 3.0);
+ TestEq(pos.test2(), Color.Green);
+ Test t = pos.test3();
+ TestEq(t.a(), (short)5);
+ TestEq(t.b(), (byte)6);
+
+ TestEq(monster.testType(), (byte)Any.Monster);
+ Monster monster2 = new Monster();
+ TestEq(monster.test(monster2) != null, true);
+ TestEq(monster2.name(), "Fred");
+
+ TestEq(monster.inventoryLength(), 5);
+ int invsum = 0;
+ for (int i = 0; i < monster.inventoryLength(); i++)
+ invsum += monster.inventory(i);
+ TestEq(invsum, 10);
+
+ // Alternative way of accessing a vector:
+ ByteBuffer ibb = monster.inventoryAsByteBuffer();
+ invsum = 0;
+ while (ibb.position() < ibb.limit())
+ invsum += ibb.get();
+ TestEq(invsum, 10);
+
+ Test test_0 = monster.test4(0);
+ Test test_1 = monster.test4(1);
+ TestEq(monster.test4Length(), 2);
+ TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
+ TestEq(monster.testarrayofstringLength(), 2);
+ TestEq(monster.testarrayofstring(0),"test1");
+ TestEq(monster.testarrayofstring(1),"test2");
+
+ TestEq(monster.testbool(), false);
+ }
+
+ // this method checks additional fields not present in the binary buffer read from file
+ // these new tests are performed on top of the regular tests
+ static void TestExtendedBuffer(ByteBuffer bb) {
+ TestBuffer(bb);
+
+ Monster monster = Monster.getRootAsMonster(bb);
+
+ TestEq(monster.testhashu32Fnv1(), Integer.MAX_VALUE + 1L);
+ }
+
+ static <T> void TestEq(T a, T b) {
+ if (!a.equals(b)) {
+ System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
+ System.out.println("FlatBuffers test FAILED: \'" + a + "\' != \'" + b + "\'");
+ assert false;
+ System.exit(1);
+ }
+ }
+}
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Any.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Any.java
new file mode 100644
index 0000000..cdc3ec5
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Any.java
@@ -0,0 +1,15 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+public final class Any {
+ private Any() { }
+ public static final byte NONE = 0;
+ public static final byte Monster = 1;
+ public static final byte TestSimpleTableWithEnum = 2;
+
+ private static final String[] names = { "NONE", "Monster", "TestSimpleTableWithEnum", };
+
+ public static String name(int e) { return names[e]; }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Color.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Color.java
new file mode 100644
index 0000000..822d2bb
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Color.java
@@ -0,0 +1,15 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+public final class Color {
+ private Color() { }
+ public static final byte Red = 1;
+ public static final byte Green = 2;
+ public static final byte Blue = 8;
+
+ private static final String[] names = { "Red", "Green", "", "", "", "", "", "Blue", };
+
+ public static String name(int e) { return names[e - Red]; }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Monster.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Monster.java
new file mode 100644
index 0000000..9f97590
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Monster.java
@@ -0,0 +1,120 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Monster extends Table {
+ public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
+ public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
+ public Monster __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public Vec3 pos() { return pos(new Vec3()); }
+ public Vec3 pos(Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
+ public short mana() { int o = __offset(6); return o != 0 ? bb.getShort(o + bb_pos) : 150; }
+ public boolean mutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.putShort(o + bb_pos, mana); return true; } else { return false; } }
+ public short hp() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 100; }
+ public boolean mutateHp(short hp) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, hp); return true; } else { return false; } }
+ public String name() { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; }
+ public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(10, 1); }
+ public int inventory(int j) { int o = __offset(14); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+ public int inventoryLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }
+ public ByteBuffer inventoryAsByteBuffer() { return __vector_as_bytebuffer(14, 1); }
+ public boolean mutateInventory(int j, int inventory) { int o = __offset(14); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)inventory); return true; } else { return false; } }
+ public byte color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) : 8; }
+ public boolean mutateColor(byte color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, color); return true; } else { return false; } }
+ public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; }
+ public boolean mutateTestType(byte test_type) { int o = __offset(18); if (o != 0) { bb.put(o + bb_pos, test_type); return true; } else { return false; } }
+ public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o) : null; }
+ public Test test4(int j) { return test4(new Test(), j); }
+ public Test test4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__init(__vector(o) + j * 4, bb) : null; }
+ public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+ public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
+ public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+ /**
+ * an example documentation comment: this will end up in the generated code
+ * multiline too
+ */
+ public Monster testarrayoftables(int j) { return testarrayoftables(new Monster(), j); }
+ public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
+ public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
+ public Monster enemy() { return enemy(new Monster()); }
+ public Monster enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+ public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
+ public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
+ public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
+ public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testnestedflatbuffer); return true; } else { return false; } }
+ public Stat testempty() { return testempty(new Stat()); }
+ public Stat testempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
+ public boolean testbool() { int o = __offset(34); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
+ public boolean mutateTestbool(boolean testbool) { int o = __offset(34); if (o != 0) { bb.put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
+ public int testhashs32Fnv1() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+ public boolean mutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __offset(36); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1); return true; } else { return false; } }
+ public long testhashu32Fnv1() { int o = __offset(38); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0; }
+ public boolean mutateTesthashu32Fnv1(long testhashu32_fnv1) { int o = __offset(38); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1); return true; } else { return false; } }
+ public long testhashs64Fnv1() { int o = __offset(40); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
+ public boolean mutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __offset(40); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1); return true; } else { return false; } }
+ public long testhashu64Fnv1() { int o = __offset(42); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
+ public boolean mutateTesthashu64Fnv1(long testhashu64_fnv1) { int o = __offset(42); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1); return true; } else { return false; } }
+ public int testhashs32Fnv1a() { int o = __offset(44); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
+ public boolean mutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __offset(44); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
+ public long testhashu32Fnv1a() { int o = __offset(46); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0; }
+ public boolean mutateTesthashu32Fnv1a(long testhashu32_fnv1a) { int o = __offset(46); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1a); return true; } else { return false; } }
+ public long testhashs64Fnv1a() { int o = __offset(48); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
+ public boolean mutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __offset(48); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
+ public long testhashu64Fnv1a() { int o = __offset(50); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
+ public boolean mutateTesthashu64Fnv1a(long testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
+ public boolean testarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.get(__vector(o) + j * 1) : false; }
+ public int testarrayofboolsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; }
+ public ByteBuffer testarrayofboolsAsByteBuffer() { return __vector_as_bytebuffer(52, 1); }
+ public boolean mutateTestarrayofbools(int j, boolean testarrayofbools) { int o = __offset(52); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
+
+ public static void startMonster(FlatBufferBuilder builder) { builder.startObject(25); }
+ public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
+ public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
+ public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
+ public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(3, nameOffset, 0); }
+ public static void addInventory(FlatBufferBuilder builder, int inventoryOffset) { builder.addOffset(5, inventoryOffset, 0); }
+ public static int createInventoryVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+ public static void startInventoryVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+ public static void addColor(FlatBufferBuilder builder, byte color) { builder.addByte(6, color, 8); }
+ public static void addTestType(FlatBufferBuilder builder, byte testType) { builder.addByte(7, testType, 0); }
+ public static void addTest(FlatBufferBuilder builder, int testOffset) { builder.addOffset(8, testOffset, 0); }
+ public static void addTest4(FlatBufferBuilder builder, int test4Offset) { builder.addOffset(9, test4Offset, 0); }
+ public static void startTest4Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
+ public static void addTestarrayofstring(FlatBufferBuilder builder, int testarrayofstringOffset) { builder.addOffset(10, testarrayofstringOffset, 0); }
+ public static int createTestarrayofstringVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+ public static void startTestarrayofstringVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+ public static void addTestarrayoftables(FlatBufferBuilder builder, int testarrayoftablesOffset) { builder.addOffset(11, testarrayoftablesOffset, 0); }
+ public static int createTestarrayoftablesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
+ public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
+ public static void addEnemy(FlatBufferBuilder builder, int enemyOffset) { builder.addOffset(12, enemyOffset, 0); }
+ public static void addTestnestedflatbuffer(FlatBufferBuilder builder, int testnestedflatbufferOffset) { builder.addOffset(13, testnestedflatbufferOffset, 0); }
+ public static int createTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
+ public static void startTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+ public static void addTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.addOffset(14, testemptyOffset, 0); }
+ public static void addTestbool(FlatBufferBuilder builder, boolean testbool) { builder.addBoolean(15, testbool, false); }
+ public static void addTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.addInt(16, testhashs32Fnv1, 0); }
+ public static void addTesthashu32Fnv1(FlatBufferBuilder builder, long testhashu32Fnv1) { builder.addInt(17, (int)(testhashu32Fnv1 & 0xFFFFFFFFL), 0); }
+ public static void addTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.addLong(18, testhashs64Fnv1, 0); }
+ public static void addTesthashu64Fnv1(FlatBufferBuilder builder, long testhashu64Fnv1) { builder.addLong(19, testhashu64Fnv1, 0); }
+ public static void addTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.addInt(20, testhashs32Fnv1a, 0); }
+ public static void addTesthashu32Fnv1a(FlatBufferBuilder builder, long testhashu32Fnv1a) { builder.addInt(21, (int)(testhashu32Fnv1a & 0xFFFFFFFFL), 0); }
+ public static void addTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.addLong(22, testhashs64Fnv1a, 0); }
+ public static void addTesthashu64Fnv1a(FlatBufferBuilder builder, long testhashu64Fnv1a) { builder.addLong(23, testhashu64Fnv1a, 0); }
+ public static void addTestarrayofbools(FlatBufferBuilder builder, int testarrayofboolsOffset) { builder.addOffset(24, testarrayofboolsOffset, 0); }
+ public static int createTestarrayofboolsVector(FlatBufferBuilder builder, boolean[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addBoolean(data[i]); return builder.endVector(); }
+ public static void startTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+ public static int endMonster(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ builder.required(o, 10); // name
+ return o;
+ }
+ public static void finishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONS"); }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Stat.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Stat.java
new file mode 100644
index 0000000..73f9562
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Stat.java
@@ -0,0 +1,43 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Stat extends Table {
+ public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); }
+ public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public Stat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public String id() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
+ public ByteBuffer idAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
+ public long val() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
+ public boolean mutateVal(long val) { int o = __offset(6); if (o != 0) { bb.putLong(o + bb_pos, val); return true; } else { return false; } }
+ public int count() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
+ public boolean mutateCount(int count) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, (short)count); return true; } else { return false; } }
+
+ public static int createStat(FlatBufferBuilder builder,
+ int id,
+ long val,
+ int count) {
+ builder.startObject(3);
+ Stat.addVal(builder, val);
+ Stat.addId(builder, id);
+ Stat.addCount(builder, count);
+ return Stat.endStat(builder);
+ }
+
+ public static void startStat(FlatBufferBuilder builder) { builder.startObject(3); }
+ public static void addId(FlatBufferBuilder builder, int idOffset) { builder.addOffset(0, idOffset, 0); }
+ public static void addVal(FlatBufferBuilder builder, long val) { builder.addLong(1, val, 0); }
+ public static void addCount(FlatBufferBuilder builder, int count) { builder.addShort(2, (short)(count & 0xFFFF), 0); }
+ public static int endStat(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Test.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Test.java
new file mode 100644
index 0000000..ffd7394
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Test.java
@@ -0,0 +1,27 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Test extends Struct {
+ public Test __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public short a() { return bb.getShort(bb_pos + 0); }
+ public void mutateA(short a) { bb.putShort(bb_pos + 0, a); }
+ public byte b() { return bb.get(bb_pos + 2); }
+ public void mutateB(byte b) { bb.put(bb_pos + 2, b); }
+
+ public static int createTest(FlatBufferBuilder builder, short a, byte b) {
+ builder.prep(2, 4);
+ builder.pad(1);
+ builder.putByte(b);
+ builder.putShort(a);
+ return builder.offset();
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/TestSimpleTableWithEnum.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/TestSimpleTableWithEnum.java
new file mode 100644
index 0000000..3000cab
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/TestSimpleTableWithEnum.java
@@ -0,0 +1,33 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class TestSimpleTableWithEnum extends Table {
+ public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
+ public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public TestSimpleTableWithEnum __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public byte color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 2; }
+ public boolean mutateColor(byte color) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, color); return true; } else { return false; } }
+
+ public static int createTestSimpleTableWithEnum(FlatBufferBuilder builder,
+ byte color) {
+ builder.startObject(1);
+ TestSimpleTableWithEnum.addColor(builder, color);
+ return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(builder);
+ }
+
+ public static void startTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.startObject(1); }
+ public static void addColor(FlatBufferBuilder builder, byte color) { builder.addByte(0, color, 2); }
+ public static int endTestSimpleTableWithEnum(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Vec3.java b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Vec3.java
new file mode 100644
index 0000000..86edb6d
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/MyGame/Example/Vec3.java
@@ -0,0 +1,44 @@
+// automatically generated, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class Vec3 extends Struct {
+ public Vec3 __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
+
+ public float x() { return bb.getFloat(bb_pos + 0); }
+ public void mutateX(float x) { bb.putFloat(bb_pos + 0, x); }
+ public float y() { return bb.getFloat(bb_pos + 4); }
+ public void mutateY(float y) { bb.putFloat(bb_pos + 4, y); }
+ public float z() { return bb.getFloat(bb_pos + 8); }
+ public void mutateZ(float z) { bb.putFloat(bb_pos + 8, z); }
+ public double test1() { return bb.getDouble(bb_pos + 16); }
+ public void mutateTest1(double test1) { bb.putDouble(bb_pos + 16, test1); }
+ public byte test2() { return bb.get(bb_pos + 24); }
+ public void mutateTest2(byte test2) { bb.put(bb_pos + 24, test2); }
+ public Test test3() { return test3(new Test()); }
+ public Test test3(Test obj) { return obj.__init(bb_pos + 26, bb); }
+
+ public static int createVec3(FlatBufferBuilder builder, float x, float y, float z, double test1, byte test2, short test3_a, byte test3_b) {
+ builder.prep(16, 32);
+ builder.pad(2);
+ builder.prep(2, 4);
+ builder.pad(1);
+ builder.putByte(test3_b);
+ builder.putShort(test3_a);
+ builder.pad(1);
+ builder.putByte(test2);
+ builder.putDouble(test1);
+ builder.pad(4);
+ builder.putFloat(z);
+ builder.putFloat(y);
+ builder.putFloat(x);
+ return builder.offset();
+ }
+};
+
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/FlatbuffersBackendTest.java b/kerby-backend/flatbuffers-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/FlatbuffersBackendTest.java
new file mode 100644
index 0000000..aa3b4eb
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/FlatbuffersBackendTest.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.kerby.kerberos.kerb.identity.backend;
+
+import org.apache.kerby.config.Conf;
+import org.apache.kerby.config.Config;
+import org.apache.kerby.kerberos.kdc.identitybackend.FlatbuffersIdentityBackend;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.File;
+
+/**
+ * Flatbuffers backend test
+ */
+public class FlatbuffersBackendTest extends BackendTestBase {
+ private static File fbsBackendFile;
+
+ @BeforeClass
+ public static void setup() throws KrbException {
+ File testDir = new File(System.getProperty("test.dir", "target"));
+ fbsBackendFile = new File(testDir, "fbs-identity-backend-file");
+ String jsonBackendFileString = fbsBackendFile.getAbsolutePath();
+
+ Config backendConfig = new Conf();
+ backendConfig.setString(FlatbuffersIdentityBackend.FBS_IDENTITY_BACKEND_DIR,
+ jsonBackendFileString);
+ backend = new FlatbuffersIdentityBackend(backendConfig);
+ backend.initialize();
+ }
+
+ @AfterClass
+ public static void cleanJsonBackendFile() {
+ if (fbsBackendFile.exists()) {
+ fbsBackendFile.delete();
+ }
+ }
+}
diff --git a/kerby-backend/flatbuffers-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/FlatbuffersBackendTestUtil.java b/kerby-backend/flatbuffers-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/FlatbuffersBackendTestUtil.java
new file mode 100644
index 0000000..8061ae5
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/java/org/apache/kerby/kerberos/kerb/identity/backend/FlatbuffersBackendTestUtil.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.kerby.kerberos.kerb.identity.backend;
+
+import MyGame.Example.*;
+import com.google.flatbuffers.FlatBufferBuilder;
+import org.apache.kerby.kerberos.kdc.identitybackend.FbsEncryptionKey;
+import org.apache.kerby.kerberos.kdc.identitybackend.FbsKerby;
+import org.apache.kerby.kerberos.kdc.identitybackend.FbsKrbIdentity;
+import org.apache.kerby.kerberos.kdc.identitybackend.FbsPrincipalName;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * Flatbuffers test utilities
+ */
+public class FlatbuffersBackendTestUtil {
+
+ public static void main(String[] args) throws KrbException {
+ List<KrbIdentity> idendenties = BackendTestUtil.createManyIdentities(2);
+
+ FlatBufferBuilder fbb = new FlatBufferBuilder(1024);
+
+ int name = fbb.createString("KerbyBackend");
+
+ KrbIdentity krbId = idendenties.get(0);
+ int princNameOff = fbb.createString(krbId.getPrincipalName());
+ int nameType = krbId.getPrincipal().getNameType().getValue();
+ int princOff = FbsPrincipalName.createFbsPrincipalName(fbb, nameType, princNameOff);
+ EncryptionKey encKey = krbId.getKeys().entrySet().iterator().next().getValue();
+ int keyValueOff = FbsEncryptionKey.createKeyValueVector(fbb, encKey.getKeyData());
+ int encKeyOff = FbsEncryptionKey.createFbsEncryptionKey(fbb,
+ encKey.getKeyType().getValue(), keyValueOff);
+ int keysOff = FbsKrbIdentity.createKeysVector(fbb, new int[]{encKeyOff});
+ int identityOff = FbsKrbIdentity.createFbsKrbIdentity(fbb, princOff, 1, 1, false, keysOff);
+ int idsOff = FbsKerby.createIdentitiesVector(fbb, new int[]{identityOff});
+
+ FbsKerby.startFbsKerby(fbb);
+ FbsKerby.addName(fbb, name);
+ FbsKerby.addIdentities(fbb, idsOff);
+ int kerbyOff = FbsKerby.endFbsKerby(fbb);
+ FbsKerby.finishFbsKerbyBuffer(fbb, kerbyOff);
+
+ ByteBuffer dataBuffer = fbb.dataBuffer().duplicate();
+
+ FbsKerby fbsKerby2 = FbsKerby.getRootAsFbsKerby(dataBuffer);
+ String kerbyName = fbsKerby2.name();
+ FbsKrbIdentity krbId2 = fbsKerby2.identities(0);
+ String princName2 = krbId2.principal().nameString();
+ return;
+ }
+}
diff --git a/kerby-backend/flatbuffers-backend/src/test/monsterdata_test.mon b/kerby-backend/flatbuffers-backend/src/test/monsterdata_test.mon
new file mode 100644
index 0000000..0505aee
--- /dev/null
+++ b/kerby-backend/flatbuffers-backend/src/test/monsterdata_test.mon
Binary files differ
diff --git a/kerby-backend/pom.xml b/kerby-backend/pom.xml
index 1305721..d49f40b 100644
--- a/kerby-backend/pom.xml
+++ b/kerby-backend/pom.xml
@@ -30,6 +30,7 @@
<module>mavibot-backend</module>
<module>json-backend</module>
<module>zookeeper-backend</module>
+ <module>flatbuffers-backend</module>
</modules>
<dependencies>
diff --git a/monsterdata_java_wire.mon b/monsterdata_java_wire.mon
new file mode 100644
index 0000000..24602bc
--- /dev/null
+++ b/monsterdata_java_wire.mon
Binary files differ