AppEngine について色々

AppEngine は無課金ではソケットが使えないため、そのままでは HttpClient が使えません。それで困ってる方は

  • GAEClientConnection
  • GAEConnectionManager

を使いましょう!

new DefaultHttpClient(new GAEConnectionManager());

といった感じで、コンストラクタに渡してあげます。これで GAE でも HttpClient が動作します。


さらに、GAEClientConnection.java の FetchOptions.Builder に、setDeadline(10.0) を追加してあげましょう。
デフォルトは 5 秒でタイムアウトです。限界の 10 秒に設定します。
デフォルトの 5 秒では、通信先や自分自身の状態によってはタイムアウトする可能性が普通にあります。


AppEngine で作るのが初めての方向きに、String => String のキーバリューユーティルを作ってみました。
永続化データを適当に放り込んだりする際の実装の一助になると思います。適当にご利用くださいませ。

EMF.java

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public final class EMF {
    private static final EntityManagerFactory emfInstance = Persistence.createEntityManagerFactory("transactions-optional");

    private EMF() {
        throw new AssertionError();
    }

    public static EntityManagerFactory get() {
        return emfInstance;
    }
}

KeyValue.java

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "KEYVALUE")
public class KeyValue {
    private String key;

    private String value;

    public KeyValue(final String key, final String value) {
        this.key = key;
        this.value = value;
    }

    @Id
    @Column(name = "KEY")
    public String getKey() {
        return key;
    }

    public void setKey(final String key) {
        this.key = key;
    }

    @Column(name = "VALUE")
    public String getValue() {
        return value;
    }

    public void setValue(final String value) {
        this.value = value;
    }
}

KeyValueUtil.java

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

public class KeyValueUtil {
    public static String find(final String key) {
        final EntityManagerFactory emf = EMF.get();
        final EntityManager em = emf.createEntityManager();

        try {
            final EntityTransaction txn = em.getTransaction();

            txn.begin();

            try {
                final String result = find(em, key);

                txn.commit();

                return result;
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public static String find(final EntityManager em, final String key) {
        if (em == null) {
            return find(key);
        } else {
            final KeyValue keyValue = em.find(KeyValue.class, key);

            return keyValue == null ? null : keyValue.getValue();
        }
    }

    public static KeyValue findKeyValue(final String key) {
        final EntityManagerFactory emf = EMF.get();
        final EntityManager em = emf.createEntityManager();

        try {
            final EntityTransaction txn = em.getTransaction();

            txn.begin();

            try {
                final KeyValue result = findKeyValue(em, key);

                txn.commit();

                return result;
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public static KeyValue findKeyValue(final EntityManager em, final String key) {
        if (em == null) {
            return findKeyValue(key);
        } else {
            return em.find(KeyValue.class, key);
        }
    }

    public static void merge(final KeyValue keyValue) {
        final EntityManagerFactory emf = EMF.get();
        final EntityManager em = emf.createEntityManager();

        try {
            final EntityTransaction txn = em.getTransaction();

            txn.begin();

            try {
                merge(em, keyValue);
                txn.commit();
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public static void merge(final EntityManager em, final KeyValue keyValue) {
        if (em == null) {
            merge(keyValue);
        } else {
            em.merge(keyValue);
        }
    }

    public static void remove(final KeyValue keyValue) {
        final EntityManagerFactory emf = EMF.get();
        final EntityManager em = emf.createEntityManager();

        try {
            final EntityTransaction txn = em.getTransaction();

            txn.begin();

            try {
                remove(em, keyValue);
                txn.commit();
            } finally {
                if (txn.isActive()) {
                    txn.rollback();
                }
            }
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public static void remove(final EntityManager em, final KeyValue keyValue) {
        if (em == null) {
            remove(keyValue);
        } else {
            em.remove(keyValue);
        }
    }
}