Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Common module #801

Merged
merged 10 commits into from
Jun 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018-2020 The Feast 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
~
~ https://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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<artifactId>feast-parent</artifactId>
<groupId>dev.feast</groupId>
<version>${revision}</version>
</parent>

<name>Feast Common</name>
<description>Feast common module with functionality that can be reused</description>
<artifactId>feast-common</artifactId>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<argLine>-Xms2048m -Xmx2048m -Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>dev.feast</groupId>
<artifactId>datatypes-java</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2018-2019 The Feast Authors
* Copyright 2018-2020 The Feast Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,25 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package feast.serving.util;
package feast.common.models;

import feast.proto.core.FeatureSetProto.FeatureSetSpec;
import feast.proto.serving.ServingAPIProto.FeatureReference;

public class RefUtil {
public static String generateFeatureStringRef(FeatureReference featureReference) {
public class Feature {

/**
* Accepts FeatureReference object and returns its reference in String
* "project/featureset_name:feature_name".
*
* @param featureReference {@link FeatureReference}
* @param ignoreProject Flag whether to return FeatureReference with project name
* @return String format of FeatureReference
*/
public static String getFeatureStringRef(
FeatureReference featureReference, boolean ignoreProject) {
woop marked this conversation as resolved.
Show resolved Hide resolved
String ref = featureReference.getName();
if (!featureReference.getFeatureSet().isEmpty()) {
ref = featureReference.getFeatureSet() + ":" + ref;
}
if (!featureReference.getProject().isEmpty()) {
if (!featureReference.getProject().isEmpty() && !ignoreProject) {
ref = featureReference.getProject() + "/" + ref;
}
return ref;
}

public static String generateFeatureSetStringRef(FeatureSetSpec featureSetSpec) {
String ref = String.format("%s/%s", featureSetSpec.getProject(), featureSetSpec.getName());
return ref;
}
}
44 changes: 44 additions & 0 deletions common/src/main/java/feast/common/models/FeatureSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2018-2020 The Feast 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
*
* https://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 feast.common.models;

import feast.proto.core.FeatureSetProto.FeatureSetSpec;
import feast.proto.core.FeatureSetReferenceProto.FeatureSetReference;

public class FeatureSet {

/**
* Accepts FeatureSetSpec object and returns its reference in String "project/featureset_name".
*
* @param featureSetSpec {@link FeatureSetSpec}
* @return String format of FeatureSetReference
*/
public static String getFeatureSetStringRef(FeatureSetSpec featureSetSpec) {
return String.format("%s/%s", featureSetSpec.getProject(), featureSetSpec.getName());
}

/**
* Accepts FeatureSetReference object and returns its reference in String
* "project/featureset_name".
*
* @param featureSetReference {@link FeatureSetReference}
* @return String format of FeatureSetReference
*/
public static String getFeatureSetStringRef(FeatureSetReference featureSetReference) {
return String.format("%s/%s", featureSetReference.getProject(), featureSetReference.getName());
}
}
98 changes: 98 additions & 0 deletions common/src/main/java/feast/common/models/Store.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2018-2020 The Feast 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
*
* https://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 feast.common.models;

import feast.proto.core.StoreProto.Store.Subscription;
import java.util.List;
import java.util.regex.Pattern;

public class Store {

/**
* Accepts a Subscription class object and returns it in string format
*
* @param subscription Subscription class to be converted to string format
* @return String formatted Subscription class
*/
public static String parseSubscriptionFrom(Subscription subscription) {
if (subscription.getName().isEmpty() || subscription.getProject().isEmpty()) {
throw new IllegalArgumentException(
String.format("Missing arguments in subscription string: %s", subscription.toString()));
}

return String.format("%s:%s", subscription.getProject(), subscription.getName());
}

/**
* Accepts a exclude parameter to determine whether to return subscriptions that are excluded.
*
* @param subscription String formatted Subscription to be converted to Subscription class
* @return Subscription class with its respective attributes
*/
public static Subscription convertStringToSubscription(String subscription) {
if (subscription.equals("")) {
return Subscription.newBuilder().build();
}
String[] split = subscription.split(":");
return Subscription.newBuilder().setProject(split[0]).setName(split[1]).build();
}

/**
* The current use of this function is to determine whether a FeatureRow is subscribed to a
* Featureset.
*
* @param subscriptions List of Subscriptions available in Store
* @param projectName Project name used for matching Subscription's Project
* @param featureSetName Featureset name used for matching Subscription's Featureset
* @return boolean flag to signify if FeatureRow is subscribed to Featureset
*/
public static boolean isSubscribedToFeatureSet(
List<Subscription> subscriptions, String projectName, String featureSetName) {
for (Subscription sub : subscriptions) {
// If configuration missing, fail
if (sub.getProject().isEmpty() || sub.getName().isEmpty()) {
throw new IllegalArgumentException(
String.format("Subscription is missing arguments: %s", sub.toString()));
}

// If all wildcards, subscribe to everything
if (sub.getProject().equals("*") || sub.getName().equals("*")) {
return true;
}

// Match project name
if (!projectName.equals(sub.getProject())) {
continue;
}

// Convert wildcard to regex
String subName = sub.getName();
if (!sub.getName().contains(".*")) {
subName = subName.replace("*", ".*");
}

// Match feature set name to pattern
Pattern pattern = Pattern.compile(subName);
if (!pattern.matcher(featureSetName).matches()) {
continue;
}
return true;
}

return false;
}
}
97 changes: 97 additions & 0 deletions common/src/test/java/feast/common/models/FeatureSetTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2018-2020 The Feast 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
*
* https://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 feast.common.models;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;

import feast.proto.core.FeatureSetProto.EntitySpec;
import feast.proto.core.FeatureSetProto.FeatureSetSpec;
import feast.proto.core.FeatureSetProto.FeatureSpec;
import feast.proto.core.FeatureSetReferenceProto;
import feast.proto.types.ValueProto;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.tensorflow.metadata.v0.*;

public class FeatureSetTest {

private List<EntitySpec> entitySpecs;
private List<FeatureSpec> featureSpecs;

@Before
public void setUp() {
// Entity Specs
EntitySpec entitySpec1 =
EntitySpec.newBuilder()
.setName("entity1")
.setValueType(ValueProto.ValueType.Enum.INT64)
.build();
EntitySpec entitySpec2 =
EntitySpec.newBuilder()
.setName("entity2")
.setValueType(ValueProto.ValueType.Enum.INT64)
.build();

// Feature Specs
FeatureSpec featureSpec1 =
FeatureSpec.newBuilder()
.setName("feature1")
.setValueType(ValueProto.ValueType.Enum.INT64)
.setPresence(FeaturePresence.getDefaultInstance())
.setShape(FixedShape.getDefaultInstance())
.setDomain("mydomain")
.build();
FeatureSpec featureSpec2 =
FeatureSpec.newBuilder()
.setName("feature2")
.setValueType(ValueProto.ValueType.Enum.INT64)
.setGroupPresence(FeaturePresenceWithinGroup.getDefaultInstance())
.setValueCount(ValueCount.getDefaultInstance())
.setIntDomain(IntDomain.getDefaultInstance())
.build();

entitySpecs = Arrays.asList(entitySpec1, entitySpec2);
featureSpecs = Arrays.asList(featureSpec1, featureSpec2);
}

@Test
public void shouldReturnFeatureSetStringRef() {
FeatureSetSpec featureSetSpec =
FeatureSetSpec.newBuilder()
.setProject("project1")
.setName("featureSetWithConstraints")
.addAllEntities(entitySpecs)
.addAllFeatures(featureSpecs)
.build();

FeatureSetReferenceProto.FeatureSetReference featureSetReference =
FeatureSetReferenceProto.FeatureSetReference.newBuilder()
.setName(featureSetSpec.getName())
.setProject(featureSetSpec.getProject())
.build();

String actualFeatureSetStringRef1 = FeatureSet.getFeatureSetStringRef(featureSetSpec);
String actualFeatureSetStringRef2 = FeatureSet.getFeatureSetStringRef(featureSetReference);
String expectedFeatureSetStringRef = "project1/featureSetWithConstraints";

assertThat(actualFeatureSetStringRef1, equalTo(expectedFeatureSetStringRef));
assertThat(actualFeatureSetStringRef2, equalTo(expectedFeatureSetStringRef));
}
}
Loading