/* * Copyright amoeba.meidusa.com * * This program is free software; you can redistribute it and/or modify it under the terms of * the GNU AFFERO GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU AFFERO GENERAL PUBLIC LICENSE for more details. * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package com.meidusa.amoeba.mongodb.handler; import java.util.ArrayList; import org.bson.BSONObject; import org.bson.BasicBSONObject; import com.meidusa.amoeba.context.ProxyRuntimeContext; import com.meidusa.amoeba.mongodb.handler.merge.FunctionMerge; import com.meidusa.amoeba.mongodb.io.MongodbPacketConstant; import com.meidusa.amoeba.mongodb.net.MongodbClientConnection; import com.meidusa.amoeba.mongodb.net.MongodbServerConnection; import com.meidusa.amoeba.mongodb.packet.RequestMongodbPacket; import com.meidusa.amoeba.mongodb.packet.ResponseMongodbPacket; import com.meidusa.amoeba.mongodb.route.MongodbQueryRouter; import com.meidusa.amoeba.net.poolable.ObjectPool; public class ModifyOperateMessageHandler<T extends RequestMongodbPacket> extends AbstractSessionHandler<T> { private int lastRequestId = 0; public ModifyOperateMessageHandler(MongodbClientConnection clientConn,T t) { super(clientConn, t); } @Override protected void doClientRequest(MongodbClientConnection conn, byte[] message) throws Exception { MongodbQueryRouter router = (MongodbQueryRouter)ProxyRuntimeContext.getInstance().getQueryRouter(); ObjectPool[] pools = router.doRoute(clientConn, (RequestMongodbPacket)requestPacket); if(pools == null || pools.length==0){ pools = router.getDefaultObjectPool(); } if(pools != null && pools.length >1){ isMulti = true; this.multiResponsePacket = new ArrayList<ResponseMongodbPacket>(); } RequestMongodbPacket lastErrorRequest = clientConn.getLastErrorRequest(); byte[] bts = lastErrorRequest.toByteBuffer(this.clientConn).array(); this.lastRequestId = lastErrorRequest.requestID; MongodbServerConnection[] conns = new MongodbServerConnection[pools.length]; int index =0; for(ObjectPool pool: pools){ MongodbServerConnection serverConn = (MongodbServerConnection)pool.borrowObject(); handlerMap.put(serverConn, serverConn.getMessageHandler()); serverConn.setSessionMessageHandler(this); conns[index++] = serverConn; } byte[] array = new byte[message.length+bts.length]; System.arraycopy(message, 0, array, 0, message.length); System.arraycopy(bts, 0, array, message.length, bts.length); for(MongodbServerConnection serverConn : conns){ if(PACKET_LOGGER.isDebugEnabled()){ PACKET_LOGGER.debug("--->>>@errorRequestPakcet="+lastErrorRequest+"," +clientConn.getSocketId()+" send packet --->"+serverConn.getSocketId()); } serverConn.postMessage(array); } } @Override protected void doServerResponse(MongodbServerConnection conn, byte[] message) { ResponseMongodbPacket lastResponsePacket = new ResponseMongodbPacket(); lastResponsePacket.init(message, clientConn); if(ROUTER_TRACE.isDebugEnabled()){ putDebugInfoToResponsePacket(lastResponsePacket,conn); } if(PACKET_LOGGER.isDebugEnabled()){ PACKET_LOGGER.debug("<<---["+this.requestPacket.requestID+"]--pakcet="+lastResponsePacket+"," +conn.getSocketId()); } if(isMulti){ multiResponsePacket.add(lastResponsePacket); if(endQuery(conn)){ FunctionMerge merge = FUNCTION_MERGE_MAP.get(MongodbPacketConstant.CMD_GETLASTERROR); ResponseMongodbPacket result = merge.mergeResponse(requestPacket, multiResponsePacket); result.responseTo = lastRequestId; clientConn.setLastErrorMessage(result.toByteBuffer(this.clientConn).array()); } }else{ clientConn.setLastErrorMessage(message); endQuery(conn); } } public synchronized void forceEndSession(String cause){ if(isEnd){ return; } closeAllServerConnection(); BSONObject errObject = new BasicBSONObject(); errObject.put("err", cause); errObject.put("errmsg", cause); errObject.put("n", 0); errObject.put("ok", 0.0); ResponseMongodbPacket packet = new ResponseMongodbPacket(); packet.numberReturned = 1; packet.documents = new ArrayList<BSONObject>(1); packet.documents.add(errObject); packet.responseTo = this.lastRequestId; clientConn.setLastErrorMessage(packet.toByteBuffer(this.clientConn).array()); } }