/*
* Copyright 2014 Jive Software Inc.
*
* Licensed 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 com.jivesoftware.os.amza.sync.deployable.endpoints;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jivesoftware.os.amza.api.AmzaInterner;
import com.jivesoftware.os.amza.api.partition.PartitionName;
import com.jivesoftware.os.amza.api.partition.PartitionProperties;
import com.jivesoftware.os.amza.sync.deployable.AmzaSyncReceiver;
import com.jivesoftware.os.amza.sync.deployable.Rows;
import com.jivesoftware.os.mlogger.core.MetricLogger;
import com.jivesoftware.os.mlogger.core.MetricLoggerFactory;
import com.jivesoftware.os.routing.bird.shared.ResponseHelper;
import java.io.InputStream;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.xerial.snappy.SnappyInputStream;
/**
* @author jonathan
*/
@Singleton
@Path("/api/sync/v1")
public class AmzaSyncApiEndpoints {
private static final MetricLogger LOG = MetricLoggerFactory.getLogger();
private final AmzaSyncReceiver syncReceiver;
private final ObjectMapper mapper;
private final AmzaInterner amzaInterner;
private final ResponseHelper responseHelper = ResponseHelper.INSTANCE;
public AmzaSyncApiEndpoints(@Context AmzaSyncReceiver syncReceiver, @Context ObjectMapper mapper, @Context AmzaInterner amzaInterner) {
this.syncReceiver = syncReceiver;
this.mapper = mapper;
this.amzaInterner = amzaInterner;
}
@POST
@Path("/commit/rows/{partitionNameBase64}")
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_JSON)
public Response commitRows(@PathParam("partitionNameBase64") String partitionNameBase64,
InputStream inputStream) throws Exception {
Rows rows;
try {
rows = mapper.readValue(new SnappyInputStream(inputStream), Rows.class);
} catch (Exception x) {
LOG.error("Failed decompressing commitRows({})",
new Object[] { partitionNameBase64 }, x);
return responseHelper.errorResponse("Server error", x);
}
try {
PartitionName partitionName = amzaInterner.internPartitionNameBase64(partitionNameBase64);
syncReceiver.commitRows(partitionName, rows);
return responseHelper.jsonResponse("ok");
} catch (Exception x) {
LOG.error("Failed calling commitRows({},count:{})",
new Object[] { partitionNameBase64, rows != null ? rows.size() : null }, x);
return responseHelper.errorResponse("Server error", x);
}
}
@POST
@Path("/ensure/partition/{partitionNameBase64}/{ringSize}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response ensurePartition(@PathParam("partitionNameBase64") String partitionNameBase64,
@PathParam("ringSize") int ringSize,
PartitionProperties properties) throws Exception {
try {
PartitionName partitionName = amzaInterner.internPartitionNameBase64(partitionNameBase64);
syncReceiver.ensurePartition(partitionName, properties, ringSize);
return responseHelper.jsonResponse("ok");
} catch (Exception x) {
LOG.error("Failed calling ensurePartition({},{})",
new Object[] { partitionNameBase64, ringSize }, x);
return responseHelper.errorResponse("Server error", x);
}
}
}