-
Notifications
You must be signed in to change notification settings - Fork 46
Implement GET API of ip2geo datasource #279
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.geospatial.ip2geo.action; | ||
|
||
import org.opensearch.action.ActionType; | ||
|
||
/** | ||
* Ip2Geo datasource get action | ||
*/ | ||
public class GetDatasourceAction extends ActionType<GetDatasourceResponse> { | ||
/** | ||
* Get datasource action instance | ||
*/ | ||
public static final GetDatasourceAction INSTANCE = new GetDatasourceAction(); | ||
/** | ||
* Name of a get datasource action | ||
*/ | ||
public static final String NAME = "cluster:admin/geospatial/datasource/get"; | ||
|
||
private GetDatasourceAction() { | ||
super(NAME, GetDatasourceResponse::new); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.geospatial.ip2geo.action; | ||
|
||
import java.io.IOException; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import org.opensearch.OpenSearchException; | ||
import org.opensearch.action.ActionRequest; | ||
import org.opensearch.action.ActionRequestValidationException; | ||
import org.opensearch.common.io.stream.StreamInput; | ||
import org.opensearch.common.io.stream.StreamOutput; | ||
|
||
/** | ||
* Ip2Geo datasource get request | ||
*/ | ||
@Getter | ||
@Setter | ||
public class GetDatasourceRequest extends ActionRequest { | ||
/** | ||
* @param names the datasource names | ||
* @return the datasource names | ||
*/ | ||
private String[] names; | ||
|
||
/** | ||
* Constructs a new get datasource request with a list of datasources. | ||
* | ||
* If the list of datasources is empty or it contains a single element "_all", all registered datasources | ||
* are returned. | ||
* | ||
* @param names list of datasource names | ||
*/ | ||
public GetDatasourceRequest(final String[] names) { | ||
this.names = names; | ||
} | ||
|
||
/** | ||
* Constructor with stream input | ||
* @param in the stream input | ||
* @throws IOException IOException | ||
*/ | ||
public GetDatasourceRequest(final StreamInput in) throws IOException { | ||
super(in); | ||
this.names = in.readStringArray(); | ||
} | ||
|
||
@Override | ||
public ActionRequestValidationException validate() { | ||
if (names == null) { | ||
throw new OpenSearchException("names should not be null"); | ||
} | ||
return null; | ||
navneet1v marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
public void writeTo(final StreamOutput out) throws IOException { | ||
super.writeTo(out); | ||
out.writeStringArray(names); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.geospatial.ip2geo.action; | ||
|
||
import java.io.IOException; | ||
import java.time.Instant; | ||
import java.util.List; | ||
|
||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import org.opensearch.action.ActionResponse; | ||
import org.opensearch.common.io.stream.StreamInput; | ||
import org.opensearch.common.io.stream.StreamOutput; | ||
import org.opensearch.core.ParseField; | ||
import org.opensearch.core.xcontent.ToXContentObject; | ||
import org.opensearch.core.xcontent.XContentBuilder; | ||
import org.opensearch.geospatial.ip2geo.jobscheduler.Datasource; | ||
|
||
/** | ||
* Ip2Geo datasource get request | ||
*/ | ||
@Getter | ||
@Setter | ||
@EqualsAndHashCode | ||
public class GetDatasourceResponse extends ActionResponse implements ToXContentObject { | ||
private static final ParseField FIELD_NAME_DATASOURCES = new ParseField("datasources"); | ||
private static final ParseField FIELD_NAME_NAME = new ParseField("name"); | ||
private static final ParseField FIELD_NAME_STATE = new ParseField("state"); | ||
private static final ParseField FIELD_NAME_ENDPOINT = new ParseField("endpoint"); | ||
private static final ParseField FIELD_NAME_UPDATE_INTERVAL = new ParseField("update_interval_in_days"); | ||
private static final ParseField FIELD_NAME_NEXT_UPDATE_AT = new ParseField("next_update_at_in_epoch_millis"); | ||
private static final ParseField FIELD_NAME_NEXT_UPDATE_AT_READABLE = new ParseField("next_update_at"); | ||
private static final ParseField FIELD_NAME_DATABASE = new ParseField("database"); | ||
private static final ParseField FIELD_NAME_UPDATE_STATS = new ParseField("update_stats"); | ||
private List<Datasource> datasources; | ||
|
||
/** | ||
* Default constructor | ||
* | ||
* @param datasources List of datasources | ||
*/ | ||
public GetDatasourceResponse(final List<Datasource> datasources) { | ||
heemin32 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.datasources = datasources; | ||
} | ||
|
||
/** | ||
* Constructor with StreamInput | ||
* | ||
* @param in the stream input | ||
*/ | ||
public GetDatasourceResponse(final StreamInput in) throws IOException { | ||
datasources = in.readList(Datasource::new); | ||
heemin32 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
public void writeTo(final StreamOutput out) throws IOException { | ||
out.writeList(datasources); | ||
navneet1v marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { | ||
builder.startObject(); | ||
builder.startArray(FIELD_NAME_DATASOURCES.getPreferredName()); | ||
for (Datasource datasource : datasources) { | ||
builder.startObject(); | ||
builder.field(FIELD_NAME_NAME.getPreferredName(), datasource.getName()); | ||
builder.field(FIELD_NAME_STATE.getPreferredName(), datasource.getState()); | ||
builder.field(FIELD_NAME_ENDPOINT.getPreferredName(), datasource.getEndpoint()); | ||
builder.field(FIELD_NAME_UPDATE_INTERVAL.getPreferredName(), datasource.getSchedule().getInterval()); | ||
builder.timeField( | ||
FIELD_NAME_NEXT_UPDATE_AT.getPreferredName(), | ||
FIELD_NAME_NEXT_UPDATE_AT_READABLE.getPreferredName(), | ||
datasource.getSchedule().getNextExecutionTime(Instant.now()).toEpochMilli() | ||
); | ||
builder.field(FIELD_NAME_DATABASE.getPreferredName(), datasource.getDatabase()); | ||
builder.field(FIELD_NAME_UPDATE_STATS.getPreferredName(), datasource.getUpdateStats()); | ||
builder.endObject(); | ||
} | ||
builder.endArray(); | ||
builder.endObject(); | ||
return builder; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.geospatial.ip2geo.action; | ||
|
||
import java.util.List; | ||
|
||
import org.opensearch.OpenSearchException; | ||
import org.opensearch.action.ActionListener; | ||
import org.opensearch.action.support.ActionFilters; | ||
import org.opensearch.action.support.HandledTransportAction; | ||
import org.opensearch.common.inject.Inject; | ||
import org.opensearch.geospatial.ip2geo.common.DatasourceFacade; | ||
import org.opensearch.geospatial.ip2geo.jobscheduler.Datasource; | ||
import org.opensearch.tasks.Task; | ||
import org.opensearch.transport.TransportService; | ||
|
||
/** | ||
* Transport action to get datasource | ||
*/ | ||
public class GetDatasourceTransportAction extends HandledTransportAction<GetDatasourceRequest, GetDatasourceResponse> { | ||
private final DatasourceFacade datasourceFacade; | ||
|
||
/** | ||
* Default constructor | ||
* @param transportService the transport service | ||
* @param actionFilters the action filters | ||
* @param datasourceFacade the datasource facade | ||
*/ | ||
@Inject | ||
public GetDatasourceTransportAction( | ||
final TransportService transportService, | ||
final ActionFilters actionFilters, | ||
final DatasourceFacade datasourceFacade | ||
) { | ||
super(GetDatasourceAction.NAME, transportService, actionFilters, GetDatasourceRequest::new); | ||
this.datasourceFacade = datasourceFacade; | ||
} | ||
|
||
@Override | ||
protected void doExecute(final Task task, final GetDatasourceRequest request, final ActionListener<GetDatasourceResponse> listener) { | ||
if (shouldGetAllDatasource(request)) { | ||
// We don't expect too many data sources. Therefore, querying all data sources without pagination should be fine. | ||
datasourceFacade.getAllDatasources(newActionListener(listener)); | ||
} else { | ||
datasourceFacade.getDatasources(request.getNames(), newActionListener(listener)); | ||
} | ||
} | ||
|
||
private boolean shouldGetAllDatasource(final GetDatasourceRequest request) { | ||
if (request.getNames() == null) { | ||
throw new OpenSearchException("names in a request should not be null"); | ||
} | ||
|
||
return request.getNames().length == 0 || (request.getNames().length == 1 && "_all".equals(request.getNames()[0])); | ||
} | ||
|
||
private ActionListener<List<Datasource>> newActionListener(final ActionListener<GetDatasourceResponse> listener) { | ||
return new ActionListener<>() { | ||
@Override | ||
public void onResponse(final List<Datasource> datasources) { | ||
listener.onResponse(new GetDatasourceResponse(datasources)); | ||
} | ||
|
||
@Override | ||
public void onFailure(final Exception e) { | ||
listener.onFailure(e); | ||
} | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.geospatial.ip2geo.action; | ||
|
||
import static org.opensearch.geospatial.shared.URLBuilder.URL_DELIMITER; | ||
import static org.opensearch.geospatial.shared.URLBuilder.getPluginURLPrefix; | ||
import static org.opensearch.rest.RestRequest.Method.GET; | ||
|
||
import java.util.List; | ||
|
||
import org.opensearch.client.node.NodeClient; | ||
import org.opensearch.common.Strings; | ||
import org.opensearch.rest.BaseRestHandler; | ||
import org.opensearch.rest.RestRequest; | ||
import org.opensearch.rest.action.RestToXContentListener; | ||
|
||
/** | ||
* Rest handler for Ip2Geo datasource get request | ||
*/ | ||
public class RestGetDatasourceHandler extends BaseRestHandler { | ||
private static final String ACTION_NAME = "ip2geo_datasource_get"; | ||
|
||
@Override | ||
public String getName() { | ||
return ACTION_NAME; | ||
} | ||
|
||
@Override | ||
protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) { | ||
final String[] names = request.paramAsStringArray("name", Strings.EMPTY_ARRAY); | ||
final GetDatasourceRequest getDatasourceRequest = new GetDatasourceRequest(names); | ||
|
||
return channel -> client.executeLocally(GetDatasourceAction.INSTANCE, getDatasourceRequest, new RestToXContentListener<>(channel)); | ||
} | ||
|
||
@Override | ||
public List<Route> routes() { | ||
return List.of( | ||
new Route(GET, String.join(URL_DELIMITER, getPluginURLPrefix(), "ip2geo/datasource")), | ||
new Route(GET, String.join(URL_DELIMITER, getPluginURLPrefix(), "ip2geo/datasource/{name}")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't support regex. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are changing from id to name in get. I assume you are validating that data source name should be unique There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This naming is just for labeling. Still it is used as doc id internally. |
||
); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.