/*
* Copyright (C) 2011 lightcouch.org
*
* 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 org.lightcouch;
import static org.lightcouch.CouchDbUtil.assertNotEmpty;
import static org.lightcouch.CouchDbUtil.close;
import static org.lightcouch.CouchDbUtil.getStream;
import static org.lightcouch.URIBuilder.buildUri;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Map;
import org.apache.commons.codec.Charsets;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.lightcouch.ReplicationResult.ReplicationHistory;
import com.google.gson.JsonObject;
/**
* This class provides access to the database replication API; a replication request
* is sent via HTTP POST to <code>_replicate</code> URI.
*
* <h3>Usage Example:</h3>
* <pre>
* ReplicationResult replication = dbClient.replication()
* .source("source-db")
* .target("target-db")
* .createTarget(true)
* .filter("example/filter1")
* .trigger();
*
* {@code
* List<ReplicationHistory> histories = replication.getHistories();
* }
* </pre>
*
* @see CouchDbClientBase#replication()
* @see ReplicationResult
* @see ReplicationHistory
* @see Replicator
* @since 0.0.2
* @author Ahmed Yehia
*
*/
public class Replication {
static final Log log = LogFactory.getLog(Replication.class);
private String source;
private String target;
private Boolean cancel;
private Boolean continuous;
private String filter;
private JsonObject queryParams;
private String[] docIds;
private String proxy;
private Boolean createTarget;
private Integer sinceSeq;
// OAuth
private JsonObject targetOauth;
private String consumerSecret;
private String consumerKey;
private String tokenSecret;
private String token;
private CouchDbClientBase dbc;
public Replication(CouchDbClientBase dbc) {
this.dbc = dbc;
}
/**
* Triggers a replication request.
*/
public ReplicationResult trigger() {
assertNotEmpty(source, "Source");
assertNotEmpty(target, "Target");
HttpResponse response = null;
try {
JsonObject json = createJson();
if(log.isDebugEnabled()) {
log.debug(json);
}
final URI uri = buildUri(dbc.getBaseUri()).path("_replicate").build();
response = dbc.post(uri, json.toString());
final InputStreamReader reader = new InputStreamReader(getStream(response), Charsets.UTF_8);
return dbc.getGson().fromJson(reader, ReplicationResult.class);
} finally {
close(response);
}
}
// fields
public Replication source(String source) {
this.source = source;
return this;
}
public Replication target(String target) {
this.target = target;
return this;
}
public Replication continuous(Boolean continuous) {
this.continuous = continuous;
return this;
}
public Replication filter(String filter) {
this.filter = filter;
return this;
}
public Replication queryParams(String queryParams) {
this.queryParams = dbc.getGson().fromJson(queryParams, JsonObject.class);
return this;
}
public Replication queryParams(Map<String, Object> queryParams) {
this.queryParams = dbc.getGson().toJsonTree(queryParams).getAsJsonObject();
return this;
}
public Replication docIds(String... docIds) {
this.docIds = docIds;
return this;
}
public Replication proxy(String proxy) {
this.proxy = proxy;
return this;
}
public Replication cancel(Boolean cancel) {
this.cancel = cancel;
return this;
}
public Replication createTarget(Boolean createTarget) {
this.createTarget = createTarget;
return this;
}
/**
* Starts a replication since an update sequence.
*/
public Replication sinceSeq(Integer sinceSeq) {
this.sinceSeq = sinceSeq;
return this;
}
public Replication targetOauth(String consumerSecret, String consumerKey, String tokenSecret, String token) {
targetOauth = new JsonObject();
this.consumerSecret = consumerKey;
this.consumerKey = consumerKey;
this.tokenSecret = tokenSecret;
this.token = token;
return this;
}
// helper
private JsonObject createJson() {
JsonObject json = new JsonObject();
addProperty(json, "source", source);
addProperty(json, "cancel", cancel);
addProperty(json, "continuous", continuous);
addProperty(json, "filter", filter);
if(queryParams != null)
json.add("query_params", queryParams);
if(docIds != null)
json.add("doc_ids", dbc.getGson().toJsonTree(docIds, String[].class));
addProperty(json, "proxy", proxy);
addProperty(json, "since_seq", sinceSeq);
addProperty(json, "create_target", createTarget);
if(targetOauth != null) {
JsonObject auth = new JsonObject();
JsonObject oauth = new JsonObject();
addProperty(oauth, "consumer_secret", consumerSecret);
addProperty(oauth, "consumer_key", consumerKey);
addProperty(oauth, "token_secret", tokenSecret);
addProperty(oauth, "token", token);
addProperty(targetOauth, "url", target);
auth.add("oauth", oauth);
targetOauth.add("auth", auth);
json.add("target", targetOauth);
} else {
addProperty(json, "target", target);
}
return json;
}
private void addProperty(JsonObject json, String name, Object value) {
if(value != null) {
if(value instanceof Boolean)
json.addProperty(name, (Boolean)value);
else if (value instanceof String)
json.addProperty(name, (String)value);
else if (value instanceof Integer)
json.addProperty(name, (Integer)value);
}
}
}