'X-Appengine-Inbound-Appid' header is not set when using Spring RestTemplate - spring

I have two services running on the Google App Engine (MS1 & MS2). MS1 is deployed in the Standard Environment and MS2 is deployed in the Flexible Environment. I am invoking an API from Standard Environment to the Flexible Environment. I want to make sure that MS2 only accepts requests originating from MS1. So, I decided to use this feature from App Engine. I am setting the X-Appengine-Inbound-Appid header and setInstanceFollowRedirects to false in MS1, but looks like App Engine is removing this header. I am not able to find this header in MS2.
HttpHeaders headers = new HttpHeaders();
headers.add("X-Appengine-Inbound-Appid", ApiProxy.getCurrentEnvironment().getAppId());
HttpEntity<MergePdfsResource> entity = new HttpEntity<MergePdfsResource>(mergePdfsResource, headers);
restTemplate.setRequestFactory(new SimpleClientHttpRequestFactory() {
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
super.prepareConnection(connection, httpMethod);
connection.setInstanceFollowRedirects(false);
}
});
ResponseEntity<SomeClass> response = restTemplate.postForEntity(apiUrl, entity, SomeClass.class);

Following is the answer I got from the Google Support:
The X-Appengine-Inbound-Appid header is set only if we are using the URLFetch service. In the java8 runtime environment, the default is native which uses the standard Java network classes. So, I had to set the URL stream handler to urlfetch in appengine-web.xml as below:
<url-stream-handler>urlfetch</url-stream-handler>

Related

Reactive rest client headers injection in Quarkus

I am following the guide of the new quarkus-resteasy-reactive-jackson extension to use it in an existing Quarkus application deployed in production.
In the Custom headers support section it's introduced the ClientHeadersFactory interface to allow injecting headers in a request, but you are forced to return a sync response. One can not use Uni<MultivaluedMap<String, String>>, which is of what is desired in my case, because I need to add a token in the header, and this token is retrieved by a request to another rest endpoint that returns a Uni<Token>.
How can I achieve this in the new implementation? If not possible, is there a workaround?
It's not possible to use Uni<MultivaluedMap<...>> in ClientHeadersFactory in Quarkus 2.2.x (and older versions). We may add such a feature in the near future.
Currently, you can #HeaderParam directly. Your code could probably look as follows:
Uni<String> token = tokenService.getToken();
token.onItem().transformToUni(tokenValue -> client.doTheCall(tokenValue));
Where the client interface would be something like:
#Path("/")
public interface MyClient {
#GET
Uni<Foo> doTheCall(#HeaderParam("token") String tokenValue);
}

HTTP Basic Authentication in Spring Web Services Integration Tests

I have a SOAP web service written in Spring Web Services that I would like to integration test.
I would like to use spring-ws-test as the reference documentation points to. So, the test code is similar to the example in the reference, something like that:
#Autowired
private ApplicationContext applicationContext;
private MockWebServiceClient mockClient;
#Before
public void createClient() {
mockClient = MockWebServiceClient.createClient(applicationContext);
}
#Test
public void customerEndpoint() throws Exception {
Source requestEnvelope = new ResourceSource(new ClassPathResource("request.xml"));
Source responsePayload = new ResourceSource(new ClassPathResource("response.xml"));
mockClient.sendRequest(withSoapEnvelope(requestPayload)).
andExpect(payload(responsePayload));
}
However, the endpoint I am testing is using basic authentication and it expects to read values in the Authorization header. It is not using spring-security for that task but it has custom logic that gets the HTTP headers by getting the HttpServletResponse from the TransportContextHolder. So, the request triggers the endpoint but it fails to retrieve the basic authentication base64 token.
The question is, how may I pass HTTP headers in that situation? Is it possible at all? If not what is the preferred alternative?
I have read the javadoc and I cannot find a way to pass the headers. Also, I have found this question which is similar but it doesn't help me much.

SpringBoot get InputStream and OutputStream from websocket

we want to integrate third party library(Eclipse XText LSP) into our SpringBoot webapp.
This library works "interactively" with the user (like chat). XText API requires input and output stream to work. We want to use WebSocket to let users interact with this library smoothly (send/retrieve json messages).
We have a problem with SpringBoot because SpringBoot support for WebSocket doesn't expose input/output streams. We wrote custom TextWebSocketHandler (subclass) but none of it's methods provide access to in/out streams.
We also tried with HandshakeInterceptor (to obtain in/out streams after handshake ) but with no success.
Can we use SpringBoot WebSocket API in this scenario or should we use some lower level (Servlet?) API ?
Regards Daniel
I am not sure if this will fit your architecture or not, but I have achieved this by using Spring Boot's STOMP support and wiring it into a custom org.eclipse.lsp4j.jsonrpc.RemoteEndpoint, rather than using a lower level API.
The approach was inspired by reading through the code provided in org.eclipse.lsp4j.launch.LSPLauncher.
JSON handler
Marhalling and unmarshalling the JSON needs to be done with the API provided with the xtext language server, rather than Jackson (which would be used by the Spring STOMP integration)
Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<String, JsonRpcMethod>();
supportedMethods.putAll(ServiceEndpoints.getSupportedMethods(LanguageClient.class));
supportedMethods.putAll(languageServer.supportedMethods());
jsonHandler = new MessageJsonHandler(supportedMethods);
jsonHandler.setMethodProvider(remoteEndpoint);
Response / notifications
Responses and notifications are sent by a message consumer which is passed to the remoteEndpoint when constructed. The message must be marshalled by the jsonHandler so as to prevent Jackson doing it.
remoteEndpoint = new RemoteEndpoint(new MessageConsumer() {
#Override
public void consume(Message message) {
simpMessagingTemplate.convertAndSendToUser('user', '/lang/message',
jsonHandler.serialize(message));
}
}, ServiceEndpoints.toEndpoint(languageServer));
Requests
Requests can be received by using a #MessageMapping method that takes the whole #Payload as a String to avoid Jackson unmarshalling it. You can then unmarshall yourself and pass the message to the remoteEndpoint.
#MessageMapping("/lang/message")
public void incoming(#Payload String message) {
remoteEndpoint.consume(jsonHandler.parseMessage(message));
}
There may be a better way to do this, and I'll watch this question with interest, but this is an approach that I have found to work.

How to trust ssl certificate programatically while using Spring Rest Client

I am using resttemplate from spring for consuming the Rest Json Webservice
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<Object> entity = new HttpEntity<Object>(glassRequest, headers);
postForObject = restTemplate.postForObject(url, entity, responseClass );
I am using above code for same. It works fine if there is no ssl certification at provider end. However , I get 403 if he uses certificate.
I know this can be handled by below two approches :-
1. Add certificate in trust store of application server.[But i am not running this code from application server but my junit test class]
2. Two add the certificate in java trust store. [However , i want to schedule this junit from enviroment where I don't have access ]
Is this can be done programmatically ?? Like i will include the certificates in my source code itself and then refer them by reading from classpath while making call to service.

HttpClient with asp.net WebApi in unit testing scenario

I have an integration test which I wanted to use as the basis of testing my WebAPI controllers with.
Initially I thought I would have to set-up WebAPI in self-host mode and carry-out end-to-end tests over local Http.
However I realised later by looking at the tests in the WebApiContrib project that its possible to set up an HttpClient with an HttpServer set-up with the correct service route to the WebAPI controller. I seems I can unit test the controllers without setting up WebApi in self-host mode. I can put in any domain name in the request on the client and HttpClient seems to auto-magically bind to the correct controller.
Is there any Http transport happening here, using some local interprocess comms or purely 'seeing' that the server is in the same app domain and thus using reflection?
What is happening under the hood for this to happen?
code:
[Test]
public void Test_WebApi_Controller()
{
Assembly.Load("myproj.Web");
var prodServiceMock = new Mock<IProductService>();
ObjectFactory.Initialize(x => x.For<IProductService>().Use(prodServiceMock.Object));
var config = new HttpConfiguration();
config.Routes.MapHttpRoute("default", "webapi/{controller}/{id}", new { id = RouteParameter.Optional });
config.ServiceResolver.SetResolver(new WebApiDependencyResolver());
var server = new HttpServer(config);
var client = new HttpClient(server);
var response = client.GetAsync("http://anything.com/webapi/product").Result;
}
HttpClient has a pluggable pipeline model. Normally when you new up a HttpClient you get a HttpClientHandler instance as the default request processor. That HttpClientHandler is the one actually does the HttpWebRequest. HttpClientHandler derives from HttpMessageHandler.
By no concidence HttpServer also derives from HttpMessageHandler. So in this example the HttpServer is being passed to the HttpClient instance to provide it's request processing. By passing a HttpMessageHandler to the constructor of HttpClient you are telling HttpClient to use the provided handler instead of the default one. If you look at WebRequestHandler in System.Net.Http.WebRequest you will see this is derived from HttpClientHandler and adds some extra functionality that is specific to the Windows Desktop OS.
This means when you make a request to the HTTPClient it is delivered directly to the HttpServer message handler and then processed as it normally would be on the server.

Resources