diff --git a/gradle/node.gradle b/gradle/node.gradle index ba895450573..bb0ea5b3f82 100644 --- a/gradle/node.gradle +++ b/gradle/node.gradle @@ -15,7 +15,7 @@ * limitations under the License. */ -configure([project(":solr:packaging"), project(":solr:solr-ref-guide")]) { +configure([project(":solr:packaging"), project(":solr:solr-ref-guide"), project(":solr:webapp")]) { apply plugin: "com.github.node-gradle.node" ext { diff --git a/solr/api/build.gradle b/solr/api/build.gradle index 8e50d634485..b83b61683d5 100644 --- a/solr/api/build.gradle +++ b/solr/api/build.gradle @@ -17,6 +17,7 @@ plugins { id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.2' + id "org.openapi.generator" version "6.0.1" } apply plugin: 'java-library' @@ -24,6 +25,7 @@ apply plugin: 'java-library' description = 'API - Interfaces and classes used to represent Solrs APIs' ext { + jsClientDir = "${buildDir}/generated/js" openApiSpecDir = "${buildDir}/generated/openapi" openApiSpecFile = "${project.openApiSpecDir}/openapi.json" } @@ -33,6 +35,10 @@ configurations { canBeConsumed = true canBeResolved = false } + jsClient { + canBeConsumed = true + canBeResolved = false + } } resolve { @@ -55,8 +61,29 @@ dependencies { testImplementation 'org.apache.lucene:lucene-test-framework' } +// Non-Java client generation tasks below: + +task buildJSClient(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) { + generatorName.set("javascript") + inputSpec.set("$openApiSpecFile") + outputDir.set("$jsClientDir") + packageName.set("solr") + generateApiTests.set(false) + generateModelTests.set(false) +} + +tasks.withType(org.openapitools.generator.gradle.plugin.tasks.GenerateTask) { + dependsOn(resolve) +} + artifacts { + // Ensure the OAS is available to other modules who want to generate code (i.e. solrj) openapiSpec resolve.outputDir, { builtBy resolve } + + // Makes our Javascript client available to the Admin UI build + jsClient file(project.jsClientDir), { + builtBy buildJSClient + } } diff --git a/solr/webapp/build.gradle b/solr/webapp/build.gradle index d0074eed77d..6cd0189ac61 100644 --- a/solr/webapp/build.gradle +++ b/solr/webapp/build.gradle @@ -26,6 +26,14 @@ configurations { war {} serverLib solrCore + generatedJSClient + generatedJSClientBundle +} + +ext { + jsClientWorkspace = layout.buildDirectory.dir("jsClientWorkspace").get() + jsClientBundleDir = layout.buildDirectory.dir("jsClientBundle").get() + browserifyVersion = "17.0.0" } dependencies { @@ -34,6 +42,77 @@ dependencies { serverLib project(path: ":solr:server", configuration: "serverLib") solrCore project(":solr:core") implementation(configurations.solrCore - configurations.serverLib) + + generatedJSClient project(path: ":solr:api", configuration: "jsClient") + generatedJSClientBundle files(jsClientBundleDir) { + builtBy "generateJsClientBundle" + } +} + +task syncJSClientSourceCode(type: Sync) { + group = 'Solr JS Client' + from configurations.generatedJSClient + + into project.jsClientWorkspace +} + +task jsClientDownloadDeps(type: NpmTask) { + group = 'Solr JS Client' + dependsOn tasks.syncJSClientSourceCode + + args = ["install"] + workingDir = file(project.jsClientWorkspace) + + inputs.dir("${jsClientWorkspace}/src") + inputs.file("${jsClientWorkspace}/package.json") + outputs.dir("${jsClientWorkspace}/node_modules") +} + +task jsClientBuild(type: NpmTask) { + group = 'Solr JS Client' + dependsOn tasks.jsClientDownloadDeps + + args = ["run", "build"] + workingDir = file(project.jsClientWorkspace) + + inputs.dir("${jsClientWorkspace}/src") + inputs.file("${jsClientWorkspace}/package.json") + inputs.dir("${jsClientWorkspace}/node_modules") + outputs.dir("${jsClientWorkspace}/dist") +} + +task downloadBrowserify(type: NpmTask) { + group = 'Build Dependency Download' + args = ["install", "browserify@${project.browserifyVersion}"] + + inputs.property("browserify version", project.browserifyVersion) + outputs.dir("${project.nodeProjectDir}/node_modules/browserify") +} + +task setupJsBundleDir(type: Sync) { + group = 'Solr JS Client' + dependsOn tasks.syncJSClientSourceCode + + from configurations.generatedJSClient + + include "README.md" + include "docs/**" + + into project.jsClientBundleDir +} + +task generateJsClientBundle(type: NpxTask) { + group = 'Solr JS Client' + dependsOn tasks.downloadBrowserify + dependsOn tasks.jsClientBuild + dependsOn tasks.setupJsBundleDir + + command = 'browserify' + args = ['dist/index.js', '-s', 'solrApi', '-o', "${jsClientBundleDir}/index.js"] + workingDir = file(project.jsClientWorkspace) + + + outputs.dir("${jsClientBundleDir}") } war { @@ -44,6 +123,10 @@ war { exclude "libs/angular-utf8-base.js" exclude "libs/angular.js" exclude "libs/chosen.jquery.js" + + from (configurations.generatedJSClientBundle, { + into "libs/solr" + }) } // Expose 'war' archive as an artifact so that it can be packaged in the distribution. diff --git a/solr/webapp/web/index.html b/solr/webapp/web/index.html index 35b1d664860..dbe9a840c1a 100644 --- a/solr/webapp/web/index.html +++ b/solr/webapp/web/index.html @@ -68,6 +68,7 @@ + diff --git a/solr/webapp/web/js/angular/controllers/collections.js b/solr/webapp/web/js/angular/controllers/collections.js index be24620abf0..830290a1806 100644 --- a/solr/webapp/web/js/angular/controllers/collections.js +++ b/solr/webapp/web/js/angular/controllers/collections.js @@ -16,7 +16,7 @@ */ solrAdminApp.controller('CollectionsController', - function($scope, $routeParams, $location, $timeout, Collections, Zookeeper, Constants, ConfigSets){ + function($scope, $routeParams, $location, $timeout, Collections, CollectionsV2, Zookeeper, Constants, ConfigSets){ $scope.resetMenu("collections", Constants.IS_ROOT_PAGE); $scope.refresh = function() { @@ -215,16 +215,16 @@ solrAdminApp.controller('CollectionsController', alert("No collection selected."); return; } - Collections.reload({name: $scope.collection.name}, - function(successData) { - $scope.reloadSuccess = true; - $timeout(function() {$scope.reloadSuccess=false}, 1000); - }, - function(failureData) { - $scope.reloadFailure = true; - $timeout(function() {$scope.reloadFailure=false}, 1000); - $location.path("/~collections"); - }); + CollectionsV2.reloadCollection($scope.collection.name, function(error, data,response) { + if (error) { + $scope.reloadFailure = true; + $timeout(function() {$scope.reloadFailure=false}, 1000); + $location.path("/~collections"); + } else { + $scope.reloadSuccess = true; + $timeout(function() {$scope.reloadSuccess=false}, 1000); + } + }); }; $scope.toggleAddReplica = function(shard) { diff --git a/solr/webapp/web/js/angular/services.js b/solr/webapp/web/js/angular/services.js index 2b870ab53ff..0a2f5d95266 100644 --- a/solr/webapp/web/js/angular/services.js +++ b/solr/webapp/web/js/angular/services.js @@ -25,6 +25,12 @@ solrAdminServices.factory('System', ['$resource', function($resource) { return $resource('admin/metrics', {"wt":"json", "nodes": "@nodes", "prefix":"@prefix", "_":Date.now()}); }]) +.factory('CollectionsV2', + function() { + solrApi.ApiClient.instance.basePath = '/api'; + delete solrApi.ApiClient.instance.defaultHeaders["User-Agent"]; + return new solrApi.CollectionsApi(); + }) .factory('Collections', ['$resource', function($resource) { return $resource('admin/collections',