Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.solr.client.api.model;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
import java.util.List;
Expand All @@ -25,6 +27,20 @@
/** Response from /node/system */
public class NodeSystemResponse extends SolrJerseyResponse {

// TODO The typing here is kindof wonky - can I tighten 'Object' here to be NodeSystemResponse or
// will Jackson choke on that?
public Map<String, Object> remoteNodeData;

@JsonAnyGetter
public Map<String, Object> remoteNodeData() {
return remoteNodeData;
}

@JsonAnySetter
public void setRemoteNodeResponse(String field, Object value) {
remoteNodeData.put(field, value);
}

@JsonProperty public String host;
@JsonProperty public String node;
@JsonProperty public String mode;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.solr.core.CoreContainer;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.admin.api.NodeLogging;
import org.apache.solr.handler.admin.proxy.GenericV1RequestProxy;
import org.apache.solr.handler.api.V2ApiUtils;
import org.apache.solr.logging.LogWatcher;
import org.apache.solr.request.SolrQueryRequest;
Expand Down Expand Up @@ -91,9 +92,7 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw
}

rsp.setHttpCaching(false);
if (cc != null && AdminHandlersProxy.maybeProxyToNodes(req, rsp, cc)) {
return; // Request was proxied to other node
}
new GenericV1RequestProxy(cc, req, rsp).proxyRequest();
}

private void squashV2Response(SolrQueryResponse rsp, LoggingResponse response) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package org.apache.solr.handler.admin;

import static org.apache.solr.common.params.CommonParams.METRICS_PATH;

import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import java.util.ArrayList;
Expand All @@ -26,12 +28,17 @@
import java.util.SortedMap;
import java.util.function.BiConsumer;
import org.apache.solr.api.JerseyResource;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.response.InputStreamResponseParser;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.admin.api.GetMetrics;
import org.apache.solr.handler.admin.proxy.GenericV1RequestProxy;
import org.apache.solr.handler.admin.proxy.RemoteRequestProxy;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.otel.FilterablePrometheusMetricReader;
import org.apache.solr.request.SolrQueryRequest;
Expand Down Expand Up @@ -101,9 +108,12 @@ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throw
+ format);
}

if (cc != null && AdminHandlersProxy.maybeProxyToNodes(req, rsp, cc)) {
final var reqProxy = createMetricProxy(cc, req, rsp);
if (cc != null && reqProxy.shouldProxy()) {
reqProxy.proxyRequest();
return; // Request was proxied to other node
}

SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp));
try {
handleRequest(req.getParams(), (k, v) -> rsp.add(k, v));
Expand Down Expand Up @@ -143,6 +153,37 @@ public void handleRequest(SolrParams params, BiConsumer<String, Object> consumer
consumer.accept("metrics", mergedSnapshots);
}

public static RemoteRequestProxy createMetricProxy(
CoreContainer cc, SolrQueryRequest req, SolrQueryResponse rsp) {
return new GenericV1RequestProxy(cc, req, rsp) {

// Metric requests use 'node' to proxy rather than the generally accepted "nodes"
@Override
protected String getDestinationNodeParamName() {
return "node";
}

// Metrics requests require a particular ResponseParser
@Override
protected SolrRequest<?> createGenericRequest(String apiPath, SolrParams params) {
final var toProxy = super.createGenericRequest(apiPath, params);
// Metrics proxy might be called from either v1 or v2, but end up proxying to v1 for
// simplicity
toProxy.setPath(METRICS_PATH);
String wt = params.get(CommonParams.WT, MetricUtils.PROMETHEUS_METRICS_WT);
toProxy.setResponseParser(new InputStreamResponseParser(wt));

return toProxy;
}

// Metrics requests only proxy to single host, so proxied response is added at root level
@Override
public void processProxiedResponse(String nodeName, NamedList<Object> proxiedResponse) {
rsp.getValues().addAll(proxiedResponse);
}
};
}

@Override
public String getDescription() {
return "A handler to return all the metrics gathered by Solr";
Expand Down
Loading
Loading