NewRelic::Rack middleware not exposing Sinatra::Base settings - rack

I have a modular Sinatra app, where I use
run Rack::URLMap
to add various services, where each service is a Sinatra::Base
I've added a middleware in one of the services that uses the settings method. It seems that the NewRelic rack middlewares are not exposing this method.
class MyService < Sinatra::Base
configure do
set :optional_auth, [
{ method: :get, path: ''},
{ method: :get, path: '/:id'},
{ method: :get, path: '/:id/attachments'},
{ method: :get, path: '/:id/comments'}
]
mime_type :json, 'application/json'
use Rack::PostBodyContentTypeParser
use MyMiddleware
end
get '/' ....
Locally, things work fine, however, when deployed, it seems that MyMiddleware is being added after NewRelic::Rack, so when the middleware is invoked, the #app is no longer MyService, it's NewRelic::Rack without the exposed settings method.
Has anyone else experienced this? I'm running the application with bundle exec puma

I was able to work around this by updating my middleware
def initialize app, &block
#app = app
#block = block
end
def call env
#block.call(env)
do_something(env[:my_middleware_option])
...
#app.call(env)
end
And initializing my middleware with
use MyMiddleware do |env|
env[:my_middleware_option] = "any data type"
end

Related

symfony6 $this->container->get('app.our.useful.thing')

I am sorry, I read the docs, but I don't get symfony6 anymore.
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/EventListener
app.our.useful.thing:
class: App\OurUsefulThing
public: true
My src/OurUsefulThing.php:
<?php
namespace App;
class OurUsefulThing
{
public function sayHello()
{
return "Hello Service";
}
}
In the controller:
public function someActionName(Request $request)() {
$value = $this->container->get('app.our.useful.thing')->sayHello();
}
Error Message
Service "app.our.useful.thing" not found: even though it exists in the app's container, the container inside "App\Controller\CategoriesController" is a smaller service locator that only knows about the "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer" and "twig" services. Try using dependency injection instead.
It was in symfony4 so easy. What I am doing wrong?

Request-based Sticky Session configuration with Spring Cloud LoadBalancer

I have the following configuration for request-based sticky session using Spring Cloud LoadBalancer
spring:
cloud:
discovery.client.simple.instances:
say-hello:
- instanceId: say-hello1
uri: http://localhost:8080
- instanceId: say-hello2
uri: http://localhost:8081
loadbalancer:
configurations: request-based-sticky-session
sticky-session:
add-service-instance-cookie: true
server.port:9090
the following call:
$ http :9090/hi 'Cookie:sc-lb-instance-id=say-hello1'
should go only to the say-hello1 instance based on the Request-based Sticky Session for LoadBalancer but instead is using round robin load balancing.
What do I miss here?
Here is the source code to try it: https://github.com/altfatterz/client-side-loadbalancing
There are 2 things to consider here:
In the sample, the cookie has to be passed on to the actual load-balanced request, for example like so:
#GetMapping("/hi")
public String hi(#RequestParam(value = "name", defaultValue = "Mary") String name) {
logger.info("Accessing /hi endpoint");
HttpHeaders headers = new HttpHeaders();
headers.set("Cookie", "sc-lb-instance-id=say-hello1");
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> greeting = restTemplate.exchange("http://say-hello/greeting", HttpMethod.GET, entity, String.class, new HashMap<>());
return greeting + " " + name;
}
This feature is only supported for WebClient-backed load-balancing. It was not properly documented. I have documented it here.
I have also created a GitHub issue for adding the non-reactive implementation, however, the decision to implement it will be dependant on larger community interest.

GRPC Repeated field does not transcode to an array as body parameter in REST API

I´m having little luck trying to send a PUT request with JSON containing an array of objects to my GRPC Server using REST. Using GRPC however it accepts an array just like expected. This is what I have defined in my proto file:
message UpdateRequest {
repeated Data data = 1;
int32 Id = 2;
}
message UpdateResponse {
}
message Data {
int32 id = 1;
string name = 2;
}
rpc Update(UpdateRequest) returns (UpdateResponse) {
option (google.api.http) = {
put: "/v1/data/{Id}"
body: "*"
};
}
This deploys successfully to GCP Endpoints but according to the GCP enpointsportal the request body is supposed to only contain a single object like:
{
"data": {
}
}
instead of an array of objects like expected:
{
"data": [
{},
{}
]
}
I´ve tried with replacing the "*" in the body with "data"
rpc Update(UpdateRequest) returns (UpdateResponse) {
option (google.api.http) = {
put: "/v1/data/{Id}"
body: "data"
};
}
This also compiles, but fails when trying to deploy to GCP endpoints with the following message:
kind: ERROR
message: "http: body field path 'data' must be a non-repeated message."
Any suggestions as to how I should go about solving this would be greatly appreciated.
Update:
Heres the contents of my .yaml file.
type: google.api.Service
config_version: 3
name: xxx.xxx-xxx.dev
title: xxxx
apis:
- name: x.x
- name: x.y
backend:
rules:
- selector: "*"
address: grpcs://xxx-xxx-app-xxxx-lz.a.run.app
This is a known issue, according to GCP support.
Here is the google issuetracker link: https://issuetracker.google.com/issues/178486575
There seems that this is a bug in GCP endpoints portal. I´m now successfully sending update requests with arrays containing object through CURL and my frontend application, although this does not work through endpoints.

Zuul Routing on Root Path

I want to config zuul to route request to root / to a home page. I tried:
root:
path: /
url: http://hostname/home/index.jsp
and
root:
path: /**
url: http://hostname/home/index.jsp
But neither of them works. I just got a 404 NOT FOUND. I think the path match config should be similar to those with contexts, such as /service/**, but it's not.
This is what I have done to make this work.
Within Zuul -> controller:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String handleRequest() {
return "forward:/ux/";
}
Zuul Properties:
zuul:
addProxyHeaders: true
routes:
example-ux:
path: /ux/**
stripPrefix: false
Within example-ux Service properties:
server:
servlet-path: /*
context-path: /ux
This configuration also solves the problem of static resources resolution. i.e. /static/css static/js etc...

Locale in Routing, Default Language also without Parameter

I want to define the page language via url on a Symfony2 installation. My routing works via annotation inside the controller.
routing.yml
_index:
resource: "#MyMainBundle/Controller/SiteController.php"
type: annotation
siteController.php
/**
* #Route( "/{_locale}/{site}", name="_site_site", defaults={"_locale" = "en"}, requirements={"site" = "about|cities|download|blog", "_locale" = "en|de|fr|es"} )
*/
This works quiet well, but waht I want, is that the following url call the same action.
http://example.com/download
http://example.com/en/download
http://example.com/de/download
Without the languge-parameter, the page should switch back to the default language, but this is something I can handle inside my action.
I found this Answer, but could not get it to work at all.
Symfony2 default locale in routing
Just add another #Route annotation that does not include the locale.
/**
* #Route("/{_locale}/{site}/")
* #Route("/{site}/")
*/
This also works within annotations.yaml
frontend_controllers:
resource: ../../src/Controller/Frontend
type: annotation
prefix:
- /
- /{_locale}
defaults:
_locale: 'en'
Another simular solution for Symfony 5 that worked for me :
# config/routes/annotations.yaml
controllers:
resource: '../../src/Controller/'
type: annotation
prefix:
fr: ''
en: '/en'
Symfony documentation : https://symfony.com/doc/current/routing.html#localized-routes-i18n
Also if you have an api prefix you can use next config
controllers:
resource: ../../src/Controller/
type: annotation
prefix:
- api
- api/{_locale}
defaults:
_locale: en