Skip to content

PHPC-1893: Implement TopologyOpeningEvent class #1250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ if test "$PHP_MONGODB" != "no"; then
src/MongoDB/Monitoring/SDAMSubscriber.c \
src/MongoDB/Monitoring/Subscriber.c \
src/MongoDB/Monitoring/TopologyChangedEvent.c \
src/MongoDB/Monitoring/TopologyOpeningEvent.c \
src/MongoDB/Monitoring/functions.c \
"

Expand Down
2 changes: 1 addition & 1 deletion config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ if (PHP_MONGODB != "no") {
MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c");
MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c ServerApi.c ServerDescription.c Session.c TopologyDescription.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
MONGODB_ADD_SOURCES("/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c");
MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c SDAMSubscriber.c Subscriber.c TopologyChangedEvent.c functions.c");
MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c SDAMSubscriber.c Subscriber.c TopologyChangedEvent.c TopologyOpeningEvent.c functions.c");
MONGODB_ADD_SOURCES("/src/libmongoc/src/common", PHP_MONGODB_COMMON_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES);
MONGODB_ADD_SOURCES("/src/libmongoc/src/libbson/src/jsonsl", PHP_MONGODB_JSONSL_SOURCES);
Expand Down
1 change: 1 addition & 0 deletions php_phongo.c
Original file line number Diff line number Diff line change
Expand Up @@ -3858,6 +3858,7 @@ PHP_MINIT_FUNCTION(mongodb)
php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_sdamsubscriber_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_topologychangedevent_init_ce(INIT_FUNC_ARGS_PASSTHRU);
php_phongo_topologyopeningevent_init_ce(INIT_FUNC_ARGS_PASSTHRU);

REGISTER_STRING_CONSTANT("MONGODB_VERSION", (char*) PHP_MONGODB_VERSION, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("MONGODB_STABILITY", (char*) PHP_MONGODB_STABILITY, CONST_CS | CONST_PERSISTENT);
Expand Down
8 changes: 8 additions & 0 deletions php_phongo_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ static inline php_phongo_topologychangedevent_t* php_topologychangedevent_fetch_
{
return (php_phongo_topologychangedevent_t*) ((char*) obj - XtOffsetOf(php_phongo_topologychangedevent_t, std));
}
static inline php_phongo_topologyopeningevent_t* php_topologyopeningevent_fetch_object(zend_object* obj)
{
return (php_phongo_topologyopeningevent_t*) ((char*) obj - XtOffsetOf(php_phongo_topologyopeningevent_t, std));
}

#define Z_CLIENTENCRYPTION_OBJ_P(zv) (php_clientencryption_fetch_object(Z_OBJ_P(zv)))
#define Z_COMMAND_OBJ_P(zv) (php_command_fetch_object(Z_OBJ_P(zv)))
Expand Down Expand Up @@ -199,6 +203,7 @@ static inline php_phongo_topologychangedevent_t* php_topologychangedevent_fetch_
#define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) (php_commandstartedevent_fetch_object(Z_OBJ_P(zv)))
#define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) (php_commandsucceededevent_fetch_object(Z_OBJ_P(zv)))
#define Z_TOPOLOGYCHANGEDEVENT_OBJ_P(zv) (php_topologychangedevent_fetch_object(Z_OBJ_P(zv)))
#define Z_TOPOLOGYOPENINGEVENT_OBJ_P(zv) (php_topologyopeningevent_fetch_object(Z_OBJ_P(zv)))

#define Z_OBJ_CLIENTENCRYPTION(zo) (php_clientencryption_fetch_object(zo))
#define Z_OBJ_COMMAND(zo) (php_command_fetch_object(zo))
Expand Down Expand Up @@ -235,6 +240,7 @@ static inline php_phongo_topologychangedevent_t* php_topologychangedevent_fetch_
#define Z_OBJ_COMMANDSTARTEDEVENT(zo) (php_commandstartedevent_fetch_object(zo))
#define Z_OBJ_COMMANDSUCCEEDEDEVENT(zo) (php_commandsucceededevent_fetch_object(zo))
#define Z_OBJ_TOPOLOGYCHANGEDEVENT(zo) (php_topologychangedevent_fetch_object(zo))
#define Z_OBJ_TOPOLOGYOPENINGEVENT(zo) (php_topologyopeningevent_fetch_object(zo))

extern zend_class_entry* php_phongo_clientencryption_ce;
extern zend_class_entry* php_phongo_command_ce;
Expand Down Expand Up @@ -308,6 +314,7 @@ extern zend_class_entry* php_phongo_commandsucceededevent_ce;
extern zend_class_entry* php_phongo_sdamsubscriber_ce;
extern zend_class_entry* php_phongo_subscriber_ce;
extern zend_class_entry* php_phongo_topologychangedevent_ce;
extern zend_class_entry* php_phongo_topologyopeningevent_ce;

extern void php_phongo_binary_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_dbpointer_init_ce(INIT_FUNC_ARGS);
Expand Down Expand Up @@ -381,6 +388,7 @@ extern void php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_sdamsubscriber_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_subscriber_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_topologychangedevent_init_ce(INIT_FUNC_ARGS);
extern void php_phongo_topologyopeningevent_init_ce(INIT_FUNC_ARGS);

/* Shared function entries for disabling constructors and unserialize() */
PHP_FUNCTION(MongoDB_disabled___construct);
Expand Down
5 changes: 5 additions & 0 deletions php_phongo_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,11 @@ typedef struct {
zend_object std;
} php_phongo_topologychangedevent_t;

typedef struct {
bson_oid_t topology_id;
zend_object std;
} php_phongo_topologyopeningevent_t;

#endif /* PHONGO_STRUCTS */

/*
Expand Down
127 changes: 127 additions & 0 deletions src/MongoDB/Monitoring/TopologyOpeningEvent.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright 2021-present MongoDB, Inc.
*
* Licensed 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.
*/

#include <php.h>
#include <Zend/zend_interfaces.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "phongo_compat.h"
#include "php_phongo.h"

zend_class_entry* php_phongo_topologyopeningevent_ce;

/* {{{ proto MongoDB\BSON\ObjectId TopologyOpeningEvent::getTopologyId()
Returns this event's topology id */
static PHP_METHOD(TopologyOpeningEvent, getTopologyId)
{
php_phongo_objectid_t* topology_id;
php_phongo_topologyopeningevent_t* intern = Z_TOPOLOGYOPENINGEVENT_OBJ_P(getThis());

PHONGO_PARSE_PARAMETERS_NONE();

object_init_ex(return_value, php_phongo_objectid_ce);

topology_id = Z_OBJECTID_OBJ_P(return_value);
bson_oid_to_string(&intern->topology_id, topology_id->oid);
topology_id->initialized = true;
} /* }}} */

/* {{{ MongoDB\Driver\Monitoring\TopologyOpeningEvent function entries */
ZEND_BEGIN_ARG_INFO_EX(ai_TopologyOpeningEvent_void, 0, 0, 0)
ZEND_END_ARG_INFO()

static zend_function_entry php_phongo_topologyopeningevent_me[] = {
/* clang-format off */
ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_TopologyOpeningEvent_void, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL)
PHP_ME(TopologyOpeningEvent, getTopologyId, ai_TopologyOpeningEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_TopologyOpeningEvent_void, ZEND_ACC_PUBLIC | ZEND_ACC_FINAL)
PHP_FE_END
/* clang-format on */
};
/* }}} */

/* {{{ MongoDB\Driver\Monitoring\TopologyOpeningEvent object handlers */
static zend_object_handlers php_phongo_handler_topologyopeningevent;

static void php_phongo_topologyopeningevent_free_object(zend_object* object) /* {{{ */
{
php_phongo_topologyopeningevent_t* intern = Z_OBJ_TOPOLOGYOPENINGEVENT(object);

zend_object_std_dtor(&intern->std);
} /* }}} */

static zend_object* php_phongo_topologyopeningevent_create_object(zend_class_entry* class_type) /* {{{ */
{
php_phongo_topologyopeningevent_t* intern = NULL;

intern = PHONGO_ALLOC_OBJECT_T(php_phongo_topologyopeningevent_t, class_type);

zend_object_std_init(&intern->std, class_type);
object_properties_init(&intern->std, class_type);

intern->std.handlers = &php_phongo_handler_topologyopeningevent;

return &intern->std;
} /* }}} */

static HashTable* php_phongo_topologyopeningevent_get_debug_info(phongo_compat_object_handler_type* object, int* is_temp) /* {{{ */
{
php_phongo_topologyopeningevent_t* intern;
zval retval = ZVAL_STATIC_INIT;
char topology_id[25];

intern = Z_OBJ_TOPOLOGYOPENINGEVENT(PHONGO_COMPAT_GET_OBJ(object));
*is_temp = 1;
array_init_size(&retval, 1);

bson_oid_to_string(&intern->topology_id, topology_id);
ADD_ASSOC_STRING(&retval, "topologyId", topology_id);

return Z_ARRVAL(retval);
} /* }}} */
/* }}} */

void php_phongo_topologyopeningevent_init_ce(INIT_FUNC_ARGS) /* {{{ */
{
zend_class_entry ce;
(void) type;
(void) module_number;

INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "TopologyOpeningEvent", php_phongo_topologyopeningevent_me);
php_phongo_topologyopeningevent_ce = zend_register_internal_class(&ce);
php_phongo_topologyopeningevent_ce->create_object = php_phongo_topologyopeningevent_create_object;
PHONGO_CE_FINAL(php_phongo_topologyopeningevent_ce);
PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_topologyopeningevent_ce);

memcpy(&php_phongo_handler_topologyopeningevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_topologyopeningevent.get_debug_info = php_phongo_topologyopeningevent_get_debug_info;
php_phongo_handler_topologyopeningevent.free_obj = php_phongo_topologyopeningevent_free_object;
php_phongo_handler_topologyopeningevent.offset = XtOffsetOf(php_phongo_topologyopeningevent_t, std);

return;
} /* }}} */

/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
30 changes: 30 additions & 0 deletions src/phongo_apm.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,35 @@ static void phongo_apm_topology_changed(const mongoc_apm_topology_changed_t* eve
FREE_HASHTABLE(subscribers);
}

static void phongo_apm_topology_opening(const mongoc_apm_topology_opening_t* event)
{
mongoc_client_t* client;
HashTable* subscribers;
php_phongo_topologyopeningevent_t* p_event;
zval z_event;

client = mongoc_apm_topology_opening_get_context(event);
subscribers = phongo_apm_get_subscribers_to_notify(php_phongo_sdamsubscriber_ce, client);

/* Return early if there are no APM subscribers to notify */
if (zend_hash_num_elements(subscribers) == 0) {
goto cleanup;
}

object_init_ex(&z_event, php_phongo_topologyopeningevent_ce);
p_event = Z_TOPOLOGYOPENINGEVENT_OBJ_P(&z_event);

mongoc_apm_topology_opening_get_topology_id(event, &p_event->topology_id);
;

phongo_apm_dispatch_event(subscribers, "topologyOpening", &z_event);
zval_ptr_dtor(&z_event);

cleanup:
zend_hash_destroy(subscribers);
FREE_HASHTABLE(subscribers);
}

/* Assigns APM callbacks to a client, which will notify any global or per-client
* subscribers. This should be called for all clients created by the driver.
* Returns true on success; otherwise, throws an exception and returns false. */
Expand All @@ -305,6 +334,7 @@ bool phongo_apm_set_callbacks(mongoc_client_t* client)
mongoc_apm_set_command_succeeded_cb(callbacks, phongo_apm_command_succeeded);
mongoc_apm_set_command_failed_cb(callbacks, phongo_apm_command_failed);
mongoc_apm_set_topology_changed_cb(callbacks, phongo_apm_topology_changed);
mongoc_apm_set_topology_opening_cb(callbacks, phongo_apm_topology_opening);

retval = mongoc_client_set_apm_callbacks(client, callbacks, client);

Expand Down
2 changes: 2 additions & 0 deletions tests/apm/monitoring-topologyChanged-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class MySubscriber implements MongoDB\Driver\Monitoring\SDAMSubscriber
echo "- getNewDescription() returns a TopologyDescription: ", ($event->getNewDescription() instanceof MongoDB\Driver\TopologyDescription) ? 'yes' : 'no', "\n";
echo "- getPreviousDescription() returns a TopologyDescription: ", ($event->getPreviousDescription() instanceof MongoDB\Driver\TopologyDescription) ? 'yes' : 'no', "\n";
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}
}

$subscriber = new MySubscriber;
Expand Down
33 changes: 33 additions & 0 deletions tests/apm/monitoring-topologyOpening-001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--TEST--
MongoDB\Driver\Monitoring\TopologyOpeningEvent
--SKIPIF--
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
<?php skip_if_not_live(); ?>
--FILE--
<?php
require_once __DIR__ . "/../utils/basic.inc";

$m = create_test_manager();

class MySubscriber implements MongoDB\Driver\Monitoring\SDAMSubscriber
{
public function topologyChanged(MongoDB\Driver\Monitoring\TopologyChangedEvent $event) {}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event)
{
echo "- getTopologyId() returns an ObjectId: ", ($event->getTopologyId() instanceof MongoDB\BSON\ObjectId) ? 'yes' : 'no', "\n";
}
}

$subscriber = new MySubscriber;
MongoDB\Driver\Monitoring\addSubscriber($subscriber);

$command = new MongoDB\Driver\Command(['ping' => 1]);
$m->executeCommand(DATABASE_NAME, $command);

?>
===DONE===
<?php exit(0); ?>
--EXPECT--
- getTopologyId() returns an ObjectId: yes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this wasn't done in the previous PR for TopologyChangedEvent, but it occurred to me that we have no tests (and therefore no code coverage) for the event object's debug handler. Would you mind making a ticket within the epic so we don't forget to add those? Something like "Create tests for event object debug handlers" should suffice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

===DONE===
2 changes: 2 additions & 0 deletions tests/topologyDescription/topologyDescription-debug-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class TopologyDescriptionProvider implements MongoDB\Driver\Monitoring\SDAMSubsc
$this->topologyDescription = $event->getNewDescription();
}

public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event) {}

public function getTopologyDescription()
{
$manager = create_test_manager();
Expand Down