You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@olingo.apache.org by Alain <al...@gmail.com> on 2022/04/06 18:54:43 UTC

Support for bound functions

In implementing bound functions generically, we are facing a few issues.

*1. Invoking a parameterless bound function without parentheses.*
When using Power Query, the request received for a parameterless bound
function contains no parentheses like:

https://example.com/MyServicesvc/Values('_IofvkJOJSG-nn9eyKS6G2A')/com.example.core.getMainStereotype

and this fails with:
org.apache.olingo.server.core.uri.parser.UriParserSemanticException: Type
'com.example.core.getMainStereotype' not found. in
ResourcePathParser#boundOperationOrTypeCast since the tokenizer doesn't
expect to be at EOF,while the version with the parentheses as a suffix
works fine.

Reading the spec at
http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_InvokingaFunction
covers this but is formatted in a way that can lead to believe that this
should only apply to import functions:
*"Services MAY support omitting the parentheses when invoking a function
import with no parameters, but for maximum interoperability MUST also
support invoking the function import with empty parentheses." *

Is this a bug in Olingo or not and if not what is the solution as I'm not
sure this class can easily be replaced.

*2. Handling of derived binding type*
I found out that there was an issue with the handling of derived binding
types in EdmProviderImpl which is a bit of a pain to extend as it is not
planned to be extended.

The method isEntityPreviousTypeCompatibleToBindingParam only looks at the
previous type (hence the name) instead of looking for a match in the full
lineage of base types. I replaced the method with:

private boolean isEntityCompatibleToBindingParam(final FullQualifiedName
bindingParameterTypeName, final CsdlParameter parameter) throws
ODataException {
  CsdlEntityType entityType =
provider.getEntityType(bindingParameterTypeName);
  if (entityType != null) {
    FullQualifiedName baseTypeFqn = entityType.getBaseTypeFQN();
    if (baseTypeFqn != null) {
      return baseTypeFqn.equals(parameter.getTypeFQN()) ||
isEntityCompatibleToBindingParam(baseTypeFqn, parameter);
    }
  }
  return false;
}

I can submit a PR if I am allowed to do so.

*3. Generic handling of UriResourceFunction*
As mentioned in a previous post here, I leveraged the code from the
reference implementation which was a real time saver and provided a lot of
insight into implementing a generic server implementation.

But I am now realizing that the support for bound functions is kind of
lacking. In TechnicalProcess, readEntity we see support for
UriResourceFunction in the first position, which AFAICT are made to handle
import functions. My assumption here is that since bound function can be
part of an overall navigation, they should be handle in a way pretty
similar to how that function handles UriResourceNavigation and probably in
a way where all such paths are processed in sequence, so that the count and
looping is performed on both UriResourceNavigation and UriResourceFunction.
Am I on the right track here? And are there any examples of such a pattern
? The tutorial for bound function is helpful, but it lacks details about
generically processing arbitrary requests.

Thanks
Alain