Skip to content

Commit

Permalink
prime-1.12.0 - Merged pseudonym-server into prime as prime-module
Browse files Browse the repository at this point in the history
  • Loading branch information
vihangpatil authored Aug 24, 2018
2 parents 5e79283 + 3b0b205 commit 3f4fe09
Show file tree
Hide file tree
Showing 43 changed files with 577 additions and 899 deletions.
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ by the github repository. It should all be open.
* [Greg's wiki about shell scripting is a very good resource](http://mywiki.wooledge.org/)
* For complex output (multiple lines etc.), consider using "printf"
instead of the simple "echo".
* Scripts, in particular scripts that are run during startup of containers
either for production or testing, should die cleanly and visibly as soon as
possible if they have to. For instance, if the script depends on
an executable that may be missing, the script should test for the
existance of the executable before any of the script's "payload" is
executed. Example:

DEPENDENCIES="foo bar baz gazonk"
for dep in $DEPENDENCIES; do
if [[ -z "$(type $dep)" ]] ; then
echo "Cannot locate executable '${dep}', bailing out"
exit 1
fi
done

## Kotlin

Expand Down
8 changes: 0 additions & 8 deletions acceptance-tests/script/wait.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@ done

echo "Prime launched"

echo "Waiting for pseudonym-server to launch on pseudonym-server:8080..."

while ! nc -z pseudonym-server 8080; do
sleep 0.1 # wait for 1/10 of the second before check again
done

echo "pseudonym-server launched"

java -cp '/acceptance-tests.jar' org.junit.runner.JUnitCore \
org.ostelco.at.okhttp.GetPseudonymsTest \
org.ostelco.at.okhttp.GetProductsTest \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.ostelco.at.common

import com.stripe.Stripe
import com.stripe.model.Customer
import com.stripe.model.Token

object Payment {
object StripePayment {
fun createPaymentSourceId(): String {

// https://stripe.com/docs/api/java#create_card_token
Expand All @@ -19,4 +20,16 @@ object Payment {
val token = Token.create(tokenMap)
return token.id
}

fun deleteAllCustomers() {
// https://stripe.com/docs/api/java#create_card_token
Stripe.apiKey = System.getenv("STRIPE_API_KEY")

do {
val customers = Customer.list(emptyMap()).data
customers.forEach { customer ->
customer.delete()
}
} while (customers.isNotEmpty())
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.ostelco.at.jersey

import org.junit.Test
import org.ostelco.at.common.Payment.createPaymentSourceId
import org.ostelco.at.common.StripePayment
import org.ostelco.at.common.createProfile
import org.ostelco.at.common.createSubscription
import org.ostelco.at.common.expectedProducts
Expand Down Expand Up @@ -228,6 +228,8 @@ class PurchaseTest {
@Test
fun `jersey test - POST products purchase`() {

StripePayment.deleteAllCustomers()

val email = "purchase-${randomInt()}@test.com"
createProfile(name = "Test Purchase User", email = email)

Expand All @@ -238,7 +240,7 @@ class PurchaseTest {
val balanceBefore = subscriptionStatusBefore.remaining

val productSku = "1GB_249NOK"
val sourceId = createPaymentSourceId()
val sourceId = StripePayment.createPaymentSourceId()

post<String> {
path = "/products/$productSku/purchase"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.ostelco.at.okhttp

import org.junit.Test
import org.ostelco.at.common.Payment.createPaymentSourceId
import org.ostelco.at.common.StripePayment
import org.ostelco.at.common.createProfile
import org.ostelco.at.common.createSubscription
import org.ostelco.at.common.expectedProducts
Expand Down Expand Up @@ -168,14 +168,16 @@ class PurchaseTest {
@Test
fun `okhttp test - POST products purchase`() {

StripePayment.deleteAllCustomers()

val email = "purchase-${randomInt()}@test.com"
createProfile(name = "Test Purchase User", email = email)

val client = clientForSubject(subject = email)

val balanceBefore = client.subscriptionStatus.remaining

val sourceId = createPaymentSourceId()
val sourceId = StripePayment.createPaymentSourceId()

client.purchaseProduct("1GB_249NOK", sourceId, false)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,4 @@ class ClientApiConfiguration {
fun setAuthenticationCachePolicy(spec: String) {
this.authenticationCachePolicy = CacheBuilderSpec.parse(spec)
}

@NotNull
var pseudonymEndpoint: String? = null
// TODO vihang: make @NotBlank or @NotEmpty work again
set(value) {
if (value == null || value.isBlank()) {
throw Error("modules.type['api'].config.pseudonymEndpoint is blank")
}
field = value
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ class ClientApiModule : PrimeModule {
jerseyEnv.register(ProfileResource(dao))
jerseyEnv.register(ReferralResource(dao))
jerseyEnv.register(PaymentResource(dao))
jerseyEnv.register(SubscriptionResource(
dao = dao,
pseudonymEndpoint = config.pseudonymEndpoint ?: "", // this will never be empty
client = client))
jerseyEnv.register(SubscriptionResource(dao))
jerseyEnv.register(SubscriptionsResource(dao))
jerseyEnv.register(ApplicationTokenResource(dao))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import io.dropwizard.auth.Auth
import org.ostelco.prime.client.api.auth.AccessTokenPrincipal
import org.ostelco.prime.client.api.store.SubscriberDAO
import org.ostelco.prime.model.Subscriber
import org.ostelco.prime.module.getResource
import org.ostelco.prime.paymentprocessor.PaymentProcessor
import javax.validation.constraints.NotNull
import javax.ws.rs.Consumes
import javax.ws.rs.GET
Expand All @@ -23,8 +21,6 @@ import javax.ws.rs.core.Response
@Path("/profile")
class ProfileResource(private val dao: SubscriberDAO) {

private val paymentProcessor by lazy { getResource<PaymentProcessor>() }

@GET
@Produces("application/json")
fun getProfile(@Auth token: AccessTokenPrincipal?): Response {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.ostelco.prime.client.api.store.SubscriberDAO
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.client.Client
import javax.ws.rs.core.Response

/**
Expand All @@ -16,9 +15,7 @@ import javax.ws.rs.core.Response

@Path("/subscription")
@Deprecated("use SubscriptionsResource", ReplaceWith("SubscriptionsResource", "org.ostelco.prime.client.api.resources.SubscriptionsResource"))
class SubscriptionResource(private val dao: SubscriberDAO,
val client: Client,
private val pseudonymEndpoint: String) {
class SubscriptionResource(private val dao: SubscriberDAO) {

@GET
@Path("status")
Expand All @@ -44,9 +41,10 @@ class SubscriptionResource(private val dao: SubscriberDAO,
.build()
}

return dao.getMsisdn(token.name).fold(
{ apiError -> Response.status(apiError.status).entity(asJson(apiError.description)).build() },
{ msisdn -> client.target("$pseudonymEndpoint/pseudonym/active/$msisdn").request().get() })
return dao.getActivePseudonymOfMsisdnForSubscriber(token.name).fold(
{ apiError -> Response.status(apiError.status).entity(asJson(apiError.description)) },
{ pseudonym -> Response.status(Response.Status.OK).entity(pseudonym) })
.build()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.ostelco.prime.client.api.model.Consent
import org.ostelco.prime.client.api.model.Person
import org.ostelco.prime.client.api.model.SubscriptionStatus
import org.ostelco.prime.core.ApiError
import org.ostelco.prime.model.ActivePseudonyms
import org.ostelco.prime.model.ApplicationToken
import org.ostelco.prime.model.Product
import org.ostelco.prime.model.PurchaseRecord
Expand All @@ -13,7 +14,6 @@ import org.ostelco.prime.model.Subscription
import org.ostelco.prime.paymentprocessor.core.ProductInfo
import org.ostelco.prime.paymentprocessor.core.ProfileInfo
import org.ostelco.prime.paymentprocessor.core.SourceInfo
import javax.ws.rs.core.Response

/**
*
Expand Down Expand Up @@ -90,4 +90,6 @@ interface SubscriberDAO {

@Deprecated(message = "use purchaseProduct")
fun purchaseProductWithoutPayment(subscriberId: String, sku: String): Either<ApiError, Unit>

fun getActivePseudonymOfMsisdnForSubscriber(subscriberId: String): Either<ApiError, ActivePseudonyms>
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.ostelco.prime.core.ForbiddenError
import org.ostelco.prime.core.InsuffientStorageError
import org.ostelco.prime.core.NotFoundError
import org.ostelco.prime.logger
import org.ostelco.prime.model.ActivePseudonyms
import org.ostelco.prime.model.ApplicationToken
import org.ostelco.prime.model.Product
import org.ostelco.prime.model.PurchaseRecord
Expand All @@ -24,6 +25,7 @@ import org.ostelco.prime.paymentprocessor.PaymentProcessor
import org.ostelco.prime.paymentprocessor.core.ProductInfo
import org.ostelco.prime.paymentprocessor.core.ProfileInfo
import org.ostelco.prime.paymentprocessor.core.SourceInfo
import org.ostelco.prime.pseudonymizer.PseudonymizerService
import org.ostelco.prime.storage.ClientDataSource
import java.time.Instant
import java.util.*
Expand All @@ -37,6 +39,7 @@ class SubscriberDAOImpl(private val storage: ClientDataSource, private val ocsSu
private val logger by logger()

private val paymentProcessor by lazy { getResource<PaymentProcessor>() }
private val pseudonymizer by lazy { getResource<PseudonymizerService>() }

/* Table for 'profiles'. */
private val consentMap = ConcurrentHashMap<String, ConcurrentHashMap<String, Boolean>>()
Expand Down Expand Up @@ -135,6 +138,12 @@ class SubscriberDAOImpl(private val storage: ClientDataSource, private val ocsSu
}
}

override fun getActivePseudonymOfMsisdnForSubscriber(subscriberId: String): Either<ApiError, ActivePseudonyms> {
return storage.getMsisdn(subscriberId)
.mapLeft { NotFoundError("Failed to msisdn for user. ${it.message}") }
.map { msisdn -> pseudonymizer.getActivePseudonymsForMsisdn(msisdn) }
}

override fun getPurchaseHistory(subscriberId: String): Either<ApiError, Collection<PurchaseRecord>> {
return try {
return storage.getPurchaseRecords(subscriberId).bimap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,13 @@ import org.ostelco.prime.client.api.auth.OAuthAuthenticator
import org.ostelco.prime.client.api.model.SubscriptionStatus
import org.ostelco.prime.client.api.store.SubscriberDAO
import org.ostelco.prime.client.api.util.AccessToken
import org.ostelco.prime.core.ApiError
import org.ostelco.prime.model.ActivePseudonyms
import org.ostelco.prime.model.Price
import org.ostelco.prime.model.Product
import org.ostelco.prime.model.PseudonymEntity
import org.ostelco.prime.model.PurchaseRecord
import java.time.Instant
import java.util.*
import javax.ws.rs.client.Client
import javax.ws.rs.client.Invocation
import javax.ws.rs.client.WebTarget
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response

Expand All @@ -49,21 +45,18 @@ class SubscriptionResourceTest {
product = Product(sku = "1", price = Price(10, "NOK")),
timestamp = Instant.now().toEpochMilli()))

private val subscriptionStatus = SubscriptionStatus(5, purchaseRecords)

@Before
@Throws(Exception::class)
fun setUp() {
`when`(AUTHENTICATOR.authenticate(ArgumentMatchers.anyString()))
.thenReturn(Optional.of(AccessTokenPrincipal(email)))
}

@Test
@Throws(Exception::class)
fun getSubscriptionStatus() {
val subscriptionStatus = SubscriptionStatus(5, purchaseRecords)
val arg = argumentCaptor<String>()

`when`<Either<ApiError, SubscriptionStatus>>(DAO.getSubscriptionStatus(arg.capture())).thenReturn(Either.right(subscriptionStatus))
`when`(DAO.getSubscriptionStatus(arg.capture())).thenReturn(Either.right(subscriptionStatus))

val resp = RULE.target("/subscription/status")
.request()
Expand All @@ -79,22 +72,17 @@ class SubscriptionResourceTest {
}

@Test
@Throws(Exception::class)
fun getActivePseudonyms() {
val arg = argumentCaptor<String>()

val msisdn = "4790300001"
val url = "${PSEUDONYMENDPOINT}/pseudonym/active/$msisdn"
val pseudonym = PseudonymEntity(msisdn, "random", 0, 1)
val activePseudonyms = ActivePseudonyms(pseudonym, pseudonym)
val responseJsonString = ObjectMapper().writeValueAsString(activePseudonyms)
val response = Response.status(Response.Status.OK)
.entity(responseJsonString)
.build()

`when`<Either<ApiError, String>>(DAO.getMsisdn(arg.capture())).thenReturn(Either.right(msisdn))
`when`<WebTarget>(client.target(url)).thenReturn(target)
`when`<Invocation.Builder>(target.request()).thenReturn(request)
`when`<Response>(request.get()).thenReturn(response)
`when`(DAO.getActivePseudonymOfMsisdnForSubscriber(arg.capture()))
.thenReturn(Either.right(activePseudonyms))

val responseJsonString = ObjectMapper().writeValueAsString(activePseudonyms)

val resp = RULE.target("/subscription/activePseudonyms")
.request()
Expand All @@ -111,10 +99,6 @@ class SubscriptionResourceTest {

val DAO: SubscriberDAO = mock(SubscriberDAO::class.java)
val AUTHENTICATOR: OAuthAuthenticator = mock(OAuthAuthenticator::class.java)
val PSEUDONYMENDPOINT = "http://localhost"
val client: Client = mock(Client::class.java)
val target: WebTarget = mock(WebTarget::class.java)
val request: Invocation.Builder = mock(Invocation.Builder::class.java)

@JvmField
@ClassRule
Expand All @@ -125,7 +109,7 @@ class SubscriptionResourceTest {
.setPrefix("Bearer")
.buildAuthFilter()))
.addResource(AuthValueFactoryProvider.Binder(AccessTokenPrincipal::class.java))
.addResource(SubscriptionResource(DAO, client, PSEUDONYMENDPOINT))
.addResource(SubscriptionResource(DAO))
.setTestContainerFactory(GrizzlyWebTestContainerFactory())
.build()
}
Expand Down
22 changes: 3 additions & 19 deletions docker-compose.override.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ services:
- PUBSUB_EMULATOR_HOST=pubsub-emulator:8085
- PUBSUB_PROJECT_ID=pantel-2decb
- STRIPE_API_KEY=${STRIPE_API_KEY}
- DATASTORE_EMULATOR_HOST=localhost:9090
- DATASTORE_PROJECT_ID=pantel-2decb
- LOCAL_TESTING=true
ports:
- "9090:8080"
# - "7687:7687"
depends_on:
- "pubsub-emulator"
- "neo4j"
Expand Down Expand Up @@ -73,19 +75,6 @@ services:
ipv4_address: 172.16.238.2
default:

pseudonym-server:
container_name: pseudonym-server
build: pseudonym-server
ports:
- "8090:8080"
environment:
- DATASTORE_EMULATOR_HOST=localhost:9090
- DATASTORE_PROJECT_ID=pantel-2decb
- PUBSUB_EMULATOR_HOST=localhost:9080
- PUBSUB_PROJECT_ID=pantel-2decb
- LOCAL_TESTING=true
command: ["/bin/bash", "./wait_for_emulators.sh"]

neo4j:
container_name: "neo4j"
image: neo4j:3.4.4
Expand All @@ -100,11 +89,6 @@ services:
container_name: pubsub-emulator
image: knarz/pubsub-emulator

gpubsub-emulator:
container_name: gpubsub-emulator
image: google/cloud-sdk
command: ["gcloud", "beta", "emulators", "pubsub", "start", "--host-port=0.0.0.0:8085"]

datastore-emulator:
container_name: datastore-emulator
image: google/cloud-sdk
Expand Down
Loading

0 comments on commit 3f4fe09

Please sign in to comment.