All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebeaninternal.server.transaction.BeanPersistIds Maven / Gradle / Ivy

There is a newer version: 8.1.1
Show newest version
package com.avaje.ebeaninternal.server.transaction;

import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.cluster.BinaryMessage;
import com.avaje.ebeaninternal.server.cluster.BinaryMessageList;
import com.avaje.ebeaninternal.server.core.PersistRequest;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.id.IdBinder;

import java.io.DataInput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Wraps the information representing a Inserted Updated or Deleted Bean.
 * 

* This information is broadcast across the cluster so that remote BeanListeners * are notified of the inserts updates and deletes that occurred. *

*

* You control it the data is broadcast and what data is broadcast by the * BeanListener.getClusterData() method. It is guessed that often just the Id * property or perhaps a few properties in a Map will be broadcast to reduce the * size of data sent around the network. *

*/ public class BeanPersistIds { private final BeanDescriptor beanDescriptor; private final String descriptorId; private List insertIds; private List updateIds; private List deleteIds; /** * Create the payload. */ public BeanPersistIds(BeanDescriptor desc) { this.beanDescriptor = desc; this.descriptorId = desc.getDescriptorId(); } public static BeanPersistIds readBinaryMessage(SpiEbeanServer server, DataInput dataInput) throws IOException { String descriptorId = dataInput.readUTF(); BeanDescriptor desc = server.getBeanDescriptorById(descriptorId); BeanPersistIds bp = new BeanPersistIds(desc); bp.read(dataInput); return bp; } private void read(DataInput dataInput) throws IOException { IdBinder idBinder = beanDescriptor.getIdBinder(); int iudType = dataInput.readInt(); List idList = readIdList(dataInput, idBinder); switch (iudType) { case 0: insertIds = idList; break; case 1: updateIds = idList; break; case 2: deleteIds = idList; break; default: throw new RuntimeException("Invalid iudType " + iudType); } } /** * Write the contents into a BinaryMessage form. *

* For a RemoteBeanPersist with a large number of id's note that this is * broken up into many BinaryMessages each with a maximum of 100 ids. This * enables the contents of a large RemoteTransactionEvent to be split up * across multiple Packets. *

*/ void writeBinaryMessage(BinaryMessageList msgList) throws IOException { writeIdList(beanDescriptor, 0, insertIds, msgList); writeIdList(beanDescriptor, 1, updateIds, msgList); writeIdList(beanDescriptor, 2, deleteIds, msgList); } private List readIdList(DataInput dataInput, IdBinder idBinder) throws IOException { int count = dataInput.readInt(); if (count < 1) { return null; } List idList = new ArrayList(count); for (int i = 0; i < count; i++) { idList.add(idBinder.readData(dataInput)); } return idList; } /** * Write a BinaryMessage containing the descriptorId, iudType and list of Id * values. *

* Note that a given BinaryMessage has a maximum of 100 Ids. This is due to * the limit of UDP packet sizes. We break up the RemoteBeanPersist into * potentially many smaller BinaryMessages which may be put into multiple * Packets. *

*/ private void writeIdList(BeanDescriptor desc, int iudType, List idList, BinaryMessageList msgList) throws IOException { IdBinder idBinder = desc.getIdBinder(); int count = idList == null ? 0 : idList.size(); if (count > 0) { int loop = 0; int i = 0; int eof = idList.size(); do { ++loop; int endOfLoop = Math.min(eof, loop * 100); BinaryMessage m = new BinaryMessage(endOfLoop * 4 + 20); DataOutputStream os = m.getOs(); os.writeInt(BinaryMessage.TYPE_BEANIUD); os.writeUTF(descriptorId); os.writeInt(iudType); os.writeInt(count); for (; i < endOfLoop; i++) { idBinder.writeData(os, idList.get(i)); } os.flush(); msgList.add(m); } while (i < eof); } } public String toString() { StringBuilder sb = new StringBuilder(); if (beanDescriptor != null) { sb.append(beanDescriptor.getFullName()); } else { sb.append("descId:").append(descriptorId); } if (insertIds != null) { sb.append(" insertIds:").append(insertIds); } if (updateIds != null) { sb.append(" updateIds:").append(updateIds); } if (deleteIds != null) { sb.append(" deleteIds:").append(deleteIds); } return sb.toString(); } void addId(PersistRequest.Type type, Serializable id) { switch (type) { case INSERT: addInsertId(id); break; case UPDATE: addUpdateId(id); break; case DELETE: case SOFT_DELETE: addDeleteId(id); break; default: break; } } private void addInsertId(Serializable id) { if (insertIds == null) { insertIds = new ArrayList(); } insertIds.add(id); } private void addUpdateId(Serializable id) { if (updateIds == null) { updateIds = new ArrayList(); } updateIds.add(id); } private void addDeleteId(Serializable id) { if (deleteIds == null) { deleteIds = new ArrayList(); } deleteIds.add(id); } public BeanDescriptor getBeanDescriptor() { return beanDescriptor; } List getDeleteIds() { return deleteIds; } /** * Notify the cache of this event that came from another server in the cluster. */ void notifyCacheAndListener() { // any change invalidates the query cache beanDescriptor.queryCacheClear(); if (updateIds != null) { for (int i = 0; i < updateIds.size(); i++) { Object id = updateIds.get(i); beanDescriptor.cacheHandleDeleteById(id); } } if (deleteIds != null) { for (int i = 0; i < deleteIds.size(); i++) { Object id = deleteIds.get(i); beanDescriptor.cacheHandleDeleteById(id); } } } }