Skip to content

Commit

Permalink
Apache Http Client 5.x Use Timeout and TimeValue classes (#399)
Browse files Browse the repository at this point in the history
  • Loading branch information
Joan Viladrosa authored Jul 31, 2023
1 parent 0c20814 commit e95a680
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ bin/
.project
.classpath
.settings/
.DS_Store
.moderne/
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 org.openrewrite.java.apache.httpclient5;

import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.J;

import java.util.Arrays;
import java.util.List;

public class UseTimeValue extends Recipe {
@Override
public String getDisplayName() {
return "Use `TimeValue` class to define time values (duration)";
}

@Override
public String getDescription() {
return "Use `TimeValue` class to define time values (duration).";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>("org.apache.hc..*", true), new JavaIsoVisitor<ExecutionContext>() {

List<MethodMatcher> methodMatchers = Arrays.asList(
new MethodMatcher("org.apache.hc.core5.http.io.SocketConfig.Builder setSoLinger(int)")
);

JavaTemplate template = JavaTemplate.builder("TimeValue.ofMilliseconds(#{})")
.contextSensitive()
.javaParser(JavaParser.fromJavaVersion().classpath(
"httpclient5", "httpcore5"
))
.imports("org.apache.hc.core5.util.TimeValue")
.build();

@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation m = super.visitMethodInvocation(method, ctx);

if (methodMatches(m)) {
m = template.apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0));
maybeAddImport("org.apache.hc.core5.util.TimeValue");
}
return m;
}

private boolean methodMatches(J.MethodInvocation method) {
for (MethodMatcher matcher : methodMatchers) {
if (matcher.matches(method)) {
return true;
}
}
return false;
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 org.openrewrite.java.apache.httpclient5;

import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.J;

import java.util.Arrays;
import java.util.List;


public class UseTimeout extends Recipe {
@Override
public String getDisplayName() {
return "Use `Timeout` class to define timeouts";
}

@Override
public String getDescription() {
return "Use Timeout class to define timeouts.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>("org.apache.hc..*", true), new JavaIsoVisitor<ExecutionContext>() {

final List<MethodMatcher> methodMatchers = Arrays.asList(
new MethodMatcher("org.apache.hc.client5.http.config.RequestConfig.Builder setConnectionRequestTimeout(int)"),
new MethodMatcher("org.apache.hc.client5.http.config.RequestConfig.Builder setConnectTimeout(int)"),
new MethodMatcher("org.apache.hc.client5.http.config.RequestConfig.Builder setResponseTimeout(int)"),
new MethodMatcher("org.apache.hc.core5.http.io.SocketConfig.Builder setSoTimeout(int)")
);

final JavaTemplate template = JavaTemplate.builder("Timeout.ofMilliseconds(#{})")
.contextSensitive()
.javaParser(JavaParser.fromJavaVersion().classpath(
"httpclient5", "httpcore5"
))
.imports("org.apache.hc.core5.util.Timeout")
.build();

@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation m = super.visitMethodInvocation(method, ctx);

if (methodMatches(m)) {
m = template.apply(updateCursor(m), m.getCoordinates().replaceArguments(), m.getArguments().get(0));
maybeAddImport("org.apache.hc.core5.util.Timeout");
}
return m;
}

private boolean methodMatches(J.MethodInvocation method) {
for (MethodMatcher matcher : methodMatchers) {
if (matcher.matches(method)) {
return true;
}
}
return false;
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.
*/
@NonNullApi @NonNullFields
package org.openrewrite.java.apache.httpclient5;

import org.openrewrite.internal.lang.NonNullApi;
import org.openrewrite.internal.lang.NonNullFields;
18 changes: 17 additions & 1 deletion src/main/resources/META-INF/rewrite/apache-httpclient-5.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ recipeList:
newVersion: 5.1.x
overrideManagedVersion: true
- org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_ClassMapping
- org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_DeprecatedMethods
- org.openrewrite.java.apache.httpclient5.UseTimeout
- org.openrewrite.java.apache.httpclient5.UseTimeValue

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_ClassMapping
Expand Down Expand Up @@ -251,8 +255,11 @@ recipeList:
oldPackageName: org.apache.http.config
newPackageName: org.apache.hc.core5.http.config
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: org.apache.http.config.SocketConfig
oldFullyQualifiedTypeName: org.apache.hc.core5.http.config.SocketConfig
newFullyQualifiedTypeName: org.apache.hc.core5.http.io.SocketConfig
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: org.apache.hc.core5.http.config.SocketConfig.Builder
newFullyQualifiedTypeName: org.apache.hc.core5.http.io.SocketConfig.Builder

- org.openrewrite.java.ChangePackage:
oldPackageName: org.apache.http.impl
Expand Down Expand Up @@ -396,3 +403,12 @@ recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: org.apache.hc.core5.http.HttpConnectionFactory
newFullyQualifiedTypeName: org.apache.hc.core5.http.io.HttpConnectionFactory
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_DeprecatedMethods
displayName: Migrate to ApacheHttpClient 5.x deprecated methods from 4.x
description: Migrates deprecated methods to their equivalent ones in 5.x
recipeList:
- org.openrewrite.java.ChangeMethodName:
methodPattern: org.apache.hc.client5.http.config.RequestConfig.Builder setSocketTimeout(int)
newMethodName: setResponseTimeout
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,70 @@ void method(HttpEntity entity, String urlStr) throws Exception {
""")
);
}

@Test
void useTimeoutClass() {
rewriteRun(
//language=java
java("""
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.SocketConfig;
class A {
void method() {
RequestConfig.custom()
.setConnectionRequestTimeout(300)
.setConnectTimeout(500)
.setSocketTimeout(1500);
SocketConfig.custom()
.setSoTimeout(1000);
}
}
""", """
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.util.Timeout;
class A {
void method() {
RequestConfig.custom()
.setConnectionRequestTimeout(Timeout.ofMilliseconds(300))
.setConnectTimeout(Timeout.ofMilliseconds(500))
.setResponseTimeout(Timeout.ofMilliseconds(1500));
SocketConfig.custom()
.setSoTimeout(Timeout.ofMilliseconds(1000));
}
}
""")
);
}

@Test
void useTimeValueClass() {
rewriteRun(
//language=java
java("""
import org.apache.http.config.SocketConfig;
class A {
void method() {
SocketConfig.custom()
.setSoLinger(500);
}
}
""", """
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.util.TimeValue;
class A {
void method() {
SocketConfig.custom()
.setSoLinger(TimeValue.ofMilliseconds(500));
}
}
""")
);
}
}

0 comments on commit e95a680

Please sign in to comment.