/** * Method is called if all defined conditions are met and the feature is marked as enabled. * Use this method to configure and initialize all required components for the feature like * the steps in the pipeline or the instances/factories in the container. * * @param Settings $settings * @param BuilderInterface $builder * @param PipelineModifications $pipelineModifications */ public function setup(Settings $settings, BuilderInterface $builder, PipelineModifications $pipelineModifications) { $outboxEnabled = FeatureSettingsExtensions::isFeatureActive(OutboxFeature::class, $settings); if ($outboxEnabled) { $builder->defineSingleton(OutboxStorageInterface::class, function () use($builder, $settings) { return new InMemoryOutboxStorage(); }); } }
/** * @param Feature $feature * @param Feature[] $enabledFeatures * @param BuilderInterface $builder * @param PipelineModifications $pipelineModifications * * @return bool */ private function activateFeature(Feature $feature, $enabledFeatures, BuilderInterface $builder, PipelineModifications $pipelineModifications) { if ($feature->isActive()) { return true; } $dependencyGroups = $feature->getDependencies(); $groupsActivationStatus = []; foreach ($dependencyGroups as $dependencyGroup) { $dependentFeaturesToActivate = []; foreach ($dependencyGroup as $dependencyFqcn) { if (isset($enabledFeatures[$dependencyFqcn])) { $dependentFeaturesToActivate[$dependencyFqcn] = $enabledFeatures[$dependencyFqcn]; } } $dependenciesActivationStatus = []; foreach ($dependentFeaturesToActivate as $featureFqcn => $dependentFeature) { $dependenciesActivationStatus[$featureFqcn] = $this->activateFeature($dependentFeature, $enabledFeatures, $builder, $pipelineModifications); } // if at least one dependency in the group has been activated $groupsActivationStatus[] = in_array(true, $dependenciesActivationStatus); } $featureFqcn = get_class($feature); // if all groups have been activated if (!in_array(false, $groupsActivationStatus)) { if (!$feature->checkPrerequisites($this->settings, $builder, $pipelineModifications)) { FeatureSettingsExtensions::markFeatureAsInactive($featureFqcn, $this->settings); return false; } FeatureSettingsExtensions::markFeatureAsActive($featureFqcn, $this->settings); $feature->activate($this->settings, $builder, $pipelineModifications); return true; } FeatureSettingsExtensions::markFeatureAsInactive($featureFqcn, $this->settings); return false; }
/** * This is where subclasses declare what storage types they support together with * the initializers for those types. */ public function formalize() { $this->supports(StorageType::OUTBOX(), function (Settings $s) { FeatureSettingsExtensions::enableFeatureByDefault(InMemoryOutboxPersistenceFeature::class, $s); }); }
private function registerKnownFeatures() { $featureFqcnList = [RootFeature::class, TransportFeature::class, SendingFeature::class, ReceivingFeature::class, SerializationFeature::class, RoutingFeature::class, AutoSubscribeFeature::class, OutgoingPipelineFeature::class, IncomingPipelineFeature::class, OutboxFeature::class, InMemoryOutboxPersistenceFeature::class, OutgoingMessageMutationFeature::class, IncomingMessageMutationFeature::class, ErrorLastResortFeature::class, FirstLevelRetryFeature::class, MessageCorrelationFeature::class]; foreach ($featureFqcnList as $featureFqcn) { FeatureSettingsExtensions::registerFeature($featureFqcn, $this->settings); } }