Skip to content

Commit

Permalink
Merge pull request #6 from agorapulse/chore/request-info
Browse files Browse the repository at this point in the history
added support for HTTP
  • Loading branch information
musketyr committed Oct 23, 2020
2 parents c9fad45 + 9216512 commit 2a6fa65
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 0 deletions.
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ sentryVersion = 1.7.30
log4jVersion = 2.13.3
awsLog4jVersion = 1.2.0
systemRulesVersion = 1.19.0
gruVersion = 0.8.4
bytebuddyVersion = 1.10.17
objenesisVersion = 3.1
9 changes: 9 additions & 0 deletions subprojects/micronaut-log4aws/micronaut-log4aws.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,23 @@ dependencies {
compile "io.micronaut:micronaut-core"
compileOnly "io.micronaut:micronaut-inject-groovy"

compileOnly 'io.micronaut:micronaut-http'
compileOnly 'io.reactivex.rxjava2:rxjava'

testAnnotationProcessor "io.micronaut:micronaut-inject-java"

testCompile "io.micronaut:micronaut-inject-groovy"
testCompile "io.micronaut:micronaut-http-server-netty"

testCompile "com.github.stefanbirkner:system-rules:$systemRulesVersion"

testCompile("org.spockframework:spock-core") {
exclude group: "org.codehaus.groovy", module: "groovy-all"
}

testCompile "com.agorapulse:gru-http:$gruVersion"
testCompile "net.bytebuddy:byte-buddy:$bytebuddyVersion"
testCompile "org.objenesis:objenesis:$objenesisVersion"

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Agorapulse.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.agorapulse.micronaut.log4aws.http;

import io.micronaut.http.HttpRequest;
import io.sentry.event.EventBuilder;
import io.sentry.event.helper.EventBuilderHelper;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class MicronautRequestBuildHelper implements EventBuilderHelper {

private static final List<String> SENSITIVE_HEADERS = Arrays.asList("X-FORWARDED-FOR", "AUTHORIZATION", "COOKIE");

private static final List<String> SENSITIVE_PARAMS = Arrays.asList("TOKEN");

private final HttpRequest<?> request;

public MicronautRequestBuildHelper(HttpRequest<?> request) {
this.request = request;
}

@Override
public void helpBuildingEvent(EventBuilder eventBuilder) {
eventBuilder.withTag("req.path", request.getPath());
eventBuilder.withTag("req.method", request.getMethod().toString());
eventBuilder.withTag("req.remoteHost", request.getRemoteAddress().getHostString());
eventBuilder.withTag("req.serverHost", request.getServerAddress().getHostString());
eventBuilder.withExtra("req.parameters", resolveParameters(request));
eventBuilder.withExtra("req.headers", resolveHeaders(request));
}

private static Map<String, String> resolveParameters(final HttpRequest<?> request) {
return StreamSupport.stream(request.getParameters().spliterator(), false)
.filter(e -> !SENSITIVE_PARAMS.contains(e.getKey().toUpperCase()))
.collect(Collectors.toMap(Map.Entry::getKey, e -> String.join(",", e.getValue())));
}

private Map<String, String> resolveHeaders(final HttpRequest<?> request) {
final Map<String, String> headersMap = new HashMap<>();
for (String headerName : request.getHeaders().names()) {
if (!SENSITIVE_HEADERS.contains(headerName.toUpperCase())) {
headersMap.put(headerName, String.join(",", request.getHeaders().getAll(headerName)));
}
}
return headersMap;
}

@Override
public String toString() {
return String.format("MicronautRequestBuildHelper{ request = %s }", request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Agorapulse.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.agorapulse.micronaut.log4aws.http;

import io.micronaut.http.HttpRequest;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Filter;
import io.micronaut.http.filter.HttpServerFilter;
import io.micronaut.http.filter.ServerFilterChain;
import io.reactivex.Flowable;
import io.sentry.SentryClient;
import io.sentry.event.helper.EventBuilderHelper;
import org.reactivestreams.Publisher;

import java.util.concurrent.atomic.AtomicReference;

@Filter("/**")
public class SentryFilter implements HttpServerFilter {

private final SentryClient client;

public SentryFilter(SentryClient client) {
this.client = client;
}

@Override
public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
AtomicReference<EventBuilderHelper> helperReference = new AtomicReference<>(new MicronautRequestBuildHelper(request));
return Flowable
.just(request)
.doOnNext(r -> {
client.addBuilderHelper(helperReference.get());
})
.switchMap(chain::proceed)
.doOnNext(res -> {
client.removeBuilderHelper(helperReference.get());
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Agorapulse.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.agorapulse.micronaut.log4aws.http

import com.agorapulse.gru.Gru
import com.agorapulse.gru.http.Http
import io.micronaut.context.ApplicationContext
import io.micronaut.runtime.server.EmbeddedServer
import io.sentry.SentryClient
import io.sentry.event.helper.EventBuilderHelper
import org.junit.Rule
import spock.lang.AutoCleanup
import spock.lang.Specification

class SentryFilterSpec extends Specification {

@Rule Gru gru = Gru.equip(Http.steal(this))

@AutoCleanup ApplicationContext context
@AutoCleanup EmbeddedServer server

SentryClient client = Mock()

void setup() {
context = ApplicationContext.build().build()
context.registerSingleton(SentryClient, client)

context.start()

server = context.getBean(EmbeddedServer)
server.start()

gru.prepare(server.URL.toString())
}

void 'try ok message'() {
when:
gru.test {
get('/test/parameter')
expect {
text inline('parameter')
}
}
then:
gru.verify()

1 * client.addBuilderHelper(_)
1 * client.removeBuilderHelper(_)

0 * _._
}

@SuppressWarnings('Println')
void 'try error message'() {
when:
gru.test {
post('/test/parameter')
expect {
status INTERNAL_SERVER_ERROR
}
}
then:
gru.verify()

_ * client.addBuilderHelper(_) >> { EventBuilderHelper helper ->
println "adding $helper"
}

_ * client.removeBuilderHelper(_) >> { EventBuilderHelper helper ->
println "removing $helper"
}

0 * _._
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Agorapulse.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.agorapulse.micronaut.log4aws.http

import groovy.transform.CompileStatic
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.PathVariable
import io.micronaut.http.annotation.Post

@CompileStatic
@Controller('/test')
class TestController {

@Get('/{someparam}')
HttpResponse<String> someparam(@PathVariable String someparam) {
HttpResponse.ok(someparam)
}

@Post('/{someerror}')
@SuppressWarnings('ThrowRuntimeException')
HttpResponse<String> someerror(@PathVariable String someerror) {
throw new RuntimeException(someerror)
}

}

0 comments on commit 2a6fa65

Please sign in to comment.