Skip to content

Commit

Permalink
HDDS-11963. Unify client version and layout version under one interfa…
Browse files Browse the repository at this point in the history
…ce to accomodate in the request validator framework

Change-Id: I4c1844a1dfb6127a73b46a92933db33b09c6b06e
  • Loading branch information
swamirishi committed Dec 19, 2024
1 parent f5ff2f0 commit 49efb20
Show file tree
Hide file tree
Showing 6 changed files with 166 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.Version;

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

/**
* 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 Version {
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.Version;

import java.util.Optional;

/**
* Generic Layout feature interface for Ozone.
*/
public interface LayoutFeature {
public interface LayoutFeature extends Version {
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.Version;
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 Version 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 Version 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 Version extractVersion(OMRequest req, ValidationContext ctx);
public abstract Class<? extends Version> getVersionClass();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.apache.hadoop.ozone.om.request.validation;

import org.apache.hadoop.ozone.ClientVersion;
import org.apache.hadoop.ozone.Version;
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.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;

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

class TestVersionExtractor {

private static Stream<Arguments> layoutValues() {
return Arrays.stream(OMLayoutFeature.values()).map(Arguments::of);
}

private static Stream<Arguments> clientVersionValues() {
return Stream.of(
Arrays.stream(ClientVersion.values())
.map(clientVersion -> Arguments.of(clientVersion, clientVersion.version())),
IntStream.range(1, 10)
.mapToObj(delta -> Arguments.of(ClientVersion.FUTURE_VERSION, ClientVersion.CURRENT_VERSION + delta))
).flatMap(Function.identity());
}

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

@ParameterizedTest
@MethodSource("clientVersionValues")
void testClientVersionExtractor(ClientVersion expectedClientVersion, int clientVersion) {
OMRequest request = mock(OMRequest.class);
when(request.getVersion()).thenReturn(clientVersion);
Version version = VersionExtractor.CLIENT_VERSION_EXTRACTOR.extractVersion(request, null);
assertEquals(expectedClientVersion, version);
assertEquals(ClientVersion.class, VersionExtractor.CLIENT_VERSION_EXTRACTOR.getVersionClass());
}
}

0 comments on commit 49efb20

Please sign in to comment.