blob: 0209794507161f1e01857cd366512414033c8eeb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.usergrid.corepersistence.pipeline.cursor;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A cursor that has been passed in with our request. Adds utils for parsing values
*/
public class RequestCursor {
/**
* Arbitrary number, just meant to keep us from having a DOS issue
*/
private static final int MAX_SIZE = 1024;
private static final int MAX_CURSOR_COUNT = 100;
private static final ObjectMapper MAPPER = CursorSerializerUtil.getMapper();
private final Map<Integer, JsonNode> parsedCursor;
public RequestCursor( final Optional<String> cursor ) {
if ( cursor.isPresent() ) {
parsedCursor = fromCursor( cursor.get() );
}
else {
parsedCursor = Collections.EMPTY_MAP;
}
}
/**
* Get the cursor with the specified id
*
* May return null if not found
*/
public <T> T getCursor( final int id, final CursorSerializer<T> serializer ) {
final JsonNode node = parsedCursor.get( id );
if(node == null){
return null;
}
return serializer.fromJsonNode( node, MAPPER );
}
/**
* Deserialize from the cursor as json nodes
*/
private Map<Integer, JsonNode> fromCursor( final String cursor ) throws CursorParseException {
Preconditions.checkArgument( cursor != null, "Cursor cannot be null");
Preconditions.checkArgument( cursor.length() <= MAX_SIZE,
"Your cursor must be less than " + MAX_SIZE + " chars in length" );
Preconditions.checkArgument( !cursor.isEmpty(), "Cursor cannot have an empty value");
try {
JsonNode jsonNode = CursorSerializerUtil.fromString( cursor );
Preconditions
.checkArgument( jsonNode.size() <= MAX_CURSOR_COUNT, " You cannot have more than " + MAX_CURSOR_COUNT + " cursors" );
Map<Integer, JsonNode> cursors = new HashMap<>();
final Iterable<Map.Entry<String, JsonNode>> iterable = () -> jsonNode.fields();
for ( final Map.Entry<String, JsonNode> node : iterable ) {
cursors.put( Integer.parseInt( node.getKey() ), node.getValue() );
}
return cursors;
}
catch ( IllegalArgumentException ie ){
throw new IllegalArgumentException("Provided cursor has an invalid format and cannot be parsed.");
}
catch ( Exception e ) {
throw new CursorParseException( "Unable to deserialize cursor", e );
}
}
}