Skip to content

Commit

Permalink
[#768] feat(cli): Cli method for blacklist update (#931)
Browse files Browse the repository at this point in the history
### What changes were proposed in this pull request?

 I created a command called uniffle cli to update blacklist, the following is the case of using the command.
```
Usage:
   Optional
     -a,--admin <arg>   This is an admin command that will print args.
     -c,--cli <arg>     This is an client cli command that will print args.
     -h,--help          Help for the Uniffle CLI.
     -rc,--refreshChecker    This is an admin command that will refresh access checker..
     -cc,--checkerClass <arg>     This is an client cli command that will print args.
     -s,--help <arg>          This is coordinator server host.
     -p,--port <arg>          This is coordinator server port.
```
> Run the example-cli command

uniffle admin-cli -rc -cc org.apache.uniffle.test.AccessClusterTest$MockedAccessChecker -s localhost -p 12345

### Why are the changes needed?

We use refreshChecker cli to update blacklist.

### Does this PR introduce _any_ user-facing change?

No.

### How was this patch tested?

Unit test verification.
  • Loading branch information
beryllw committed Jun 19, 2023
1 parent 0c3d60f commit f9369ab
Show file tree
Hide file tree
Showing 20 changed files with 870 additions and 2 deletions.
2 changes: 1 addition & 1 deletion bin/uniffle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function uniffle_cmd_case
UNIFFLE_CLASSNAME=org.apache.uniffle.cli.UniffleCLI
;;
admin-cli)
UNIFFLE_CLASSNAME=org.apache.uniffle.cli.UniffleCLI
UNIFFLE_CLASSNAME=org.apache.uniffle.cli.UniffleAdminCLI
;;
*)
UNIFFLE_CLASSNAME="${subcmd}"
Expand Down
8 changes: 8 additions & 0 deletions cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,13 @@
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<dependency>
<groupId>org.apache.uniffle</groupId>
<artifactId>rss-internal-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
</project>
44 changes: 44 additions & 0 deletions cli/src/main/java/org/apache/uniffle/api/AdminRestApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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 org.apache.uniffle.api;

import java.util.HashMap;
import java.util.Map;

import org.apache.uniffle.client.RestClient;
import org.apache.uniffle.client.UniffleRestClient;

public class AdminRestApi {
private UniffleRestClient client;

private AdminRestApi() {
}

public AdminRestApi(UniffleRestClient client) {
this.client = client;
}

public String refreshAccessChecker() {
Map<String, Object> params = new HashMap<>();
return this.getClient().get("/api/admin/refreshChecker", params, null);
}

private RestClient getClient() {
return this.client.getHttpClient();
}
}
129 changes: 129 additions & 0 deletions cli/src/main/java/org/apache/uniffle/cli/UniffleAdminCLI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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 org.apache.uniffle.cli;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.uniffle.AbstractCustomCommandLine;
import org.apache.uniffle.UniffleCliArgsException;
import org.apache.uniffle.api.AdminRestApi;
import org.apache.uniffle.client.UniffleRestClient;

public class UniffleAdminCLI extends AbstractCustomCommandLine {

private static final Logger LOG = LoggerFactory.getLogger(UniffleAdminCLI.class);

private final Options allOptions;
private final Option refreshCheckerCli;
private final Option coordinatorHost;
private final Option coordPort;
private final Option ssl;

private final Option help;
protected UniffleRestClient client;

public UniffleAdminCLI(String shortPrefix, String longPrefix) {
allOptions = new Options();
refreshCheckerCli = new Option(shortPrefix + "r", longPrefix + "refreshChecker",
false, "This is an admin command that will refresh access checker.");
help = new Option(shortPrefix + "h", longPrefix + "help",
false, "Help for the Uniffle Admin CLI.");
coordinatorHost = new Option(shortPrefix + "s", longPrefix + "coordinatorHost",
true, "This is coordinator server host.");
coordPort = new Option(shortPrefix + "p", longPrefix + "port",
true, "This is coordinator server port.");
ssl = new Option(null, longPrefix + "ssl", false, "use SSL");

allOptions.addOption(refreshCheckerCli);
allOptions.addOption(coordinatorHost);
allOptions.addOption(coordPort);
allOptions.addOption(ssl);
allOptions.addOption(help);
}

public UniffleAdminCLI(String shortPrefix, String longPrefix, UniffleRestClient client) {
this(shortPrefix, longPrefix);
this.client = client;
}

public int run(String[] args) throws UniffleCliArgsException {
final CommandLine cmd = parseCommandLineOptions(args, true);

if (cmd.hasOption(help.getOpt())) {
printUsage();
return 0;
}

if (cmd.hasOption(coordinatorHost.getOpt()) && cmd.hasOption(coordPort.getOpt())) {
String host = cmd.getOptionValue(coordinatorHost.getOpt()).trim();
int port = Integer.parseInt(cmd.getOptionValue(coordPort.getOpt()).trim());
String hostUrl;
if (cmd.hasOption(ssl.getOpt())) {
hostUrl = String.format("https://%s:%d", host, port);
} else {
hostUrl = String.format("http://%s:%d", host, port);
}
LOG.info("connected to coordinator: {}.", hostUrl);
client = UniffleRestClient.builder(hostUrl).build();
}

if (cmd.hasOption(refreshCheckerCli.getOpt())) {
LOG.info("uniffle-admin-cli : refresh coordinator access checker!");
refreshAccessChecker();
return 0;
}
return 1;
}

private String refreshAccessChecker() throws UniffleCliArgsException {
if (client == null) {
throw new UniffleCliArgsException("Missing Coordinator host address and grpc port parameters.");
}
AdminRestApi adminRestApi = new AdminRestApi(client);
return adminRestApi.refreshAccessChecker();
}

@Override
public void addRunOptions(Options baseOptions) {
baseOptions.addOption(refreshCheckerCli);
baseOptions.addOption(coordinatorHost);
baseOptions.addOption(coordPort);
}

@Override
public void addGeneralOptions(Options baseOptions) {
baseOptions.addOption(help);
}

public static void main(String[] args) {
int retCode;
try {
final UniffleAdminCLI cli = new UniffleAdminCLI("", "");
retCode = cli.run(args);
} catch (UniffleCliArgsException e) {
retCode = AbstractCustomCommandLine.handleCliArgsException(e, LOG);
} catch (Exception e) {
retCode = AbstractCustomCommandLine.handleError(e, LOG);
}
System.exit(retCode);
}
}
60 changes: 60 additions & 0 deletions cli/src/main/java/org/apache/uniffle/client/HttpClientFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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 org.apache.uniffle.client;

import javax.net.ssl.SSLContext;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.uniffle.client.exception.UniffleRestException;


public class HttpClientFactory {
private static final Logger LOG = LoggerFactory.getLogger(HttpClientFactory.class);

public static CloseableHttpClient createHttpClient(RestClientConf conf) {
RequestConfig requestConfig =
RequestConfig.custom()
.setSocketTimeout(conf.getSocketTimeout())
.setConnectTimeout(conf.getConnectTimeout())
.build();
SSLConnectionSocketFactory sslSocketFactory;
try {
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLContext sslContext =
SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
} catch (Exception e) {
LOG.error("Error: ", e);
throw new UniffleRestException("Failed to create HttpClient", e);
}

return HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setSSLSocketFactory(sslSocketFactory)
.build();
}
}
29 changes: 29 additions & 0 deletions cli/src/main/java/org/apache/uniffle/client/RestClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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 org.apache.uniffle.client;

import java.util.Map;

/**
* A underlying http client interface for common rest request.
*/
public interface RestClient extends AutoCloseable, Cloneable {

String get(String path, Map<String, Object> params, String authHeader);

}
57 changes: 57 additions & 0 deletions cli/src/main/java/org/apache/uniffle/client/RestClientConf.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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 org.apache.uniffle.client;

public class RestClientConf {
private int maxAttempts;
private int attemptWaitTime;
private int socketTimeout;
private int connectTimeout;

public int getMaxAttempts() {
return maxAttempts;
}

public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
}

public int getAttemptWaitTime() {
return attemptWaitTime;
}

public void setAttemptWaitTime(int attemptWaitTime) {
this.attemptWaitTime = attemptWaitTime;
}

public int getSocketTimeout() {
return socketTimeout;
}

public void setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
}

public int getConnectTimeout() {
return connectTimeout;
}

public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
}
Loading

0 comments on commit f9369ab

Please sign in to comment.