Skip to content

Commit

Permalink
Convert Key to ResourceName in v2 services (#111)
Browse files Browse the repository at this point in the history
* Convert Key to ResourceName in v2 services

* added ProtocolConfigKey for HeraldTest

* fix lint

* using failgrpc methods

* exception when neither DataProvider nor ModelProvider provided

* fix error message

* fix error message in test

* dropping v2 in variable name

* lint fix

* fix HeraldTest dependency

* making resource keys public for all repos

* make exchangestepattemptid equal to attempt number

* make exchangestepid equal to step index
  • Loading branch information
yunyeng authored Jun 22, 2021
1 parent ecc7b7b commit 8399fe4
Show file tree
Hide file tree
Showing 23 changed files with 549 additions and 144 deletions.
4 changes: 2 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,9 @@ load("//build/wfa:repositories.bzl", "wfa_repo_archive")

wfa_repo_archive(
name = "wfa_measurement_proto",
commit = "ab647fffd78f29769611f05ef131ec1f1feed820",
commit = "584b40ca7b4275d194cc4cedfb877c05ec5ab24e",
repo = "cross-media-measurement-api",
sha256 = "c7d87a438a446ebeacdcae8bcfed270c513ae5c5d26bccd36fb179d47e7d3365",
sha256 = "12f231fe7c8f75e3170ee9c6e308d355eccc354ed60ef4505f6f537812652626",
)

wfa_repo_archive(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@ package(default_visibility = [
"//src/test/kotlin/org/wfanet/measurement/integration/common:__pkg__",
])

kt_jvm_library(
name = "resource_key",
srcs = glob(["*Key.kt"]) + ["IdVariable.kt"],
visibility = ["//visibility:public"],
deps = [
"//src/main/kotlin/org/wfanet/measurement/common",
],
)

kt_jvm_library(
name = "requisition_fulfillment_service",
srcs = ["RequisitionFulfillmentService.kt"],
deps = [
":resource_key",
"//imports/kotlin/kotlinx/coroutines:core",
"//src/main/kotlin/org/wfanet/measurement/common/grpc",
"//src/main/kotlin/org/wfanet/measurement/duchy/storage:metric_value_store",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.duchy.service.api.v2alpha

import org.wfanet.measurement.common.ResourceNameParser

internal enum class IdVariable() {
DATA_PROVIDER,
REQUISITION,
PROTOCOL_CONFIG
}

internal fun ResourceNameParser.assembleName(idMap: Map<IdVariable, String>): String {
return assembleName(idMap.mapKeys { it.key.name.toLowerCase() })
}

internal fun ResourceNameParser.parseIdVars(resourceName: String): Map<IdVariable, String>? {
return parseIdSegments(resourceName)?.mapKeys { IdVariable.valueOf(it.key.toUpperCase()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.duchy.service.api.v2alpha

import org.wfanet.measurement.common.ResourceNameParser

private val parser = ResourceNameParser("protocolConfigs/{protocol_config}")

/** [ResourceKey] of a ProtocolConfig. */
data class ProtocolConfigKey(val protocolConfigId: String) : ResourceKey {
override fun toName(): String {
return parser.assembleName(mapOf(IdVariable.PROTOCOL_CONFIG to protocolConfigId))
}

companion object {
val defaultValue = ProtocolConfigKey("")

fun fromName(resourceName: String): ProtocolConfigKey? {
return parser.parseIdVars(resourceName)?.let {
ProtocolConfigKey(it.getValue(IdVariable.PROTOCOL_CONFIG))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import org.wfanet.measurement.internal.duchy.GetComputationTokenRequest
import org.wfanet.measurement.internal.duchy.GetComputationTokenResponse
import org.wfanet.measurement.internal.duchy.RecordRequisitionBlobPathRequest
import org.wfanet.measurement.system.v1alpha.FulfillRequisitionRequest as SystemFulfillRequisitionRequest
import org.wfanet.measurement.system.v1alpha.RequisitionKey
import org.wfanet.measurement.system.v1alpha.RequisitionKey as SystemRequisitionKey
import org.wfanet.measurement.system.v1alpha.RequisitionsGrpcKt.RequisitionsCoroutineStub

private val FULFILLED_RESPONSE =
Expand All @@ -52,13 +52,19 @@ class RequisitionFulfillmentService(
): FulfillRequisitionResponse {
grpcRequireNotNull(requests.consumeFirst()) { "Empty request stream" }.use { consumed ->
val header = consumed.item.header
grpcRequire(header.valid) { "resource_key/fingerprint missing or incomplete in the header." }
val key =
grpcRequireNotNull(RequisitionKey.fromName(header.name)) {
"Resource name unspecified or invalid."
}
grpcRequire(!header.dataProviderParticipationSignature.isEmpty) {
"DataProviderParticipationSignature is missing in the header."
}

val externalRequisitionKey =
ExternalRequisitionKey.newBuilder()
.apply {
externalDataProviderId = header.key.dataProviderId
externalRequisitionId = header.key.requisitionId
externalDataProviderId = key.dataProviderId
externalRequisitionId = key.requisitionId
}
.build()

Expand Down Expand Up @@ -90,13 +96,6 @@ class RequisitionFulfillmentService(
}
}

private val FulfillRequisitionRequest.Header.valid: Boolean
get() {
return key.dataProviderId.isNotBlank() &&
key.requisitionId.isNotBlank() &&
!dataProviderParticipationSignature.isEmpty
}

/** Gets the token of the computation that this requisition is used in. */
private suspend fun ExternalRequisitionKey.toComputationToken(): ComputationToken {
val request = GetComputationTokenRequest.newBuilder().also { it.requisitionKey = this }.build()
Expand Down Expand Up @@ -146,7 +145,7 @@ class RequisitionFulfillmentService(
systemRequisitionsClient.fulfillRequisition(
SystemFulfillRequisitionRequest.newBuilder()
.apply {
name = RequisitionKey(computationId, requisitionId).toName()
name = SystemRequisitionKey(computationId, requisitionId).toName()
dataProviderParticipationSignature = signature
}
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.duchy.service.api.v2alpha

import org.wfanet.measurement.common.ResourceNameParser

private val parser = ResourceNameParser("dataProviders/{data_provider}/requisitions/{requisition}")

/** [ResourceKey] of a Requisition. */
data class RequisitionKey(val dataProviderId: String, val requisitionId: String) : ResourceKey {
override fun toName(): String {
return parser.assembleName(
mapOf(IdVariable.DATA_PROVIDER to dataProviderId, IdVariable.REQUISITION to requisitionId)
)
}

companion object {
val defaultValue = RequisitionKey("", "")

fun fromName(resourceName: String): RequisitionKey? {
return parser.parseIdVars(resourceName)?.let {
RequisitionKey(it.getValue(IdVariable.DATA_PROVIDER), it.getValue(IdVariable.REQUISITION))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.duchy.service.api.v2alpha

interface ResourceKey {
/** Converts this [ResourceKey] into a resource name. */
fun toName(): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ kt_jvm_library(
],
)

kt_jvm_library(
name = "resource_key",
srcs = glob(["*Key.kt"]) + ["IdVariable.kt"],
visibility = ["//visibility:public"],
deps = [
"//src/main/kotlin/org/wfanet/measurement/common",
],
)

kt_jvm_library(
name = "recurring_exchanges_service",
srcs = ["RecurringExchangesService.kt"],
Expand Down Expand Up @@ -51,6 +60,7 @@ kt_jvm_library(
name = "exchange_step_attempts_service",
srcs = ["ExchangeStepAttemptsService.kt"],
deps = [
":resource_key",
":util",
"//imports/kotlin/kotlinx/coroutines:core",
"//src/main/kotlin/org/wfanet/measurement/common",
Expand All @@ -69,6 +79,7 @@ kt_jvm_library(
name = "exchange_steps_service",
srcs = ["ExchangeStepsService.kt"],
deps = [
":resource_key",
":util",
"//imports/kotlin/kotlinx/coroutines:core",
"//src/main/kotlin/org/wfanet/measurement/common",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.kingdom.service.api.v2alpha

import org.wfanet.measurement.common.ResourceNameParser

private val parser = ResourceNameParser("dataProviders/{data_provider}")

/** [DataProviderKey] of a Data Provider. */
data class DataProviderKey(val dataProviderId: String) : ResourceKey {
override fun toName(): String {
return parser.assembleName(mapOf(IdVariable.DATA_PROVIDER to dataProviderId))
}

companion object {
val defaultValue = DataProviderKey("")

fun fromName(resourceName: String): DataProviderKey? {
return parser.parseIdVars(resourceName)?.let {
DataProviderKey(it.getValue(IdVariable.DATA_PROVIDER))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.kingdom.service.api.v2alpha

import org.wfanet.measurement.common.ResourceNameParser

private val parser =
ResourceNameParser("recurringExchanges/{recurring_exchange}/exchanges/{exchange}")

/** [ExchangeKey] of an Exchange. */
data class ExchangeKey(val recurringExchangeId: String, val exchangeId: String) : ResourceKey {
override fun toName(): String {
return parser.assembleName(
mapOf(IdVariable.RECURRING_EXCHANGE to recurringExchangeId, IdVariable.EXCHANGE to exchangeId)
)
}

companion object {
val defaultValue = ExchangeKey("", "")

fun fromName(resourceName: String): ExchangeKey? {
return parser.parseIdVars(resourceName)?.let {
ExchangeKey(it.getValue(IdVariable.RECURRING_EXCHANGE), it.getValue(IdVariable.EXCHANGE))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2021 The Cross-Media Measurement Authors
//
// 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.wfanet.measurement.kingdom.service.api.v2alpha

import org.wfanet.measurement.common.ResourceNameParser

private val parser =
ResourceNameParser(
"recurringExchanges/{recurring_exchange}/exchanges/{exchange}/steps/{exchange_step}/" +
"attempts/{exchange_step_attempt}"
)

/** [ExchangeStepAttemptKey] of an Exchange Step Attempt. */
data class ExchangeStepAttemptKey(
val recurringExchangeId: String,
val exchangeId: String,
val exchangeStepId: String,
val exchangeStepAttemptId: String
) : ResourceKey {
override fun toName(): String {
return parser.assembleName(
mapOf(
IdVariable.RECURRING_EXCHANGE to recurringExchangeId,
IdVariable.EXCHANGE to exchangeId,
IdVariable.EXCHANGE_STEP to exchangeStepId,
IdVariable.EXCHANGE_STEP_ATTEMPT to exchangeStepAttemptId
)
)
}

companion object {
val defaultValue = ExchangeStepAttemptKey("", "", "", "")

fun fromName(resourceName: String): ExchangeStepAttemptKey? {
return parser.parseIdVars(resourceName)?.let {
ExchangeStepAttemptKey(
it.getValue(IdVariable.RECURRING_EXCHANGE),
it.getValue(IdVariable.EXCHANGE),
it.getValue(IdVariable.EXCHANGE_STEP),
it.getValue(IdVariable.EXCHANGE_STEP_ATTEMPT)
)
}
}
}
}
Loading

0 comments on commit 8399fe4

Please sign in to comment.