Using oauth2 Service Account within a Java-Webapplication - oauth-2.0

I'm develop a simple HTML5-Client for DFA-Reporting. For this I use a Google OAuth Service account, which works pretty fine on a client solution. But know I've been in trouble when I want to read the .p12-File within my Webapplication-Backend. Following problem appears:
java.io.IOException: DerInputStream.getLength(): lengthTag=111, too big.
at sun.security.util.DerInputStream.getLength(DerInputStream.java:561)
The application runs on an embedded Tomcat (Spring Boot) and I'm using the following approach the read to file:
File p12File = new java.io.File(this.getClass().getResource("/test-privatekey.p12").toURI());
this.httpTransport = GoogleNetHttpTransport.newTrustedTransport();
credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKeyFromP12File(p12File)
.build();
The Client-Solutions read the p12-File like this:
File p12File = new java.io.File("test-privatekey.p12");
Did anybody have a solution, or an solution-idea for this problem?
Many thanks and greetings from Berlin

Exclude p12 files in your POM.
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>

Related

Duplicate headers in restAssured requests in parallel run

I support implemented tests framework and can't change version of tools, so need to resolve it with current version.
The test framework use RestAssered, Cucumber, Serenity.
When tests run in parallel sometimes they are failed due to several Authorization headers in request. In single run, everything is ok.
As I know Serenity just reuse features of the framework. So I think, maybe I configured in wrong way RestAssured.
My flow is:
In Before method I set up
#cucumber.api.java.Before
public void beforeScenario(Scenario scenario) {
RestAssured.baseURI = "https://test.net";
RestAssured.requestSpecification = new
Specification().requestSpecificationWithAdminToken(token);
RestAssured.responseSpecification = new Specification().responseSpecification();
RestAssured.config = RestAssuredConfig.config().decoderConfig(decoderConfig().noContentDecoders());
}
public class Specification {
public RequestSpecification requestSpecificationWithAdminToken(String token) {
return new RequestSpecBuilder().
addHeader("Authorization", "Bearer " + token).
setAccept(ContentType.JSON).
setContentType(ContentType.JSON).
log(LogDetail.ALL).
build();
}
public ResponseSpecification responseSpecification() {
return new ResponseSpecBuilder().
log(LogDetail.ALL).
build();
}
}
Tests like this
SomeBinding bindings = SerenityRest.
given().queryParams(params).
when().get("/api/some/GetEntities").
then().statusCode(HttpStatus.SC_OK).extract().response().as(SomeBinding.class);
For parallel run I use maven-failsafe-plugin with configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>-Xmx1024m</argLine>
<includes>
<include>${test.include}</include>
</includes>
<excludes>
<exclude>${test.exclude}</exclude>
</excludes>
<parallel>classes</parallel>
<threadCount>${parallel.count}</threadCount>
<perCoreThreadCount>false</perCoreThreadCount>
<rerunFailingTestsCount>1</rerunFailingTestsCount>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
When I run tests in parallel I faced with issue that sometimes requests contain several Authorithation headers.
Authorization=Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImJjYzM3YjliOTM4ODQ3ODJiOWRhYjN
Authorization=Bearer OTM4ODQ3ODJiOWRhYjNmYjI5NDgyYzdjIiwianRpIjoiMjg3M2VjNDA0MmFjNGNkNzk0ODE5NTE0N2I5YzczMjUiL
Accept=application/json, application/javascript, text/javascript, text/json
Content-Type=application/json; charset=UTF-8
Could somebody please give advice how to resolve it?

"HttpException: 500 - Read-only block manager" when loading data using Apache Jena into Fuseki

I cant get google or stackoverflow to tell me how to load into my Fuseki server a named grapah from a ttl file.
My Java function is
public static void uploadTtl(String ttlFileLocation, String graphname) {
RDFConnection conn = RDFConnectionFactory.connect(serviceURL);
if (graphname == null)
conn.load(ttlFileLocation);
else
conn.load(graphname, ttlFileLocation);
conn.close();
}
If
graphname = null;
Then
loads fine
If
graphname = "graphname";
Then
Exception in thread "main" org.apache.jena.atlas.web.HttpException: 500 - Read-only block manager
at org.apache.jena.riot.web.HttpOp.exec(HttpOp.java:1093)
at org.apache.jena.riot.web.HttpOp.execHttpPost(HttpOp.java:721)
at org.apache.jena.riot.web.HttpOp.execHttpPost(HttpOp.java:665)
at org.apache.jena.rdfconnection.RDFConnectionRemote.lambda$doPutPost$3(RDFConnectionRemote.java:320)
at org.apache.jena.rdfconnection.RDFConnectionRemote.exec(RDFConnectionRemote.java:518)
at org.apache.jena.rdfconnection.RDFConnectionRemote.doPutPost(RDFConnectionRemote.java:315)
at org.apache.jena.rdfconnection.RDFConnectionRemote.upload(RDFConnectionRemote.java:297)
at org.apache.jena.rdfconnection.RDFConnectionRemote.load(RDFConnectionRemote.java:240)
at modelDTriplestore.MdFuseki_uploadFile.uploadTtl(MdFuseki_uploadFile.java:36)
at modelDTriplestore.MdFuseki_uploadFile.main(MdFuseki_uploadFile.java:15)
What is giving exception from?
conn.load(graphname, ttlFileLocation);
Envionment details include:
Fuseki Version 3.14.0
Running inside stain/jena-fuseki docker image
Jave 8
POM
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
<type>pom</type>
<version>3.17.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.jena/jena -->
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-shaded-guava</artifactId>
<version>3.17.0</version>
<type>pom</type>
</dependency>
The calling code is fine.
The 500 error coming from the server and passed on by the client.
The server log file will have details but it looks like the server is running on an read-only file area for a TDB database.

spring-cloud-starter-openfeign: Invalid HTTP method: PATCH executing PATCH

Context
I have a spring boot (version 2.2.6.RELEASE) web project.
From this web application (I call "APP1") I want to call another URI using the PATCH method from another web application (Let's call it "APP2").
In my pom.xml, I have the following dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Here is how I call the PATCH method of the other web application.
#FeignClient(name = "clientName", url = "base-uri")
public interface MyInterface{
#PatchMapping(value = "/target-uri")
void callClientMethod(Map<String, Object> args);
Problem
The APP2's PATCH method is effectively being called
But then APP1 throws the following error:
feign.RetryableException: Invalid HTTP method: PATCH executing PATCH
I looked on the Internet for a solution, and added the following snipet to my pom.xml
<dependency>
<groupId>com.netflix.feign</groupId> <!-- Also tried io.github.openfeign -->
<artifactId>feign-httpclient</artifactId>
<version>8.18.0</version>
</dependency>
After that, APP2's PATCH method is stille properly called but in APP1 I got the following error :
java.lang.NoSuchMethodError: feign.Response.create(ILjava/lang/String;Ljava/util/Map;Lfeign/Response$Body;)Lfeign/Response;
Question
Does anyone know how to solve this error ?
Thanks in advance for your help !
I had the same problem and spent a lot of time for understand and resolve this problem.
First what you need to understand that is the Feign doesn't support PATCH http method for call from the box!
And if you can change methods in both services use PUT for update instead PATCH...
But if you integrate with third party implementation you should add some configurations:
1. Add dependency which support PATCH http method:
// https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp
compile group: 'io.github.openfeign', name: 'feign-okhttp', version:
'10.2.0'
Add configuration:
#Configuration
public class FeignConfiguration {
#Bean
public OkHttpClient client() {
return new OkHttpClient();
}
}
And example for PATCH request with Feign:
#FeignClient(name = "someapi", url = "${client.someapi.url}")
#Component
#RequestMapping("/users")
public interface SomeClient {
#RequestMapping(value = "/{id}",
method = RequestMethod.PATCH,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
FeignUser update(#PathVariable("id") Long id, #RequestBody Map<String, Object> fields);
}
Hope it helps someone.
Just Add:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
If you are adding Feign with the following dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <!-- has dependecy on spring-cloud-openfeign-core inside, which already maintains version of feign-okhttp artifact -->
</dependency>
you can add okhttp client (without hardcoding artifact version) to fix the issue with PATCH request:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId> <!-- Required to use PATCH -->
</dependency>
No other steps needed. The okhttp client will be applied automatically by auto configuration.
Also, this way you don't need to manage feign-okhttp artifact version. Spring Cloud will manage version for you.
Tested with Spring Boot 2.7.6
The following config works for me:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>${feign.version}</version>
</dependency>
Where:
feign.version - 11.0
Spring Boot - 2.3.0.RELEASE
Spring-cloud.version - 2.2.3.RELEASE

can't set up swagger with jax-rs

I can't understand, why swagger doesn't work with my spring boot jax-rs app.
I add this dependencies to pom.xml:
<!-- Swagger -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description-swagger</artifactId>
<version>3.3.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>3.1.5</version>
</dependency>
also I set up -> cxf.jaxrs.component-scan=true in application properties,my rest requests:
#Path("/")
#Api("/")
#Service
public interface IService {
#GET
#Path("/health")
#ApiOperation("/health")
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Status getStatus();
#GET
#Path("/info")
#ApiOperation("/info")
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Info getInfo();
}
work as I expected, but I can't get documentation, when I call:
http://localhost:8000/swagger-ui.html
get -> Whitelabel Error Page.
Maybe someone can help me?
just in case here is my properties file:
#cxf url mapping
cxf.path=/api
cxf.jaxrs.component-scan=true
cxf.jaxrs.classes-scan-packages=com,org.apache.cxf.jaxrs.swagger.Swagger2Feature,org.codehaus.jackson.jaxrs,org.apache.cxf.jaxrs.swagger.ui.SwaggerUiResourceLocator
#port
server.port=8000
server.servlet.context-path=/
Can you please share the complete project?
You'll find working samples in https://github.com/apache/cxf/tree/cxf-3.3.4/distribution/src/main/release/samples/jax_rs, if you start a new project I suggest to go with OpenAPI v3 instead of Swagger.

how to generate URI parameter for dynamic feign basePath using swagger codegen?

I have a pretty simple question :)
According to feign documents, they are supporting in changing the basePath of a feign client object dynamically by passing URI parameter trough the api function like so:
GOOD Example:
interface MyClient {
#RequestLine("GET /internal-service")
String internalService(URI baseUrl);
}
The thing is I'm using swagger, who generates my API from a yaml file and adding #Param annotation to all function parameters, which is not good for me.
BAD Example:
interface MyClient {
#RequestLine("GET {baseUrl}/internal-service")
String internalService(#Param("baseUrl") String host);
}
Is there a way to make swagger generator to generate an API with a URI param, without the #Param annotation?
Desired Outcome Example:
interface MyClient {
#RequestLine("POST /internal-service")
String internalService(URI baseUrl, #Param("someParam") String someParam);
}
Initial solution:
After some investigation I came to realize that there is no support in swagger-codegen 2.2.3 for generating URI parameter as part of the client API function.
But there is an option in swagger-codegen-maven-plugin configuration of
"templateDirectory - directory with mustache templates", for giving a path to a folder including mustache templates, which will take the templates in that folder and override the existing with the same name.
example:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<executions>
<execution>
<id>my-project-api-client-kit</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.build.directory}/my-project-api.yaml</inputSpec>
<language>java</language>
<configOptions>
<dateLibrary>java8</dateLibrary>
<sourceFolder>src/main/java</sourceFolder>
</configOptions>
<modelPackage>my.project.ck.resources.models</modelPackage>
<apiPackage>my.project.ck.resources.interfaces</apiPackage>
<library>feign</library>
<templateDirectory>/myTemplateFolder/</templateDirectory>
</configuration>
</execution>
</executions>
</plugin>
And inside the custom templates folder, put your own api.mustache file with the additional "URI basePath" parameter:
...
{{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}(URI basePath, {{#allParams}}{{^isBodyParam}}{{^legacyDates}}#Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}#Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isBodyParam}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
...
Note:
Swagger provides a lot of templates for a variety of uses, make sure to take and modify the correct api.mustache template file according to which you are using.
in the above example I modified (and override) the java.libraries.feign/api.mustache file because this is the file my plugin is configured too (as in the example).

Resources