From a50fa64a9c30f7cfa3dd34b7649e73e42e2f39ee Mon Sep 17 00:00:00 2001 From: Soner Koksal Date: Thu, 11 Jul 2019 16:14:20 +0300 Subject: [PATCH] CAMEL-13747: Added basic auth support to camel-solr --- .../src/main/docs/solr-component.adoc | 4 +- .../camel/component/solr/SolrEndpoint.java | 26 ++++++++++ .../camel/component/solr/SolrProducer.java | 47 ++++++++++++++----- .../component/solr/InitSolrEndpointTest.java | 3 +- .../solr/SolrComponentTestSupport.java | 5 +- .../camel/component/solr/SolrFixtures.java | 26 +++++----- .../src/test/resources/solr/security.json | 13 +++++ 7 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 components/camel-solr/src/test/resources/solr/security.json diff --git a/components/camel-solr/src/main/docs/solr-component.adoc b/components/camel-solr/src/main/docs/solr-component.adoc index 1d439fc7248de..9d2c7ce6841fd 100644 --- a/components/camel-solr/src/main/docs/solr-component.adoc +++ b/components/camel-solr/src/main/docs/solr-component.adoc @@ -66,7 +66,7 @@ with the following path and query parameters: |=== -==== Query Parameters (15 parameters): +==== Query Parameters (17 parameters): [width="100%",cols="2,5,^1,2",options="header"] @@ -85,6 +85,8 @@ with the following path and query parameters: | *streamingThreadCount* (producer) | Set the number of threads for the StreamingUpdateSolrServer | 2 | int | *basicPropertyBinding* (advanced) | Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean | *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean +| *password* (security) | Sets password for basic auth plugin enabled servers | | String +| *username* (security) | Sets username for basic auth plugin enabled servers | | String | *collection* (solrCloud) | Set the collection name which the solrCloud server could use | | String | *zkHost* (solrCloud) | Set the ZooKeeper host information which the solrCloud could use, such as zkhost=localhost:8123. | | String |=== diff --git a/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrEndpoint.java b/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrEndpoint.java index 525bf67b68613..26cd2a4f0a982 100644 --- a/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrEndpoint.java +++ b/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrEndpoint.java @@ -67,6 +67,10 @@ public class SolrEndpoint extends DefaultEndpoint { private String collection; @UriParam private String requestHandler; + @UriParam(label = "security", secret = true) + private String username; + @UriParam(label = "security", secret = true) + private String password; public SolrEndpoint(String endpointUri, SolrComponent component, String address) throws Exception { super(endpointUri, component); @@ -273,4 +277,26 @@ public void setAllowCompression(Boolean allowCompression) { this.allowCompression = allowCompression; } + public String getUsername() { + return username; + } + + /** + * Sets username for basic auth plugin enabled servers + */ + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + /** + * Sets password for basic auth plugin enabled servers + */ + public void setPassword(String password) { + this.password = password; + } + } diff --git a/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrProducer.java b/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrProducer.java index 6ca4450254ebb..924e274358fd4 100644 --- a/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrProducer.java +++ b/components/camel-solr/src/main/java/org/apache/camel/component/solr/SolrProducer.java @@ -20,7 +20,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; - +import java.util.stream.Collectors; import javax.activation.MimetypesFileTypeMap; import org.apache.camel.Exchange; @@ -28,6 +28,7 @@ import org.apache.camel.support.DefaultProducer; import org.apache.camel.util.ObjectHelper; import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION; import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest; import org.apache.solr.client.solrj.request.DirectXmlRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -76,19 +77,34 @@ public void process(Exchange exchange) throws Exception { } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_INSERT_STREAMING)) { insert(exchange, serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_DELETE_BY_ID)) { - serverToUse.deleteById(exchange.getIn().getBody(String.class)); + UpdateRequest updateRequest = createUpdateRequest(); + updateRequest.deleteById(exchange.getIn().getBody(String.class)); + updateRequest.process(serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_DELETE_BY_QUERY)) { - serverToUse.deleteByQuery(exchange.getIn().getBody(String.class)); + UpdateRequest updateRequest = createUpdateRequest(); + updateRequest.deleteByQuery(exchange.getIn().getBody(String.class)); + updateRequest.process(serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_ADD_BEAN)) { - serverToUse.addBean(exchange.getIn().getBody()); + UpdateRequest updateRequest = createUpdateRequest(); + updateRequest.add(serverToUse.getBinder().toSolrInputDocument(exchange.getIn().getBody())); + updateRequest.process(serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_ADD_BEANS)) { - serverToUse.addBeans(exchange.getIn().getBody(Collection.class)); + UpdateRequest updateRequest = createUpdateRequest(); + Collection body = exchange.getIn().getBody(Collection.class); + updateRequest.add(body.stream().map(serverToUse.getBinder()::toSolrInputDocument).collect(Collectors.toList())); + updateRequest.process(serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_COMMIT)) { - serverToUse.commit(); + UpdateRequest updateRequest = createUpdateRequest(); + updateRequest.setAction(ACTION.COMMIT, true, true); + updateRequest.process(serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_ROLLBACK)) { - serverToUse.rollback(); + UpdateRequest updateRequest = createUpdateRequest(); + updateRequest.rollback(); + updateRequest.process(serverToUse); } else if (operation.equalsIgnoreCase(SolrConstants.OPERATION_OPTIMIZE)) { - serverToUse.optimize(); + UpdateRequest updateRequest = createUpdateRequest(); + updateRequest.setAction(ACTION.OPTIMIZE, true, true, 1); + updateRequest.process(serverToUse); } else { throw new IllegalArgumentException( SolrConstants.OPERATION + " header value '" + operation + "' is not supported"); @@ -105,6 +121,7 @@ private void insert(Exchange exchange, SolrClient solrServer) throws Exception { if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class))) { String mimeType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class); ContentStreamUpdateRequest updateRequest = new ContentStreamUpdateRequest(getRequestHandler()); + updateRequest.setBasicAuthCredentials(getEndpoint().getUsername(), getEndpoint().getPassword()); updateRequest.addFile((File) body, mimeType); for (Map.Entry entry : exchange.getIn().getHeaders().entrySet()) { @@ -121,6 +138,7 @@ private void insert(Exchange exchange, SolrClient solrServer) throws Exception { MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap(); String mimeType = mimeTypesMap.getContentType((File) body); ContentStreamUpdateRequest updateRequest = new ContentStreamUpdateRequest(getRequestHandler()); + updateRequest.setBasicAuthCredentials(getEndpoint().getUsername(), getEndpoint().getPassword()); updateRequest.addFile((File) body, mimeType); for (Map.Entry entry : exchange.getIn().getHeaders().entrySet()) { @@ -134,7 +152,7 @@ private void insert(Exchange exchange, SolrClient solrServer) throws Exception { } else if (body instanceof SolrInputDocument) { - UpdateRequest updateRequest = new UpdateRequest(getRequestHandler()); + UpdateRequest updateRequest = createUpdateRequest(); updateRequest.add((SolrInputDocument) body); for (Map.Entry entry : exchange.getIn().getHeaders().entrySet()) { @@ -150,7 +168,7 @@ private void insert(Exchange exchange, SolrClient solrServer) throws Exception { List list = (List) body; if (list.size() > 0 && list.get(0) instanceof SolrInputDocument) { - UpdateRequest updateRequest = new UpdateRequest(getRequestHandler()); + UpdateRequest updateRequest = createUpdateRequest(); updateRequest.add((List) list); for (Map.Entry entry : exchange.getIn().getHeaders().entrySet()) { @@ -177,7 +195,7 @@ private void insert(Exchange exchange, SolrClient solrServer) throws Exception { if (hasSolrHeaders) { - UpdateRequest updateRequest = new UpdateRequest(getRequestHandler()); + UpdateRequest updateRequest = createUpdateRequest(); SolrInputDocument doc = new SolrInputDocument(); for (Map.Entry entry : exchange.getIn().getHeaders().entrySet()) { @@ -198,6 +216,7 @@ private void insert(Exchange exchange, SolrClient solrServer) throws Exception { } DirectXmlRequest xmlRequest = new DirectXmlRequest(getRequestHandler(), bodyAsString); + xmlRequest.setBasicAuthCredentials(getEndpoint().getUsername(), getEndpoint().getPassword()); solrServer.request(xmlRequest); } else { @@ -217,6 +236,12 @@ private String getRequestHandler() { return (requestHandler == null) ? "/update" : requestHandler; } + private UpdateRequest createUpdateRequest() { + UpdateRequest updateRequest = new UpdateRequest(getRequestHandler()); + updateRequest.setBasicAuthCredentials(getEndpoint().getUsername(), getEndpoint().getPassword()); + return updateRequest; + } + @Override public SolrEndpoint getEndpoint() { return (SolrEndpoint) super.getEndpoint(); diff --git a/components/camel-solr/src/test/java/org/apache/camel/component/solr/InitSolrEndpointTest.java b/components/camel-solr/src/test/java/org/apache/camel/component/solr/InitSolrEndpointTest.java index fbf3cf6d2b3ec..d7d01dce25dd5 100644 --- a/components/camel-solr/src/test/java/org/apache/camel/component/solr/InitSolrEndpointTest.java +++ b/components/camel-solr/src/test/java/org/apache/camel/component/solr/InitSolrEndpointTest.java @@ -49,6 +49,7 @@ private String getFullOptions() { + "&maxRetries=1&soTimeout=100&connectionTimeout=100" + "&defaultMaxConnectionsPerHost=100&maxTotalConnections=100" + "&followRedirects=false&allowCompression=true" - + "&requestHandler=/update"; + + "&requestHandler=/update" + + "&username=solr&password=SolrRocks"; } } diff --git a/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrComponentTestSupport.java b/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrComponentTestSupport.java index 8d4d7f80da364..7bde7622a869d 100644 --- a/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrComponentTestSupport.java +++ b/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrComponentTestSupport.java @@ -26,6 +26,7 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.response.QueryResponse; import org.junit.AfterClass; import org.junit.Before; @@ -71,8 +72,10 @@ protected void solrCommit() { protected QueryResponse executeSolrQuery(String query) throws SolrServerException, IOException { SolrQuery solrQuery = new SolrQuery(); solrQuery.setQuery(query); + QueryRequest queryRequest = new QueryRequest(solrQuery); + queryRequest.setBasicAuthCredentials("solr", "SolrRocks"); SolrClient solrServer = solrFixtures.getServer(); - return solrServer.query("collection1", solrQuery); + return queryRequest.process(solrServer, "collection1"); } @BeforeClass diff --git a/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrFixtures.java b/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrFixtures.java index 6a6323e574bc1..9c671fa6b1cbe 100644 --- a/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrFixtures.java +++ b/components/camel-solr/src/test/java/org/apache/camel/component/solr/SolrFixtures.java @@ -23,8 +23,9 @@ import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrClient; - - +import org.apache.solr.client.solrj.request.AbstractUpdateRequest; +import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION; +import org.apache.solr.client.solrj.request.UpdateRequest; public class SolrFixtures { static Logger log = Logger.getLogger(SolrFixtures.class); @@ -50,13 +51,15 @@ public enum TestServerType { String solrRouteUri() { if (serverType == TestServerType.USE_HTTPS) { - return "solrs://127.0.0.1:" + httpsPort + "/solr/collection1"; + return "solrs://127.0.0.1:" + httpsPort + "/solr/collection1" + + "?username=solr&password=SolrRocks"; } else if (serverType == TestServerType.USE_CLOUD) { String zkAddrStr = cloudFixture.miniCluster.getZkServer().getZkAddress(); return "solrCloud://localhost:" + httpsPort + "/solr?zkHost=" + zkAddrStr - + "&collection=collection1"; + + "&collection=collection1&username=solr&password=SolrRocks"; } else { - return "solr://localhost:" + port + "/solr/collection1"; + return "solr://localhost:" + port + "/solr/collection1" + + "?username=solr&password=SolrRocks"; } } @@ -99,18 +102,19 @@ public static void teardownSolrFixtures() throws Exception { } public static void clearIndex() throws SolrServerException, IOException { + UpdateRequest updateRequest = new UpdateRequest(); + updateRequest.setBasicAuthCredentials("solr", "SolrRocks"); + updateRequest.deleteByQuery("*:*"); + updateRequest.setAction(ACTION.COMMIT, true, true); if (solrServer != null) { // Clear the Solr index. - solrServer.deleteByQuery("collection1", "*:*"); - solrServer.commit("collection1"); + updateRequest.process(solrServer, "collection1"); } if (solrHttpsServer != null) { - solrHttpsServer.deleteByQuery("collection1", "*:*"); - solrHttpsServer.commit("collection1"); + updateRequest.process(solrHttpsServer, "collection1"); } if (cloudFixture != null) { - cloudFixture.solrClient.deleteByQuery("*:*"); - cloudFixture.solrClient.commit(); + updateRequest.process(cloudFixture.solrClient); } } } diff --git a/components/camel-solr/src/test/resources/solr/security.json b/components/camel-solr/src/test/resources/solr/security.json new file mode 100644 index 0000000000000..bfaa8e1651fa8 --- /dev/null +++ b/components/camel-solr/src/test/resources/solr/security.json @@ -0,0 +1,13 @@ +{ + "authentication":{ + "blockUnknown": false, + "class":"solr.BasicAuthPlugin", + "credentials":{"solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}, + "realm":"My Solr users" + }, + "authorization":{ + "class":"solr.RuleBasedAuthorizationPlugin", + "permissions":[{"name":"security-edit", + "role":"admin"}], + "user-role":{"solr":"admin"} + }} \ No newline at end of file