Skip to content
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

Example needed for dealing with Google Cloud Storage with Gaufrette #123

Closed
mappedinn opened this issue Nov 9, 2015 · 8 comments
Closed

Comments

@mappedinn
Copy link

Good morning,

I am uploading my files locally through VichUploaderBundle. Every thing works perfectly.

Now I want no more store my files locally: I want to store them on Google Cloud Storage. I found that KnpGaufretteBundle could be used for storing files in the cloud.

So, is there any example or a example's link on how to configure Gaufrette or KnpGaufretteBundle for storing/uploading/reading files on google-cloud-storage?

The only thing I found is that link which is an adapter class for GoogleCloudStorage.

I found another link regarding this issue but it proposes an example for storing files on amazon-s3: upload-files-to-amazon-s3-with-symfony2-and-gaufrette

Thanks for you help...

@mappedinn
Copy link
Author

There is PR on that... this is the proposed fork to be merged... This is the PR link...

Please accept the PR.

ping @Einenlum @l3l0 @Herzult @iampersistent @Palleas @pilot @Karisch @stof

@QuingKhaos
Copy link
Contributor

Since the PR is merged, is it clear to you? You need to configure GCS like described in the README: https://github.com/KnpLabs/KnpGaufretteBundle#googlecloudstorage

Then it's similar from the step Implementing an uploader in your linked tutorial with gaufrette and AWS S3.

@mappedinn
Copy link
Author

Thank you so much @patkar for your help.

I am trying to configure it but without success. The given configuration is deprecated for symfony 2.7.
So I adopted the new way to do this.

app.google_cloud_storage.service:
    class: \Google_Service_Storage
    factory: ["@knp_gaufrette.adapter.factory.google_cloud_storage", create] 
    arguments:
        - 123456789@developer.gserviceaccount.com
        - http://localhost/file.p12
        - password   

knp_gaufrette:
    stream_wrapper: ~
    adapters:
        gcs_minn_images:
            google_cloud_storage:
                service_id: 'app.google_cloud_storage.service'
                bucket_name: 'minn-images'           
    filesystems:
        gcs_minn_images_fs:
            adapter: gcs_minn_images

I am getting an error telling me that

You have requested a non-existent service "knp_gaufrette.adapter.factory.google_cloud_storage".

Notice that the list of the working knp services in my symfony project are:

php app/console debug:container | grep knp
 knp_gaufrette.filesystem_map                                       Knp\Bundle\GaufretteBundle\FilesystemMap                                                   
 knp_menu.factory                                                   Knp\Menu\MenuFactory                                                                       
 knp_menu.listener.voters                                           Knp\Bundle\MenuBundle\EventListener\VoterInitializerListener                               
 knp_menu.matcher                                                   Knp\Menu\Matcher\Matcher                                                                   
 knp_menu.menu_provider                                             Knp\Menu\Provider\ChainProvider                                                            
 knp_menu.renderer.list                                             Knp\Menu\Renderer\ListRenderer                                                             
 knp_menu.renderer.twig                                             Knp\Menu\Renderer\TwigRenderer                                                             
 knp_menu.renderer_provider                                         Knp\Bundle\MenuBundle\Renderer\ContainerAwareProvider                                      
 knp_menu.voter.router                                              Knp\Menu\Matcher\Voter\RouteVoter 

Can you @patkar give me the correct config of the bundle for google cloud storage? Is there any thing else missing?

Thanks...


Forget that post.

@mappedinn
Copy link
Author

I tried many time to config the bundle but without success. So I am here back with all my trials below. This is the config:

## definition of the GCS service
app.google_cloud_storage.service:
    class: \Google_Service_Storage
    factory_class: Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory
    factory_method: 'create'
    arguments: 
        - "123@developer.gserviceaccount.com"
        - "http://localhost/file.p12"
        - "pwd"

## config of knp_gaufrette
knp_gaufrette:
    stream_wrapper: ~
    adapters:
        gcs_minn_images:
            google_cloud_storage:
                service_id: 'app.google_cloud_storage.service'
                bucket_name: 'minn-images'
    filesystems:
        gcs_minn_images_fs:
            adapter: gcs_minn_images 

The error message I got is:

ContextErrorException in GoogleCloudStorageAdapterFactory.php line 16:
Catchable Fatal Error: Argument 1 passed to Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory::create() must be an instance of Symfony\Component\DependencyInjection\ContainerBuilder, string given, called in /home/amine/NetBeansProjects/tuto/app/cache/dev/appDevDebugProjectContainer.php on line 724 and defined

According to the error message, I gave a string of stead of ContainerBuilder. Great! Let's add the ContainerBuilder to the arguments as follows:

## definition of the GCS service
app.google_cloud_storage.service:
    class: \Google_Service_Storage
    factory_class: Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory
    factory_method: 'create'
    arguments: 
        - @service_container
        - "123@developer.gserviceaccount.com"
        - "http://localhost/file.p12"
        - "pwd"

The result is again an error:

Catchable Fatal Error: Argument 1 passed to Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory::create() must be an instance of Symfony\Component\DependencyInjection\ContainerBuilder, instance of appDevDebugProjectContainer given, called in /home/amine/NetBeansProjects/tuto/app/cache/dev/appDevDebugProjectContainer.php on line 724 and defined

So now, the error is telling me that I provide an instance of appDevDebugProjectContainer in stead of ContainerBuilder!!

Ok, let's have a look to /home/amine/NetBeansProjects/tuto/app/cache/dev/appDevDebugProjectContainer.php on line 724...

class appDevDebugProjectContainer extends Container{
// ...
/**
 * Gets the 'app.google_cloud_storage.service' service.
 *
 * This service is shared.
 * This method always returns the same instance of the service.
 *
 * @return \Google_Service_Storage A Google_Service_Storage instance.
 */
protected function getApp_GoogleCloudStorage_ServiceService()
{
    return $this->services['app.google_cloud_storage.service'] =\Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory::create($this, '123@developer.gserviceaccount.com', 'http://localhost/file.p12', 'pwd');
}

I am really lost...
So, is there any complete example to config google cloud storage?

@QuingKhaos
Copy link
Contributor

As said in the readme, you have to create your own factory class. The Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory is a internal class to create the real filesystem service, not the \Google_Service_Storage class.

It's a bit more complex than Amazon S3, because the \Google_Service_Storage needs an OAuth Server token and depending, on which system you are (custom server or Google Compute Engine), there are several methods to get the token. And you need to think about token caching strategy. This is the reason, why you have to create your own factory service, which creates a \Google_Client and authorizes with the correct scopes and then returns a \Google_Service_Storage class connected to the client class.

An example how creating the client, auth, etc. works is in the Gaufrette library itself: https://github.com/KnpLabs/Gaufrette#using-googlecloudstorage

@mappedinn
Copy link
Author

Thank you so much @patkar

It is working now (no symfony errors displayed & I have to check the uploads after because now I have to go to work). I have to tell that I misunderstood your readme.

This is the class of the service I have created:

class GoogleCloudStorageService extends \Google_Service_Storage{
    public function __construct() {
        // instanciation of a google client
        $client = new \Google_Client();

        // setting the service acount credentials
        $serviceAccountName = '123@developer.gserviceaccount.com';
        $scopes = array(
            'https://www.googleapis.com/auth/devstorage.read_write',
        );
        $privateKey = file_get_contents('http://localhost/file.p12');
        $privateKeyPassword = 'pws';

        $credential = new \Google_Auth_AssertionCredentials(
                $serviceAccountName, $scopes, $privateKey, $privateKeyPassword);

        // set assertion credentials
        $client->setAssertionCredentials($credential);

        // setting the instance of \Google_Service_Storage
        parent::__construct($client);
        }
}

Do you think that there will be changes if the code will run on Google Compute engine?

Thanks

@QuingKhaos
Copy link
Contributor

Ok, it works. But you should not extend \Google_Service_Storage. You have to create a static factory, which returns a instance of it. Btw. the private key must reside in a location, where it is only accessible on the local filesystem, not via http!

If you run on google compute engine, you can set the scopes on the instance and get the auth token, without to have any credentials in the code: https://cloud.google.com/compute/docs/authentication

@mappedinn
Copy link
Author

Thank you so much @patkar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants