Skip to content

Commit

Permalink
HDDS-11963. Add parent interface of component and layout versions for…
Browse files Browse the repository at this point in the history
… use in request validator (apache#7598)
  • Loading branch information
swamirishi authored Dec 20, 2024
1 parent 0306d97 commit 7af38a9
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
*/
package org.apache.hadoop.hdds;

import org.apache.hadoop.ozone.Versioned;

/**
* Base type for component version enums.
*/
public interface ComponentVersion {
public interface ComponentVersion extends Versioned {

/**
* Returns the description of the version enum value.
Expand All @@ -34,4 +36,9 @@ public interface ComponentVersion {
* @return the version associated with the enum value.
*/
int toProtoValue();

@Override
default int version() {
return toProtoValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.hadoop.hdds.ComponentVersion;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;

import static java.util.function.Function.identity;
Expand Down Expand Up @@ -75,8 +76,8 @@ public static ClientVersion fromProtoValue(int value) {
}

private static ClientVersion latest() {
ClientVersion[] versions = ClientVersion.values();
return versions[versions.length - 2];
return Arrays.stream(ClientVersion.values())
.max(Comparator.comparingInt(ComponentVersion::toProtoValue)).orElse(null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.apache.hadoop.ozone;


/**
* Base class defining the version in the entire system.
*/
public interface Versioned {
int version();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@

package org.apache.hadoop.ozone.upgrade;

import org.apache.hadoop.ozone.Versioned;

import java.util.Optional;

/**
* Generic Layout feature interface for Ozone.
*/
public interface LayoutFeature {
public interface LayoutFeature extends Versioned {
String name();

int layoutVersion();
Expand All @@ -48,6 +50,11 @@ default String name() {
void execute(T arg) throws Exception;
}

@Override
default int version() {
return this.layoutVersion();
}

/**
* Phase of execution for this action.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.apache.hadoop.ozone.om.request.validation;

import org.apache.hadoop.ozone.ClientVersion;
import org.apache.hadoop.ozone.Versioned;
import org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.upgrade.LayoutVersionManager;

/**
* Class to extract version out of OM request.
*/
public enum VersionExtractor {
/**
* Extracts current metadata layout version.
*/
LAYOUT_VERSION_EXTRACTOR {
@Override
public Versioned extractVersion(OMRequest req, ValidationContext ctx) {
LayoutVersionManager layoutVersionManager = ctx.versionManager();
return ctx.versionManager().getFeature(layoutVersionManager.getMetadataLayoutVersion());
}

@Override
public Class<OMLayoutFeature> getVersionClass() {
return OMLayoutFeature.class;
}
},

/**
* Extracts client version from the OMRequests.
*/
CLIENT_VERSION_EXTRACTOR {
@Override
public Versioned extractVersion(OMRequest req, ValidationContext ctx) {
return req.getVersion() > ClientVersion.CURRENT_VERSION ?
ClientVersion.FUTURE_VERSION : ClientVersion.fromProtoValue(req.getVersion());
}

@Override
public Class<ClientVersion> getVersionClass() {
return ClientVersion.class;
}
};

public abstract Versioned extractVersion(OMRequest req, ValidationContext ctx);
public abstract Class<? extends Versioned> getVersionClass();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.apache.hadoop.ozone.om.request.validation;

import org.apache.hadoop.ozone.ClientVersion;
import org.apache.hadoop.ozone.Versioned;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature;
import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.upgrade.LayoutVersionManager;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class TestVersionExtractor {

@ParameterizedTest
@EnumSource(OMLayoutFeature.class)
void testLayoutVersionExtractor(OMLayoutFeature layoutVersionValue) throws OMException {
ValidationContext context = mock(ValidationContext.class);
LayoutVersionManager layoutVersionManager = new OMLayoutVersionManager(layoutVersionValue.version());
when(context.versionManager()).thenReturn(layoutVersionManager);
Versioned version = VersionExtractor.LAYOUT_VERSION_EXTRACTOR.extractVersion(null, context);
assertEquals(layoutVersionValue, version);
assertEquals(OMLayoutFeature.class, VersionExtractor.LAYOUT_VERSION_EXTRACTOR.getVersionClass());
}

@ParameterizedTest
@EnumSource(ClientVersion.class)
void testClientVersionExtractor(ClientVersion expectedClientVersion) {
OMRequest request = mock(OMRequest.class);
when(request.getVersion()).thenReturn(expectedClientVersion.version());
Versioned version = VersionExtractor.CLIENT_VERSION_EXTRACTOR.extractVersion(request, null);
assertEquals(expectedClientVersion, version);
assertEquals(ClientVersion.class, VersionExtractor.CLIENT_VERSION_EXTRACTOR.getVersionClass());
}

@ParameterizedTest
@ValueSource(ints = {1, 2, 5, 10, 1000, 10000})
void testClientVersionExtractorForFutureValues(int futureVersion) {
OMRequest request = mock(OMRequest.class);
when(request.getVersion()).thenReturn(ClientVersion.CURRENT_VERSION + futureVersion);
Versioned version = VersionExtractor.CLIENT_VERSION_EXTRACTOR.extractVersion(request, null);
assertEquals(ClientVersion.FUTURE_VERSION, version);
assertEquals(ClientVersion.class, VersionExtractor.CLIENT_VERSION_EXTRACTOR.getVersionClass());
}
}

0 comments on commit 7af38a9

Please sign in to comment.