Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
SOLVED

Reference file from inside a service

Avatar

Level 4

I am trying to implement maxmind's geoip2 and I am at the step where I need to initialize the DatabaseReader, my database file is currently stored at ui.content/src/main/content/jcr_root/conf/<my-app>/geoip/GeoLite2-City.mmdb and I am trying to access it like this:

    public Location getLocation(InetAddress ip) throws GeoIp2Exception {
        try {
            File database = new File(this.path);
            this.db = new DatabaseReader.Builder(database).build();
            return db.city(ip).getLocation();
        } catch (Exception e) {
            throw new GeoIp2Exception(String.format("Could not determine data for %s", ip));
        }
    }

 

But I am getting the following error: java.io.FileNotFoundException: /conf/<my-app>/geoip/GeoLite2-Country.mmdb (No such file or directory)

 

I have verified the file is named correctly and that is shows up on the CRX so I am guessing I need something to actually access this.

 

Jeanmaradiaga_0-1669070082540.png

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @Jeanmaradiaga ,

There are few things might cause this problem,

  • I'm not sure what type of Session you are referring to access JCR repository, there are few options to get Session to access JCR repository. However, It is recommended to create System User in AEM for specific functionality. For more details please check [0].
  • Assuming you have service user created and you have dedicated service (best practice) or you have an JCR Session to access repository refer below code.
  • GeoLite2-City.mmdb File should have an nt:file node, which has a jcr:content node with jcr:data property. Use Node data as stream to read jcrContent.getProperty("jcr:data").getBinary().getStream();
    InputStream in = node.getNode("jcr:content").getProperty("jcr:data").getStream();
    Resource dataResource = resourceResolver.getResource("/path/to/db/file.mmdb"); 
    Node jcnode = dataResource.adaptTo(Node.class).getNode("jcr:content");
    InputStream is = jcnode.getProperty("jcr:data").getBinary().getStream();
    StringBuilder sb = new StringBuilder();
    String line; try { br = new BufferedReader(new InputStreamReader(is)); while ((line = br.readLine()) != null) { sb.append(line); } } catch (IOException e) { //do something } //do whatever with sb

[0]: https://one-inside.com/aem6-resourceresolver-access-in-services/

Hope that helps!

Regards,

Santosh

View solution in original post

3 Replies

Avatar

Community Advisor

@Jeanmaradiaga Please refer to the below article which explains about how you can access the file stored in JCR repo

 

http://www.wemblog.com/2011/10/how-to-read-external-file-in-cq.html 

 

Hope this helps!

Avatar

Level 4

Thanks for the reply!

I haven't had a chance to try it yet, but it seems a bit complicated because I would need to open the stream, get the file, convert it to a File object and then start the DB, this each time I want to loop up an user. Surely there must be a faster way since 2011 on AEM Cloud?

Avatar

Correct answer by
Community Advisor

Hi @Jeanmaradiaga ,

There are few things might cause this problem,

  • I'm not sure what type of Session you are referring to access JCR repository, there are few options to get Session to access JCR repository. However, It is recommended to create System User in AEM for specific functionality. For more details please check [0].
  • Assuming you have service user created and you have dedicated service (best practice) or you have an JCR Session to access repository refer below code.
  • GeoLite2-City.mmdb File should have an nt:file node, which has a jcr:content node with jcr:data property. Use Node data as stream to read jcrContent.getProperty("jcr:data").getBinary().getStream();
    InputStream in = node.getNode("jcr:content").getProperty("jcr:data").getStream();
    Resource dataResource = resourceResolver.getResource("/path/to/db/file.mmdb"); 
    Node jcnode = dataResource.adaptTo(Node.class).getNode("jcr:content");
    InputStream is = jcnode.getProperty("jcr:data").getBinary().getStream();
    StringBuilder sb = new StringBuilder();
    String line; try { br = new BufferedReader(new InputStreamReader(is)); while ((line = br.readLine()) != null) { sb.append(line); } } catch (IOException e) { //do something } //do whatever with sb

[0]: https://one-inside.com/aem6-resourceresolver-access-in-services/

Hope that helps!

Regards,

Santosh