Property sets are not returning any values

I am using Property sets in Apigee Hybrid to store key value pairs. When I try to read the keys it gives null value or returns error.

File Name - myprops.properties

# myProps.properties file
foo=bar

Using ExtractVariables policy -

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables name="ExtractVariables-1">
    <DisplayName>ExtractVariables-1</DisplayName>
    <Source>request</Source>
    <Variable name="myVar">
        <Pattern>{propertyset.myprops.properties.foo}</Pattern>
    </Variable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</ExtractVariables>

This variable returns empty value.

Using AssignMessage Policy - This returns error response as Key is invalid.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1">
    <DisplayName>Assign Message-1</DisplayName>
    <Properties/>
    <Set>
        <Payload content-type="application/json">{
                "message": "{myVar}",
                "value": "{propertyset.myprops.properties.foo}"
            }
        </Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

Using Javascript - This also returns error as invalid Key

 var property = context.getVariable('propertyset.myprops.properties.foo');
 print("property is -"+ property);

Is there anything I am missing here.

1 Like

Can you try using {propertyset.myprops.foo} instead?

Also, I’m assuming you have already used the Management API to update the property set? and also, to view and verify?

https://cloud.google.com/apigee/docs/api-platform/cache/property-sets#create-api

https://cloud.google.com/apigee/docs/api-platform/cache/property-sets#view-api

I have tried with both -

{propertyset.myprops.foo} - This give null value.

{propertyset.myprops.properties.foo}
  • This gives error response.

I have added properties file through gui and deployed as new revision.

The docs are wrong, internal bug filed b/178508219

Should be:

<ExtractVariables name="ExtractVariables-1">
   <DisplayName>Extract a property value</DisplayName>
   <Source>request</Source>
   <Variable name="propertyset.MyPropSet.foo">
      <Pattern>{myVar}</Pattern>
   </Variable>
   <VariablePrefix>foobar</VariablePrefix>
   <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</ExtractVariables>

The variable to read from is the property identifier in the attribute name and the value is assigned to the variable in Pattern.

You can also do the same using Assign Message policy:

    <AssignVariable>
        <Name>myVar</Name>
        <PropertySetRef>MyPropSet.foo"</PropertySetRef>
    </AssignVariable>

I tried with above but still not getting the values.

Extract Variable policy -

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables name="ExtractVariables-1">
    <DisplayName>ExtractVariables-1</DisplayName>
    <Source>request</Source>
    <Variable name="propertyset.myprops.properties.foo">
        <Pattern>{myVar}</Pattern>
    </Variable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</ExtractVariables>

This give below error -

{
    "fault": {
        "faultstring": "Illegal propertyset key {} [myprops.properties.foo]",
        "detail": {
            "errorcode": "Bad Request"
        }
    }
}

I tried below after removing .properties but it gives empty value -

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables name="ExtractVariables-1">
    <DisplayName>ExtractVariables-1</DisplayName>
    <Source>request</Source>
    <Variable name="propertyset.myprops.foo">
        <Pattern>{myVar}</Pattern>
    </Variable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</ExtractVariables><p>

Same is the case with Assign Message Policy -

<AssignVariable>
        <Name>myVar1</Name>
        <PropertySetRef>myprops.properties.foo</PropertySetRef>
    </AssignVariable>

This give 400 Bad Request error.

Below gives empty values -

 <AssignVariable>
        <Name>myVar1</Name>
        <PropertySetRef>myprops.foo</PropertySetRef>
    </AssignVariable>

I was successfully able to access a property set that’s attached to my api proxy by using the following pattern in my API proxy

{propertyset..}

eg if my propertyset file is named testprop.properties, and it contains a property foo:

{propertyset.testprop.foo}

eg

{propertyset.testprop.foo}

If this doesn’t work, I suspect that your propertyset resource isnt created as expected?

Hi @dane knezic

I have attached my proxy here. Can you please check if I am missing something?sampletest.zip

Your example works for me, it returns me a response with message bar

Same proxy is returning empty value for me. Is there a way we can check if propertyset resource file is created properly in hybrid run time or not?

I was able to reproduce your situation in my Apigee X (formerly NG SaaS).

It’s not working when the Property Set is at the API Proxy scope.

It does work when the Property Set is at the environment scope.

Hi @Kurt Googler Kanaskie,

Is there a way to resolve this issue?

You could create a Property Set at the environment level based on the name of the proxy.

Thanks @Kurt Googler Kanaskie, I am able to retrieve the values from environment level property set.

But we wanted to use proxy level property set as we have a limitation that only 10 environment scoped property sets can created. And if we start creating Property Set at the environment level based on the name of the proxy then soon we will reach this limit.

How can we fix this Proxy level property set issue?

We’ve fixed the examples in the prop set docs:

1 Like

In Apigee X, If you use a proxy-scoped propertyset, there is a bug that you will not be able to retrieve the values if the propertyset resource has a .properties suffix.

If you add the propertyset resource without the suffix, then at runtime you will be able to retrieve the properties.

Let me give a further explanation.

Suppose your apiproxy bundle looks like this:

  Length      Date    Time    Name
---------  ---------- -----   ----
        0  02-18-2021 12:41   apiproxy/
        0  02-18-2021 12:43   apiproxy/resources/
        0  02-18-2021 13:19   apiproxy/resources/properties/
       67  02-18-2021 13:08   apiproxy/resources/properties/set2
       67  02-18-2021 13:08   apiproxy/resources/properties/set1.properties
      360  02-18-2021 12:41   apiproxy/propset-demo1.xml
        0  02-18-2021 13:12   apiproxy/policies/
      421  02-18-2021 13:11   apiproxy/policies/...
        0  02-18-2021 13:11   apiproxy/proxies/
     1458  02-18-2021 13:11   apiproxy/proxies/endpoint1.xml
---------                     -------
     4145                     XX files

Then, at runtime, your proxy WILL be able to retrieve properties from set2, and will not be able to retrieve properties from set1.

This is a bug, ref: b/179371811

We expect to fix this soon. In that case you will be able to retrieve from either set1 or set2.

There is a second factor: if you use the UI to create your proxy and add the propertyset, it always adds the .properties suffix. This means, for now, you need to use the API to import your API proxy, or to add the propertyset to the API proxy, in order to be able to retrieve them at runtime.

1 Like

Thanks Dino-at-Google for the response. Yes this looks like a bug and it is fixed in Apigee hybrid 1.3.5

I am able to read the property sets in this version. I will try this approach in older versions also.

I’m happy to report that the Property Set issue at the proxy scope is now fixed.

Attached is an example proxy showing usage for Assign Message, Extract Variables and JavaScript policies.

property-set-proxy-test-rev3-2021-02-26.zip

1 Like

Whoo-hoo! Thank for the followup, Kurt. And the nice example!

@Anup Rai FYI

1 Like

This thread helped me to get started on property sets. However, I discovered & was wondering that this capability is not extended at a shared-flow level (though addition of properties is possible it doesn’t work).

Scenarios like say for example I want to create a shared-flow that builds target.url taking configurations from .properties file at runtime across APIs proxies, then having properties within that shared-flow and the file contains target endpoint config details for all API proxies in the environment.

Also, though documentation says that API Proxy scope level property sets can be created & edited via Apigee API, not able to find relevant API at the given link: https://cloud.google.com/apigee/docs/reference/apis/apigee/rest#rest-resource:-v1.organizations.environments.resourcefiles (all APIs listed here are for Environment scope is what I believe).

Scope Runtime behavior Administration

API proxy Properties are available only to the revision of the API proxy that contains the property set resource. No other API proxy or revision of the same proxy can access that particular property set. Administrators can use the /resourcefiles Apigee API or the UI to create and edit property sets. Saving the API proxy in the UI will create a new revision, and the modified property set will be associated with that revision only.
Environment Properties are available to all revisions of all API proxies within that environment. API proxies within other environments cannot access that property set. Administrators must use the /resourcefiles Apigee API to create, view, update or delete environment-scoped property sets. These property sets are not displayed and cannot be edited in the Apigee UI.
1 Like