Authenticating Google DLP API from Java without setting GOOGLE_APPLICATION_CREDENTIALS? - google-api

I am playing around with the Google Cloud DLP Java library. I've set up my service credentials and saved them in a JSON file as per the instructions here:
https://cloud.google.com/dlp/docs/libraries.
The documentation states that the preferred way to authenticate is by setting the environment variable GOOGLE_APPLICATION_CREDENTIALS to point to the path of the JSON file that contains the credentials. This is not all that practical in my case. I have a Spring Boot application where all the code (as well as the JSON file with the credentials) is embedded in a "fat jar". I can easily use the class loader to obtain an InputStream to the resource, but I can't really point to it inside the jar file from an environment variable. It's also not practical to create an environment variable from within a running JVM without resorting to hacks like using reflection, etc.
Some other Google Cloud libraries have service classes that can be initialized with a GoogleCredentials object, but I haven't found a way of doing this with the DLP library. Is there any way of passing a GoogleCredentials into the DlpServiceClient?

I ended up figuring it out after quite a bit of Googling. This worked fine:
Resource r = new ClassPathResource("/path-to-my-cred-file.json");
GoogleCredentials creds = GoogleCredentials.fromStream(r.getInputStream());
DlpServiceSettings settings = DlpServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(creds)).build();
try (DlpServiceClient dlpServiceClient = DlpServiceClient.create(settings)) {
///... other stuff here ...
}

Using Document AI the following worked for me:
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("path-to-json-file"))
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
DocumentProcessorServiceClient client = DocumentProcessorServiceClient.create(
DocumentProcessorServiceSettings.newBuilder()
.setEndpoint("eu-documentai.googleapis.com:443")
.setCredentialsProvider(FixedCredentialsProvider.create(credentials))
.build()
);
...
ProcessResponse result = client.processDocument(request);
Taken from here https://www.googlecloudcommunity.com/gc/AI-ML/DocAI-Response-in-a-single-json-file/m-p/491257
If you use maven, "GoogleCredentials" is not visible at compile-time but only at runtime.
You have to configure something like that:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>1.11.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>

Related

Spring boot azure keyvault refresh on demand

I am using spring boot with azure's keyvault
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-keyvault-secrets</artifactId>
</dependency>
but there is a problem, when I want to update secret.
How to force for example via rest api lets say, refresh of this value ?
#Value("${x-value}") private val xValue: String = "0"
thanks!
Can you rephrase you're question to clarify what exactly do you want to refresh? If you want to refresh the value from AKV (AKV secret changes -> value in code changes) you need to use environment to get the property:
#Autowired
Environment environment
...
xValue = environment.getProperty("x-value");
because #Value() is set during construction of the component. It won't change during it's lifetime.
If you want the change the AKV contents: this is not the purpose of azure-spring-boot-starter-keyvault-secrets.

Wrapping the application.name value with '#', what does it mean?

What does adding the '#' to name value of application.properties to the beginning and to the end mean?
I couldn't find usage of something like this. I checked the Spring docs as well, but I couldn't find it. Is this usage a generic thing for programming or specific to application.properties of Spring?
Please go through the documentation
Rather than hardcoding some properties that are also specified in your
project’s build configuration, you can automatically expand them by
instead using the existing build configuration. This is possible in
both Maven and Gradle.
The format you mentioned is for Maven
You can automatically expand properties from the Maven project by
using resource filtering. If you use the spring-boot-starter-parent,
you can then refer to your Maven ‘project properties’ with #..#
placeholders
Update
With Spring Boot Actuator dependency added to pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
and
info endpoint exposed (for http : management.endpoints.web.exposure.include=info )
a quick verification of this can be done.
Add the following property to pom.xml
<properties>
<app.info.test>Test Value</app.info.test>
</properties>
and following entries in the application.properties file
info.app.name= Test App
info.app.java.source=1.8
info.app.test=#app.info.test#
Hitting http://localhost:8080/actuator/info will give the following response
{"app":{"name":"Test App","java":{"source":"1.8"},"test":"Test Value"}}
Straight Forward answer is the value which you store with #name# in application.properties are initialized when your project build start (based on same parameter name you pass with command).
It's used when you want to pass value of that variable at time of build
or value which are different based on environment.If you don't do that then it value becomes fixed.
when you're want to pass some parameter which are constant or repetitively use in your application like mail configuration or AWS configuration, version or etc. that things define in application.properties file.

Spring basic security confiugred userid/password not working

Our application is based on Spring-boot 2.0. I've enabled basic security by adding the following dependency to pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
I also have added properties so that I can define my own userid and password for basic security, instead of the generated ones. I defined them like this in /resources/applicaiton.properties file:
security.user.name=user1
security.user.password=pass1
When I startup my application, I can see that is still generates the password for me in the log. Also, I am unable to login using user1/pass1 combination. I can only successfully login with the user=user and password=generated-password-from-log file.
Why won't spring security allow me to login with user1/pass1? What could be the problem?
Those properties need the spring prefix.
spring.security.user.name=user # Default user name.
spring.security.user.password= # Password for the default user name.
If I want to configure something I often take a look at this List
I hope this helps.

WildFly 10, JCache - method caching

i have simple application using Spring Boot. I wanted allow method caching with JSR107 - JCache. So with help of tutorial i put together this code :
#CacheResult(cacheName = "testpoc")
public Country getCountry(Integer id){
System.out.println("---> Loading country with code '" + id + "'");
return new Country(id, "X", "Title");
}
with this POM file
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
...
(dependency 'spring-boot-starter-web' is there for simple REST service which call getCountry method)
Everything works like documentations says - method is invoked only once.
Now i wanted to try it on WildFly 10 application server
I have modified pom file :
excluded tomcat
exluded spring-boot-starter-cache
added infinispan-jcache (because i want to use cache configured / managed by wildfly in standalone/domain.xml)
Check pom file here on pastebin.
Problem is, that i am receiving following error :
Cannot find cache named 'java:jboss/infinispan/app-cache'
(i have tried to use both JNDI assigned and name to infinispan cache configured in wildfly).
Following code created Cache object (so i can used it) :
CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = cacheManager.createCache("testpoc", new MutableConfiguration<String, String>());
Question :
It is possible to use JCache method caching on WildFly 10 using Infinispan managed by WildFly ?
Or Infinispan should be used for method caching like JCache, hence JCache has "more functionality" than Infinispan.
Thank you very much
PS :It is not problem for me to put whole code on github and post link - it is few lines of code ...
There are a couple of problems with your approach so let me go through them in steps.
At first you need to use proper Infinispan setup. Infinispan bits shipped with WF should be considered as internal or private. In order to use Infinispan in your app properly - either add org.infinispan:infinispan-embedded to your deployment or install Infinispan Wildfly modules. You can find installation guide here (it's a bit outdated but still, the procedure is exactly the same - unpack modules into WF and use Dependencies MANIFEST.MF entry).
Once you have successfully installed Infinispan (or added it to your app), you need to consider whether you want to use Spring Cache or JCache. If you're only interested in using annotations - I would recommend the former since it's much easier to setup (all you need to do is to add #EnableCaching to one of your configurations). Finally with Spring Cache you will create an Infinispan CacheManager bean. An example can be found here.
Final note - if you still need to use JCache - use this manual to setup Caching Provider.

Spring-Social-facebook + Spring MVC integration

I am trying to access facebook data via spring social facebook integration using the instructions provided at http://spring.io/guides/gs/accessing-facebook.
But currently i am facing 2 type of problem
When i run example as mentioned in tutorial i get following error
No matching bean of type [org.springframework.social.facebook.api.Facebook] found for dependency
When i run this with #Configuration on FacebookConfig class, i get below mentioned error
A ConnectionFactory for provider 'facebook' has already been registered
Is there a workaround to it?
I have kept the war file with source code at https://skydrive.live.com/redir?resid=EA49CD7184E0E40!168&authkey=!AIkoKKx5-Um8AQE
What version are you using?
Try using the version 1.1.0.RELEASE
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-facebook</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
If it not works, please try post the stacktrace printed.
You need to create a the beans to your class, please post more information like your pom.xml and your spring context configuration.
Ihad the same problem. Spring Social Facebook will automatically add connection factory based on the configuration in application.properties. This auto-configured connection factory is clashing with the one that you're trying to add. Try just to remove your connection factory you add through addConnectionFactories.
Try to use different setting to load your custom connection factory...
E.g. Instead of using OOTB keys use different keys:
#Facebook Social App Details:
# Commented below 2 OOTB Keys & Bingo it worked.
#spring.social.facebook.appId=APP_ID
#spring.social.facebook.appSecret=APP_SECRET
facebook.app.id=APP_ID
facebook.app.secret=APP_SECRET
This will resolve your problem.

Resources