-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #494 from microsoft/rsh/Url_replace_handler
Rsh/url replace handler
- Loading branch information
Showing
5 changed files
with
253 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
...ents/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/UrlReplaceHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package com.microsoft.kiota.http.middleware; | ||
|
||
import com.microsoft.kiota.http.middleware.options.UrlReplaceHandlerOption; | ||
import io.opentelemetry.api.trace.Span; | ||
import io.opentelemetry.context.Scope; | ||
import okhttp3.Interceptor; | ||
import okhttp3.Request; | ||
import okhttp3.Response; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.io.IOException; | ||
import java.io.UnsupportedEncodingException; | ||
import java.net.URLDecoder; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* A middleware to replace the url with the specified replacement pairs. | ||
*/ | ||
public class UrlReplaceHandler implements Interceptor { | ||
|
||
private UrlReplaceHandlerOption mUrlReplaceHandlerOption; | ||
|
||
/** | ||
* Instantiate a UrlReplaceHandler with default UrlReplaceHandlerOption. | ||
*/ | ||
public UrlReplaceHandler(){ | ||
this(new UrlReplaceHandlerOption()); | ||
} | ||
/** | ||
* Instantiate a UrlReplaceHandler with specified UrlReplaceHandlerOption | ||
* @param urlReplaceHandlerOption the specified UrlReplaceHandlerOption for the UrlReplaceHandler. | ||
*/ | ||
public UrlReplaceHandler(@Nonnull UrlReplaceHandlerOption urlReplaceHandlerOption){ | ||
Objects.requireNonNull(urlReplaceHandlerOption); | ||
this.mUrlReplaceHandlerOption = new UrlReplaceHandlerOption(urlReplaceHandlerOption.getReplacementPairs(), urlReplaceHandlerOption.isEnabled()); | ||
} | ||
/** {@inheritDoc} */ | ||
@Nonnull | ||
@Override | ||
public Response intercept(@Nonnull Chain chain) throws IOException { | ||
Objects.requireNonNull(chain, "parameter chain cannot be null"); | ||
Request request = Objects.requireNonNull(chain.request(), "request cannot be null"); | ||
UrlReplaceHandlerOption replaceOption = request.tag(UrlReplaceHandlerOption.class); | ||
replaceOption = replaceOption == null ? mUrlReplaceHandlerOption : replaceOption; | ||
if(!replaceOption.isEnabled() || replaceOption.getReplacementPairs().isEmpty()) { | ||
return chain.proceed(request); | ||
} | ||
|
||
final Span span = ObservabilityHelper.getSpanForRequest(request, "UrlReplaceHandler_Intercept"); | ||
Scope scope = null; | ||
if (span != null) { | ||
scope = span.makeCurrent(); | ||
span.setAttribute("com.microsoft.kiota.handler.urlreplace.enable", true); | ||
} | ||
try{ | ||
request = replaceRequestUrl(request, replaceOption.getReplacementPairs()); | ||
} finally { | ||
if (scope != null) { | ||
scope.close(); | ||
} | ||
if (span != null) { | ||
span.end(); | ||
} | ||
} | ||
return chain.proceed(request); | ||
} | ||
/** | ||
* Gets the UrlReplaceHandlerOption for the UrlReplaceHandler. | ||
* @return the UrlReplaceHandlerOption for the UrlReplaceHandler. | ||
*/ | ||
@Nonnull | ||
public UrlReplaceHandlerOption getUrlReplaceHandlerOption() { | ||
return new UrlReplaceHandlerOption(mUrlReplaceHandlerOption.getReplacementPairs(), mUrlReplaceHandlerOption.isEnabled()); | ||
} | ||
/** | ||
* Sets the UrlReplaceHandlerOption for the UrlReplaceHandler. | ||
* @param urlReplaceHandlerOption the UrlReplaceHandlerOption to set. | ||
*/ | ||
public void setUrlReplaceHandlerOption(@Nonnull UrlReplaceHandlerOption urlReplaceHandlerOption) { | ||
this.mUrlReplaceHandlerOption = new UrlReplaceHandlerOption(urlReplaceHandlerOption.getReplacementPairs(), urlReplaceHandlerOption.isEnabled()); | ||
} | ||
/** | ||
* Replaces the url of the request using the replacement pairs provided. | ||
* @param request the request to replace the url of. | ||
* @param replacementPairs the replacement pairs to use. | ||
* @return the request with the updated url. | ||
*/ | ||
@Nonnull | ||
public static Request replaceRequestUrl(@Nonnull Request request, @Nonnull Map<String, String> replacementPairs) { | ||
Request.Builder builder = request.newBuilder(); | ||
try { | ||
//Decoding the url since Request.url is encoded by default. | ||
String replacedUrl = URLDecoder.decode(request.url().toString(), "UTF-8");//Using decode(String,String) method to maintain source compatibility with Java 8 | ||
for (Map.Entry<String, String> entry : replacementPairs.entrySet()) { | ||
replacedUrl = replacedUrl.replace(entry.getKey(), entry.getValue()); | ||
} | ||
builder.url(replacedUrl); | ||
return builder.build(); | ||
|
||
} catch (UnsupportedEncodingException e) { | ||
return request; //This should never happen since "UTF-8" is a supported encoding. | ||
} | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
...tp/src/main/java/com/microsoft/kiota/http/middleware/options/UrlReplaceHandlerOption.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package com.microsoft.kiota.http.middleware.options; | ||
|
||
import com.microsoft.kiota.RequestOption; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* The options to be passed to the UrlReplaceHandler. | ||
* Defines the replacement pairs and whether the handler is enabled or not. | ||
*/ | ||
public class UrlReplaceHandlerOption implements RequestOption { | ||
|
||
private Map<String, String> replacementPairs; | ||
private boolean enabled; | ||
|
||
/** | ||
* Instantiates a new UrlReplaceOption with an empty replacementPairs map and enabled set to true. | ||
*/ | ||
public UrlReplaceHandlerOption() { | ||
this(new HashMap<>()); | ||
} | ||
/** | ||
* Instantiates a new UrlReplaceOption with the specified replacementPairs map and enabled set to true. | ||
* @param replacementPairs the replacement pairs map. | ||
*/ | ||
public UrlReplaceHandlerOption(@Nonnull Map<String, String> replacementPairs) { | ||
this(replacementPairs, true); | ||
} | ||
/** | ||
* Instantiates a new UrlReplaceOption with the specified replacementPairs map and enabled set to the specified value. | ||
* @param enabled whether the handler is enabled or not. | ||
* @param replacementPairs the replacement pairs map. | ||
*/ | ||
public UrlReplaceHandlerOption(@Nonnull Map<String, String> replacementPairs, boolean enabled) { | ||
Objects.requireNonNull(replacementPairs); | ||
this.replacementPairs = new HashMap<>(replacementPairs); | ||
this.enabled = enabled; | ||
} | ||
/** | ||
* Gets the replacement pairs map. | ||
* @return the replacement pairs map. | ||
*/ | ||
@Nonnull | ||
public Map<String, String> getReplacementPairs() { | ||
return new HashMap<>(replacementPairs); | ||
} | ||
/** | ||
* Sets the replacement pairs map. | ||
* @param replacementPairs the replacement pairs map. | ||
*/ | ||
public void setReplacementPairs(@Nonnull final Map<String, String> replacementPairs) { | ||
this.replacementPairs = new HashMap<>(replacementPairs); | ||
} | ||
/** | ||
* Enables the handler. | ||
*/ | ||
public void enable() { | ||
this.enabled = true; | ||
} | ||
/** | ||
* Disables the handler. | ||
*/ | ||
public void disable() { | ||
this.enabled = false; | ||
} | ||
/** | ||
* Gets whether the handler is enabled or not. | ||
* @return whether the handler is enabled or not. | ||
*/ | ||
public boolean isEnabled() { | ||
return enabled; | ||
} | ||
@Nonnull | ||
@SuppressWarnings("unchecked") | ||
@Override | ||
public <T extends RequestOption> Class<T> getType() { | ||
return (Class<T>) UrlReplaceHandlerOption.class; | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
components/http/okHttp/src/test/java/com/microsoft/kiota/http/UrlReplaceHandlerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.microsoft.kiota.http; | ||
|
||
import com.microsoft.kiota.http.middleware.UrlReplaceHandler; | ||
import com.microsoft.kiota.http.middleware.options.UrlReplaceHandlerOption; | ||
import okhttp3.Interceptor; | ||
import okhttp3.OkHttpClient; | ||
import okhttp3.Request; | ||
import okhttp3.Response; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.IOException; | ||
import java.util.HashMap; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
class UrlReplaceHandlerTest { | ||
|
||
private final static String defaultUsersWithTokenUrl = "https://graph.microsoft.com/v1.0/users/TokenToReplace"; | ||
private final static HashMap<String, String> defaultReplacementPairs = new HashMap<>(); | ||
|
||
@Test | ||
void testUrlReplaceHandler_no_replacementPairs() throws IOException { | ||
Interceptor[] interceptors = new Interceptor[]{new UrlReplaceHandler(new UrlReplaceHandlerOption())}; | ||
final OkHttpClient client = KiotaClientFactory.create(interceptors).build(); | ||
final Request request = new Request.Builder().url(defaultUsersWithTokenUrl).build(); | ||
final Response response = client.newCall(request).execute(); | ||
|
||
assertNotNull(response); | ||
assertEquals(defaultUsersWithTokenUrl, response.request().url().toString()); //url should remain the same without replacement pairs | ||
|
||
} | ||
@Test | ||
void testUrlReplaceHandler_default_url() throws IOException { | ||
defaultReplacementPairs.put("/users/TokenToReplace", "/me"); | ||
Interceptor[] interceptors = new Interceptor[]{new UrlReplaceHandler(new UrlReplaceHandlerOption(defaultReplacementPairs))}; | ||
final OkHttpClient client = KiotaClientFactory.create(interceptors).build(); | ||
final Request request = new Request.Builder().url(defaultUsersWithTokenUrl).build(); | ||
final Response response = client.newCall(request).execute(); | ||
final String expectedNewUrl = "https://graph.microsoft.com/v1.0/me"; | ||
|
||
assertNotNull(response); | ||
assertEquals(expectedNewUrl, response.request().url().toString()); | ||
} | ||
@Test | ||
void testUrlReplaceHandler_multiple_pairs() throws IOException { | ||
defaultReplacementPairs.put("/users/TokenToReplace", "/me"); | ||
defaultReplacementPairs.put("{secondToken}", "expectedValue"); | ||
String customUrl = "https://graph.microsoft.com/beta/users/TokenToReplace/{secondToken}"; //using special characters to test decoding. | ||
Interceptor[] interceptors = new Interceptor[]{new UrlReplaceHandler(new UrlReplaceHandlerOption(defaultReplacementPairs))}; | ||
final OkHttpClient client = KiotaClientFactory.create(interceptors).build(); | ||
final Request request = new Request.Builder().url(customUrl).build(); | ||
final Response response = client.newCall(request).execute(); | ||
final String expectedNewUrl = "https://graph.microsoft.com/beta/me/expectedValue"; | ||
|
||
assertNotNull(response); | ||
assertEquals(expectedNewUrl, response.request().url().toString()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters