[ 
https://issues.apache.org/jira/browse/SOLR-11722?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16322996#comment-16322996
 ] 

ASF GitHub Bot commented on SOLR-11722:
---------------------------------------

Github user dsmiley commented on a diff in the pull request:

    https://github.com/apache/lucene-solr/pull/304#discussion_r161079147
  
    --- Diff: solr/core/src/java/org/apache/solr/cloud/CreateAliasCmd.java ---
    @@ -68,34 +249,100 @@ public void call(ClusterState state, ZkNodeProps 
message, NamedList results)
         Thread.sleep(100);
       }
     
    +  private Map<String, String> buildAliasMap(String routedField, String 
routingType, String tz, String increment, String maxFutureMs, ZkNodeProps 
collectionProps) {
    +    Map<String, Object> properties = collectionProps.getProperties();
    +    Map<String,String> cleanMap = properties.entrySet().stream()
    +        .filter(stringObjectEntry ->
    +            !"fromApi".equals(stringObjectEntry.getKey())
    +                && !"stateFormat".equals(stringObjectEntry.getKey())
    +                && !"name".equals(stringObjectEntry.getKey()))
    +        .collect(Collectors.toMap((e) -> "collection-create." + 
e.getKey(), e -> String.valueOf(e.getValue())));
    +    cleanMap.put(ROUTING_FIELD, routedField);
    +    cleanMap.put(ROUTING_TYPE, routingType);
    +    cleanMap.put(ROUTING_INCREMENT, increment);
    +    cleanMap.put(ROUTING_MAX_FUTURE, maxFutureMs);
    +    cleanMap.put(TZ, tz);
    +    return cleanMap;
    +  }
    +
    +  private Instant validateStart(TimeZone zone, DateTimeFormatter fmt, 
String start) {
    +    // This is the normal/easy case, if we can get away with this great!
    +    TemporalAccessor startTime = attemptTimeStampParsing(start, 
zone.toZoneId());
    +    if (startTime == null) {
    +      // No luck, they gave us either date math, or garbage, so we have to 
do more work to figure out which and
    +      // to make sure it's valid date math and that it doesn't encode any 
millisecond precision.
    +      ZonedDateTime now = 
ZonedDateTime.now(zone.toZoneId()).truncatedTo(ChronoUnit.MILLIS);
    +      try {
    +        Date date = DateMathParser.parseMath(Date.from(now.toInstant()), 
start);
    +        String reformatted = 
fmt.format(date.toInstant().truncatedTo(ChronoUnit.MILLIS));
    +        Date reparse = 
Date.from(Instant.from(DATE_TIME_FORMATTER.parse(reformatted)));
    +        if (!reparse.equals(date)) {
    +          throw new SolrException(BAD_REQUEST,
    +              "Formatted time did not have the same milliseconds as 
original: " + date.getTime() + " vs. " +
    +                  reparse.getTime() + " This indicates that you used date 
math that includes milliseconds. " +
    +                  "(Hint: 'NOW' used without rounding always has this 
problem)" );
    +        }
    +        return date.toInstant();
    +      } catch (SolrException e) {
    +        throw new SolrException(BAD_REQUEST,
    +            "Start Time for the first collection must be a timestamp of 
the format yyyy-MM-dd_HH_mm_ss, " +
    +                "or a valid date math expression not containing specific 
milliseconds", e);
    +      }
    +    }
    +    return Instant.from(startTime);
    +  }
    +
    +  private TemporalAccessor attemptTimeStampParsing(String start, ZoneId 
zone) {
    +    try {
    +      DATE_TIME_FORMATTER.withZone(zone);
    +      return DATE_TIME_FORMATTER.parse(start);
    +    } catch (DateTimeParseException e) {
    +      return null;
    +    }
    +  }
    +
    +  private boolean anyRoutingParams(ZkNodeProps message) {
    +
    +    return message.containsKey(ROUTING_FIELD) || 
message.containsKey(ROUTING_TYPE) || message.containsKey(START)
    +        || message.containsKey(ROUTING_INCREMENT) || 
message.containsKey(TZ);
    +  }
    +
       private void validateAllCollectionsExistAndNoDups(List<String> 
collectionList, ZkStateReader zkStateReader) {
         final String collectionStr = StrUtils.join(collectionList, ',');
     
         if (new HashSet<>(collectionList).size() != collectionList.size()) {
    -      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
    +      throw new SolrException(BAD_REQUEST,
               String.format(Locale.ROOT,  "Can't create collection alias for 
collections='%s', since it contains duplicates", collectionStr));
         }
         ClusterState clusterState = zkStateReader.getClusterState();
         Set<String> aliasNames = 
zkStateReader.getAliases().getCollectionAliasListMap().keySet();
         for (String collection : collectionList) {
           if (clusterState.getCollectionOrNull(collection) == null && 
!aliasNames.contains(collection)) {
    -        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
    +        throw new SolrException(BAD_REQUEST,
                 String.format(Locale.ROOT,  "Can't create collection alias for 
collections='%s', '%s' is not an existing collection or alias", collectionStr, 
collection));
           }
         }
       }
    -  
    +
       /**
        * The v2 API directs that the 'collections' parameter be provided as a 
JSON array (e.g. ["a", "b"]).  We also
        * maintain support for the legacy format, a comma-separated list (e.g. 
a,b).
        */
       @SuppressWarnings("unchecked")
       private List<String> parseCollectionsParameter(Object colls) {
    -    if (colls == null) throw new 
SolrException(SolrException.ErrorCode.BAD_REQUEST, "missing collections param");
    +    if (colls == null) throw new SolrException(BAD_REQUEST, "missing 
collections param");
         if (colls instanceof List) return (List<String>) colls;
         return StrUtils.splitSmart(colls.toString(), ",", true).stream()
             .map(String::trim)
             .collect(Collectors.toList());
       }
     
    +  private ZkNodeProps selectByPrefix(String prefix, ZkNodeProps source) {
    --- End diff --
    
    I think the use of the single element array as a holder should be avoided 
-- I mean I've done it in some circumstances but here you're only doing it to 
use Java 8 streams, which IMO isn't a good reason for that hack. Either use a 
standard loop construction, or use the version of Stream.collect that takes the 
supplier & accumulator to take your Java 8 kung-foo to the next level ;-)  
'course most people reading code using such esoteric Java 8 stream features 
will need to read the docs to figure out what the heck is going on.  
Trade-offs...



> API to create a Time Routed Alias and first collection
> ------------------------------------------------------
>
>                 Key: SOLR-11722
>                 URL: https://issues.apache.org/jira/browse/SOLR-11722
>             Project: Solr
>          Issue Type: Sub-task
>      Security Level: Public(Default Security Level. Issues are Public) 
>          Components: SolrCloud
>            Reporter: David Smiley
>         Attachments: SOLR-11722.patch, SOLR-11722.patch
>
>
> This issue is about creating a single API command to create a "Time Routed 
> Alias" along with its first collection.  Need to decide what endpoint URL it 
> is and parameters.
> Perhaps in v2 it'd be {{/api/collections?command=create-routed-alias}} or 
> alternatively piggy-back off of command=create-alias but we add more options, 
> perhaps with a prefix like "router"?
> Inputs:
> * alias name
> * misc collection creation metadata (e.g. config, numShards, ...) perhaps in 
> this context with a prefix like "collection."
> * metadata for TimeRoutedAliasUpdateProcessor, currently: router.field
> * date specifier for first collection; can include "date math".
> We'll certainly add more options as future features unfold.
> I believe the collection needs to be created first (referring to the alias 
> name via a core property), and then the alias pointing to it which demands 
> collections exist first.  When figuring the collection name, you'll need to 
> reference the format in TimeRoutedAliasUpdateProcessor.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org
For additional commands, e-mail: dev-h...@lucene.apache.org

Reply via email to