ONGR Elasticsearch Bundle AWS Connection Issue - symfony

Hello Ther i try to connenct to ES indet that is located on AWS, but i still get he Error.
[Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]
You have requested a non-existent service "es.managers.default".
I installed the bundle using Conposer, as described on the Docs.
then added a config part tom my config.ylm
ongr_elasticsearch:
managers:
default:
index:
index_name: contents
hosts:
- https://search-***.es.amazonaws.com:443
mappings:
- StatElasticBundle
i have a awsaccesskey and a awssecretkey, but i don't now where i have to put them, so i created a aws_connection section in the parameters.yml and try to load it
Then i try to establish a connection in my SymfonyBundle and created a class in my Bundle->DepandencyInjection folder to extend my bundle, this is where i get the error. Mayby someone of you struggled with the same error?
Thanks for help.
Class StatElasticExtension extends Extension
{
const YAML_FILES = [
'parameters.yml',
'config.yml',
'services.yml'
];
/**
* {#inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
foreach (self::YAML_FILES as $yml) {
$loader->load($yml);
}
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$serviceDefinition = $container->getDefinition('es.managers.default');
$awsConnections = $container->getParameter('aws_connections');
$elasticsearchClient = $this->getClient($awsConnections);
$serviceDefinition->replaceArgument(2, $elasticsearchClient);
}

The correct service name is es.manager.default.

Related

You have requested a non-existent service "test.service_container". Did you mean this: "service_container"?

PHPUnit 7.5.15 by Sebastian Bergmann and contributors.
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException : You have requested a non-existent service "test.service_container". Did you mean this: "service_container"?
/opt/project/backend/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:277
/opt/project/backend/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:225
/opt/project/backend/tests/Functional/KernelAwareTest.php:49
/opt/project/backend/tests/Functional/FlightTaskManagement/AssignEmployeeToTaskTest.php:47
public function setUp(): void
{
global $kernel;
$this->kernel = TestKernel::get();
$kernel = $this->kernel;
$container = $this->kernel->getContainer();
if ($container === null)
throw new \InvalidArgumentException('Container can not be null.');
$this->container = $container->get('test.service_container');
// $this->container = $container->get('service_container');
/** #var Registry $doctrine */
$doctrine = $this->container->get('doctrine');
/** #var \Doctrine\ORM\EntityManager $manager */
$manager = $doctrine->getManager();
$this->entityManager = $manager;
$this->entityManager->beginTransaction();
if (!$this->container->initialized(WorkDistributionTransport::class)) {
$this->container->set(WorkDistributionTransport::class, new InMemoryTransport());
}
if (!$this->container->initialized(Configuration::class)) {
$this->container->set(Configuration::class, new TestConfiguration());
}
parent::setUp();
}
It fails at line
$this->container = $container->get('test.service_container');
Symfony is 4.1 but looks like not finished to update. I can't remember by what we decided that it was not finished to update from earlier version.
Not clear if that is the problem that it is not finished to update. Looks like in 4.0 there is no such service so thats why. But then how to make it appear here?
Or maybe I can use
$this->container = $container->get('service_container');
as with earlier versions? Just what is faster way?
I just tried using
$this->container = $container->get('service_container');
but I then get
Doctrine\DBAL\DBALException : An exception occured while establishing a connection to figure out your platform version.
You can circumvent this by setting a 'server_version' configuration value
But I had set the version in config_test.yml so not clear which way is faster to fix.
doctrine:
dbal:
server_version: 5.7
driver: pdo_mysql
host: db_test
port: null
dbname: project
user: project
password: project
Probably if I load service_container then it does not load test config and thats why I get this server_version error. So then need to somehow make it load test config.
Found: I had hardcoded dev environment in AppKernel. Probably thats why I was getting this error. Hardcoding test env fixed. Would be good somehow to make it without hardcoding, but it is still better than nothing:
public function __construct($environment, $debug)
{
// $environment ='dev';
$environment ='test';
$debug= true;
parent::__construct($environment, $debug);
date_default_timezone_set('UTC');
}

SF 3.4 inject bundle config in services

Using Symfony 3.4, I just try a simple case for a new bundle (name: APiToolBundle).
Here is the content of src/ApiToolBundle/Resources/config/config.yml :
imports:
- { resource: parameters.yml }
api_tool:
api_url: %myapi_url%
api_authorization_name: 'Bearer'
This file is loaded by ApiToolBundleExtension :
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
}
I have set the Configuration file too :
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('production_tool');
$rootNode
->children()
->scalarNode('api_url')->defaultValue('')->end()
->scalarNode('api_authorization_name')->defaultValue('')->end()
->end()
;
return $treeBuilder;
}
}
But then I just want to bind a config parameter to one of my service :
# src/ApiToolBundle/Resources/config/services.yml
ApiToolBundle\Service\MyApi:
bind:
$apiUrl: '%api_tool.api_url%'
I am based on this doc : https://symfony.com/doc/3.4/bundles/configuration.html
But I am not sure to understand everything, since they talk about mergin in other way ... Do I need to do something else to load my own bundle config file ?
This is indeed a bit tricky to grasp. The bundle configuration is distinct from the parameters you use in your service configuration (even though inside your config you can also define services, which seems a bit odd at first). This is one of the reasons why Symfony in Version 4 discouraged using the semantic configuration inside applications, not use bundles & configuration, and instead directly work with parameters and services instead.
You will need to map the configuration to parameters or directly inject them into the service where you need them, in case you don't want them to be publicly available to other services or to be pulled from the container using getParameter. You can do this in the Extension where you have access to the ContainerBuilder.
See for example the FrameworkExtension where you have large configs that change the container: https://github.com/symfony/symfony/blob/v3.4.30/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L194-L196
In your case it could look something like this:
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
# Below is the new part, the rest is copied from your question
# If you only want to use the configuration values internally in your services:
$container->getDefinition('ApiToolBundle\Service\MyApi')->setArgument(
0 # Offset of the argument where you want to use the api url
$config['api_url']
);
# If you want to make the values publicly available as parameters:
$container->setParameter('api_tool.api_url', $config['api_url']);
}

symfony2 recompile container from controller

I want to recompile container from controller when I use $this->container->compile();
public function changeAction(Request $request)
{
//......
echo($this->container->getParameter('mailer_user')."\n");
/*$cmd='php ../app/console cache:clear';
$process=new Process($cmd);
$process->run(function ($type, $buffer) {
if ('err' === $type) {
echo 'ERR > '.$buffer;
}
else {
echo 'OUT > '.$buffer;
}
});*/
$this->container->compile();
echo($this->container->getParameter('mailer_user')."\n");
die();
}
I got an error : You cannot compile a dumped frozen container
I want to know if when I clear the cache from controller the container will recompile?
If you are trying to get values of parameters that have been modified during request, you can do this:
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
public function changeAction(Request $request)
{
$originalParam = $this->container->getParameter('mailer_user');
// Rebuild the container
$container = new ContainerBuilder();
$fileLocator = new FileLocator($this->getParameter('kernel.root_dir').'/config');
// Load the changed config file(s)
$loader = new PhpFileLoader($container, $fileLocator);
$loader->setResolver(new LoaderResolver([$loader]));
$loader->load('parameters.php'); // The file that loads your parameters
// Get the changed parameter value
$changedParam = $container->get('mailer_user');
// Or reset the whole container
$this->container = $container;
}
Also, if you need to clear the cache from a controller, there is a cleaner way:
$kernel = $this->get('kernel');
$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
$application->setAutoExit(false);
$application->run(new \Symfony\Component\Console\Input\ArrayInput(
['command' => 'cache:clear']
));
In short the answer is no, the container will not be recompiled, because it is already loaded into memory, and deleting files from disk will take no effect on current request. And on the next request cache will be warmed up and container will be compiled before you reach the controller.

Alter service (ClientManager) based on configuration inside bundle extension class

I have a bundle named: "ApiBundle". In this bundle I have the class "ServiceManager", this class is responsible for retrieving a specific Service object. Those Service objects needs to be created based on some configuration, so after this piece of code in my bundle extension class:
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
// Create Service objects...
I create those Service objects right after I have processed the configuration, something like this:
foreach ($services as $name => $service) {
$service = new Service();
$service->setName($name);
$manager = $container->get($this->getAlias() . '.service_manager');
$manager->add($service);
}
Unfortunately, this does not work, probably because the container isn't compiled yet. So I tried to add those Service objects the following way:
$manager = $container->getDefinition($this->getAlias() . '.service_manager');
$manager->addMethodCall('add', array($service));
But again, this throws the following exception: RuntimeException: Unable to dump a service container if a parameter is an object or a resource.
I can't seem to get a grasp on how to use the service container correctly. Does someone knows how I can add those Service objects to the ServiceManager (which is a service) inside the bundle extension class?
This is how the configuration of the bundle looks like:
api_client:
services:
some_api:
endpoint: http://api.yahoo.com
some_other_api:
endpoint: http://api.google.com
Every 'service' will be a seperate Service object.
I hope I explained it well enough, my apologies if my english is incorrect.
Steffen
EDIT
I think I may have solved the problem, I made a Compiler Pass to manipulate the container there with the following:
public function process(ContainerBuilder $container)
{
$services = $container->getParameter('mango_api.services');
foreach ($services as $name => $service) {
$clientManager = $container->getDefinition('mango_api.client_manager');
$client = new Definition('Mango\Bundle\ApiBundle\Client\Client', array($name, 'client', 'secret'));
$container->setDefinition('mango_api.client.' .$name, $client);
$clientManager->addMethodCall('add', array($client));
}
}
Is this appropriate?
To create services based on configuration you need to create compiler pass and enable it.
Compiler passes give you an opportunity to manipulate other service
definitions that have been registered with the service container.
I think I may have solved the problem, I made a Compiler Pass to manipulate the container there with the following:
public function process(ContainerBuilder $container)
{
$services = $container->getParameter('mango_api.services');
foreach ($services as $name => $service) {
$clientManager = $container->getDefinition('mango_api.client_manager');
$client = new Definition('Mango\Bundle\ApiBundle\Client\Client', array($name, 'client', 'secret'));
$client->setPublic(false);
$container->setDefinition('mango_api.client.' .$name, $client);
$clientManager->addMethodCall('add', array($client));
}
}

Optional parameter dependency for a service

I know that i is possible to add optional service dependency for a service. The syntax is
arguments: [#?my_mailer]
But how do i add optional parameter dependency for a service?
arguments: [%my_parameter%]
I tried
arguments: [%?my_parameter%]
arguments: [?%my_parameter%]
But neither of them work, is this feature implemented in sf2?
From Symfony 2.4 you can use expression for this:
arguments: ["#=container.hasParameter('some_param') ?
parameter('some_param') : 'default_value'"]
More at http://symfony.com/doc/current/book/service_container.html#using-the-expression-language
I think that if you don't pass/set the parameter, Symfony will complain about the service dependency. You want to make the parameter optional so that it is not required to always set in the config.yml file. And you want to use that parameter whenever it is set.
There is my solution:
# src/Acme/HelloBundle/Resources/config/services.yml
parameters:
my_parameter:
services:
my_mailer:
class: "%my_mailer.class%"
arguments: ["%my_parameter%"]
And then
# you-bundle-dir/DependencyInjection/Configuration.php
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('you_bundle_ns');
// This is for wkhtmltopdf configuration
$rootNode
->children()
->scalarNode('my_parameter')->defaultNull()->end()
->end();
// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
// more information on that topic.
return $treeBuilder;
}
And then
# you-bundle-dir/DependencyInjection/YourBundleExtension.php
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.xml');
$container->setParameter(
'you_bundle_ns.your_parameter',
isset($$config['you_bundle_ns']['your_parameter'])?$$config['you_bundle_ns']['your_parameter']:null
);
}
You make the your parameter optional by giving default value to the '%parameter%'
Please let me know if you have better alternatives.
Did you try to set a default value for a parameter? Like so:
namespace Acme\FooBundle\Services;
class BarService
{
public function __construct($param = null)
{
// Your login
}
}
and not injecting anything.

Resources