Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release CSEC Java Agent Version 1.6.0 #366

Merged
merged 37 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3a24ea8
NR-325523: Incoming request interception support in Http4s Blaze Server
IshikaDawda Oct 18, 2024
d239f0f
NR-325525: Extract HTTP response in Http4s-Blaze server
IshikaDawda Oct 21, 2024
e9b7015
NR-325526: Instrument outgoing HTTP Request in HTTP4s Blaze client
IshikaDawda Oct 29, 2024
73e380c
NR-325527: Http4s Blaze client outgoing HTTP Request header manipulation
IshikaDawda Oct 30, 2024
9cebbf3
NR-332541: Unit tests for http4s-blaze client instrumentation support
IshikaDawda Nov 5, 2024
ba91d11
Merge pull request #348 from newrelic/unittest/http-blaze-client
IshikaDawda Nov 5, 2024
db61896
NR-336715: Fix for NR-322822 Where Incorrect user class details found…
IshikaDawda Nov 7, 2024
aeca803
process stacktrace in mule server for both RXSS and non RXSS events
IshikaDawda Nov 7, 2024
ef4a6f1
Unit tests for http4s blaze 2.21 version support
IshikaDawda Nov 11, 2024
53b3284
Fix for duplicate RXSS events and code optimization in http4s blaze s…
IshikaDawda Nov 11, 2024
747acf7
NR-333392: Adds Unit tests for http4s blaze server instrumentation su…
IshikaDawda Nov 12, 2024
f964b5a
Merge branch 'refs/heads/main' into support/http-blaze
IshikaDawda Nov 26, 2024
e22afdd
NR-293846: Extracting request and response body in http4s-blaze server
IshikaDawda Nov 26, 2024
121f95a
Extracting request body in http4s-blaze server
IshikaDawda Nov 26, 2024
17d84df
Update instrumentation unit tests for blaze body extraction
IshikaDawda Nov 26, 2024
2cda0d3
Merge branch 'refs/heads/support/http-blaze' into support/http-blaze-…
IshikaDawda Dec 4, 2024
87e123b
Do not generate RXSS events if RXSS is disabled
IshikaDawda Dec 5, 2024
1cfb29b
Merge branch 'refs/heads/support/http-blaze' into support/http-blaze-…
IshikaDawda Dec 5, 2024
b6ce325
Merge branch 'refs/heads/main' into support/http-blaze-client
IshikaDawda Dec 11, 2024
26694d6
Merge branch 'refs/heads/main' into support/http-blaze
IshikaDawda Dec 12, 2024
2c27d2c
Merge branch 'refs/heads/support/http-blaze' into support/http-blaze-…
IshikaDawda Dec 12, 2024
476ccde
Merge pull request #352 from newrelic/fix/mule-NR-322822
IshikaDawda Dec 12, 2024
40a3a6d
Merge pull request #346 from newrelic/support/http-blaze-client
IshikaDawda Dec 12, 2024
9beb46d
Add changelog for CSEC release version 1.6.0
lovesh-ap Dec 12, 2024
6241f53
Add Jira & PRs links to Changelogs for documentation
IshikaDawda Dec 13, 2024
3d67b5d
Merge branch 'release/v1.6.0' into support/http-blaze
IshikaDawda Dec 13, 2024
f6b7518
Merge pull request #344 from newrelic/support/http-blaze
IshikaDawda Dec 13, 2024
46b46f4
Merge branch 'refs/heads/develop' into release/v1.6.0
IshikaDawda Dec 13, 2024
28b3abe
Merge remote-tracking branch 'origin/release/v1.6.0' into release/v1.6.0
IshikaDawda Dec 13, 2024
0cc841e
this utility is invoked even before agent initiallization which makes…
lovesh-ap Dec 16, 2024
aaefbef
Disable url encoding
lovesh-ap Dec 16, 2024
7275b99
Minor log fix
lovesh-ap Dec 16, 2024
c923894
fix endpoint selection
lovesh-ap Dec 16, 2024
413c6b7
Fix for status code check
lovesh-ap Dec 16, 2024
49e7ece
Fix for status code check in 4xx list
lovesh-ap Dec 16, 2024
a073771
Use NoopHostname verifier in IAST Apache client
IshikaDawda Dec 16, 2024
74ac184
Merge pull request #367 from newrelic/fix/disable-url-encoding
lovesh-ap Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ Noteworthy changes to the agent are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.6.0] - 2024-12-16
### Adds
- [PR-329](https://github.com/newrelic/csec-java-agent/pull/329) Apache Pekko Server Support: The security agent now supports Apache Pekko Server version 1.0.0 and newer, compatible with Scala 2.13 and above. [NR-308780](https://new-relic.atlassian.net/browse/NR-308780), [NR-308781](https://new-relic.atlassian.net/browse/NR-308781), [NR-308791](https://new-relic.atlassian.net/browse/NR-308791), [NR-308792](https://new-relic.atlassian.net/browse/NR-308792) [NR-308782](https://new-relic.atlassian.net/browse/NR-308782)
- [PR-228](https://github.com/newrelic/csec-java-agent/pull/228) HTTP4s Ember Server Support: Added support for HTTP4s Ember Server version 0.23 and newer, compatible with Scala 2.12 and above. [NR-293957](https://new-relic.atlassian.net/browse/NR-293957), [NR-293847](https://new-relic.atlassian.net/browse/NR-293847), [NR-293844](https://new-relic.atlassian.net/browse/NR-293844)
- [PR-344](https://github.com/newrelic/csec-java-agent/pull/344) HTTP4s Blaze Server Support: The security agent now supports HTTP4s Blaze Server version 0.21 and newer, compatible with Scala 2.12 and above. [NR-325523](https://new-relic.atlassian.net/browse/NR-325523), [NR-325525](https://new-relic.atlassian.net/browse/NR-325525), [NR-293846](https://new-relic.atlassian.net/browse/NR-293846)
- [PR-228](https://github.com/newrelic/csec-java-agent/pull/228) HTTP4s Ember Client Support: Introduced support for HTTP4s Ember Client version 0.23 and above, compatible with Scala 2.12 and above. [NR-307676](https://new-relic.atlassian.net/browse/NR-307676)
- [PR-346](https://github.com/newrelic/csec-java-agent/pull/346) HTTP4s Blaze Client Support: Added support for HTTP4s Blaze Client version 0.21 and newer, compatible with Scala 2.12 and above. [NR-325526](https://new-relic.atlassian.net/browse/NR-325526), [NR-325527](https://new-relic.atlassian.net/browse/NR-325527)
- [PR-363](https://github.com/newrelic/csec-java-agent/pull/363) GraphQL Support: GraphQL support is now enabled by default.

### Changes
- [PR-331](https://github.com/newrelic/csec-java-agent/pull/331) REST Client Update for IAST Request Replay: Migrated to utilize the Apache HTTP Client for enhanced request replay functionality. [NR-283130](https://new-relic.atlassian.net/browse/NR-283130)
- [PR-311](https://github.com/newrelic/csec-java-agent/pull/311) Status File Removed: The status file used for debugging has been eliminated. All debugging capabilities have been integrated into Init Logging or the Error Inbox. [NR-297214](https://new-relic.atlassian.net/browse/NR-297214)
- [PR-356](https://github.com/newrelic/csec-java-agent/pull/356) Code Optimization: Optimized code to minimize the overhead of the Security Agent in relation to the APM Agent. [NR-338596](https://new-relic.atlassian.net/browse/NR-338596)

### Fixes
- [PR-352](https://github.com/newrelic/csec-java-agent/pull/352) Corrected the issue regarding inaccurate user class details in the mule-demo-app. [NR-336715](https://new-relic.atlassian.net/browse/NR-336715)
- [PR-355](https://github.com/newrelic/csec-java-agent/pull/355) Improved logging for scenarios where delay is set to a negative value. [NR-338578](https://new-relic.atlassian.net/browse/NR-338578)


## [1.5.1] - 2024-11-9
### New features
- [PR-350](https://github.com/newrelic/csec-java-agent/pull/350) IAST support for CI/CD.
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The agent version.
agentVersion=1.5.1
agentVersion=1.6.0
jsonVersion=1.2.9
# Updated exposed NR APM API version.
nrAPIVersion=8.12.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apply plugin: 'scala'

isScalaProjectEnabled(project, "scala-2.12")

dependencies {
implementation(project(":newrelic-security-api"))
implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}")
implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}")
implementation("org.scala-lang:scala-library:2.12.14")
implementation('org.http4s:http4s-blaze-client_2.12:0.21.24')
implementation("org.typelevel:cats-effect_2.12:2.5.5")
}

jar {
manifest {
attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.http4s-blaze-client-2.12_0.21', 'Priority': '-1'
}
}

verifyInstrumentation {
passes 'org.http4s:http4s-blaze-client_2.12:[0.21,0.22)'
excludeRegex '.*(RC|M)[0-9]*'
}

sourceSets.main.scala.srcDirs = ['src/main/scala', 'src/main/java']
sourceSets.main.java.srcDirs = []
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.http4s;

import cats.effect.ConcurrentEffect;
import cats.effect.Resource;
import com.newrelic.agent.security.instrumentation.http4s.blaze.NewrelicSecurityClientMiddleware$;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import org.http4s.client.Client;

@Weave(type = MatchType.ExactClass, originalName = "org.http4s.client.blaze.BlazeClientBuilder")
public abstract class BlazeClientBuilder_Instrumentation<F> {

public ConcurrentEffect F() {
return Weaver.callOriginal();
}

public Resource<F, Client<F>> resource() {
Resource<F, Client<F>> delegateResource = Weaver.callOriginal();
return NewrelicSecurityClientMiddleware$.MODULE$.resource(delegateResource, F());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.newrelic.agent.security.instrumentation.http4s.blaze

import cats.effect.{Async, ConcurrentEffect, Resource, Sync}
import com.newrelic.api.agent.security.NewRelicSecurity
import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, ServletHelper}
import com.newrelic.api.agent.security.schema.exceptions.NewRelicSecurityException
import com.newrelic.api.agent.security.schema.operation.SSRFOperation
import com.newrelic.api.agent.security.schema.{AbstractOperation, StringUtils, VulnerabilityCaseType}
import com.newrelic.api.agent.security.utils.SSRFUtils
import com.newrelic.api.agent.security.utils.logging.LogLevel
import org.http4s.Request
import org.http4s.client.Client

import java.net.URI

object NewrelicSecurityClientMiddleware {
private final val nrSecCustomAttrName: String = "HTTP4S-BLAZE-CLIENT-OUTBOUND"
private final val HTTP4S_BLAZE_CLIENT: String = "HTTP4S-BLAZE-CLIENT-2.12_0.21"

private def construct[F[_] : Sync, T](t: T): F[T] = Sync[F].delay(t)

private def clientResource[F[_] : ConcurrentEffect](client: Client[F]): Client[F] =
Client { req: Request[F] =>
for {
// pre-process hook
operation <- Resource.liftF(construct {
val isLockAcquired = GenericHelper.acquireLockIfPossible(VulnerabilityCaseType.HTTP_REQUEST, nrSecCustomAttrName)
var operation: AbstractOperation = null
if (isLockAcquired) {
operation = preprocessSecurityHook(req)
}
operation
})

request <- Resource.liftF(construct {addSecurityHeaders(req, operation)})

// original call
response <- client.run(request)

// post process and register exit event
newRes <- Resource.liftF(construct{
val isLockAcquired = GenericHelper.isLockAcquired(nrSecCustomAttrName);
if (isLockAcquired) {
GenericHelper.releaseLock(nrSecCustomAttrName)
}
registerExitOperation(isLockAcquired, operation)
response
})

} yield newRes
}

def resource[F[_] : ConcurrentEffect](delegate: Resource[F, Client[F]]): Resource[F, Client[F]] = {
val res: Resource[F, Client[F]] = delegate.map(c =>clientResource(c))
res
}

private def addSecurityHeaders[F[_] : Async](request: Request[F], operation: AbstractOperation): Request[F] = {
val outboundRequest = new OutboundRequest(request)
if (operation != null) {
val securityMetaData = NewRelicSecurity.getAgent.getSecurityMetaData
val iastHeader = NewRelicSecurity.getAgent.getSecurityMetaData.getFuzzRequestIdentifier.getRaw
if (iastHeader != null && iastHeader.trim.nonEmpty) {
outboundRequest.setHeader(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID, iastHeader)
}
val csecParentId = securityMetaData.getCustomAttribute(GenericHelper.CSEC_PARENT_ID, classOf[String])
if (StringUtils.isNotBlank(csecParentId)) {
outboundRequest.setHeader(GenericHelper.CSEC_PARENT_ID, csecParentId)
}
try {
NewRelicSecurity.getAgent.getSecurityMetaData.getMetaData.setFromJumpRequiredInStackTrace(Integer.valueOf(4))
NewRelicSecurity.getAgent.registerOperation(operation)
}
finally {
if (operation.getApiID != null && operation.getApiID.trim.nonEmpty && operation.getExecutionId != null && operation.getExecutionId.trim.nonEmpty) {
outboundRequest.setHeader(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER, SSRFUtils.generateTracingHeaderValue(securityMetaData.getTracingHeaderValue, operation.getApiID, operation.getExecutionId, NewRelicSecurity.getAgent.getAgentUUID))
}
}
}
outboundRequest.getRequest
}


private def preprocessSecurityHook[F[_] : Async](httpRequest: Request[F]): AbstractOperation = {
try {
val securityMetaData = NewRelicSecurity.getAgent.getSecurityMetaData
if (!NewRelicSecurity.isHookProcessingActive || securityMetaData.getRequest.isEmpty) return null
// Generate required URL
var methodURI: URI = null
var uri: String = null
try {
methodURI = new URI(httpRequest.uri.toString)
uri = methodURI.toString
if (methodURI == null) return null
} catch {
case ignored: Exception =>
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.URI_EXCEPTION_MESSAGE, HTTP4S_BLAZE_CLIENT, ignored.getMessage), ignored, this.getClass.getName)
return null
}
return new SSRFOperation(uri, this.getClass.getName, "run")
} catch {
case e: Throwable =>
if (e.isInstanceOf[NewRelicSecurityException]) {
NewRelicSecurity.getAgent.log(LogLevel.WARNING, String.format(GenericHelper.SECURITY_EXCEPTION_MESSAGE, HTTP4S_BLAZE_CLIENT, e.getMessage), e, this.getClass.getName)
throw e
}
NewRelicSecurity.getAgent.log(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP4S_BLAZE_CLIENT, e.getMessage), e, this.getClass.getName)
NewRelicSecurity.getAgent.reportIncident(LogLevel.SEVERE, String.format(GenericHelper.REGISTER_OPERATION_EXCEPTION_MESSAGE, HTTP4S_BLAZE_CLIENT, e.getMessage), e, this.getClass.getName)
}
null
}

private def registerExitOperation(isProcessingAllowed: Boolean, operation: AbstractOperation): Unit = {
try {
if (operation == null || !isProcessingAllowed || !NewRelicSecurity.isHookProcessingActive || NewRelicSecurity.getAgent.getSecurityMetaData.getRequest.isEmpty) return
NewRelicSecurity.getAgent.registerExitEvent(operation)
} catch {
case e: Throwable =>
NewRelicSecurity.getAgent.log(LogLevel.FINEST, String.format(GenericHelper.EXIT_OPERATION_EXCEPTION_MESSAGE, HTTP4S_BLAZE_CLIENT, e.getMessage), e, this.getClass.getName)
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.newrelic.agent.security.instrumentation.http4s.blaze

import org.http4s.util.CaseInsensitiveString
import org.http4s.{Header, Request}

/**
* Http4s's HttpRequest is immutable so we have to create a copy with the new headers.
*/

class OutboundRequest[F[_]](request: Request[F]) {
private var req: Request[F] = request

def setHeader(key: String, value: String): Unit = {
req = req.withHeaders(req.headers.put(Header.Raw.apply(CaseInsensitiveString.apply(key), value)))
}
def getRequest: Request[F] = {
req
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.nr.agent.security.instrumentation.blaze.client

import cats.effect.{ConcurrentEffect, ContextShift, IO, Timer}
import com.newrelic.agent.security.introspec.internal.HttpServerRule
import com.newrelic.agent.security.introspec.{InstrumentationTestConfig, SecurityInstrumentationTestRunner, SecurityIntrospector}
import com.newrelic.api.agent.security.instrumentation.helpers.{GenericHelper, ServletHelper}
import com.newrelic.api.agent.security.schema.operation.SSRFOperation
import com.newrelic.api.agent.security.schema.{AbstractOperation, VulnerabilityCaseType}
import com.nr.agent.security.instrumentation.blaze.client.Http4sTestUtils.makeRequest
import org.http4s.client.blaze.BlazeClientBuilder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.{Assert, FixMethodOrder, Rule, Test}

import java.util
import java.util.UUID
import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext.global
import scala.concurrent.duration.DurationInt

@RunWith(classOf[SecurityInstrumentationTestRunner])
@InstrumentationTestConfig(includePrefixes = Array("org.http4s", "com.newrelic.agent.security.instrumentation.http4s"))
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class BlazeClientTest {

@Rule
def server: HttpServerRule = httpServer

implicit val ec: ExecutionContext = global
implicit val cs: ContextShift[IO] = IO.contextShift(global)
implicit val timer: Timer[IO] = IO.timer(global)

val httpServer = new HttpServerRule()

@Test
def blazeClientTest(): Unit = {

val introspector: SecurityIntrospector = SecurityInstrumentationTestRunner.getIntrospector
makeRequest(s"${server.getEndPoint}").unsafeRunTimed(2.seconds)
assertSSRFOperation(introspector.getOperations)

}

@Test
def blazeClientTestWithHeaders(): Unit = {
val headerValue = String.valueOf(UUID.randomUUID)

val introspector: SecurityIntrospector = SecurityInstrumentationTestRunner.getIntrospector
setCSECHeaders(headerValue = headerValue, introspector = introspector)
makeRequest(s"${server.getEndPoint}").unsafeRunTimed(2.seconds)
assertSSRFOperation(introspector.getOperations)
verifyHeaders(headerValue, httpServer.getHeaders)
}


private def assertSSRFOperation(operations: util.List[AbstractOperation]): Unit = {
Assert.assertTrue("Incorrect number of operations detected!", operations.size == 1)
Assert.assertTrue("SSRFOperation not found!", operations.get(0).isInstanceOf[SSRFOperation])
val operation: SSRFOperation = operations.get(0).asInstanceOf[SSRFOperation]

Assert.assertFalse("operation should not be empty", operation.isEmpty)
Assert.assertFalse("JNDILookup should be false", operation.isJNDILookup)
Assert.assertFalse("LowSeverityHook should be disabled", operation.isLowSeverityHook)
Assert.assertEquals("Invalid event category.", VulnerabilityCaseType.HTTP_REQUEST, operation.getCaseType)
Assert.assertEquals("Invalid executed method name.", "run", operation.getMethodName)
Assert.assertEquals("Invalid executed parameters.", server.getEndPoint.toString, operation.getArg)
}

private def verifyHeaders(headerValue: String, headers: util.Map[String, String]): Unit = {
Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headers.containsKey(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID))
Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID), headerValue + "a", headers.get(ServletHelper.CSEC_IAST_FUZZ_REQUEST_ID))
Assert.assertTrue(String.format("Missing CSEC header: %s", GenericHelper.CSEC_PARENT_ID), headers.containsKey(GenericHelper.CSEC_PARENT_ID))
Assert.assertEquals(String.format("Invalid CSEC header value for: %s", GenericHelper.CSEC_PARENT_ID), headerValue + "b", headers.get(GenericHelper.CSEC_PARENT_ID))
Assert.assertTrue(String.format("Missing CSEC header: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), headers.containsKey(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase))
Assert.assertEquals(String.format("Invalid CSEC header value for: %s", ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER), String.format("%s;DUMMY_UUID/dummy-api-id/dummy-exec-id;", headerValue), headers.get(ServletHelper.CSEC_DISTRIBUTED_TRACING_HEADER.toLowerCase))
}

private def setCSECHeaders(headerValue: String, introspector: SecurityIntrospector): Unit = {
introspector.setK2FuzzRequestId(headerValue + "a")
introspector.setK2ParentId(headerValue + "b")
introspector.setK2TracingData(headerValue)
}
}

object Http4sTestUtils {
def makeRequest[F[_] : ContextShift : Timer](url: String)(
implicit ex: ExecutionContext, c: ConcurrentEffect[F]): F[String] = {
BlazeClientBuilder[F](ex).resource.use { client =>
client.expect[String](url)
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apply plugin: 'scala'

isScalaProjectEnabled(project, "scala-2.12")

dependencies {
implementation(project(":newrelic-security-api"))
implementation("com.newrelic.agent.java:newrelic-api:${nrAPIVersion}")
implementation("com.newrelic.agent.java:newrelic-weaver-api:${nrAPIVersion}")
implementation("org.scala-lang:scala-library:2.12.14")
implementation('org.http4s:http4s-blaze-client_2.12:0.22.14')
implementation("org.typelevel:cats-effect_2.12:2.5.5")
}

jar {
manifest {
attributes 'Implementation-Title': 'com.newrelic.instrumentation.security.http4s-blaze-client-2.12_0.22', 'Priority': '-1'
}
}

verifyInstrumentation {
passes 'org.http4s:http4s-blaze-client_2.12:[0.22.0,0.23.0)'
excludeRegex '.*(RC|M)[0-9]*'
excludeRegex '.*0.22\\-[0-9].*'
}

sourceSets.main.scala.srcDirs = ['src/main/scala', 'src/main/java']
sourceSets.main.java.srcDirs = []
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.http4s;

import cats.effect.ConcurrentEffect;
import cats.effect.Resource;
import com.newrelic.agent.security.instrumentation.http4s.blaze.NewrelicSecurityClientMiddleware$;
import com.newrelic.api.agent.weaver.MatchType;
import com.newrelic.api.agent.weaver.Weave;
import com.newrelic.api.agent.weaver.Weaver;
import org.http4s.client.Client;

@Weave(type = MatchType.ExactClass, originalName = "org.http4s.blaze.client.BlazeClientBuilder")
public abstract class BlazeClientBuilder_Instrumentation<F> {

public ConcurrentEffect F() {
return Weaver.callOriginal();
}

public Resource<F, Client<F>> resource() {
Resource<F, Client<F>> delegateResource = Weaver.callOriginal();
return NewrelicSecurityClientMiddleware$.MODULE$.resource(delegateResource, F());
}
}
Loading
Loading