You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by GitBox <gi...@apache.org> on 2019/01/15 15:51:53 UTC

[geode] Diff for: [GitHub] dschneider-pivotal closed pull request #3072: Stable pdx instance (not yet ready for review)

diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java
index 1b5ae6c5f47..274468a166a 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java
@@ -34,10 +34,10 @@
 import org.apache.geode.cache.query.QueryService;
 import org.apache.geode.internal.cache.Token;
 import org.apache.geode.pdx.JSONFormatter;
-import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.pdx.PdxSerializationException;
-import org.apache.geode.pdx.internal.FieldNotFoundInPdxVersion;
-import org.apache.geode.pdx.internal.PdxInstanceImpl;
+import org.apache.geode.pdx.internal.InternalPdxInstance;
+import org.apache.geode.pdx.internal.PdxType;
+import org.apache.geode.pdx.internal.TypeRegistry;
 
 /**
  * Utility for managing an attribute
@@ -49,12 +49,15 @@
 public class AttributeDescriptor {
   private final String _name;
   private final MethodInvocationAuthorizer _methodInvocationAuthorizer;
+  private final TypeRegistry _pdxRegistry;
   /** cache for remembering the correct Member for a class and attribute */
   private static final ConcurrentMap<List, Member> _localCache = new ConcurrentHashMap();
 
 
 
-  public AttributeDescriptor(MethodInvocationAuthorizer methodInvocationAuthorizer, String name) {
+  public AttributeDescriptor(TypeRegistry pdxRegistry,
+      MethodInvocationAuthorizer methodInvocationAuthorizer, String name) {
+    _pdxRegistry = pdxRegistry;
     _methodInvocationAuthorizer = methodInvocationAuthorizer;
     _name = name;
   }
@@ -75,8 +78,8 @@ public Object read(Object target) throws NameNotFoundException, QueryInvocationT
     if (target == null || target == QueryService.UNDEFINED) {
       return QueryService.UNDEFINED;
     }
-    if (target instanceof PdxInstance) {
-      return readPdx((PdxInstance) target);
+    if (target instanceof InternalPdxInstance) {
+      return readPdx((InternalPdxInstance) target);
     }
     // for non pdx objects
     return readReflection(target);
@@ -202,70 +205,58 @@ private Method getReadMethod(Class targetType, String methodName) {
    *
    * @return the value of the field from PdxInstance
    */
-  private Object readPdx(PdxInstance target)
+  private Object readPdx(InternalPdxInstance pdxInstance)
       throws NameNotFoundException, QueryInvocationTargetException {
-    if (target instanceof PdxInstanceImpl) {
-      PdxInstanceImpl pdxInstance = (PdxInstanceImpl) target;
-      // if the field is present in the pdxinstance
-      if (pdxInstance.hasField(_name)) {
-        // return PdxString if field is a String otherwise invoke readField
-        return pdxInstance.getRawField(_name);
-      } else {
-        // field not found in the pdx instance, look for the field in any of the
-        // PdxTypes (versions of the pdxinstance) in the type registry
-        String className = pdxInstance.getClassName();
-
-        // don't look further for field or method or reflect on GemFire JSON data
-        if (className.equals(JSONFormatter.JSON_CLASSNAME)) {
-          return QueryService.UNDEFINED;
-        }
+    // if the field is present in the pdxinstance
+    if (pdxInstance.hasField(_name)) {
+      // return PdxString if field is a String otherwise invoke readField
+      return pdxInstance.getRawField(_name);
+    } else {
+      // field not found in the pdx instance, look for the field in any of the
+      // PdxTypes (versions of the pdxinstance) in the type registry
+      String className = pdxInstance.getClassName();
 
+      // don't look further for field or method or reflect on GemFire JSON data
+      if (className.equals(JSONFormatter.JSON_CLASSNAME)) {
+        return QueryService.UNDEFINED;
+      }
 
-        // check if the field was not found previously
-        if (!isFieldAlreadySearchedAndNotFound(className, _name)) {
-          try {
-            return pdxInstance.getDefaultValueIfFieldExistsInAnyPdxVersions(_name, className);
-          } catch (FieldNotFoundInPdxVersion e1) {
-            // remember the field that is not present in any version to avoid
-            // trips to the registry next time
-            updateClassToFieldsMap(className, _name);
-          }
+      // check if the field was not found previously
+      if (!isFieldAlreadySearchedAndNotFound(className, _name)) {
+        PdxType pdxType = _pdxRegistry.getPdxTypeForField(_name, className);
+        if (pdxType == null) {
+          // remember the field that is not present in any version to avoid
+          // trips to the registry next time
+          updateClassToFieldsMap(className, _name);
+        } else {
+          return pdxType.getPdxField(_name).getFieldType().getDefaultValue();
         }
-        // if the field is not present in any of the versions try to
-        // invoke implicit method call
-        if (!this.isMethodAlreadySearchedAndNotFound(className, _name)) {
-          try {
-            return readFieldFromDeserializedObject(pdxInstance, target);
-          } catch (NameNotFoundException ex) {
-            updateClassToMethodsMap(pdxInstance.getClassName(), _name);
-            throw ex;
-          }
-        } else
-          return QueryService.UNDEFINED;
-      }
-    } else {
-      // target could be another implementation of PdxInstance like
-      // PdxInstanceEnum, in this case getRawField and getCachedOjects methods are
-      // not available
-      if (((PdxInstance) target).hasField(_name)) {
-        return ((PdxInstance) target).getField(_name);
       }
-      throw new NameNotFoundException(
-          String.format("Field ' %s ' in class ' %s ' is not accessible to the query processor",
-              new Object[] {_name, target.getClass().getName()}));
+      // if the field is not present in any of the versions try to
+      // invoke implicit method call
+      if (!this.isMethodAlreadySearchedAndNotFound(className, _name)) {
+        try {
+          return readFieldFromDeserializedObject(pdxInstance);
+        } catch (NameNotFoundException ex) {
+          updateClassToMethodsMap(pdxInstance.getClassName(), _name);
+          throw ex;
+        }
+      } else
+        return QueryService.UNDEFINED;
     }
   }
 
-  private Object readFieldFromDeserializedObject(PdxInstanceImpl pdxInstance, Object target)
+  private Object readFieldFromDeserializedObject(InternalPdxInstance pdxInstance)
       throws NameNotFoundException, QueryInvocationTargetException {
+    Object obj = null;
     try {
-      Object obj = pdxInstance.getCachedObject();
-      return readReflection(obj);
+      obj = pdxInstance.getCachedObject();
     } catch (PdxSerializationException e) {
       throw new NameNotFoundException( // the domain object is not available
-          String.format("Field ' %s ' in class ' %s ' is not accessible to the query processor",
-              new Object[] {_name, target.getClass().getName()}));
+          String.format("Field '%s' is not accessible to the query processor because: %s",
+              new Object[] {_name, e.getMessage()}));
     }
+    return readReflection(obj);
   }
 
   private void updateClassToFieldsMap(String className, String field) {
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledOperation.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledOperation.java
index 81ad28dc784..0a8eb7afd21 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledOperation.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledOperation.java
@@ -35,7 +35,7 @@
 import org.apache.geode.internal.cache.PartitionedRegion;
 import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.pdx.PdxSerializationException;
-import org.apache.geode.pdx.internal.PdxInstanceImpl;
+import org.apache.geode.pdx.internal.InternalPdxInstance;
 import org.apache.geode.pdx.internal.PdxString;
 
 /**
@@ -280,13 +280,9 @@ private Object eval0(Object receiver, Class resolutionType, ExecutionContext con
       // cache
       CompiledOperation.cache.putIfAbsent(key, methodDispatch);
     }
-    if (receiver instanceof PdxInstance) {
+    if (receiver instanceof InternalPdxInstance) {
       try {
-        if (receiver instanceof PdxInstanceImpl) {
-          receiver = ((PdxInstanceImpl) receiver).getCachedObject();
-        } else {
-          receiver = ((PdxInstance) receiver).getObject();
-        }
+        receiver = ((InternalPdxInstance) receiver).getCachedObject();
       } catch (PdxSerializationException ex) {
         throw new QueryInvocationTargetException(ex);
       }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/PathUtils.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/PathUtils.java
index 62236f45f7e..0fb3fede993 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/PathUtils.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/PathUtils.java
@@ -72,7 +72,7 @@ public static Object evaluateAttribute(ExecutionContext context, Object target,
       }
     }
     try {
-      return new AttributeDescriptor(
+      return new AttributeDescriptor(context.getCache().getPdxRegistry(),
           context.getCache().getQueryService().getMethodInvocationAuthorizer(), attribute)
               .read(target);
     } catch (NameNotFoundException nfe) {
@@ -112,7 +112,7 @@ public static Object evaluateAttribute(ExecutionContext context, Object target,
 
     for (int i = 1; i < types.length; i++) {
       ObjectType currentType = types[i - 1];
-      Member member = new AttributeDescriptor(
+      Member member = new AttributeDescriptor(context.getCache().getPdxRegistry(),
           context.getCache().getQueryService().getMethodInvocationAuthorizer(), pathArray[i - 1])
               .getReadMember(currentType.resolveClass());
 
@@ -170,7 +170,7 @@ public static ObjectType computeElementTypeOfExpression(ExecutionContext context
             stepStr = stepStr.substring(0, stepStr.length() - 2);
             member = clazz.getMethod(stepStr, (Class[]) null);
           } else {
-            member = new AttributeDescriptor(
+            member = new AttributeDescriptor(context.getCache().getPdxRegistry(),
                 context.getCache().getQueryService().getMethodInvocationAuthorizer(), stepStr)
                     .getReadMember(clazz);
           }
diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/RuntimeIterator.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/RuntimeIterator.java
index 300bca3c197..ceaff47a657 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/RuntimeIterator.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/RuntimeIterator.java
@@ -196,7 +196,7 @@ boolean containsProperty(ExecutionContext context, String name, int numArgs, boo
     // if there are zero arguments and it's an attribute, then defer to
     // AttributeDescriptor
     // to see if there's a match
-    return new AttributeDescriptor(
+    return new AttributeDescriptor(context.getCache().getPdxRegistry(),
         context.getCache().getQueryService().getMethodInvocationAuthorizer(), name)
             .validateReadType(clazz);
   }
diff --git a/geode-core/src/main/java/org/apache/geode/pdx/internal/EnumInfo.java b/geode-core/src/main/java/org/apache/geode/pdx/internal/EnumInfo.java
index c8ee36efbae..249d18af39d 100644
--- a/geode-core/src/main/java/org/apache/geode/pdx/internal/EnumInfo.java
+++ b/geode-core/src/main/java/org/apache/geode/pdx/internal/EnumInfo.java
@@ -27,7 +27,6 @@
 import org.apache.geode.internal.DataSerializableFixedID;
 import org.apache.geode.internal.HeapDataOutputStream;
 import org.apache.geode.internal.InternalDataSerializer;
-import org.apache.geode.internal.Sendable;
 import org.apache.geode.internal.Version;
 import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.pdx.PdxSerializationException;
@@ -191,7 +190,7 @@ public PdxInstance getPdxInstance(int enumId) {
   }
 
   public static class PdxInstanceEnumInfo
-      implements PdxInstance, Sendable, ConvertableToBytes, ComparableEnum {
+      implements InternalPdxInstance, ComparableEnum {
     private static final long serialVersionUID = 7907582104525106416L;
     private final int enumId;
     private final EnumInfo ei;
diff --git a/geode-core/src/main/java/org/apache/geode/pdx/internal/FieldNotFoundInPdxVersion.java b/geode-core/src/main/java/org/apache/geode/pdx/internal/FieldNotFoundInPdxVersion.java
deleted file mode 100644
index 8b32295999f..00000000000
--- a/geode-core/src/main/java/org/apache/geode/pdx/internal/FieldNotFoundInPdxVersion.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.pdx.internal;
-
-public class FieldNotFoundInPdxVersion extends Exception {
-
-  private static final long serialVersionUID = 1292033563588485577L;
-
-  public FieldNotFoundInPdxVersion(String message) {
-    super(message);
-  }
-
-}
diff --git a/geode-core/src/main/java/org/apache/geode/pdx/internal/InternalPdxInstance.java b/geode-core/src/main/java/org/apache/geode/pdx/internal/InternalPdxInstance.java
index f2d895b0e81..522ef5afc86 100644
--- a/geode-core/src/main/java/org/apache/geode/pdx/internal/InternalPdxInstance.java
+++ b/geode-core/src/main/java/org/apache/geode/pdx/internal/InternalPdxInstance.java
@@ -14,7 +14,33 @@
  */
 package org.apache.geode.pdx.internal;
 
+import org.apache.geode.internal.Sendable;
 import org.apache.geode.pdx.PdxInstance;
+import org.apache.geode.pdx.PdxSerializationException;
+
+public interface InternalPdxInstance extends PdxInstance, ConvertableToBytes, Sendable {
+  /**
+   * The same as calling getObject() but may also cache the result and future calls
+   * of this method will return the cached object instead of recomputing it.
+   * Implementors that do not want to support a cache can just use the default implementation
+   * which simply calls getObject().
+   *
+   * @throws PdxSerializationException if the instance could not be deserialized
+   */
+  default Object getCachedObject() {
+    return getObject();
+  }
+
+  /**
+   * This same as calling getField(fieldName) except that some implementations may support
+   * returning a PdxString instead of String.
+   * Implementors that do not support PdxString can use use the default implementation
+   * which simply calls getField(fieldName).
+   *
+   * @throws PdxSerializationException if the field could not be deserialized
+   */
+  default Object getRawField(String fieldName) {
+    return getField(fieldName);
+  }
 
-public interface InternalPdxInstance extends PdxInstance, ConvertableToBytes {
 }
diff --git a/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceEnum.java b/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceEnum.java
index 9373a6c7c09..0b173d162a8 100644
--- a/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceEnum.java
+++ b/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceEnum.java
@@ -24,9 +24,7 @@
 import org.apache.geode.internal.DSCODE;
 import org.apache.geode.internal.HeapDataOutputStream;
 import org.apache.geode.internal.InternalDataSerializer;
-import org.apache.geode.internal.Sendable;
 import org.apache.geode.internal.Version;
-import org.apache.geode.pdx.PdxInstance;
 import org.apache.geode.pdx.PdxSerializationException;
 import org.apache.geode.pdx.WritablePdxInstance;
 
@@ -35,7 +33,7 @@
  *
  * @since GemFire 6.6.2
  */
-public class PdxInstanceEnum implements PdxInstance, Sendable, ConvertableToBytes, ComparableEnum {
+public class PdxInstanceEnum implements InternalPdxInstance, ComparableEnum {
   private static final long serialVersionUID = -7417287878052772302L;
   private final String className;
   private final String enumName;
diff --git a/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceImpl.java b/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceImpl.java
index 855759488be..ea49a2a6006 100644
--- a/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/pdx/internal/PdxInstanceImpl.java
@@ -35,7 +35,6 @@
 import org.apache.geode.internal.ClassPathLoader;
 import org.apache.geode.internal.DSCODE;
 import org.apache.geode.internal.InternalDataSerializer;
-import org.apache.geode.internal.Sendable;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.tcp.ByteBufferInputStream;
@@ -55,7 +54,7 @@
  * We do not use this normal java io serialization when serializing this class in GemFire because
  * Sendable takes precedence over Serializable.
  */
-public class PdxInstanceImpl extends PdxReaderImpl implements InternalPdxInstance, Sendable {
+public class PdxInstanceImpl extends PdxReaderImpl implements InternalPdxInstance {
 
   private static final long serialVersionUID = -1669268527103938431L;
 
@@ -186,7 +185,7 @@ public void sendTo(DataOutput out) throws IOException {
     }
   }
 
-  // this is for internal use of the query engine.
+  @Override
   public Object getCachedObject() {
     Object result = this.cachedObjectForm;
     if (result == null) {
@@ -652,20 +651,8 @@ public boolean isEnum() {
     return false;
   }
 
+  @Override
   public Object getRawField(String fieldName) {
     return getUnmodifiableReader(fieldName).readRawField(fieldName);
   }
-
-  public Object getDefaultValueIfFieldExistsInAnyPdxVersions(String fieldName, String className)
-      throws FieldNotFoundInPdxVersion {
-    PdxType pdxType =
-        GemFireCacheImpl.getForPdx("PDX registry is unavailable because the Cache has been closed.")
-            .getPdxRegistry().getPdxTypeForField(fieldName, className);
-    if (pdxType == null) {
-      throw new FieldNotFoundInPdxVersion(
-          "PdxType with field " + fieldName + " is not found for class " + className);
-    }
-    return pdxType.getPdxField(fieldName).getFieldType().getDefaultValue();
-  }
-
 }
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index a7ca52a9d2e..cfc0020febc 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -636,7 +636,6 @@ org/apache/geode/pdx/PdxInitializationException,true,5098737377658808834
 org/apache/geode/pdx/PdxRegistryMismatchException,true,-2329989020829052537
 org/apache/geode/pdx/PdxSerializationException,true,-3843814927034345635
 org/apache/geode/pdx/internal/EnumInfo$PdxInstanceEnumInfo,true,7907582104525106416,ei:org/apache/geode/pdx/internal/EnumInfo,enumId:int
-org/apache/geode/pdx/internal/FieldNotFoundInPdxVersion,true,1292033563588485577
 org/apache/geode/pdx/internal/PdxInputStream,false
 org/apache/geode/pdx/internal/PdxReaderImpl,true,-6094553093860427759,blobType:org/apache/geode/pdx/internal/PdxType,dis:org/apache/geode/pdx/internal/PdxInputStream
 org/apache/geode/redis/internal/CoderException,true,4707944288714910949


With regards,
Apache Git Services