Java tutorial
/* * Copyright 2016 Fumiharu Kinoshita * * 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 info.bunji.mongodb.synces; import java.lang.reflect.Type; import java.util.Date; import java.util.Objects; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.bson.BsonTimestamp; import org.bson.Document; import org.bson.types.ObjectId; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; /** ************************************************ * sync operation info. * @author Fumiharu Kinoshita ************************************************ */ public class SyncOperation { private static final Logger logger = LoggerFactory.getLogger(SyncOperation.class); private String destDbName; private Operation op; private String srcDbName; private String collection; private Document doc = null; private String id = null; private BsonTimestamp ts; private boolean isPartialUpdate = false; private static final Gson gson; static { GsonBuilder builder = new GsonBuilder(); // convert BsonTimestamp to JSON string builder.registerTypeAdapter(BsonTimestamp.class, new JsonSerializer<BsonTimestamp>() { @Override public JsonElement serialize(BsonTimestamp src, Type typeOfSrc, JsonSerializationContext context) { // JsonObject obj = new JsonObject(); // obj.add("seconds", new JsonPrimitive(src.getTime())); // obj.add("inc", new JsonPrimitive(src.getInc())); // return obj; // convert from epoctime DateTime dt = new DateTime((long) src.getTime() * 1000L); return new JsonPrimitive(dt.toString()); } }); // convert Date to JSON String builder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() { @Override public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) { DateTime dt = new DateTime(src); return new JsonPrimitive(dt.toString()); } }); // convert ObjectId to String builder.registerTypeAdapter(ObjectId.class, new JsonSerializer<ObjectId>() { @Override public JsonElement serialize(ObjectId src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(src.toString()); } }); gson = builder.create(); } /** ********************************** * @param op operartion type * @param destDbName * @param collection target collection * @param doc sync document * @param ts oplog timestamp ********************************** */ public SyncOperation(Operation op, String destDbName, String collection, Document doc, Object ts) { this.op = op; this.destDbName = destDbName; this.collection = collection; this.doc = doc; //this.id = doc != null ? doc.remove("_id").toString() : null; this.id = Objects.toString(doc.remove("_id"), null); if (this.id == null) { op = Operation.UNKNOWN; } this.ts = (BsonTimestamp) ts; } /** ********************************** * @param op operartion type * @param destDbName config dbName * @param collection target collection * @param doc sync document * @param id document id ********************************** */ public SyncOperation(Operation op, String collection, Document doc, String id) { this.op = op; this.destDbName = null; this.collection = collection; this.doc = doc; this.id = id; this.ts = null; } /** ********************************** * * @param oplogDoc * @param destDbName ********************************** */ public SyncOperation(Document oplogDoc, String destDbName) { this.op = Operation.valueOf(oplogDoc.get("op")); this.destDbName = destDbName; String ns = oplogDoc.getString("ns"); String[] nsVals = ns.split("\\.", 2); this.srcDbName = nsVals[0]; this.collection = nsVals[1]; this.ts = oplogDoc.get("ts", BsonTimestamp.class); Document o1Doc = oplogDoc.get("o", Document.class); Document o2Doc = oplogDoc.get("o2", Document.class); switch (op) { case INSERT: if (o1Doc != null && o1Doc.containsKey(SyncConfig.ID_FIELD)) { this.id = o1Doc.remove(SyncConfig.ID_FIELD).toString(); this.doc = o1Doc; } break; case DELETE: if (o1Doc != null && o1Doc.containsKey(SyncConfig.ID_FIELD)) { this.id = o1Doc.remove(SyncConfig.ID_FIELD).toString(); } break; case UPDATE: if (o1Doc.containsKey("$unset") || o1Doc.containsKey("$set")) { this.isPartialUpdate = true; // } else { // this.doc = o1Doc; } this.doc = o1Doc; //this.id = o2Doc.get("_id").toString(); this.id = Objects.toString(o2Doc.get("_id"), null); if (this.id == null) this.op = Operation.UNKNOWN; break; case COMMAND: if (o1Doc.containsKey("drop")) { // drop collection this.op = Operation.DROP_COLLECTION; this.collection = o1Doc.getString("drop"); } else if (o1Doc.containsKey("create")) { // create collection this.collection = o1Doc.getString("create"); this.op = Operation.CREATE_COLLECTION; } else if (o1Doc.containsKey("renameCollection")) { // rename collection(drop source collection) // this.doc = o1Doc; // doc.append("from", doc.remove("renameCollection")); // this.op = Operation.RENAME_COLLECTION; nsVals = o1Doc.getString("renameCollection").split("\\.", 2); this.srcDbName = nsVals[0]; this.op = Operation.DROP_COLLECTION; this.collection = o1Doc.getString("renameCollection"); logger.debug(this.toString()); // TODO rename?collection??oplog????(mongodb??????) // rename????(oplog??????????) } else { this.op = Operation.UNKNOWN; } break; default: break; } } /** ********************************** * * @return ********************************** */ public boolean isPartialUpdate() { return isPartialUpdate; } /** ********************************** * get oplog timestamp. * @return oplog timestamp ********************************** */ public BsonTimestamp getTimestamp() { return ts; } /** ********************************** * get operation. * @return operartion type ********************************** */ public Operation getOp() { return op; } /** ********************************** * get document id. * @return document id ********************************** */ public String getId() { return id; } public String getSrcDbName() { return srcDbName; } /** ********************************** * * @return ********************************** */ public String getDestDbName() { return destDbName; } /** ********************************** * * @param destDbName ********************************** */ public void setDestDbName(String destDbName) { this.destDbName = destDbName; } /** ********************************** * get target collection. * @return target collection ********************************** */ public String getCollection() { return collection; } /** ********************************** * get document. * @return document ********************************** */ public Document getDoc() { return doc; } /** ********************************** * set document. * @return document ********************************** */ public void setDoc(Document doc) { doc.remove("_id"); this.doc = doc; isPartialUpdate = false; } /** ********************************** * get json document . * @return json converted document ********************************** */ public String getJson() { return gson.toJson(doc); } /** ********************************** * * @param config * @return ********************************** */ public static SyncOperation fromConfig(SyncConfig config) { Document o1Doc = new Document("status", config.getStatus().name()); BsonTimestamp lastOp = config.getLastOpTime(); if (lastOp != null) { o1Doc.append("lastOpTime", new Document("seconds", lastOp.getTime()).append("inc", lastOp.getInc())); } BsonTimestamp lastSync = config.getLastSyncTime(); if (lastSync != null) { o1Doc.append("lastSyncTime", new Document("seconds", lastSync.getTime()).append("inc", lastSync.getInc())); } Document opDoc = new Document().append("op", Operation.UPDATE.getValue()) .append("ns", config.getMongoDbName() + ".status").append("o", o1Doc) .append("o2", new Document("_id", config.getSyncName())).append("ts", lastOp); return new SyncOperation(opDoc, config.getConfigDbName()); } /* ********************************** * (? Javadoc) * @see java.lang.Object#toString() ********************************** */ @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } }