Skip to content
Open
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
47 changes: 47 additions & 0 deletions Command/ExportFlowsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Smartbox\Integration\FrameworkBundle\Command;

use Smartbox\Integration\FrameworkBundle\Tools\FlowExporter\FlowExporter;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ExportFlowsCommand extends Command
{
/**
* {@inheritdoc}
*/
protected static $defaultName = 'smartesb:flows:export';

/**
* @var FlowExporter
*/
private $exporter;

public function __construct(FlowExporter $exporter)
{
$this->exporter = $exporter;

parent::__construct();
}

/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setDescription('Exports the current flows and mappings.');
$this->setHelp('Currently no file is dumped, results are just shown on screen. Only outbound flows are processed.');
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
var_dump($this->exporter->getProducerMappings('smartesb.producers.r2d2'));
}
}
12 changes: 12 additions & 0 deletions Configurability/IsConfigurableService.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ public function setMethodsConfiguration(array $methodsConfiguration)
$this->methodsConfiguration = $methodsConfiguration;
}

/**
* @return array
*/
public function getMethodsConfiguration(string $methodName = null)
{
if ($methodName) {
return $this->methodsConfiguration[$methodName] ?? null;
}

return $this->methodsConfiguration;
}

/**
* {@inheritdoc}
*/
Expand Down
13 changes: 13 additions & 0 deletions DependencyInjection/SmartboxIntegrationFrameworkExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class SmartboxIntegrationFrameworkExtension extends Extension
const NOSQL_DRIVER_PREFIX = 'smartesb.drivers.nosql.';
const HANDLER_PREFIX = 'smartesb.handlers.';
const PRODUCER_PREFIX = 'smartesb.producers.';
const PRODUCER_TAG = 'smartesb.producer';
const CONSUMER_PREFIX = 'smartesb.consumers.';
const PARAM_DEFERRED_EVENTS_URI = 'smartesb.uris.deferred_events';

Expand Down Expand Up @@ -110,6 +111,7 @@ public function loadConfigurableProducers(ContainerBuilder $container)
$definition->addMethodCall('setSerializer', [new Reference('jms_serializer')]);
$definition->addMethodCall('setEventDispatcher', [new Reference('event_dispatcher')]);
$definition->addMethodCall('setName', [$producerName]);
$definition->addTag(self::PRODUCER_TAG);

if (is_subclass_of($class, HttpClientInterface::class)) {
$definition->addMethodCall('addHandler', [
Expand Down Expand Up @@ -417,6 +419,16 @@ protected function loadHandlers(ContainerBuilder $container)
}
}

public function loadFlowExporter(ContainerBuilder $container)
{
$def = $container->findDefinition('smartesb.util.flow_exporter');
$producers = array_keys($container->findTaggedServiceIds(self::PRODUCER_TAG));
// @TODO Use references to avoid needing the container. Or use service locator directly.
$def->addMethodCall('addProducers', [$producers]);
$def->addMethodCall('addMappings', [$this->config['mappings']]);
$def->addMethodCall('setContainer', [new Reference('service_container')]);
}

public function enableLogging(ContainerBuilder $container)
{
$def = new Definition('%smartesb.event_listener.events_logger.class%', [
Expand Down Expand Up @@ -540,5 +552,6 @@ public function load(array $configs, ContainerBuilder $container)
$this->loadNoSQLDrivers($container);
$this->loadConfigurableProducers($container);
$this->loadMappings($container);
$this->loadFlowExporter($container);
}
}
14 changes: 13 additions & 1 deletion Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,16 @@ services:
# Serializers
smartesb.serialization.queue.jms_serializer:
class: Smartbox\Integration\FrameworkBundle\Components\Queues\Serialization\Serializer
arguments: ['@jms_serializer']
arguments: ['@jms_serializer']

# Flow exporter
smartesb.util.flow_exporter:
class: Smartbox\Integration\FrameworkBundle\Tools\FlowExporter\FlowExporter
calls:
- [setEvaluator, ['@smartesb.util.evaluator']]
- [setConfHelper, ['@smartesb.configurable_service_helper']]

Smartbox\Integration\FrameworkBundle\Command\ExportFlowsCommand:
arguments: ['@smartesb.util.flow_exporter']
tags:
- { name: console.command }
95 changes: 95 additions & 0 deletions Tools/FlowExporter/FlowExporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

namespace Smartbox\Integration\FrameworkBundle\Tools\FlowExporter;

use Smartbox\Integration\FrameworkBundle\Components\WebService\AbstractWebServiceProducer;
use Smartbox\Integration\FrameworkBundle\Components\WebService\Rest\RestConfigurableProducer;
use Smartbox\Integration\FrameworkBundle\DependencyInjection\Traits\UsesConfigurableServiceHelper;
use Smartbox\Integration\FrameworkBundle\DependencyInjection\Traits\UsesEvaluator;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class FlowExporter implements ContainerAwareInterface
{
use UsesEvaluator;
use UsesConfigurableServiceHelper;

/**
* @var array
*/
protected $producers;

/**
* @var array
*/
protected $mappings;
/**
* @var ContainerInterface|null
*
* @TODO replace with service locator
*/
protected $container;

public function addProducers(array $producers)
{
$this->producers = $producers;
}

public function addMappings(array $mappings)
{
$this->mappings = $mappings;
}

public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}

public function getAvailableProducers()
{
return $this->producers;
}

public function getProducerMappings(string $producer = null)
{
$this->injectUnmapper();

if (false === array_search($producer, $this->producers, true)) {
throw new \LogicException(sprintf('[FlowExporter] No producer named %s available', $producer));
}

return $this->buildProducer($this->container->get($producer));
}

protected function buildProducer(AbstractWebServiceProducer $producer): ProducerMapping
{
$mapping = new ProducerMapping($producer->getName());

foreach ($producer->getMethodsConfiguration() as $name => $definition) {
$method = new ProducerMethod($name, $definition);

$defineSteps = $method->getDefineSteps();
$flattened = [];
array_walk_recursive($defineSteps, function ($a, $b) use (&$flattened) {
$flattened[$b] = $a;
});

$request = $method->getRequestStep();

// @TODO on soap is "Parameters"
$body = $request[RestConfigurableProducer::REQUEST_BODY];
$mapping->addMethod($method->getName(), $this->getConfHelper()->evaluateStringOrExpression(!is_array($body) ? $body : reset($body), $flattened));
}

return $mapping;
}

protected function injectUnmapper()
{
$unmapper = new Unmapper();
$unmapper->addMappings($this->mappings);
$this->evaluator->setMapper($unmapper);
}
}
37 changes: 37 additions & 0 deletions Tools/FlowExporter/ProducerMapping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Smartbox\Integration\FrameworkBundle\Tools\FlowExporter;

class ProducerMapping
{
/**
* @var string
*/
protected $name;

protected $methods = [];

public function __construct(string $name)
{
$this->name = $name;
}

/**
* @param string|array $mapping
*/
public function addMethod(string $method, $mapping)
{
$this->methods[$method] = $mapping;
}

public function getMethod(string $name = null)
{
if ($name) {
return $this->methods[$name] ?? null;
}

return $this->methods;
}
}
57 changes: 57 additions & 0 deletions Tools/FlowExporter/ProducerMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Smartbox\Integration\FrameworkBundle\Tools\FlowExporter;

use Smartbox\Integration\FrameworkBundle\Core\Producers\ConfigurableProducerInterface;

class ProducerMethod
{
/**
* @var array
*/
protected $definition;
/**
* @var string
*/
protected $name;

public function __construct(string $name, array $definition)
{
$this->definition = $definition;
$this->name = $name;
}

/**
* @return string
*/
public function getName(): string
{
return $this->name;
}

public function getRequestStep(): array
{
foreach ($this->definition[ConfigurableProducerInterface::CONF_STEPS] as $step) {
if (isset($step['request'])) {
return $step['request'];
}
}

throw new \LogicException('[Producer Method Parser] Method definition has no step named "request"');
}

public function getDefineSteps()
{
$steps = [];

foreach ($this->definition[ConfigurableProducerInterface::CONF_STEPS] as $step) {
if (isset($step['define'])) {
$steps[] = $step['define'];
}
}

return $steps ?? null;
}
}
38 changes: 38 additions & 0 deletions Tools/FlowExporter/Unmapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Smartbox\Integration\FrameworkBundle\Tools\FlowExporter;

use Smartbox\Integration\FrameworkBundle\Tools\Mapper\MapperInterface;

class Unmapper implements MapperInterface
{
/**
* @var array
*/
protected $mappings;

public function map($obj, $mappingName, $context = [])
{
if (isset($this->mappings[$mappingName])) {
return $this->mappings[$mappingName];
}

throw new \LogicException(sprintf('[Unmapper] Mapping "%" not found', $mappingName));
}

public function mapAll($elements, $mappingName, $context = [])
{
if (isset($this->mappings[$mappingName])) {
return ['array' => $this->mappings[$mappingName]];
}

throw new \LogicException(sprintf('[Unmapper] Mapping "%" not found', $mappingName));
}

public function addMappings(array $mappings)
{
$this->mappings = $mappings;
}
}