package crmdna.api.endpoint;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.users.User;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.cmd.QueryKeys;
import crmdna.api.endpoint.ClientApi.ClientEnum;
import crmdna.client.Client;
import crmdna.common.StopWatch;
import crmdna.common.Utils;
import crmdna.common.api.APIException;
import crmdna.common.api.APIResponse;
import crmdna.common.api.APIResponse.Status;
import crmdna.common.api.APIUtils;
import crmdna.common.api.RequestInfo;
import crmdna.common.config.ConfigCRMDNA;
import crmdna.datamigration.DataMigration;
import crmdna.member.Member;
import crmdna.member.MemberEntity;
import crmdna.member.MemberLoader;
import crmdna.member.MemberQueryCondition;
import crmdna.participant.ParticipantEntity;
import crmdna.program.Program;
import crmdna.programtype.ProgramType;
import crmdna.registration.RegistrationEntity;
import crmdna.user.User.ClientLevelPrivilege;
import crmdna.user.UserCore;
import javax.annotation.Nullable;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import static crmdna.common.AssertUtils.ensure;
import static crmdna.common.OfyService.ofy;
@Api(name = "developersOnly")
public class DevelopersOnly {
public APIResponse purgeAllMemberData(@Named("client") String client,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
if (client == null)
client = "isha";
String login = null;
try {
login = Utils.getLoginEmail(user);
crmdna.user.User.ensureClientLevelPrivilege(client, login,
ClientLevelPrivilege.PURGE_MEMBER_DATA);
// ensure dev mode is set
boolean devMode = ConfigCRMDNA.get().toProp().devMode;
if (!devMode)
throw new APIException().status(Status.ERROR_OPERATION_NOT_ALLOWED).message(
"This operation is allowed only in dev mode");
QueryKeys<MemberEntity> memberQueryKeys = ofy(client).load().type(MemberEntity.class).keys();
QueryKeys<ParticipantEntity> participantQueryKeys =
ofy(client).load().type(ParticipantEntity.class).keys();
QueryKeys<RegistrationEntity> registrationQueryKeys =
ofy(client).load().type(RegistrationEntity.class).keys();
List<Key<MemberEntity>> memberKeys = memberQueryKeys.list();
List<Key<ParticipantEntity>> participantKeys = participantQueryKeys.list();
List<Key<RegistrationEntity>> registrationKeys = registrationQueryKeys.list();
ofy(client).delete().keys(memberKeys);
ofy(client).delete().keys(participantKeys);
ofy(client).delete().keys(registrationKeys);
StringBuilder builder = new StringBuilder();
builder.append("Deleted [" + memberQueryKeys.list().size() + "] members. ");
builder.append("Deleted [" + participantQueryKeys.list().size() + "] participants. ");
builder.append("Deleted [" + registrationQueryKeys.list().size() + "] registrants. ");
return new APIResponse().status(Status.SUCCESS).message(builder.toString());
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace, new RequestInfo().client(client).req(req)
.login(login));
}
}
@ApiMethod(name = "reconstituteKey", httpMethod = HttpMethod.GET)
public APIResponse reconstituteKey(@Named("webSafeKeyString") String webSafeKey,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req) {
try {
StopWatch stopWatch = StopWatch.createStarted();
com.google.appengine.api.datastore.Key key = KeyFactory.stringToKey(webSafeKey);
Map<String, String> map = new HashMap<>();
map.put("Kind", key.getKind());
map.put("AppId", key.getAppId());
map.put("Name", key.getName());
map.put("Namespace", key.getNamespace());
map.put("Parent", key.getNamespace());
map.put("Id", key.getId() + "");
return new APIResponse()
.status(Status.SUCCESS)
.message(
"Data store key successfully reconstituted in [" + stopWatch.nsElapsed() + "] ns. ")
.object(map).processingTimeInMS(stopWatch.msElapsed());
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace, new RequestInfo().req(req));
}
}
@ApiMethod(name = "testKeyToIDConversion", httpMethod = HttpMethod.GET)
public APIResponse testKeyToIDConversion(@Named("client") String client,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
if (null == client)
client = "isha";
String login = null;
try {
login = Utils.getLoginEmail(user);
crmdna.user.User.ensureValidUser(client, login);
StringBuilder message = new StringBuilder();
StopWatch stopWatch = StopWatch.createStarted();
List<Key<MemberEntity>> keys =
ofy(client).load().type(MemberEntity.class).limit(1000).keys().list();
message.append("[" + keys.size() + "] member keys loaded in [" + stopWatch.msElapsed()
+ "] ms. ");
List<Long> ids = new ArrayList<>();
stopWatch = StopWatch.createStarted();
for (Key<MemberEntity> key : keys) {
ids.add(key.getId());
}
message.append("[" + ids.size() + "] ids obtained in [" + stopWatch.nsElapsed() + "] ns. ");
List<String> keyStrings = new ArrayList<>(keys.size());
for (Key<MemberEntity> key : keys) {
keyStrings.add(KeyFactory.keyToString(key.getRaw()));
}
return new APIResponse().status(Status.SUCCESS).message(message.toString())
.object(keyStrings);
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace, new RequestInfo().client(client).req(req)
.login(login));
}
}
@ApiMethod(name = "testMaxDatastoreAsyncQueryLimit", httpMethod = HttpMethod.GET)
public APIResponse testMaxDatastoreAsyncQueryLimit(@Named("client") String client,
@Nullable @Named("numQueriesDefault10000") Integer numQueries,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
if (client == null)
client = "isha";
String login = null;
try {
if (numQueries == null)
numQueries = 10000;
ensure(numQueries > 0, "Invalid numQueries [" + numQueries + "]. Should be positive.");
login = Utils.getLoginEmail(user);
crmdna.user.User.ensureValidUser(client, login);
Set<String> emails = new HashSet<>(numQueries);
for (int i = 0; i < numQueries; i++) {
if (i == 0)
emails.add("sathya.t@ishafoundation.org");
else if (i == 1)
emails.add("thulasidhar@gmail.com");
else
emails.add("email" + i + "@invalid.com");
}
StopWatch sw = StopWatch.createStarted();
Map<String, Long> emailVsMemberId = Member.getMemberIdFromEmail(client, emails);
return new APIResponse()
.status(Status.SUCCESS)
.object(emailVsMemberId)
.message(
"Completed [" + numQueries
+ "] async datastore queries to get memberId from email for [" + numQueries
+ "] email(s)").processingTimeInMS(sw.msElapsed());
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace, new RequestInfo().client(client).req(req)
.login(login));
}
}
@ApiMethod(name = "copyAllEntitiesToAnotherClient", httpMethod = HttpMethod.POST)
public APIResponse copyAllEntitiesToAnotherClient(@Named("sourceClient") String sourceClient,
@Named("targetClient") String targetClient,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
String login = null;
try {
login = Utils.getLoginEmail(user);
DataMigration.copyAllEntitiesToAnotherClient(sourceClient, targetClient, login);
return new APIResponse().status(Status.SUCCESS);
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace,
new RequestInfo().client("multiple").req(req).login(login));
}
}
// To be removed after bhairavi data migration
@ApiMethod(name = "resaveAllPrograms", httpMethod = HttpMethod.POST)
public APIResponse resaveAllPrograms(@Named("clientEnum") ClientEnum clientEnum,
@Nullable @Named("clientIfOther") String clientOther,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
String login = null;
String client = EndpointUtils.getClient(clientEnum, clientOther);
try {
login = Utils.getLoginEmail(user);
Program.resaveAll(client, login);
return new APIResponse().status(Status.SUCCESS);
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace,
new RequestInfo().client("multiple").req(req).login(login));
}
}
// To be removed after bhairavi data migration
@ApiMethod(name = "resaveAllProgramTypes", httpMethod = HttpMethod.POST)
public APIResponse resaveAllProgramTypes(@Named("clientEnum") ClientEnum clientEnum,
@Nullable @Named("clientIfOther") String clientOther,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
String login = null;
String client = EndpointUtils.getClient(clientEnum, clientOther);
try {
login = Utils.getLoginEmail(user);
ProgramType.resaveAll(client, login);
return new APIResponse().status(Status.SUCCESS);
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace,
new RequestInfo().client("multiple").req(req).login(login));
}
}
@ApiMethod(name = "resaveAllMembers", httpMethod = HttpMethod.POST)
public APIResponse resaveAllMembers(@Named("clientEnum") ClientEnum clientEnum,
@Nullable @Named("clientIfOther") String clientOther,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
String login = null;
String client = EndpointUtils.getClient(clientEnum, clientOther);
try {
login = Utils.getLoginEmail(user);
Client.ensureValid(client);
ensure(UserCore.isSuperUser(login), "Allowed only for super user");
List<MemberEntity> all = ofy(client).load().type(MemberEntity.class).list();
ofy(client).save().entities(all).now();
return new APIResponse().status(Status.SUCCESS);
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace,
new RequestInfo().client("multiple").req(req).login(login));
}
}
@ApiMethod(name = "populateSubUnsubGroupIds", httpMethod = HttpMethod.POST)
public APIResponse populateSubUnsubGroupIds(@Named("clientEnum") ClientEnum clientEnum,
@Nullable @Named("clientOther") String clientOther,
@Named("firstChar") Utils.SingleChar firstChar,
@Nullable @Named("showStackTrace") Boolean showStackTrace, HttpServletRequest req, User user) {
String login = null;
String client = EndpointUtils.getClient(clientEnum, clientOther);
try {
login = Utils.getLoginEmail(user);
Client.ensureValid(client);
ensure(UserCore.isSuperUser(login), "Allowed only for super user");
MemberQueryCondition mqc = new MemberQueryCondition(client, 20000);
mqc.nameFirstChar = firstChar.toString();
List<MemberEntity> memberEntities = MemberLoader.queryEntities(mqc, login);
Set<Long> memberIds = new HashSet<>();
for (MemberEntity memberEntity : memberEntities) {
memberIds.add(memberEntity.getId());
}
Set<Long> changedMemberIds = Member.populateSubUnsubGroupIds(client, memberIds, login);
return new APIResponse().status(Status.SUCCESS)
.message("[" + changedMemberIds.size() + "] member entities changed").object(changedMemberIds);
} catch (Exception ex) {
return APIUtils.toAPIResponse(ex, showStackTrace,
new RequestInfo().client(client).req(req).login(login));
}
}
}