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 aa9d8fd + fc8001e commit 3b0b205
Show file tree
Hide file tree
Showing 42 changed files with 563 additions and 899 deletions.
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
3 changes: 2 additions & 1 deletion payment-processor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ sourceSets {
test {
java.srcDirs = ['src/test/kotlin']
}

integration {
java.srcDirs = ['src/test/kotlin', 'src/integration-tests/kotlin']
resources.srcDir 'src/integration-tests/resources'
Expand Down Expand Up @@ -53,6 +52,8 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
}
}

apply from: '../jacoco.gradle'

idea {
module {
testSourceDirs += file('src/integration-tests/kotlin')
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
org.ostelco.prime.paymentprocessor.PaymentProcessorModule
org.ostelco.prime.paymentprocessor.PaymentProcessorModule
Loading

0 comments on commit 3b0b205

Please sign in to comment.