/** * Adds the date range values to the search template. * * <pre>{@code * - _date-start * - _date-end * * }</pre> * * If there is no 'start' and 'end' request parameter, then the current day is used. A day starts * at 00:00 and ends the next day at 00:00 * * @param request The request that has been done on the search node. * @param propertiesMap The map where the key-values should be added to. */ protected void addStartEnd(SlingHttpServletRequest request, Map<String, String> propertiesMap) { try { // Default is today Calendar cStart = getDayCalendar(); Calendar cEnd = getDayCalendar(); cEnd.add(Calendar.DAY_OF_MONTH, 1); // If a parameter is specified, we try to parse it and use that one. RequestParameter startParam = request.getRequestParameter(START_DAY_PARAM); RequestParameter endParam = request.getRequestParameter(END_DAY_PARAM); if (startParam != null && endParam != null) { String start = startParam.getString("UTF-8"); String end = endParam.getString("UTF-8"); cStart.setTime(format.parse(start)); cEnd.setTime(format.parse(end)); } // Calculate the beginning and the end date. String beginning = DateUtils.iso8601jcr(cStart); String end = DateUtils.iso8601jcr(cEnd); // Add to map. propertiesMap.put("_date-start", ClientUtils.escapeQueryChars(beginning)); propertiesMap.put("_date-end", ClientUtils.escapeQueryChars(end)); } catch (UnsupportedEncodingException e) { LOGGER.error( "Caught an UnsupportedEncodingException when trying to provide properties for the calendar search templates.", e); } catch (ParseException e) { LOGGER.error( "Caught a ParseException when trying to provide properties for the calendar search templates.", e); } }
/** * Load properties from the query node, request and property provider.<br> * Overwrite order: query node < request < property provider<br> * This ordering allows the query node to set defaults, the request to override those defaults but * the property provider to have the final say in what value is set. * * @param request * @param propertyProviderName * @return * @throws RepositoryException */ private Map<String, String> loadProperties( SlingHttpServletRequest request, String propertyProviderName, Node node) throws RepositoryException { Map<String, String> propertiesMap = new HashMap<String, String>(); // 0. load authorizable (user) information String userId = request.getRemoteUser(); String userPrivatePath = ClientUtils.escapeQueryChars(LitePersonalUtils.getPrivatePath(userId)); propertiesMap.put("_userPrivatePath", userPrivatePath); propertiesMap.put("_userId", ClientUtils.escapeQueryChars(userId)); // 1. load in properties from the query template node so defaults can be set PropertyIterator props = node.getProperties(); while (props.hasNext()) { javax.jcr.Property prop = props.nextProperty(); if (!propertiesMap.containsKey(prop.getName()) && !prop.isMultiple()) { propertiesMap.put(prop.getName(), prop.getString()); } } // 2. load in properties from the request RequestParameterMap params = request.getRequestParameterMap(); for (Entry<String, RequestParameter[]> entry : params.entrySet()) { String key = entry.getKey(); RequestParameter[] vals = entry.getValue(); String requestValue = vals[0].getString(); // blank values aren't cool if (StringUtils.isBlank(requestValue)) { continue; } // KERN-1601 Wildcard searches have to be manually lowercased for case insensitive // matching as Solr bypasses the analyzer when dealing with a wildcard or fuzzy // search. if (StringUtils.contains(requestValue, '*') || StringUtils.contains(requestValue, '~')) { requestValue = requestValue.toLowerCase(); } // KERN-1703 Escape just : requestValue = StringUtils.replace(requestValue, ":", "\\:"); propertiesMap.put(entry.getKey(), requestValue); } // 3. load properties from a property provider if (propertyProviderName != null) { LOGGER.debug("Trying Provider Name {} ", propertyProviderName); SolrSearchPropertyProvider provider = propertyProvider.get(propertyProviderName); if (provider != null) { LOGGER.debug("Trying Provider {} ", provider); provider.loadUserProperties(request, propertiesMap); } else { LOGGER.warn("No properties provider found for {} ", propertyProviderName); } } else { LOGGER.debug("No Provider "); } return propertiesMap; }
private SolrQuery buildSolrQuery(HttpServletRequest req) { SolrQuery query = new SolrQuery(); query.setParam(CommonParams.WT, "json"); // $NON-NLS-1$ query.setParam(CommonParams.FL, FIELD_NAMES); String queryString = getEncodedParameter(req, CommonParams.Q); if (queryString == null) return null; if (queryString.length() > 0) { String processedQuery = ""; // $NON-NLS-1$ // divide into search terms delimited by space or plus ('+') character List<String> terms = new ArrayList<String>(Arrays.asList(queryString.split("[\\s\\+]+"))); // $NON-NLS-1$ while (!terms.isEmpty()) { String term = terms.remove(0); if (term.length() == 0) continue; if (isSearchField(term)) { if (term.startsWith("NameLower:")) { // $NON-NLS-1$ // solr does not lowercase queries containing wildcards // https://issues.apache.org/jira/browse/SOLR-219 processedQuery += "NameLower:" + term.substring(10).toLowerCase(); // $NON-NLS-1$ } else if (term.startsWith("Location:")) { // $NON-NLS-1${ // all other field searches are case sensitive processedQuery += "Location:" + term.substring(9 + req.getContextPath().length()); } else { // all other field searches are case sensitive processedQuery += term; } } else { // decode the term string now try { term = URLDecoder.decode(term, "UTF-8"); } catch (UnsupportedEncodingException e) { // try with encoded term } boolean isPhrase = term.charAt(0) == '"'; // solr does not lowercase queries containing wildcards // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=359766 String processedTerm = ClientUtils.escapeQueryChars(term.toLowerCase()); // add leading and trailing wildcards to match word segments if (!isPhrase) { if (processedTerm.charAt(0) != '*') processedTerm = '*' + processedTerm; if (processedTerm.charAt(processedTerm.length() - 1) != '*') processedTerm += '*'; } processedQuery += processedTerm; } processedQuery += " AND "; // $NON-NLS-1$ } queryString = processedQuery; } queryString += ProtocolConstants.KEY_USER_NAME + ':' + ClientUtils.escapeQueryChars(req.getRemoteUser()); query.setQuery(queryString); // other common fields setField(req, query, CommonParams.ROWS); setField(req, query, CommonParams.START); setField(req, query, CommonParams.SORT); return query; }
@Override public SolrFilterResult buildSolrQuery() { String format = dateProvider.format(date).replace("Z", ".000Z"); // Tweak to set the milliseconds return new SolrFilterResult( "item.lastmodified:[" + ClientUtils.escapeQueryChars(format) + " TO *]"); }
/** * Apply the 'search by role' filter to the lucene query string. * * @param parametersMap * @param filters */ protected void buildSearchByRoleQuery(Map<String, String> parametersMap, List<String> filters) { SearchableRole role = SearchableRole.valueOf(getSearchParam(parametersMap, REQUEST_PARAMETERS.role.toString())); String userid = getSearchParam(parametersMap, REQUEST_PARAMETERS.userid.toString()); AuthorizableManager authorizableManager = null; Session adminSession = null; try { adminSession = repository.loginAdministrative(); authorizableManager = adminSession.getAuthorizableManager(); Authorizable au = authorizableManager.findAuthorizable(userid); List<Authorizable> groups = AuthorizableUtil.getUserFacingGroups(au, authorizableManager); groups.add(au); List<String> groupStrs = new ArrayList<String>(groups.size()); for (Authorizable memberAuthz : groups) { groupStrs.add(ClientUtils.escapeQueryChars(memberAuthz.getId())); } filters.add(String.format(ROLE_TEMPLATE, role.toString(), JOINER_OR.join(groupStrs))); adminSession.logout(); } catch (ClientPoolException e) { throw new RuntimeException(e); } catch (StorageClientException e) { throw new RuntimeException(e); } catch (AccessDeniedException e) { throw new RuntimeException(e); } finally { SparseUtils.logoutQuietly(adminSession); } }
/** * Returns an array where the first value is the search string and the second is a display string. * * @param lsid * @return */ public String[] getTaxonSearch(String lsid) { String[] result = new String[0]; // use the name matching index try { if (nameIndex == null) { nameIndex = new ALANameSearcher(nameIndexLocation); } NameSearchResult nsr = nameIndex.searchForRecordByLsid(lsid); if (nsr != null) { String rank = nsr.getRank() != null ? nsr.getRank().toString() : "Unknown Rank"; String scientificName = nsr.getRankClassification() != null ? nsr.getRankClassification().getScientificName() : null; StringBuffer dispSB = new StringBuffer(rank + ": " + scientificName); StringBuilder sb = new StringBuilder("lft:["); String lft = nsr.getLeft() != null ? nsr.getLeft() : "0"; String rgt = nsr.getRight() != null ? nsr.getRight() : "0"; sb.append(lft).append(" TO ").append(rgt).append("]"); return new String[] {sb.toString(), dispSB.toString()}; } else { return new String[] { "taxon_concept_lsid:" + ClientUtils.escapeQueryChars(lsid), "taxon_concept_lsid:" + lsid }; } } catch (Exception e) { logger.error(e.getMessage(), e); } return result; }
@Override public Date read(String txt) { try { return ClientUtils.parseDate(txt); } catch (Exception ex) { ex.printStackTrace(); } return null; }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.api.solr.IndexingHandler#getDeleteQueries(org.sakaiproject.nakamura.api.solr.RepositorySession, * org.osgi.service.event.Event) */ public Collection<String> getDeleteQueries(RepositorySession repositorySession, Event event) { LOGGER.debug("GetDelete for {} ", event); String path = (String) event.getProperty("path"); boolean ignore = ignorePath(path); if (ignore) { return Collections.emptyList(); } else { return ImmutableList.of(FIELD_ID + ":" + ClientUtils.escapeQueryChars(path)); } }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.api.search.SearchPropertyProvider#loadUserProperties(org.apache.sling.api.SlingHttpServletRequest, * java.util.Map) */ public void loadUserProperties( SlingHttpServletRequest request, Map<String, String> propertiesMap) { String user = request.getRemoteUser(); String connectionPath = ClientUtils.escapeQueryChars(ConnectionUtils.getConnectionPathBase(user)); if (connectionPath.startsWith("/")) { connectionPath = connectionPath.substring(1); } propertiesMap.put(SEARCH_PROP_CONNECTIONSTORE, connectionPath); }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.api.solr.IndexingHandler#getDeleteQueries(org.sakaiproject.nakamura.api.solr.RepositorySession, * org.osgi.service.event.Event) */ @Override public Collection<String> getDeleteQueries(RepositorySession repoSession, Event event) { List<String> retval = Collections.emptyList(); LOGGER.debug("getDeleteQueries for {}", event); String path = (String) event.getProperty(IndexingHandler.FIELD_PATH); String resourceType = (String) event.getProperty("resourceType"); if (CONTENT_TYPES.contains(resourceType)) { retval = ImmutableList.of("id:" + ClientUtils.escapeQueryChars(path)); } return retval; }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.api.search.SearchPropertyProvider#loadUserProperties(org.apache.sling.api.SlingHttpServletRequest, * java.util.Map) */ public void loadUserProperties( SlingHttpServletRequest request, Map<String, String> propertiesMap) { String user = request.getRemoteUser(); Session session = StorageClientUtils.adaptToSession( request.getResourceResolver().adaptTo(javax.jcr.Session.class)); propertiesMap.put( MessageConstants.SEARCH_PROP_MESSAGESTORE, ClientUtils.escapeQueryChars(messagingService.getFullPathToStore(user, session)) + "*"); RequestParameter address = request.getRequestParameter("address"); if (address != null && !address.getString().equals("")) { // resolve the address by finding the authorizables. String addressString = address.getString(); String storePath = messagingService.getFullPathToStore(addressString, session); propertiesMap.put( MessageConstants.SEARCH_PROP_MESSAGESTORE, ClientUtils.escapeQueryChars(storePath) + "*"); } RequestParameter usersParam = request.getRequestParameter("_from"); if (usersParam != null && !usersParam.getString().equals("")) { String[] users = StringUtils.split(usersParam.getString(), ','); StringBuilder solrQuery = new StringBuilder(); // build solr query solrQuery.append("from:("); for (int i = 0; i < users.length; i++) { solrQuery.append('"').append(ClientUtils.escapeQueryChars(users[i])).append('"'); if (i < users.length - 1) { solrQuery.append(" OR "); } } solrQuery.append(")"); propertiesMap.put("_from", solrQuery.toString()); } }
/** * @param request * @param propertiesMap */ protected void addCalendarEventPath( SlingHttpServletRequest request, Map<String, String> propertiesMap) { try { RequestParameter eventParam = request.getRequestParameter("event-path"); if (eventParam != null) { String eventPath = eventParam.getString("UTF-8"); propertiesMap.put("_event-path", ClientUtils.escapeQueryChars(eventPath)); } } catch (UnsupportedEncodingException e) { LOGGER.error( "Caught an UnsupportedEncodingException when trying to provide properties for the calendar search templates.", e); } }
private String expandHomeDirectory(String queryString) { Matcher homePathMatcher = homePathPattern.matcher(queryString); if (homePathMatcher.find()) { String username = homePathMatcher.group(3); String homePrefix = homePathMatcher.group(1); String userHome = LitePersonalUtils.getHomePath(username); userHome = ClientUtils.escapeQueryChars(userHome); String homePath = homePrefix + userHome + "/"; String prefix = ""; if (homePathMatcher.start() > 0) { prefix = queryString.substring(0, homePathMatcher.start()); } String suffix = queryString.substring(homePathMatcher.end()); queryString = prefix + homePath + suffix; } return queryString; }
/** * @param request * @param propertiesMap */ protected void addCalendarPath( SlingHttpServletRequest request, Map<String, String> propertiesMap) { try { String user = request.getRemoteUser(); String path = LitePersonalUtils.getHomePath(user) + "/" + CalendarConstants.SAKAI_CALENDAR_NODENAME; RequestParameter pathParam = request.getRequestParameter(PATH_PARAM); if (pathParam != null) { path = pathParam.getString("UTF-8"); } propertiesMap.put("_calendar-path", ClientUtils.escapeQueryChars(path)); } catch (UnsupportedEncodingException e) { LOGGER.error( "Caught an UnsupportedEncodingException when trying to provide properties for the calendar search templates.", e); } }
@Override public void add(SearchDocument doc) throws IOException { SolrDocument document = ((SolrSearchDocument) doc).getDocument(); addOrUpdateList.add(ClientUtils.toSolrInputDocument(document)); }
public NamedList<Object> request(final SolrRequest request, final ResponseParser processor) throws SolrServerException, IOException { HttpRequestBase method = null; InputStream is = null; SolrParams params = request.getParams(); Collection<ContentStream> streams = requestWriter.getContentStreams(request); String path = requestWriter.getPath(request); if (path == null || !path.startsWith("/")) { path = DEFAULT_PATH; } ResponseParser parser = request.getResponseParser(); if (parser == null) { parser = this.parser; } // The parser 'wt=' and 'version=' params are used instead of the original // params ModifiableSolrParams wparams = new ModifiableSolrParams(params); if (parser != null) { wparams.set(CommonParams.WT, parser.getWriterType()); wparams.set(CommonParams.VERSION, parser.getVersion()); } if (invariantParams != null) { wparams.add(invariantParams); } int tries = maxRetries + 1; try { while (tries-- > 0) { // Note: since we aren't do intermittent time keeping // ourselves, the potential non-timeout latency could be as // much as tries-times (plus scheduling effects) the given // timeAllowed. try { if (SolrRequest.METHOD.GET == request.getMethod()) { if (streams != null) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "GET can't send streams!"); } method = new HttpGet(baseUrl + path + ClientUtils.toQueryString(wparams, false)); } else if (SolrRequest.METHOD.POST == request.getMethod()) { String url = baseUrl + path; boolean hasNullStreamName = false; if (streams != null) { for (ContentStream cs : streams) { if (cs.getName() == null) { hasNullStreamName = true; break; } } } boolean isMultipart = (this.useMultiPartPost || (streams != null && streams.size() > 1)) && !hasNullStreamName; // only send this list of params as query string params ModifiableSolrParams queryParams = new ModifiableSolrParams(); for (String param : this.queryParams) { String[] value = wparams.getParams(param); if (value != null) { for (String v : value) { queryParams.add(param, v); } wparams.remove(param); } } LinkedList<NameValuePair> postParams = new LinkedList<NameValuePair>(); if (streams == null || isMultipart) { HttpPost post = new HttpPost(url + ClientUtils.toQueryString(queryParams, false)); post.setHeader("Content-Charset", "UTF-8"); if (!isMultipart) { post.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); } List<FormBodyPart> parts = new LinkedList<FormBodyPart>(); Iterator<String> iter = wparams.getParameterNamesIterator(); while (iter.hasNext()) { String p = iter.next(); String[] vals = wparams.getParams(p); if (vals != null) { for (String v : vals) { if (isMultipart) { parts.add(new FormBodyPart(p, new StringBody(v, Charset.forName("UTF-8")))); } else { postParams.add(new BasicNameValuePair(p, v)); } } } } if (isMultipart && streams != null) { for (ContentStream content : streams) { String contentType = content.getContentType(); if (contentType == null) { contentType = BinaryResponseParser.BINARY_CONTENT_TYPE; // default } String name = content.getName(); if (name == null) { name = ""; } parts.add( new FormBodyPart( name, new InputStreamBody( content.getStream(), contentType, content.getName()))); } } if (parts.size() > 0) { MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT); for (FormBodyPart p : parts) { entity.addPart(p); } post.setEntity(entity); } else { // not using multipart post.setEntity(new UrlEncodedFormEntity(postParams, "UTF-8")); } method = post; } // It is has one stream, it is the post body, put the params in the URL else { String pstr = ClientUtils.toQueryString(wparams, false); HttpPost post = new HttpPost(url + pstr); // Single stream as body // Using a loop just to get the first one final ContentStream[] contentStream = new ContentStream[1]; for (ContentStream content : streams) { contentStream[0] = content; break; } if (contentStream[0] instanceof RequestWriter.LazyContentStream) { post.setEntity( new InputStreamEntity(contentStream[0].getStream(), -1) { @Override public Header getContentType() { return new BasicHeader("Content-Type", contentStream[0].getContentType()); } @Override public boolean isRepeatable() { return false; } }); } else { post.setEntity( new InputStreamEntity(contentStream[0].getStream(), -1) { @Override public Header getContentType() { return new BasicHeader("Content-Type", contentStream[0].getContentType()); } @Override public boolean isRepeatable() { return false; } }); } method = post; } } else { throw new SolrServerException("Unsupported method: " + request.getMethod()); } } catch (NoHttpResponseException r) { method = null; if (is != null) { is.close(); } // If out of tries then just rethrow (as normal error). if (tries < 1) { throw r; } } } } catch (IOException ex) { throw new SolrServerException("error reading streams", ex); } // XXX client already has this set, is this needed? method.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, followRedirects); method.addHeader("User-Agent", AGENT); InputStream respBody = null; boolean shouldClose = true; boolean success = false; try { // Execute the method. final HttpResponse response = httpClient.execute(method); int httpStatus = response.getStatusLine().getStatusCode(); // Read the contents respBody = response.getEntity().getContent(); Header ctHeader = response.getLastHeader("content-type"); String contentType; if (ctHeader != null) { contentType = ctHeader.getValue(); } else { contentType = ""; } // handle some http level checks before trying to parse the response switch (httpStatus) { case HttpStatus.SC_OK: case HttpStatus.SC_BAD_REQUEST: case HttpStatus.SC_CONFLICT: // 409 break; case HttpStatus.SC_MOVED_PERMANENTLY: case HttpStatus.SC_MOVED_TEMPORARILY: if (!followRedirects) { throw new SolrServerException( "Server at " + getBaseURL() + " sent back a redirect (" + httpStatus + ")."); } break; default: if (processor == null) { throw new RemoteSolrException( httpStatus, "Server at " + getBaseURL() + " returned non ok status:" + httpStatus + ", message:" + response.getStatusLine().getReasonPhrase(), null); } } if (processor == null) { // no processor specified, return raw stream NamedList<Object> rsp = new NamedList<Object>(); rsp.add("stream", respBody); // Only case where stream should not be closed shouldClose = false; success = true; return rsp; } String procCt = processor.getContentType(); if (procCt != null) { if (!contentType.equals(procCt)) { // unexpected content type String msg = "Expected content type " + procCt + " but got " + contentType + "."; Header encodingHeader = response.getEntity().getContentEncoding(); String encoding; if (encodingHeader != null) { encoding = encodingHeader.getValue(); } else { encoding = "UTF-8"; // try UTF-8 } try { msg = msg + " " + IOUtils.toString(respBody, encoding); } catch (IOException e) { throw new RemoteSolrException( httpStatus, "Could not parse response with encoding " + encoding, e); } RemoteSolrException e = new RemoteSolrException(httpStatus, msg, null); throw e; } } // if(true) { // ByteArrayOutputStream copy = new ByteArrayOutputStream(); // IOUtils.copy(respBody, copy); // String val = new String(copy.toByteArray()); // System.out.println(">RESPONSE>"+val+"<"+val.length()); // respBody = new ByteArrayInputStream(copy.toByteArray()); // } NamedList<Object> rsp = null; String charset = EntityUtils.getContentCharSet(response.getEntity()); try { rsp = processor.processResponse(respBody, charset); } catch (Exception e) { throw new RemoteSolrException(httpStatus, e.getMessage(), e); } if (httpStatus != HttpStatus.SC_OK) { String reason = null; try { NamedList err = (NamedList) rsp.get("error"); if (err != null) { reason = (String) err.get("msg"); // TODO? get the trace? } } catch (Exception ex) { } if (reason == null) { StringBuilder msg = new StringBuilder(); msg.append(response.getStatusLine().getReasonPhrase()); msg.append("\n\n"); msg.append("request: " + method.getURI()); reason = java.net.URLDecoder.decode(msg.toString(), UTF_8); } throw new RemoteSolrException(httpStatus, reason, null); } success = true; return rsp; } catch (ConnectException e) { throw new SolrServerException("Server refused connection at: " + getBaseURL(), e); } catch (SocketTimeoutException e) { throw new SolrServerException( "Timeout occured while waiting response from server at: " + getBaseURL(), e); } catch (IOException e) { throw new SolrServerException( "IOException occured when talking to server at: " + getBaseURL(), e); } finally { if (respBody != null && shouldClose) { try { respBody.close(); } catch (Throwable t) { } // ignore if (!success) { method.abort(); } } } }
protected NamedList<Object> sendRequest(SolrRequest request) throws SolrServerException, IOException { connect(); ClusterState clusterState = zkStateReader.getClusterState(); boolean sendToLeaders = false; List<String> replicas = null; if (request instanceof IsUpdateRequest) { if (request instanceof UpdateRequest) { NamedList<Object> response = directUpdate((AbstractUpdateRequest) request, clusterState); if (response != null) { return response; } } sendToLeaders = true; replicas = new ArrayList<>(); } SolrParams reqParams = request.getParams(); if (reqParams == null) { reqParams = new ModifiableSolrParams(); } List<String> theUrlList = new ArrayList<>(); if (request.getPath().equals("/admin/collections") || request.getPath().equals("/admin/cores")) { Set<String> liveNodes = clusterState.getLiveNodes(); for (String liveNode : liveNodes) { theUrlList.add(zkStateReader.getBaseUrlForNodeName(liveNode)); } } else { String collection = reqParams.get(UpdateParams.COLLECTION, defaultCollection); if (collection == null) { throw new SolrServerException( "No collection param specified on request and no default collection has been set."); } Set<String> collectionsList = getCollectionList(clusterState, collection); if (collectionsList.size() == 0) { throw new SolrException(ErrorCode.BAD_REQUEST, "Could not find collection: " + collection); } String shardKeys = reqParams.get(ShardParams._ROUTE_); if (shardKeys == null) { shardKeys = reqParams.get(ShardParams.SHARD_KEYS); // deprecated } // TODO: not a big deal because of the caching, but we could avoid looking // at every shard // when getting leaders if we tweaked some things // Retrieve slices from the cloud state and, for each collection // specified, // add it to the Map of slices. Map<String, Slice> slices = new HashMap<>(); for (String collectionName : collectionsList) { DocCollection col = getDocCollection(clusterState, collectionName); Collection<Slice> routeSlices = col.getRouter().getSearchSlices(shardKeys, reqParams, col); ClientUtils.addSlices(slices, collectionName, routeSlices, true); } Set<String> liveNodes = clusterState.getLiveNodes(); List<String> leaderUrlList = null; List<String> urlList = null; List<String> replicasList = null; // build a map of unique nodes // TODO: allow filtering by group, role, etc Map<String, ZkNodeProps> nodes = new HashMap<>(); List<String> urlList2 = new ArrayList<>(); for (Slice slice : slices.values()) { for (ZkNodeProps nodeProps : slice.getReplicasMap().values()) { ZkCoreNodeProps coreNodeProps = new ZkCoreNodeProps(nodeProps); String node = coreNodeProps.getNodeName(); if (!liveNodes.contains(coreNodeProps.getNodeName()) || !coreNodeProps.getState().equals(ZkStateReader.ACTIVE)) continue; if (nodes.put(node, nodeProps) == null) { if (!sendToLeaders || (sendToLeaders && coreNodeProps.isLeader())) { String url; if (reqParams.get(UpdateParams.COLLECTION) == null) { url = ZkCoreNodeProps.getCoreUrl( nodeProps.getStr(ZkStateReader.BASE_URL_PROP), defaultCollection); } else { url = coreNodeProps.getCoreUrl(); } urlList2.add(url); } else if (sendToLeaders) { String url; if (reqParams.get(UpdateParams.COLLECTION) == null) { url = ZkCoreNodeProps.getCoreUrl( nodeProps.getStr(ZkStateReader.BASE_URL_PROP), defaultCollection); } else { url = coreNodeProps.getCoreUrl(); } replicas.add(url); } } } } if (sendToLeaders) { leaderUrlList = urlList2; replicasList = replicas; } else { urlList = urlList2; } if (sendToLeaders) { theUrlList = new ArrayList<>(leaderUrlList.size()); theUrlList.addAll(leaderUrlList); } else { theUrlList = new ArrayList<>(urlList.size()); theUrlList.addAll(urlList); } if (theUrlList.isEmpty()) { throw new SolrException( SolrException.ErrorCode.INVALID_STATE, "Not enough nodes to handle the request"); } Collections.shuffle(theUrlList, rand); if (sendToLeaders) { ArrayList<String> theReplicas = new ArrayList<>(replicasList.size()); theReplicas.addAll(replicasList); Collections.shuffle(theReplicas, rand); theUrlList.addAll(theReplicas); } } LBHttpSolrServer.Req req = new LBHttpSolrServer.Req(request, theUrlList); LBHttpSolrServer.Rsp rsp = lbServer.request(req); return rsp.getResponse(); }
/** * {@inheritDoc} * * @see * org.sakaiproject.nakamura.api.solr.IndexingHandler#getDeleteQueries(org.sakaiproject.nakamura.api.solr.RepositorySession, * org.osgi.service.event.Event) */ public Collection<String> getDeleteQueries(RepositorySession respositorySession, Event event) { logger.debug("GetDelete for {} ", event); String path = (String) event.getProperty(FIELD_PATH); return ImmutableList.of("id:" + ClientUtils.escapeQueryChars(path)); }
public NamedList<Object> request(final SolrRequest request, ResponseParser processor) throws SolrServerException, IOException { HttpMethod method = null; InputStream is = null; SolrParams params = request.getParams(); Collection<ContentStream> streams = requestWriter.getContentStreams(request); String path = requestWriter.getPath(request); if (path == null || !path.startsWith("/")) { path = "/select"; } ResponseParser parser = request.getResponseParser(); if (parser == null) { parser = _parser; } // The parser 'wt=' and 'version=' params are used instead of the original params ModifiableSolrParams wparams = new ModifiableSolrParams(); wparams.set(CommonParams.WT, parser.getWriterType()); wparams.set(CommonParams.VERSION, parser.getVersion()); if (params == null) { params = wparams; } else { params = new DefaultSolrParams(wparams, params); } if (_invariantParams != null) { params = new DefaultSolrParams(_invariantParams, params); } int tries = _maxRetries + 1; try { while (tries-- > 0) { // Note: since we aren't do intermittent time keeping // ourselves, the potential non-timeout latency could be as // much as tries-times (plus scheduling effects) the given // timeAllowed. try { if (SolrRequest.METHOD.GET == request.getMethod()) { if (streams != null) { throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "GET can't send streams!"); } method = new GetMethod(_baseURL + path + ClientUtils.toQueryString(params, false)); } else if (SolrRequest.METHOD.POST == request.getMethod()) { String url = _baseURL + path; boolean isMultipart = (streams != null && streams.size() > 1); if (streams == null || isMultipart) { PostMethod post = new PostMethod(url); post.getParams().setContentCharset("UTF-8"); if (!this.useMultiPartPost && !isMultipart) { post.addRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); } List<Part> parts = new LinkedList<Part>(); Iterator<String> iter = params.getParameterNamesIterator(); while (iter.hasNext()) { String p = iter.next(); String[] vals = params.getParams(p); if (vals != null) { for (String v : vals) { if (this.useMultiPartPost || isMultipart) { parts.add(new StringPart(p, v, "UTF-8")); } else { post.addParameter(p, v); } } } } if (isMultipart) { int i = 0; for (ContentStream content : streams) { final ContentStream c = content; String charSet = null; String transferEncoding = null; parts.add( new PartBase(c.getName(), c.getContentType(), charSet, transferEncoding) { @Override protected long lengthOfData() throws IOException { return c.getSize(); } @Override protected void sendData(OutputStream out) throws IOException { InputStream in = c.getStream(); try { IOUtils.copy(in, out); } finally { in.close(); } } }); } } if (parts.size() > 0) { post.setRequestEntity( new MultipartRequestEntity( parts.toArray(new Part[parts.size()]), post.getParams())); } method = post; } // It is has one stream, it is the post body, put the params in the URL else { String pstr = ClientUtils.toQueryString(params, false); PostMethod post = new PostMethod(url + pstr); // Single stream as body // Using a loop just to get the first one final ContentStream[] contentStream = new ContentStream[1]; for (ContentStream content : streams) { contentStream[0] = content; break; } if (contentStream[0] instanceof RequestWriter.LazyContentStream) { post.setRequestEntity( new RequestEntity() { public long getContentLength() { return -1; } public String getContentType() { return contentStream[0].getContentType(); } public boolean isRepeatable() { return false; } public void writeRequest(OutputStream outputStream) throws IOException { ((RequestWriter.LazyContentStream) contentStream[0]).writeTo(outputStream); } }); } else { is = contentStream[0].getStream(); post.setRequestEntity( new InputStreamRequestEntity(is, contentStream[0].getContentType())); } method = post; } } else { throw new SolrServerException("Unsupported method: " + request.getMethod()); } } catch (NoHttpResponseException r) { // This is generally safe to retry on method.releaseConnection(); method = null; if (is != null) { is.close(); } // If out of tries then just rethrow (as normal error). if ((tries < 1)) { throw r; } // log.warn( "Caught: " + r + ". Retrying..." ); } } } catch (IOException ex) { throw new SolrServerException("error reading streams", ex); } method.setFollowRedirects(_followRedirects); method.addRequestHeader("User-Agent", AGENT); if (_allowCompression) { method.setRequestHeader(new Header("Accept-Encoding", "gzip,deflate")); } try { // Execute the method. // System.out.println( "EXECUTE:"+method.getURI() ); int statusCode = _httpClient.executeMethod(method); if (statusCode != HttpStatus.SC_OK) { StringBuilder msg = new StringBuilder(); msg.append(method.getStatusLine().getReasonPhrase()); msg.append("\n\n"); msg.append(method.getStatusText()); msg.append("\n\n"); msg.append("request: " + method.getURI()); throw new SolrException(statusCode, java.net.URLDecoder.decode(msg.toString(), "UTF-8")); } // Read the contents String charset = "UTF-8"; if (method instanceof HttpMethodBase) { charset = ((HttpMethodBase) method).getResponseCharSet(); } InputStream respBody = method.getResponseBodyAsStream(); // Jakarta Commons HTTPClient doesn't handle any // compression natively. Handle gzip or deflate // here if applicable. if (_allowCompression) { Header contentEncodingHeader = method.getResponseHeader("Content-Encoding"); if (contentEncodingHeader != null) { String contentEncoding = contentEncodingHeader.getValue(); if (contentEncoding.contains("gzip")) { // log.debug( "wrapping response in GZIPInputStream" ); respBody = new GZIPInputStream(respBody); } else if (contentEncoding.contains("deflate")) { // log.debug( "wrapping response in InflaterInputStream" ); respBody = new InflaterInputStream(respBody); } } else { Header contentTypeHeader = method.getResponseHeader("Content-Type"); if (contentTypeHeader != null) { String contentType = contentTypeHeader.getValue(); if (contentType != null) { if (contentType.startsWith("application/x-gzip-compressed")) { // log.debug( "wrapping response in GZIPInputStream" ); respBody = new GZIPInputStream(respBody); } else if (contentType.startsWith("application/x-deflate")) { // log.debug( "wrapping response in InflaterInputStream" ); respBody = new InflaterInputStream(respBody); } } } } } return processor.processResponse(respBody, charset); } catch (HttpException e) { throw new SolrServerException(e); } catch (IOException e) { throw new SolrServerException(e); } finally { method.releaseConnection(); if (is != null) { is.close(); } } }