private void handleUpdate(Message clientMessage) {
    String regionName = null;
    Object key = null;
    Part valuePart = null;
    final boolean isDebugEnabled = logger.isDebugEnabled();

    try {
      isOpCompleted = false;

      // Retrieve the data from the put message parts
      if (isDebugEnabled) {
        logger.debug("Received put message of length ({} bytes)", clientMessage.getPayloadLength());
      }

      int partCnt = 0;
      Part regionNamePart = clientMessage.getPart(partCnt++);
      Part keyPart = clientMessage.getPart(partCnt++);
      boolean isDeltaSent = (Boolean) clientMessage.getPart(partCnt++).getObject();
      valuePart = clientMessage.getPart(partCnt++);
      Part callbackArgumentPart = clientMessage.getPart(partCnt++);
      VersionTag versionTag = (VersionTag) clientMessage.getPart(partCnt++).getObject();
      if (versionTag != null) {
        versionTag.replaceNullIDs((InternalDistributedMember) endpoint.getMemberId());
      }
      Part isInterestListPassedPart = clientMessage.getPart(partCnt++);
      Part hasCqsPart = clientMessage.getPart(partCnt++);

      EventID eventId =
          (EventID) clientMessage.getPart(clientMessage.getNumberOfParts() - 1).getObject();

      boolean withInterest = (Boolean) isInterestListPassedPart.getObject();
      boolean withCQs = (Boolean) hasCqsPart.getObject();

      regionName = regionNamePart.getCachedString();
      key = keyPart.getStringOrObject();
      Object callbackArgument = callbackArgumentPart.getObject();

      // Don't automatically deserialize the value.
      // Pass it onto the region as a byte[]. If it is a serialized
      // object, it will be stored as a CachedDeserializable and
      // deserialized only when requested.

      boolean isCreate = clientMessage.getMessageType() == LOCAL_CREATE;

      if (isDebugEnabled) {
        logger.debug(
            "Putting entry for region: {} key: {} create: {}{} callbackArgument: {} withInterest={} withCQs={} eventID={} version={}",
            regionName, key, isCreate,
            valuePart.isObject()
                ? new StringBuilder(" value: ").append(deserialize(valuePart.getSerializedForm()))
                : "",
            callbackArgument, withInterest, withCQs, eventId, versionTag);
      }

      LocalRegion region = (LocalRegion) cacheHelper.getRegion(regionName);

      byte[] deltaBytes = null;
      Object objectValue = null;
      boolean isValueObject;

      if (!isDeltaSent) {
        byte[] serializedForm = valuePart.getSerializedForm();

        if (!isCreate || !InternalDataSerializer.isSerializedNull(serializedForm)) {
          objectValue = valuePart.getSerializedForm();
        }

        if (withCQs) {
          objectValue = valuePart.getObject();
        }

        isValueObject = valuePart.isObject();
      } else {
        deltaBytes = valuePart.getSerializedForm();
        isValueObject = true;
      }

      if (region == null) {
        if (isDebugEnabled && !quitting()) {
          logger.debug("{}: Region named {} does not exist", this, regionName);
        }

      } else if (region.hasServerProxy() && ServerResponseMatrix
          .checkForValidStateAfterNotification(region, key, clientMessage.getMessageType())
          && (withInterest || !withCQs)) {
        @Released
        EntryEventImpl newEvent = null;

        try {
          // Create an event and put the entry
          newEvent = EntryEventImpl.create(region,
              clientMessage.getMessageType() == LOCAL_CREATE ? Operation.CREATE
                  : Operation.UPDATE,
              key, null /* newValue */, callbackArgument /* callbackArg */, true /* originRemote */,
              eventId.getDistributedMember());

          newEvent.setVersionTag(versionTag);
          newEvent.setFromServer(true);

          region.basicBridgeClientUpdate(eventId.getDistributedMember(), key, objectValue,
              deltaBytes,
              isValueObject, callbackArgument,
              clientMessage.getMessageType() == LOCAL_CREATE,
              qManager.getState().getProcessedMarker() || !isDurableClient, newEvent,
              eventId);

          isOpCompleted = true;

          // bug 45520 - ConcurrentCacheModificationException is not thrown and we must check this
          // flag
          if (withCQs && isDeltaSent) {
            objectValue = newEvent.getNewValue();
          }
        } catch (InvalidDeltaException ignore) {
          Part fullValuePart = requestFullValue(eventId, "Caught InvalidDeltaException.");
          region.getCachePerfStats().incDeltaFullValuesRequested();
          objectValue = fullValuePart.getObject();
          isValueObject = fullValuePart.isObject();

          region.basicBridgeClientUpdate(eventId.getDistributedMember(), key, objectValue, null,
              isValueObject, callbackArgument,
              clientMessage.getMessageType() == LOCAL_CREATE,
              qManager.getState().getProcessedMarker() || !isDurableClient, newEvent,
              eventId);

          isOpCompleted = true;
        } finally {
          if (newEvent != null) {
            newEvent.release();
          }
        }

        if (isDebugEnabled) {
          logger.debug("Put entry for region: {} key: {} callbackArgument: {}", regionName, key,
              callbackArgument);
        }
      }

      // Update CQs. CQs can exist without client region.
      if (withCQs) {
        Part numCqsPart = clientMessage.getPart(partCnt++);
        if (isDebugEnabled) {
          logger.debug("Received message has CQ Event. Number of cqs interested in the event : {}",
              numCqsPart.getInt() / 2);
        }
        processCqs(clientMessage, partCnt, numCqsPart.getInt(),
            clientMessage.getMessageType(), key, objectValue, deltaBytes, eventId);
        isOpCompleted = true;
      }
    } catch (Exception e) {
      String message =
          String.format(
              "The following exception occurred while attempting to put entry (region: %s key: %s value: %s)",
              regionName, key, deserialize(valuePart.getSerializedForm()));
      handleException(message, e);
    }
  }
Create or update an entry

@param clientMessage message containing the data
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java