/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch 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 * * 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.elasticsearch.repositories.gcs; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Map; import com.google.api.client.auth.oauth2.TokenRequest; import com.google.api.client.auth.oauth2.TokenResponse; import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpHeaders; import com.google.api.client.json.GenericJson; import com.google.api.client.json.webtoken.JsonWebSignature; import com.google.api.client.json.webtoken.JsonWebToken; import com.google.api.client.util.ClassInfo; import com.google.api.client.util.Data; import com.google.api.services.storage.Storage; import com.google.api.services.storage.model.Bucket; import com.google.api.services.storage.model.Objects; import com.google.api.services.storage.model.StorageObject; import org.elasticsearch.SpecialPermission; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.env.Environment; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.RepositoryPlugin; import org.elasticsearch.repositories.Repository; import org.elasticsearch.repositories.gcs.GoogleCloudStorageRepository; import org.elasticsearch.repositories.gcs.GoogleCloudStorageService; public class GoogleCloudStoragePlugin extends Plugin implements RepositoryPlugin { public static final String NAME = "repository-gcs"; static { /* * Google HTTP client changes access levels because its silly and we * can't allow that on any old stack stack so we pull it here, up front, * so we can cleanly check the permissions for it. Without this changing * the permission can fail if any part of core is on the stack because * our plugin permissions don't allow core to "reach through" plugins to * change the permission. Because that'd be silly. */ SpecialPermission.check(); AccessController.doPrivileged((PrivilegedAction<Void>) () -> { // ClassInfo put in cache all the fields of a given class // that are annoted with @Key; at the same time it changes // the field access level using setAccessible(). Calling // them here put the ClassInfo in cache (they are never evicted) // before the SecurityManager is installed. ClassInfo.of(HttpHeaders.class, true); ClassInfo.of(JsonWebSignature.Header.class, false); ClassInfo.of(JsonWebToken.Payload.class, false); ClassInfo.of(TokenRequest.class, false); ClassInfo.of(TokenResponse.class, false); ClassInfo.of(GenericJson.class, false); ClassInfo.of(GenericUrl.class, false); Data.nullOf(GoogleJsonError.ErrorInfo.class); ClassInfo.of(GoogleJsonError.class, false); Data.nullOf(Bucket.Cors.class); ClassInfo.of(Bucket.class, false); ClassInfo.of(Bucket.Cors.class, false); ClassInfo.of(Bucket.Lifecycle.class, false); ClassInfo.of(Bucket.Logging.class, false); ClassInfo.of(Bucket.Owner.class, false); ClassInfo.of(Bucket.Versioning.class, false); ClassInfo.of(Bucket.Website.class, false); ClassInfo.of(StorageObject.class, false); ClassInfo.of(StorageObject.Owner.class, false); ClassInfo.of(Objects.class, false); ClassInfo.of(Storage.Buckets.Get.class, false); ClassInfo.of(Storage.Buckets.Insert.class, false); ClassInfo.of(Storage.Objects.Get.class, false); ClassInfo.of(Storage.Objects.Insert.class, false); ClassInfo.of(Storage.Objects.Delete.class, false); ClassInfo.of(Storage.Objects.Copy.class, false); ClassInfo.of(Storage.Objects.List.class, false); return null; }); } // overridable for tests protected GoogleCloudStorageService createStorageService(Environment environment) { return new GoogleCloudStorageService.InternalGoogleCloudStorageService(environment); } @Override public Map<String, Repository.Factory> getRepositories(Environment env, NamedXContentRegistry namedXContentRegistry) { return Collections.singletonMap(GoogleCloudStorageRepository.TYPE, (metadata) -> new GoogleCloudStorageRepository(metadata, env, namedXContentRegistry, createStorageService(env))); } }