=====Schema Definition mit Avro in der Oracle NoSQL Datenbank===== ===Vorbereitung:=== Java Libraries : * Avro Java Libraries laden von http://www.apache.org/dyn/closer.cgi/avro/ * avro-1.7.4.jar * avro-tools-1.7.4.ja * Jackson JSON library laden: http://wiki.fasterxml.com/JacksonDownload * jackson-annotations-2.2.0.jar * jackson-core-2.2.0.jar * jackson-databind-2.2.0.jar Libraries in eine Verzeichnis kopieren, in unsere Beispiel unter D:\entwicklung\avro-1.7.4 === Ein Avro Schema definieren === Datei emp.avsc mit der Schema Definition anlegen: {"namespace": "gpi.avro", "type": "record", "name": "emp", "fields": [ {"name": "EMPNO" , "type": "int" , "default" : 0}, {"name": "ENAME" , "type": "string" , "default" : ""}, {"name": "JOB" , "type": "string" , "default" : ""}, {"name": "MGR" , "type": "int" , "default" : 0}, {"name": "HIREDATE", "type": "long" , "default" : 0}, {"name": "SAL" , "type": "float" , "default" : 0}, {"name": "COMM" , "type": "float" , "default" : 0}, {"name": "DEPTNO" , "type": "int" , "default" : 10} ] } } Schema Definition siehe hier: [[http://avro.apache.org/docs/current/spec.html#schema_primitive|schema_primitive]] und [[http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/avroschemas.html|Avro - Oracle NoSQL Getting Started]] Das erste Problem, dass ins Auge fällt, ist die fehlende native Unterstützung für den Datentyp "date". Wie in der Java Welt üblich, ist hier wie immer etwas Basteln angesagt, oder eben das Speichern des Datumswerts als Long Value. Damit das Schema in der Datenbank später auch angepasst/geändert werden kann, muss ein Default Wert für die einzelnen Spalten definiert werden. === Schema prüfen und übersetzen === Mit den Avro Tool kann die Schema Definition überprüft und übersetzt werden. java -jar D:\entwicklung\avro-1.7.4\avro-tools-1.7.4.jar compile schema .\emp.avsc . Damit stehen die passende Java Klassen für die Schema Definition für die Serialisierung zur Verfügung. === Schema in der NoSQL Datenbank anlegen === Über die Admin Konsole wird das Schema in der Datenbank angelegt: REM Admin Console starten: java -jar D:\entwicklung\kv-2.1.8\lib\kvstore.jar runadmin -port 5000 -host localhost REM Schema in der DB anlegen: kv-> ddl add-schema -file emp.avsc Added schema: gpi.avro.emp.1 REM Schemas in der DB anzeigen lassen: kv-> show schemas gpi.avro.emp ID: 1 Modified: 2013-08-17 14:14:41 UTC, From: jupiter === Wie kann das Avro Schema in meiner Applikation genützt werden? === Ein Avro Schema kann auf verschiedene Weise in die eigene Applikation eingebunden werden. * Generic * Specific * JSON * Raw Für die Details siehe [[http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/avrobindings.html | NoSQL Guide Chapter 8]] === Ein erster Versuch mit einem Generic Binding === Ein einfaches Beispiel um mit Hilfe der Avro Schema Definition generisch in die DB zu schreiben: (siehe auch [[http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/genericbinding-overview.html|NoSQL Guide Generic Binding]]) package com.gpi.oranosql; import java.io.File; import java.io.IOException; import java.util.Date; import oracle.kv.Consistency; import oracle.kv.KVStore; import oracle.kv.KVStoreConfig; import oracle.kv.KVStoreFactory; import oracle.kv.Key; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericRecord; import org.apache.avro.Schema; import oracle.kv.avro.AvroCatalog; import oracle.kv.avro.GenericAvroBinding; public class AvroReadWrite { // KV Store public static KVStore kvstore = null; public AvroReadWrite() { } public static void main(String[] args) { AvroReadWrite avroReadWrite = new AvroReadWrite(); // get the host to connect as first parameter String host = args[0]; // get the store Name String store = args[1]; KVStoreConfig kvconfig = new KVStoreConfig(store, host); // Connect to the store kvstore = KVStoreFactory.getStore(kvconfig); // Read the Avro Schema Schema.Parser parser = null; try { parser = new Schema.Parser(); // read our avro schema definition parser.parse(new File("emp.avsc")); } catch (IOException ex) { System.out.println("Error -- File emp.avsc not found"); } // parse the schema definition // !!! Name of the Schema is :: namespace + name !!! final Schema empSchema = parser.getTypes().get("gpi.avro.emp"); // connect to store and read Avro schema defintion in the database AvroCatalog catalog = kvstore.getAvroCatalog(); //debug //System.out.println("Info --" + catalog.getCurrentSchemas()); // Generic Binding GenericAvroBinding binding = catalog.getGenericBinding(empSchema); // Define the emp record GenericRecord emp = new GenericData.Record(empSchema); // put values in the record: emp.put("EMPNO", 7898); emp.put("ENAME", "SCOTT"); emp.put("JOB", "CLERK"); emp.put("MGR", 1000); emp.put("HIREDATE", new Date().getTime()); emp.put("SAL", 12000f); emp.put("COMM", 30f); emp.put("DEPTNO", 10); // Create the Key wiht minor und mayor component Key key = Key.createKey("Mayer", "7899"); // put the emp record into the store kvstore.put(key, binding.toValue(emp)); //close the store kvstore.close(); System.exit(0); } } Mit dem Client Tool kvcli testen: java -jar D:\entwicklung\kv-2.1.8\lib\kvcli.jar -host localhost -port 5000 -store kvstore kvshell-> get -all /SCOTT/-/7898 { "EMPNO" : 7898, "ENAME" : "SCOTT", "JOB" : "CLERK", "MGR" : 1000, "HIREDATE" : 1376751935296, "SAL" : 12000.0, "COMM" : 30.0, "DEPTNO" : 10 } Werte im Programm auslesen: // see code above for the connection to the database GenericRecord emp2; Key key2 = Key.createKey("Mayer", "7899"); ValueVersion vv = kvstore.get(key2); if (vv != null) { emp2 = binding.toObject(vv.getValue()); String empno = emp2.get("EMPNO").toString(); String ename = emp2.get("ENAME").toString(); String job = emp2.get("JOB").toString(); int mgr = (Integer)emp2.get("MGR"); long time = (Long)emp2.get("HIREDATE"); Date hiredate = new Date(); hiredate.setTime(time); System.out.println(" EMPNO ::"+empno); System.out.println(" ENAME ::"+ename); System.out.println(" JOB ::"+job); System.out.println(" MGR ::"+mgr); System.out.println(" HIREDATE ::"+hiredate); } ==== Quellen ==== Dokumentation: * http://avro.apache.org/docs/current/gettingstartedjava.html Allgemein: * http://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html