apigee / apigee-client-php Goto Github PK
View Code? Open in Web Editor NEWClient library to make API calls to Apigee Edge Management API
License: Apache License 2.0
Client library to make API calls to Apigee Edge Management API
License: Apache License 2.0
Test out the behavior of the query parameter “expand=false” - it might return the same format as current Edge.
Apigee X / Hybrid allows for MGMT APIs to be called over gRPC.
This ticket is to evaluate the performance improvements & effort estimates.
Q | A |
---|---|
Bug? | yes |
New Feature? | no |
Version | 1.0.0-alpha4 |
The OAuth Patch for Apigee Edge Client Library for PHP is not getting installed when we run composer.
composer update apigee/apigee-client-php
, but the patch was not installed.composer update drupal/apigee_edge
, but the patch was not installed.composer remove drupal/apigee_edge
and then composer require drupal/apigee_edge
and the patch was not installed.What are the steps to get the patch installed on a currently running system? If I reinstall a brand new site, will the patch get applied?
During the development of PHPUnit tests, I discovered deprecation warnings caused by SDK apigee/apigee-client-php
.
1x: Passing configuration options directly to the constructor is deprecated since Symfony 4.2, use the default context instead.
constructor with warning
vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php
public function __construct($defaultContext = [], \DateTimeZone $timezone = null)
{
$this->defaultContext = [
self::FORMAT_KEY => \DateTime::RFC3339,
self::TIMEZONE_KEY => null,
];
if (!\is_array($defaultContext)) {
@trigger_error('Passing configuration options directly to the constructor is deprecated since Symfony 4.2, use the default context instead.', \E_USER_DEPRECATED);
$defaultContext = [self::FORMAT_KEY => (string) $defaultContext];
$defaultContext[self::TIMEZONE_KEY] = $timezone;
}
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}
cause
vendor/apigee/apigee-client-php/src/Api/Monetization/Serializer/EntitySerializer.php
new DateTimeNormalizer(EntityInterface::DATE_FORMAT, new \DateTimeZone('UTC')),
1x: Using constructor parameters that are not a default context is deprecated since Symfony 4.2, use the "json_decode_associative" and "json_decode_recursion_depth" keys of the context instead.
constructor with warning
vendor/symfony/serializer/Encoder/JsonDecode.php
public function __construct($defaultContext = [], int $depth = 512)
{
if (!\is_array($defaultContext)) {
@trigger_error(sprintf('Using constructor parameters that are not a default context is deprecated since Symfony 4.2, use the "%s" and "%s" keys of the context instead.', self::ASSOCIATIVE, self::RECURSION_DEPTH), \E_USER_DEPRECATED);
$defaultContext = [
self::ASSOCIATIVE => (bool) $defaultContext,
self::RECURSION_DEPTH => $depth,
];
}
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}
cause
vendor/apigee/apigee-client-php/src/Serializer/JsonDecode.php
parent::__construct($associative, $depth);
1x: Passing an integer as first parameter of the "Symfony\Component\Serializer\Encoder\JsonEncode::__construct()" method is deprecated since Symfony 4.2, use the "json_encode_options" key of the context instead.
public function __construct($defaultContext = [])
{
if (!\is_array($defaultContext)) {
@trigger_error(sprintf('Passing an integer as first parameter of the "%s()" method is deprecated since Symfony 4.2, use the "json_encode_options" key of the context instead.', __METHOD__), \E_USER_DEPRECATED);
$this->defaultContext[self::OPTIONS] = (int) $defaultContext;
} else {
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}
}
parent::__construct(new JsonEncode(JSON_PRESERVE_ZERO_FRACTION), $decodingImpl);
Symfony: 4.4.x
Drupal core: 9.1.7
apigee/apigee-client-php: 2.0.7
The related API endpoint allows attributes to be set specified for newly created app credentials, but the current implementation in the API client hides this capability in \Apigee\Edge\Api\Management\Controller\AppCredentialController::create()
.
2.0.6
Is your feature request related to a problem? Please describe.
no.
Describe the solution you'd like
Add support for CRUDL developer categories via /mint/organizations/{org_name}/developer-categories
endpoint. Currently, this is missing from the API client, if I remember correctly it was not added because developer categories API was (is?) marked as deprecated, yet as I can see it is still actively used. (At least on the project that I am working on at this moment.)
Describe the bug
Tests are failing when running with DEPENDENCIES=""
, but not with DEPENDENCIES="--prefer-lowest"
, as seen in:
https://travis-ci.org/apigee/apigee-client-php/builds/604140258
Last successful 2.x build was on 08/25/2019, and it failed next on 08/27/2019. That should help us debug what is the dependency that is failing and if it is affecting something in the library.
Locally, it only fails if xdebug is enabled - might also be worth testing if it's related.
While installing Drupal 8/9 kick-start through composer, few warnings shows up in composer on Apigee X monetization Interfaces which says "doesn't comply with psr-4 auto-loading standards.
"
Install Drupal 8/9 by running - composer create-project apigee/devportal-kickstart-project:8.x-dev MY_PROJECT --no-interaction
Installation completes successfully but shows few warning on composer as ApigeeX interfaces "doesn't comply with psr-4 auto-loading standards.
"
Install drupal without any errors/warning for Apigee X files.
Drupal 8/9
Adding integration testing for Hybrid by testing nightly against a hybrid org to validate API calls are not changing.
Prereq: Need an org to test against.
Q | A |
---|---|
Bug? | yes |
New Feature? | no |
Version | 2.0.1 |
Serializing a rate plan revision without keepOriginalStartDate
set causes an error.
Property "keepOriginalStartDate" has not been initialized on instance of Apigee\Edge\Api\Monetization\Entity\StandardRatePlanRevision class. Expected type: "boolean".
Serializing a pate plan what was retrieved from the API via the client should not error.
Subscribe to a rate plan A, cancel it and then subscribe to a plan A again you should get the error.
Only return true if keepOriginalStartDate is explicitly set to TRUE.
Notice in recent message logs if description is empty after creating app in Apigee hybrid
Create an app with empty description
Notice: Undefined property: stdClass::$value in Apigee\Edge\Denormalizer\AttributesPropertyDenormalizer->denormalize() (line 57 of \vendor\apigee\apigee-client-php\src\Denormalizer\AttributesPropertyDenormalizer.php)
Just like there is an option to run all tests with offline data set or a real (non-hybrid) Apigee connection locally or on a CI (by setting up predefined environments variables), provide a way to also run a test build with a real connection to a hybrid org. This could help automatically identifying broken features on hybrid-enabled orgs.
Deprecate "createdBy" and "lastModifiedBy" properties, as they are not supported (returned) by Hybrid - applications using this client library should not rely on specific platform implementations.
Is your feature request related to a problem? Please describe.
PHP 8 has been officially released for more then 5 months. It was discussed earlier in multiple threads to have readiness for PHP 8, which is way forward.
apigee/devportal-kickstart-project-composer#39
#121
#127
Describe the solution you'd like
phpdocumentor/reflection-docblock:5.1.0
gets installed by default when you spin up a new Drupal test environment from https://github.com/drupal-composer/drupal-project and this library currently only supports "phpdocumentor/reflection-docblock": "^3.0 || ^4.0",
so the installed version has to be dowgraded to be able to install the https://github.com/apigee/apigee-edge-drupal and this library as its dependency.
Suggested solution:
Validate compatibility with the 5.x version and it is supported, add it to the compatibility this.
Just by playing with the Apigee APIs in Public Cloud I found a new query parameter which is supported on the above-mentioned endpoints: ids
. As of today, it seems undocumented here and here but they are used by the MGMT UI.
Supporting this new filtering option could be useful for lazy/async loading information from Apigee Edge.
How does it work?
On both endpoints the ids
parameter accepts a list of comma seperated UUIDs and it returns the related developer/app objects. If no match found for a UUID then no data is returned for that.
/apiproducts
does not support either ids
or names
.Is your feature request related to a problem? Please describe.
There is an (undocumented) query parameter that you can pass to the API products API for gettings the list of apps that are consuming an API product. Combining that with #117 we could have a powerful tool. (This API is also used by the Apigee MGMT API.)
The endpoint is: https://apigee.com/organizations/[ORGNAME]/apiproducts/[PRODUCT_NAME]?query=list&entity=apps
Response:
[ "APP_UUID1", "APP_UUID2" ]
Describe the solution you'd like
Describe alternatives you've considered
Additional context
Add missing fields to the Balance entiy:
After a new version released from the PHP API Client with the change in #54, the install instructions of the Apigee Edge module needs to be updated all places.
Q | A |
---|---|
Bug? | yes |
New Feature? | no |
Version | 2.0.1 |
\Apigee\Edge\Api\Monetization\Controller\AcceptedRatePlanController::updateSubscription
fails with the following error:
{
"code" : "mint.resourceIdMismatch",
"message" : "URL id qualifier [674cdd50-140d-459e-8b95-xxxxxxxxxxxx] does not match with the entity id [company-x] or some of these entites may not exist",
"contexts" : [ ]
}
The posted payload is as follows:
{
"created": "2018-10-03 19:53:04",
"developer": {
"id": "company-x"
},
"endDate": "2019-02-07 17:01:15",
"id": "674cdd50-140d-459e-8b95-xxxxxxxxxxxx",
"prevRecurringFeeDate": "2018-10-04 00:00:00",
"ratePlan": {
"id": "foo_plan"
},
"renewalDate": "2019-10-04 00:00:00",
"startDate": "2018-10-04 00:00:00",
"updated": "2018-12-12 00:00:58"
}
The payload should be using "company" instead of "developer" like the following.
{
"created": "2018-10-03 19:53:04",
"company": {
"id": "company-x"
},
"endDate": "2019-02-07 17:01:15",
"id": "674cdd50-140d-459e-8b95-xxxxxxxxxxxx",
"prevRecurringFeeDate": "2018-10-04 00:00:00",
"ratePlan": {
"id": "foo_plan"
},
"renewalDate": "2019-10-04 00:00:00",
"startDate": "2018-10-04 00:00:00",
"updated": "2018-12-12 00:00:58"
}
Pagination should be default for lists in hybrid.
The php-http/client-common
library has a new release So the patch (https://patch-diff.githubusercontent.com/raw/php-http/client-common/pull/103.diff
) should no longer be necessary.
Support Async API calls for loading/deleting/updating multiple entities (developers, apps, api products, etc.) from Apigee Edge much quicker.
Remove alpha notes about monetization in readme:
https://github.com/apigee/apigee-client-php#monetization-api-alpha-release
I am not sure what are the long term plans for Apigee Hybrid, but as of today, there are known and unknown differences between Apigee APIs on Hybrid and in Public/private cloud. (Is it the right naming convention? 🤔 )
Known differences are described in this document and there are plenty API "families" that are not supported by Hybrid (ex.: Company and Company apps) and there are some unsupported API calls even in the supported ones (ex.: "Get count of API resources" for Developer apps).
Other differences that we have already got bug reports:
createdBy
and lastModifiedBy
are not available on Hybridexpand=[true,false]
is not working on Hybrid: #85 #87 #114_optimized
is not supported on Hybrid: #105 #111This library can hide complexities from developers, like we did with faking CPS support in #43, to make developers' life easier. Although that workaround can be considered a smaller one compared with those differences that we know about Hybrid.
(Clear difference between #43 and the current code in #114 that in #43 we trigger a warning, let developers know that a sub-optimal query is being executed by the library (instead of 1 API call, maybe 10 or more is being sent synchronously), #114 is currently hiding that fact which can lead to unexpected performance regressions on downstream.)
Instead of adding workarounds to our codebase which was designed and built for public/private cloud, introduce a new Apigee\Edge\Api\Hybrid
(or without Edge
) or Apigee\Hybrid\Api
namespace and start collecting those APIs and data models under this namespace that are supported by Hybrid. Ex.: Apigee\Hybrid\Api\Management\Entity\DeveloperApp
In PHP version 7.3, Error while purchasing a Rateplan in Apigee X (5g org).
"Neither the property "published" nor one of the methods "getPublished()", "published()", "isPublished()", "hasPublished()", "__get()" exist and have public access in class "Apigee\Edge\Api\ApigeeX\Entity\StandardRatePlan"."
Purchase a rate plan successfully.
Drupal 8/9
PHP 7.3
Q | A |
---|---|
Bug? | yes |
New Feature? | no |
Version | 2.0.0 |
When trying to unsubscribe from an existing rate plan I get this:
URL id qualifier [[email protected]] does not match with the entity id [someID-0839-4057-84fc-...] or some of these entities may not exist
Successfully unsubscribe form a rate plan.
The code for the subscribe/unsubscribe is in my fork. I am trying to create a patch that would temporarily solve this issue or give some ideas on how this issue could be better handled in the library.
Looks like Apigee\Edge\Api\Monetization\Normalizer\EntityNormalizer::normalize
needs a special treatment for the developer ID when calling unsubscribe method. While developer entity ID is used for the subscribe to rate plan is used the unsubscribe requires actual email address as a Developer ID.
Use account key to create and sign a JWT (JSON Web Token) that is sent to the Google OAuth 2.0 Authorization Server, which returns an access token. The token can then be used in the authorization header (Authorization: Bearer TOKEN) in making calls to the API. When the token expires, the application repeats the process.
The class Apigee\Edge\Exception\ApiResponseException
needs to be updated to handle changes in error response from Hybrid:
{
"error": {
"code": 409,
"message": "...",
"status": "ABORTED",
"details": [...]
}
}
First PSR-17 and later PSR-18 accepted and PHP-HTTP libraries has started to update their code to rely on new interfaces and add return types to their methods. New major versions got released from these libraries because these changes caused BC breaks with the previous versions.
Libraries that we use:
Related conversion which contains some info about the maintenance and support of the 1.x (older) php-http packages and more: php-http/client-common#115 (comment)
Because it seems there is no good way to support both 1.x and 2.x version from all required php-http libraries in the current 2.x branch therefore we should release a new major from this library. The new 3.x version should rely on PSR-17 and PSR-18 interfaces instead of interfaces provided by php-http/httplug.
New client implementations and consumers should use the PSR-18 interfaces directly. In the long term, we expect PSR-18 to completely replace the need for HTTPlug.
(From php-http/httplug's README.md)
The new 3.x version should support only 2.x versions from php-http/client-common and php-http/guzzle6-adapter (as dev dependency) libraries.
In addition, it seems we should wait for the release of the 1.6.0 from the php-http/discovery and depend on that: php-http/discovery#134.
The same resolution happens in case of the Mailgun library: mailgun/mailgun-php#522
(This is a follow up on #24.)
Q | A |
---|---|
Bug? | no |
New Feature? | no |
Version | N/A |
I am very sorry that I have got a noob question. I spent a few days trying to get an app key with getConsumerKey() but have no luck so far. |
What is the actual behavior?
N/A
What is the behavior you expect?
getConsumerKey() gets key from my app.
What are the steps to reproduce this bug? Please add code examples,
screenshots or links to GitHub repositories that can demonstrate the problem.
..
// Create a new developer.
$dc = new DeveloperController($clientFactory->getOrganization(), $clientFactory->getClient());
$developer = new Developer(['email' => $developerEmail]);
$developer->setUserName($username);
$developer->setFirstName($fname);
$developer->setLastName($lname);
$developer->setAttributes(new AttributesProperty(['CONSUMER_TYPE' => 'PMS_VENDOR']));
$dc->create($developer);
// Create a new developer app. - works fine
$dac = new DeveloperAppController($clientFactory->getOrganization(), $developerEmail, $clientFactory->getClient());
$developerApp = new DeveloperApp(['name' => $appName]);
$developerApp->setDisplayName($appName);
$dac->create($developerApp);
// get consumer key. - does not work
$appId = $developerApp->getAppid();
$appCredential = new AppCredential(['appId' => $appId]);
$consumerKey = $appCredential->getConsumerKey();
can we get example how to use getConsumerKey please?
While installing Drupal 8/9 kickstart web installer throws Warning: array_key_exists() expects parameter 2 to be array, string given in Apigee\Edge\Exception\ApiResponseException->parseErrorResponse()
on Configure Apigee Edge section.
On Configure Apigee Edge section installer throws Warning: array_key_exists() expects parameter 2 to be array, string given in Apigee\Edge\Exception\ApiResponseException->parseErrorResponse()
Installer runs without errors
Drupal 8.9.14
Q | A |
---|---|
Bug? | yes |
New Feature? | no |
Version | 2.0.0 |
When using the getEntities() method on the ApiProductController the CpsNotEnabledException is thrown.
I expect to get a list of the API Products
public function __construct(ApigeeClient $client)
{
$organization = config('config.apigee.organization');
$this->client = new ApiProductController($organization, $client->getClient());
}
...
public function all()
{
return $this->client->getEntities();
}
Describe the bug
When trying to load the endUnit
property of the RatePlanRateRateCard
and the RatePlanRateRevShare
objects, the property isn't available.
To Reproduce
Load a rate plan with rates and try to access $rateCardRate->getEndUnit()
.
Expected behavior
$rateCardRate->getEndUnit()
should return the end unit.
Follow up from #100 (comment). Evaluate if/when Symfony 5 compatibility is needed.
Travis-Ci is using PHP 7.1 currently which is causing the tests to fail since it not familiar with the syntax changes of higher PHP versions.
Create a new branch from fork and run Travis-Ci tests
Tests are failing (syntax errors)
Tests should pass since no changes have been made to the branch
Add any other context about the problem here.
travis-ci.com (recommended newer version of travis-ci.org)
The Apigee product used to be hosted at apigee.com. The newer platform of Apigee is now at apigee.google.com and uses Google Cloud. The actual names of these platforms have been changed to:
Hybrid is the name for a specific flavor of Apigee on Google Cloud where the Apigee runtime is hosted in a different location than Google Cloud. However, the Apigee API and admin features are still at apigee.google.com.
Since we did not understand the naming when we created the feature, the constant ClientInterface::HYBRID_ENDPOINT
is not correct. In the ClientInteface, the constants should be renamed:
ClientInterface::DEFAULT_ENDPOINT
should be EDGE_ENDPOINT
ClientInterface::HYBRID_ENDPOINT
should be APIGEE_ON_GCP_ENDPOINT
To avoid breaking changes, the original constants should be marked as deprecated, and the new constants added until we can remove them in a 3.x version. Add comments to explain this info above.
The class HybridOauth2
class is also named incorrectly, and should be deprecated in favor of a class named ApigeeOnGcpOauth2
Add Hybrid base URL (https://apigee.googleapis.com/v1/) as a constant to \Apigee\Edge\ClientInterface
, analogous to ClientInterface::DEFAULT_ENDPOINT
for public cloud.
Moved conversation from an active PR: #71 (comment)
@cnovak please share your thoughts about it. I would not drop the license header plugin unless it is actually a legal requirement having different copyright headers on older files.
Add tests for hybrid using Mock client
Is your feature request related to a problem? Please describe.
Describe the solution you'd like
Add support for loading the list of non-monetized API products from Apigee.
There is a note here that only monetized API products can be loaded from Apigee, although there is OOTB support on the API level for retrieving non-monetized ones via the monetized=false
query parameter.
See: https://apidocs.apigee.com/docs/monetization/1/routes/mint/organizations/%7Borg_name%7D/products/get
Describe alternatives you've considered
Additional context
Add an Organization::isHybrid() helper method that checks the organization property “features.hybrid.enabled”.
Because we need to keep the copyright year of a file pinned, and don't change it if the file is edited/moved/copied, we had to remove the header_comment
fixer from the PHP-CS-Fixer rules (see #79 (comment)).
It would be good to have a code fixer/sniff that adds this back in a way that we it adds a copyright header with the current year to new files, and ensures the header exists on other files, or at least verifies that all files have a copyright header.
Related: PHP-CS-Fixer/PHP-CS-Fixer#4625
On the Hybrid API: Making a call to /organizations/***organization***/environments?expand=false
fails with error 400. It says the parameter "expand" isn't supported for this resource.
Full response:
TTP/1.1 400 Bad Request
Vary: X-Origin, Referer, Origin,Accept-Encoding
Content-Type: application/json; charset=UTF-8
Date: Fri, 08 Nov 2019 20:12:52 GMT
Server: ESF
Cache-Control: private
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Alt-Svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000
Accept-Ranges: none
Transfer-Encoding: chunked
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"expand\": Cannot bind query parameter. Field 'expand' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"expand\": Cannot bind query parameter. Field 'expand' could not be found in request message."
}
]
}
]
}
}
After creating a App, On Analytics page I am seeing below error:-
"Unable to retrieve analytics data. Please try again."
On checking Drupal logs I saw below error message:-
"Apigee\Edge\Exception\ClientErrorException: INVALID_ARGUMENT: Invalid JSON payload received. Unknown name "_optimized": Cannot bind query parameter. Field 'optimized' could not be found in request message. in Apigee\Edge\HttpClient\Plugin\ResponseHandlerPlugin->decodeResponse() (line 104 of G:\Projects\apigee_kickstart\vendor\apigee\apigee-client-php\src\HttpClient\Plugin\ResponseHandlerPlugin.php)."
Refer screenshot for Apigee Debug message of Request and Response
2.0.5
Changing ClientInterface::DEFAULT_ENDPOINT
for ClientInterface::PUBLIC_CLOUD_ENDPOINT
should make things more clear since there isn't a default endpoint anymore.
This would involve deprecating ClientInterface::DEFAULT_ENDPOINT
in favor of the new ClientInterface::PUBLIC_CLOUD_ENDPOINT
.
According to the official documentation \Apigee\Edge\Api\Management\Controller\DeveloperController::getDeveloperByApp()
is incorrectly implemented because the related API endpoint returns an array of developer objects instead of one developer object.
To get the developers associated with a specific app, specify the name of the app using the app query parameter.
Since fixing this requires a change in the related interface we have to be careful about how we introduce this fix. Probably we should do the following:
getDevelopersByAppName()
in the DeveloperController
with a todo that this method should be added to the DeveloperControllerInterface
in 3.0.0.DeveloperController::getDeveloperByApp()
and DeveloperControllerInterface::getDeveloperByApp()
to get them removed in 3.0.0.2.0.6
A request to the Hybrid API of the type /organizations/{{organizationsId}}/developers/{{developer_email}}
will return a 404 if the developer email contains an invalid character such as "+". Hybrid API requires such parameters to be URL encoded.
Example of failing request: /organizations/{{organizationsId}}/developers/[email protected]
Example of correct request: /organizations/{{organizationsId}}/developers/user%2B1%40example.com
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.