You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/11/13 15:48:03 UTC
[13/16] knox git commit: Merge branch 'master' into
KNOX-998-Package_Restructuring
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
----------------------------------------------------------------------
diff --cc gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
index a0035fc,0000000..9ecd7fc
mode 100644,000000..100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java
@@@ -1,657 -1,0 +1,674 @@@
+/**
+ * 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
+ *
+ * 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.apache.knox.gateway.service.admin;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.knox.gateway.i18n.GatewaySpiMessages;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.service.admin.beans.BeanConverter;
+import org.apache.knox.gateway.service.admin.beans.Topology;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.topology.TopologyService;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
+
+import static javax.ws.rs.core.Response.ok;
+import static javax.ws.rs.core.Response.created;
+import static javax.ws.rs.core.Response.notModified;
+import static javax.ws.rs.core.Response.status;
+
+
+@Path("/api/v1")
+public class TopologiesResource {
+
+ private static final String XML_EXT = ".xml";
+ private static final String JSON_EXT = ".json";
+
+ private static final String TOPOLOGIES_API_PATH = "topologies";
+ private static final String SINGLE_TOPOLOGY_API_PATH = TOPOLOGIES_API_PATH + "/{id}";
+ private static final String PROVIDERCONFIG_API_PATH = "providerconfig";
+ private static final String SINGLE_PROVIDERCONFIG_API_PATH = PROVIDERCONFIG_API_PATH + "/{name}";
+ private static final String DESCRIPTORS_API_PATH = "descriptors";
+ private static final String SINGLE_DESCRIPTOR_API_PATH = DESCRIPTORS_API_PATH + "/{name}";
+
+ private static GatewaySpiMessages log = MessagesFactory.get(GatewaySpiMessages.class);
+
+ @Context
+ private HttpServletRequest request;
+
+ @GET
+ @Produces({APPLICATION_JSON, APPLICATION_XML})
+ @Path(SINGLE_TOPOLOGY_API_PATH)
+ public Topology getTopology(@PathParam("id") String id) {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ GatewayConfig config = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ for (org.apache.knox.gateway.topology.Topology t : ts.getTopologies()) {
+ if(t.getName().equals(id)) {
+ try {
+ t.setUri(new URI( buildURI(t, config, request) ));
+ } catch (URISyntaxException se) {
+ t.setUri(null);
+ }
+ return BeanConverter.getTopology(t);
+ }
+ }
+ return null;
+ }
+
+ @GET
+ @Produces({APPLICATION_JSON, APPLICATION_XML})
+ @Path(TOPOLOGIES_API_PATH)
+ public SimpleTopologyWrapper getTopologies() {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ ArrayList<SimpleTopology> st = new ArrayList<SimpleTopology>();
+ GatewayConfig conf = (GatewayConfig) request.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
+
+ for (org.apache.knox.gateway.topology.Topology t : ts.getTopologies()) {
+ st.add(getSimpleTopology(t, conf));
+ }
+
+ Collections.sort(st, new TopologyComparator());
+ SimpleTopologyWrapper stw = new SimpleTopologyWrapper();
+
+ for(SimpleTopology t : st){
+ stw.topologies.add(t);
+ }
+
+ return stw;
+
+ }
+
+ @PUT
+ @Consumes({APPLICATION_JSON, APPLICATION_XML})
+ @Path(SINGLE_TOPOLOGY_API_PATH)
+ public Topology uploadTopology(@PathParam("id") String id, Topology t) {
++ Topology result = null;
+
- GatewayServices gs = (GatewayServices) request.getServletContext()
- .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
++ GatewayServices gs =
++ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ t.setName(id);
+ TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
+
- ts.deployTopology(BeanConverter.getTopology(t));
++ // Check for existing topology with the same name, to see if it had been generated
++ boolean existingGenerated = false;
++ for (org.apache.hadoop.gateway.topology.Topology existingTopology : ts.getTopologies()) {
++ if(existingTopology.getName().equals(id)) {
++ existingGenerated = existingTopology.isGenerated();
++ break;
++ }
++ }
++
++ // If a topology with the same ID exists, which had been generated, then DO NOT overwrite it because it will be
++ // out of sync with the source descriptor. Otherwise, deploy the updated version.
++ if (!existingGenerated) {
++ ts.deployTopology(BeanConverter.getTopology(t));
++ result = getTopology(id);
++ } else {
++ log.disallowedOverwritingGeneratedTopology(id);
++ }
+
- return getTopology(id);
++ return result;
+ }
+
+ @DELETE
+ @Produces(APPLICATION_JSON)
+ @Path(SINGLE_TOPOLOGY_API_PATH)
+ public Response deleteTopology(@PathParam("id") String id) {
+ boolean deleted = false;
+ if(!"admin".equals(id)) {
+ GatewayServices services = (GatewayServices) request.getServletContext()
+ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ for (org.apache.knox.gateway.topology.Topology t : ts.getTopologies()) {
+ if(t.getName().equals(id)) {
+ ts.deleteTopology(t);
+ deleted = true;
+ }
+ }
+ }else{
+ deleted = false;
+ }
+ return ok().entity("{ \"deleted\" : " + deleted + " }").build();
+ }
+
+ @GET
+ @Produces({APPLICATION_JSON})
+ @Path(PROVIDERCONFIG_API_PATH)
+ public HrefListing getProviderConfigurations() {
+ HrefListing listing = new HrefListing();
+ listing.setHref(buildHref(request));
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ List<HrefListItem> configs = new ArrayList<>();
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ // Get all the simple descriptor file names
+ for (File providerConfig : ts.getProviderConfigurations()){
+ String id = FilenameUtils.getBaseName(providerConfig.getName());
+ configs.add(new HrefListItem(buildHref(id, request), providerConfig.getName()));
+ }
+
+ listing.setItems(configs);
+ return listing;
+ }
+
+ @GET
+ @Produces({APPLICATION_XML})
+ @Path(SINGLE_PROVIDERCONFIG_API_PATH)
+ public Response getProviderConfiguration(@PathParam("name") String name) {
+ Response response;
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ File providerConfigFile = null;
+
+ for (File pc : ts.getProviderConfigurations()){
+ // If the file name matches the specified id
+ if (FilenameUtils.getBaseName(pc.getName()).equals(name)) {
+ providerConfigFile = pc;
+ break;
+ }
+ }
+
+ if (providerConfigFile != null) {
+ byte[] content = null;
+ try {
+ content = FileUtils.readFileToByteArray(providerConfigFile);
+ response = ok().entity(content).build();
+ } catch (IOException e) {
+ log.failedToReadConfigurationFile(providerConfigFile.getAbsolutePath(), e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+ }
+
+ } else {
+ response = Response.status(Response.Status.NOT_FOUND).build();
+ }
+ return response;
+ }
+
+ @DELETE
+ @Produces(APPLICATION_JSON)
+ @Path(SINGLE_PROVIDERCONFIG_API_PATH)
+ public Response deleteProviderConfiguration(@PathParam("name") String name) {
+ Response response;
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ if (ts.deleteProviderConfiguration(name)) {
+ response = ok().entity("{ \"deleted\" : \"provider config " + name + "\" }").build();
+ } else {
+ response = notModified().build();
+ }
+ return response;
+ }
+
+
+ @DELETE
+ @Produces(APPLICATION_JSON)
+ @Path(SINGLE_DESCRIPTOR_API_PATH)
+ public Response deleteSimpleDescriptor(@PathParam("name") String name) {
+ Response response = null;
+ if(!"admin".equals(name)) {
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ if (ts.deleteDescriptor(name)) {
+ response = ok().entity("{ \"deleted\" : \"descriptor " + name + "\" }").build();
+ }
+ }
+
+ if (response == null) {
+ response = notModified().build();
+ }
+
+ return response;
+ }
+
+
+ @PUT
+ @Consumes({APPLICATION_XML})
+ @Path(SINGLE_PROVIDERCONFIG_API_PATH)
+ public Response uploadProviderConfiguration(@PathParam("name") String name, String content) {
+ Response response = null;
+
+ GatewayServices gs =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ boolean isUpdate = configFileExists(ts.getProviderConfigurations(), name);
+
+ String filename = name.endsWith(XML_EXT) ? name : name + XML_EXT;
+ if (ts.deployProviderConfiguration(filename, content)) {
+ try {
+ if (isUpdate) {
+ response = Response.noContent().build();
+ } else{
+ response = created(new URI(buildHref(request))).build();
+ }
+ } catch (URISyntaxException e) {
+ log.invalidResourceURI(e.getInput(), e.getReason(), e);
+ response = status(Response.Status.BAD_REQUEST).entity("{ \"error\" : \"Failed to deploy provider configuration " + name + "\" }").build();
+ }
+ }
+
+ return response;
+ }
+
+
+ private boolean configFileExists(Collection<File> existing, String candidateName) {
+ boolean result = false;
+ for (File exists : existing) {
+ if (FilenameUtils.getBaseName(exists.getName()).equals(candidateName)) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+
+ @PUT
+ @Consumes({APPLICATION_JSON})
+ @Path(SINGLE_DESCRIPTOR_API_PATH)
+ public Response uploadSimpleDescriptor(@PathParam("name") String name, String content) {
+ Response response = null;
+
+ GatewayServices gs =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = gs.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ boolean isUpdate = configFileExists(ts.getDescriptors(), name);
+
+ String filename = name.endsWith(JSON_EXT) ? name : name + JSON_EXT;
+ if (ts.deployDescriptor(filename, content)) {
+ try {
+ if (isUpdate) {
+ response = Response.noContent().build();
+ } else {
+ response = created(new URI(buildHref(request))).build();
+ }
+ } catch (URISyntaxException e) {
+ log.invalidResourceURI(e.getInput(), e.getReason(), e);
+ response = status(Response.Status.BAD_REQUEST).entity("{ \"error\" : \"Failed to deploy descriptor " + name + "\" }").build();
+ }
+ }
+
+ return response;
+ }
+
+
+ @GET
+ @Produces({APPLICATION_JSON})
+ @Path(DESCRIPTORS_API_PATH)
+ public HrefListing getSimpleDescriptors() {
+ HrefListing listing = new HrefListing();
+ listing.setHref(buildHref(request));
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ List<HrefListItem> descriptors = new ArrayList<>();
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+ for (File descriptor : ts.getDescriptors()){
+ String id = FilenameUtils.getBaseName(descriptor.getName());
+ descriptors.add(new HrefListItem(buildHref(id, request), descriptor.getName()));
+ }
+
+ listing.setItems(descriptors);
+ return listing;
+ }
+
+
+ @GET
+ @Produces({APPLICATION_JSON, TEXT_PLAIN})
+ @Path(SINGLE_DESCRIPTOR_API_PATH)
+ public Response getSimpleDescriptor(@PathParam("name") String name) {
+ Response response;
+
+ GatewayServices services =
+ (GatewayServices) request.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+
+ TopologyService ts = services.getService(GatewayServices.TOPOLOGY_SERVICE);
+
+ File descriptorFile = null;
+
+ for (File sd : ts.getDescriptors()){
+ // If the file name matches the specified id
+ if (FilenameUtils.getBaseName(sd.getName()).equals(name)) {
+ descriptorFile = sd;
+ break;
+ }
+ }
+
+ if (descriptorFile != null) {
+ String mediaType = APPLICATION_JSON;
+
+ byte[] content = null;
+ try {
+ if ("yml".equals(FilenameUtils.getExtension(descriptorFile.getName()))) {
+ mediaType = TEXT_PLAIN;
+ }
+ content = FileUtils.readFileToByteArray(descriptorFile);
+ response = ok().type(mediaType).entity(content).build();
+ } catch (IOException e) {
+ log.failedToReadConfigurationFile(descriptorFile.getAbsolutePath(), e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+ }
+ } else {
+ response = Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ return response;
+ }
+
+
+ private static class TopologyComparator implements Comparator<SimpleTopology> {
+ @Override
+ public int compare(SimpleTopology t1, SimpleTopology t2) {
+ return t1.getName().compareTo(t2.getName());
+ }
+ }
+
+
+ String buildURI(org.apache.knox.gateway.topology.Topology topology, GatewayConfig config, HttpServletRequest req){
+ String uri = buildXForwardBaseURL(req);
+
+ // Strip extra context
+ uri = uri.replace(req.getContextPath(), "");
+
+ // Add the gateway path
+ String gatewayPath;
+ if(config.getGatewayPath() != null){
+ gatewayPath = config.getGatewayPath();
+ }else{
+ gatewayPath = "gateway";
+ }
+ uri += "/" + gatewayPath;
+
+ uri += "/" + topology.getName();
+ return uri;
+ }
+
+ String buildHref(HttpServletRequest req) {
+ return buildHref((String)null, req);
+ }
+
+ String buildHref(String id, HttpServletRequest req) {
+ String href = buildXForwardBaseURL(req);
+ // Make sure that the pathInfo doesn't have any '/' chars at the end.
+ String pathInfo = req.getPathInfo();
+ while(pathInfo.endsWith("/")) {
+ pathInfo = pathInfo.substring(0, pathInfo.length() - 1);
+ }
+
+ href += pathInfo;
+
+ if (id != null) {
+ href += "/" + id;
+ }
+
+ return href;
+ }
+
+ String buildHref(org.apache.knox.gateway.topology.Topology t, HttpServletRequest req) {
+ return buildHref(t.getName(), req);
+ }
+
+ private SimpleTopology getSimpleTopology(org.apache.knox.gateway.topology.Topology t, GatewayConfig config) {
+ String uri = buildURI(t, config, request);
+ String href = buildHref(t, request);
+ return new SimpleTopology(t, uri, href);
+ }
+
+ private String buildXForwardBaseURL(HttpServletRequest req){
+ final String X_Forwarded = "X-Forwarded-";
+ final String X_Forwarded_Context = X_Forwarded + "Context";
+ final String X_Forwarded_Proto = X_Forwarded + "Proto";
+ final String X_Forwarded_Host = X_Forwarded + "Host";
+ final String X_Forwarded_Port = X_Forwarded + "Port";
+ final String X_Forwarded_Server = X_Forwarded + "Server";
+
+ String baseURL = "";
+
+ // Get Protocol
+ if(req.getHeader(X_Forwarded_Proto) != null){
+ baseURL += req.getHeader(X_Forwarded_Proto) + "://";
+ } else {
+ baseURL += req.getProtocol() + "://";
+ }
+
+ // Handle Server/Host and Port Here
+ if (req.getHeader(X_Forwarded_Host) != null && req.getHeader(X_Forwarded_Port) != null){
+ // Double check to see if host has port
+ if(req.getHeader(X_Forwarded_Host).contains(req.getHeader(X_Forwarded_Port))){
+ baseURL += req.getHeader(X_Forwarded_Host);
+ } else {
+ // If there's no port, add the host and port together;
+ baseURL += req.getHeader(X_Forwarded_Host) + ":" + req.getHeader(X_Forwarded_Port);
+ }
+ } else if(req.getHeader(X_Forwarded_Server) != null && req.getHeader(X_Forwarded_Port) != null){
+ // Tack on the server and port if they're available. Try host if server not available
+ baseURL += req.getHeader(X_Forwarded_Server) + ":" + req.getHeader(X_Forwarded_Port);
+ } else if(req.getHeader(X_Forwarded_Port) != null) {
+ // if we at least have a port, we can use it.
+ baseURL += req.getServerName() + ":" + req.getHeader(X_Forwarded_Port);
+ } else {
+ // Resort to request members
+ baseURL += req.getServerName() + ":" + req.getLocalPort();
+ }
+
+ // Handle Server context
+ if( req.getHeader(X_Forwarded_Context) != null ) {
+ baseURL += req.getHeader( X_Forwarded_Context );
+ } else {
+ baseURL += req.getContextPath();
+ }
+
+ return baseURL;
+ }
+
+
+ static class HrefListing {
+ @JsonProperty
+ String href;
+
+ @JsonProperty
+ List<HrefListItem> items;
+
+ HrefListing() {}
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setItems(List<HrefListItem> items) {
+ this.items = items;
+ }
+
+ public List<HrefListItem> getItems() {
+ return items;
+ }
+ }
+
+ static class HrefListItem {
+ @JsonProperty
+ String href;
+
+ @JsonProperty
+ String name;
+
+ HrefListItem() {}
+
+ HrefListItem(String href, String name) {
+ this.href = href;
+ this.name = name;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getName() {
+ return name;
+ }
+ }
+
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ public static class SimpleTopology {
+
+ @XmlElement
+ private String name;
+ @XmlElement
+ private String timestamp;
+ @XmlElement
+ private String defaultServicePath;
+ @XmlElement
+ private String uri;
+ @XmlElement
+ private String href;
+
+ public SimpleTopology() {}
+
+ public SimpleTopology(org.apache.knox.gateway.topology.Topology t, String uri, String href) {
+ this.name = t.getName();
+ this.timestamp = Long.toString(t.getTimestamp());
+ this.defaultServicePath = t.getDefaultServicePath();
+ this.uri = uri;
+ this.href = href;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String n) {
+ name = n;
+ }
+
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setDefaultService(String defaultServicePath) {
+ this.defaultServicePath = defaultServicePath;
+ }
+
+ public String getDefaultService() {
+ return defaultServicePath;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+ }
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class SimpleTopologyWrapper{
+
+ @XmlElement(name="topology")
+ @XmlElementWrapper(name="topologies")
+ private List<SimpleTopology> topologies = new ArrayList<SimpleTopology>();
+
+ public List<SimpleTopology> getTopologies(){
+ return topologies;
+ }
+
+ public void setTopologies(List<SimpleTopology> ts){
+ this.topologies = ts;
+ }
+
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
----------------------------------------------------------------------
diff --cc gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
index e8d6915,0000000..e916568
mode 100644,000000..100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/BeanConverter.java
@@@ -1,170 -1,0 +1,172 @@@
+/**
+ * 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.knox.gateway.service.admin.beans;
+
+import org.apache.knox.gateway.topology.Version;
+
+import java.util.Collection;
+
+public class BeanConverter {
+
+ public static Topology getTopology(
+ org.apache.knox.gateway.topology.Topology topology) {
+ Topology topologyResource = new Topology();
+ topologyResource.setName(topology.getName());
+ topologyResource.setTimestamp(topology.getTimestamp());
+ topologyResource.setPath(topology.getDefaultServicePath());
+ topologyResource.setUri(topology.getUri());
++ topologyResource.setGenerated(topology.isGenerated());
+ for ( org.apache.knox.gateway.topology.Provider provider : topology.getProviders() ) {
+ topologyResource.getProviders().add( getProvider(provider) );
+ }
+ for ( org.apache.knox.gateway.topology.Service service : topology.getServices() ) {
+ topologyResource.getServices().add( getService(service) );
+ }
+ for ( org.apache.knox.gateway.topology.Application application : topology.getApplications() ) {
+ topologyResource.getApplications().add( getApplication(application) );
+ }
+ return topologyResource;
+ }
+
+ public static org.apache.knox.gateway.topology.Topology getTopology(Topology topology) {
+ org.apache.knox.gateway.topology.Topology deploymentTopology = new org.apache.knox.gateway.topology.Topology();
+ deploymentTopology.setName(topology.getName());
+ deploymentTopology.setTimestamp(topology.getTimestamp());
+ deploymentTopology.setDefaultServicePath(topology.getPath());
+ deploymentTopology.setUri(topology.getUri());
++ deploymentTopology.setGenerated(topology.isGenerated());
+ for ( Provider provider : topology.getProviders() ) {
+ deploymentTopology.addProvider( getProvider(provider) );
+ }
+ for ( Service service : topology.getServices() ) {
+ deploymentTopology.addService( getService(service) );
+ }
+ for ( Application application : topology.getApplications() ) {
+ deploymentTopology.addApplication( getApplication(application) );
+ }
+ return deploymentTopology;
+ }
+
+ private static Provider getProvider(
+ org.apache.knox.gateway.topology.Provider provider) {
+ Provider providerResource = new Provider();
+ providerResource.setName(provider.getName());
+ providerResource.setEnabled(provider.isEnabled());
+ providerResource.setRole(provider.getRole());
+ Collection<org.apache.knox.gateway.topology.Param> paramsList = provider.getParamsList();
+ if (paramsList != null && !paramsList.isEmpty()) {
+ for ( org.apache.knox.gateway.topology.Param param : paramsList ) {
+ providerResource.getParams().add(getParam(param));
+ }
+ }
+ return providerResource;
+ }
+
+ private static org.apache.knox.gateway.topology.Provider getProvider(Provider provider) {
+ org.apache.knox.gateway.topology.Provider deploymentProvider = new org.apache.knox.gateway.topology.Provider();
+ deploymentProvider.setName(provider.getName());
+ deploymentProvider.setEnabled(provider.isEnabled());
+ deploymentProvider.setRole(provider.getRole());
+ for ( Param param : provider.getParams() ) {
+ deploymentProvider.addParam( getParam(param) );
+ }
+ return deploymentProvider;
+ }
+
+ private static Service getService(
+ org.apache.knox.gateway.topology.Service service) {
+ Service serviceResource = new Service();
+ serviceResource.setRole(service.getRole());
+ serviceResource.setName(service.getName());
+ Version version = service.getVersion();
+ if (version != null) {
+ serviceResource.setVersion(version.toString());
+ }
+ Collection<org.apache.knox.gateway.topology.Param> paramsList = service.getParamsList();
+ if (paramsList != null && !paramsList.isEmpty()) {
+ for ( org.apache.knox.gateway.topology.Param param : paramsList ) {
+ serviceResource.getParams().add(getParam(param));
+ }
+ }
+ for ( String url : service.getUrls() ) {
+ serviceResource.getUrls().add( url );
+ }
+ return serviceResource;
+ }
+
+ private static org.apache.knox.gateway.topology.Service getService(Service service) {
+ org.apache.knox.gateway.topology.Service deploymentService = new org.apache.knox.gateway.topology.Service();
+ deploymentService.setRole(service.getRole());
+ deploymentService.setName(service.getName());
+ if (service.getVersion() != null) {
+ deploymentService.setVersion(new Version(service.getVersion()));
+ }
+ for ( Param param : service.getParams() ) {
+ deploymentService.addParam( getParam(param) );
+ }
+ for ( String url : service.getUrls() ) {
+ deploymentService.addUrl( url );
+ }
+ return deploymentService;
+ }
+
+ private static Application getApplication(
+ org.apache.knox.gateway.topology.Application application) {
+ Application applicationResource = new Application();
+ applicationResource.setRole(application.getRole());
+ applicationResource.setName(application.getName());
+ Version version = application.getVersion();
+ if (version != null) {
+ applicationResource.setVersion(version.toString());
+ }
+ Collection<org.apache.knox.gateway.topology.Param> paramsList = application.getParamsList();
+ if (paramsList != null && !paramsList.isEmpty()) {
+ for ( org.apache.knox.gateway.topology.Param param : paramsList ) {
+ applicationResource.getParams().add(getParam(param));
+ }
+ }
+ for ( String url : application.getUrls() ) {
+ applicationResource.getUrls().add( url );
+ }
+ return applicationResource;
+ }
+
+ private static org.apache.knox.gateway.topology.Application getApplication(Application application) {
+ org.apache.knox.gateway.topology.Application applicationResource = new org.apache.knox.gateway.topology.Application();
+ applicationResource.setRole(application.getRole());
+ applicationResource.setName(application.getName());
+ if (application.getVersion() != null) {
+ applicationResource.setVersion(new Version(application.getVersion()));
+ }
+ for ( Param param : application.getParams() ) {
+ applicationResource.addParam( getParam(param) );
+ }
+ for ( String url : application.getUrls() ) {
+ applicationResource.getUrls().add( url );
+ }
+ return applicationResource;
+ }
+
+ private static Param getParam(org.apache.knox.gateway.topology.Param param) {
+ return new Param(param.getName(), param.getValue());
+ }
+
+ private static org.apache.knox.gateway.topology.Param getParam(Param param) {
+ return new org.apache.knox.gateway.topology.Param(param.getName(), param.getValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
----------------------------------------------------------------------
diff --cc gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
index 2d2eab8,0000000..e1a8279
mode 100644,000000..100644
--- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
+++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java
@@@ -1,119 -1,0 +1,130 @@@
+/**
+ * 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.knox.gateway.service.admin.beans;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+@XmlRootElement(name="topology")
+public class Topology {
+
+ @XmlElement
+ private URI uri;
+
+ @XmlElement
+ private String name;
+
+ @XmlElement
+ private String path;
+
+ @XmlElement
+ private long timestamp;
+
++ @XmlElement(name="generated")
++ private boolean isGenerated;
++
+ @XmlElement(name="provider")
+ @XmlElementWrapper(name="gateway")
+ public List<Provider> providers;
+
+ @XmlElement(name="service")
+ public List<Service> services;
+
+ @XmlElement(name="application")
+ private List<Application> applications;
+
+ public Topology() {
+ }
+
+ public URI getUri() {
+ return uri;
+ }
+
+ public void setUri( URI uri ) {
+ this.uri = uri;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setPath( String defaultServicePath ) {
+ this.path = defaultServicePath;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setTimestamp( long timestamp ) {
+ this.timestamp = timestamp;
+ }
+
++ public boolean isGenerated() {
++ return isGenerated;
++ }
++
++ public void setGenerated(boolean isGenerated) {
++ this.isGenerated = isGenerated;
++ }
++
+ public List<Service> getServices() {
+ if (services == null) {
+ services = new ArrayList<>();
+ }
+ return services;
+ }
+
+ public List<Application> getApplications() {
+ if (applications == null) {
+ applications = new ArrayList<>();
+ }
+ return applications;
+ }
+
+ public List<Provider> getProviders() {
+ if (providers == null) {
+ providers = new ArrayList<>();
+ }
+ return providers;
+ }
+
+ public void setProviders(List<Provider> providers) {
+ this.providers = providers;
+ }
+
+ public void setServices(List<Service> services) {
+ this.services = services;
+ }
+
+ public void setApplications(List<Application> applications) {
+ this.applications = applications;
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
----------------------------------------------------------------------
diff --cc gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
index 3fe81e8,0000000..ac82b39
mode 100644,000000..100644
--- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
+++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java
@@@ -1,80 -1,0 +1,91 @@@
+/**
+ * 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
+ *
+ * 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.apache.knox.gateway.service.definition;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType(name = "dispatch")
+public class CustomDispatch {
+
+ private String contributorName;
+
+ private String haContributorName;
+
+ private String className;
+
+ private String haClassName;
+
+ private String httpClientFactory;
+
++ private boolean useTwoWaySsl = false;
++
+ @XmlAttribute(name = "contributor-name")
+ public String getContributorName() {
+ return contributorName;
+ }
+
+ public void setContributorName(String contributorName) {
+ this.contributorName = contributorName;
+ }
+
+ @XmlAttribute(name = "ha-contributor-name")
+ public String getHaContributorName() {
+ return haContributorName;
+ }
+
+ public void setHaContributorName(String haContributorName) {
+ this.haContributorName = haContributorName;
+ }
+
+ @XmlAttribute(name = "classname")
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ @XmlAttribute(name = "ha-classname")
+ public String getHaClassName() {
+ return haClassName;
+ }
+
+ public void setHaClassName(String haContributorClassName) {
+ this.haClassName = haContributorClassName;
+ }
+
+ @XmlAttribute(name = "http-client-factory")
+ public String getHttpClientFactory() {
+ return httpClientFactory;
+ }
+
+ public void setHttpClientFactory(String httpClientFactory) {
+ this.httpClientFactory = httpClientFactory;
+ }
++
++ @XmlAttribute(name = "use-two-way-ssl")
++ public boolean getUseTwoWaySsl() {
++ return useTwoWaySsl;
++ }
++
++ public void setUseTwoWaySsl(boolean useTwoWaySsl) {
++ this.useTwoWaySsl = useTwoWaySsl;
++ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-shell-launcher/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-shell-release/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
index e822364,0000000..dcb7465
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/DefaultHttpClientFactory.java
@@@ -1,233 -1,0 +1,270 @@@
+/**
+ * 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
+ *
+ * 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.apache.knox.gateway.dispatch;
+
++import java.io.IOException;
++import java.security.KeyStore;
++import java.security.Principal;
++import java.util.Collections;
++import java.util.Date;
++import java.util.List;
++
++import javax.net.ssl.SSLContext;
++import javax.servlet.FilterConfig;
++
++import org.apache.knox.gateway.services.security.AliasService;
++import org.apache.knox.gateway.services.security.AliasServiceException;
++import org.apache.knox.gateway.services.security.KeystoreService;
++import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.metrics.MetricsService;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.ProtocolException;
+import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.RedirectStrategy;
+import org.apache.http.client.config.AuthSchemes;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
++import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
++import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.protocol.HttpContext;
++import org.apache.http.ssl.SSLContexts;
+import org.joda.time.Period;
+import org.joda.time.format.PeriodFormatter;
+import org.joda.time.format.PeriodFormatterBuilder;
+
- import javax.servlet.FilterConfig;
- import java.io.IOException;
- import java.security.Principal;
- import java.util.Collections;
- import java.util.Date;
- import java.util.List;
-
+public class DefaultHttpClientFactory implements HttpClientFactory {
+
+ @Override
+ public HttpClient createHttpClient(FilterConfig filterConfig) {
+ HttpClientBuilder builder = null;
+ GatewayConfig gatewayConfig = (GatewayConfig) filterConfig.getServletContext().getAttribute(GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE);
++ GatewayServices services = (GatewayServices) filterConfig.getServletContext()
++ .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ if (gatewayConfig != null && gatewayConfig.isMetricsEnabled()) {
- GatewayServices services = (GatewayServices) filterConfig.getServletContext()
- .getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+ MetricsService metricsService = services.getService(GatewayServices.METRICS_SERVICE);
+ builder = metricsService.getInstrumented(HttpClientBuilder.class);
+ } else {
+ builder = HttpClients.custom();
+ }
++ if (Boolean.parseBoolean(filterConfig.getInitParameter("useTwoWaySsl"))) {
++ char[] keypass = null;
++ MasterService ms = services.getService("MasterService");
++ AliasService as = services.getService(GatewayServices.ALIAS_SERVICE);
++ try {
++ keypass = as.getGatewayIdentityPassphrase();
++ } catch (AliasServiceException e) {
++ // nop - default passphrase will be used
++ }
++ if (keypass == null) {
++ // there has been no alias created for the key - let's assume it is the same as the keystore password
++ keypass = ms.getMasterSecret();
++ }
++
++ KeystoreService ks = services.getService(GatewayServices.KEYSTORE_SERVICE);
++ final SSLContext sslcontext;
++ try {
++ KeyStore keystoreForGateway = ks.getKeystoreForGateway();
++ sslcontext = SSLContexts.custom()
++ .loadTrustMaterial(keystoreForGateway, new TrustSelfSignedStrategy())
++ .loadKeyMaterial(keystoreForGateway, keypass)
++ .build();
++ } catch (Exception e) {
++ throw new IllegalArgumentException("Unable to create SSLContext", e);
++ }
++ builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext));
++ }
+ if ( "true".equals(System.getProperty(GatewayConfig.HADOOP_KERBEROS_SECURED)) ) {
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(AuthScope.ANY, new UseJaasCredentials());
+
+ Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
+ .register(AuthSchemes.SPNEGO, new KnoxSpnegoAuthSchemeFactory(true))
+ .build();
+
+ builder = builder.setDefaultAuthSchemeRegistry(authSchemeRegistry)
+ .setDefaultCookieStore(new HadoopAuthCookieStore())
+ .setDefaultCredentialsProvider(credentialsProvider);
+ } else {
+ builder = builder.setDefaultCookieStore(new NoCookieStore());
+ }
+
+ builder.setKeepAliveStrategy( DefaultConnectionKeepAliveStrategy.INSTANCE );
+ builder.setConnectionReuseStrategy( DefaultConnectionReuseStrategy.INSTANCE );
+ builder.setRedirectStrategy( new NeverRedirectStrategy() );
+ builder.setRetryHandler( new NeverRetryHandler() );
+
+ int maxConnections = getMaxConnections( filterConfig );
+ builder.setMaxConnTotal( maxConnections );
+ builder.setMaxConnPerRoute( maxConnections );
+
+ builder.setDefaultRequestConfig( getRequestConfig( filterConfig ) );
+
+ HttpClient client = builder.build();
+ return client;
+ }
+
+ private static RequestConfig getRequestConfig( FilterConfig config ) {
+ RequestConfig.Builder builder = RequestConfig.custom();
+ int connectionTimeout = getConnectionTimeout( config );
+ if ( connectionTimeout != -1 ) {
+ builder.setConnectTimeout( connectionTimeout );
+ builder.setConnectionRequestTimeout( connectionTimeout );
+ }
+ int socketTimeout = getSocketTimeout( config );
+ if( socketTimeout != -1 ) {
+ builder.setSocketTimeout( socketTimeout );
+ }
+ return builder.build();
+ }
+
+ private static class NoCookieStore implements CookieStore {
+ @Override
+ public void addCookie(Cookie cookie) {
+ //no op
+ }
+
+ @Override
+ public List<Cookie> getCookies() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean clearExpired(Date date) {
+ return true;
+ }
+
+ @Override
+ public void clear() {
+ //no op
+ }
+ }
+
+ private static class NeverRedirectStrategy implements RedirectStrategy {
+ @Override
+ public boolean isRedirected( HttpRequest request, HttpResponse response, HttpContext context )
+ throws ProtocolException {
+ return false;
+ }
+
+ @Override
+ public HttpUriRequest getRedirect( HttpRequest request, HttpResponse response, HttpContext context )
+ throws ProtocolException {
+ return null;
+ }
+ }
+
+ private static class NeverRetryHandler implements HttpRequestRetryHandler {
+ @Override
+ public boolean retryRequest( IOException exception, int executionCount, HttpContext context ) {
+ return false;
+ }
+ }
+
+ private static class UseJaasCredentials implements Credentials {
+
+ public String getPassword() {
+ return null;
+ }
+
+ public Principal getUserPrincipal() {
+ return null;
+ }
+
+ }
+
+ private int getMaxConnections( FilterConfig filterConfig ) {
+ int maxConnections = 32;
+ GatewayConfig config =
+ (GatewayConfig)filterConfig.getServletContext().getAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE );
+ if( config != null ) {
+ maxConnections = config.getHttpClientMaxConnections();
+ }
+ String str = filterConfig.getInitParameter( "httpclient.maxConnections" );
+ if( str != null ) {
+ try {
+ maxConnections = Integer.parseInt( str );
+ } catch ( NumberFormatException e ) {
+ // Ignore it and use the default.
+ }
+ }
+ return maxConnections;
+ }
+
+ private static int getConnectionTimeout( FilterConfig filterConfig ) {
+ int timeout = -1;
+ GatewayConfig globalConfig =
+ (GatewayConfig)filterConfig.getServletContext().getAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE );
+ if( globalConfig != null ) {
+ timeout = globalConfig.getHttpClientConnectionTimeout();
+ }
+ String str = filterConfig.getInitParameter( "httpclient.connectionTimeout" );
+ if( str != null ) {
+ try {
+ timeout = (int)parseTimeout( str );
+ } catch ( Exception e ) {
+ // Ignore it and use the default.
+ }
+ }
+ return timeout;
+ }
+
+ private static int getSocketTimeout( FilterConfig filterConfig ) {
+ int timeout = -1;
+ GatewayConfig globalConfig =
+ (GatewayConfig)filterConfig.getServletContext().getAttribute( GatewayConfig.GATEWAY_CONFIG_ATTRIBUTE );
+ if( globalConfig != null ) {
+ timeout = globalConfig.getHttpClientSocketTimeout();
+ }
+ String str = filterConfig.getInitParameter( "httpclient.socketTimeout" );
+ if( str != null ) {
+ try {
+ timeout = (int)parseTimeout( str );
+ } catch ( Exception e ) {
+ // Ignore it and use the default.
+ }
+ }
+ return timeout;
+ }
+
+ private static long parseTimeout( String s ) {
+ PeriodFormatter f = new PeriodFormatterBuilder()
+ .appendMinutes().appendSuffix("m"," min")
+ .appendSeconds().appendSuffix("s"," sec")
+ .appendMillis().toFormatter();
+ Period p = Period.parse( s, f );
+ return p.toStandardDuration().getMillis();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
index 27a1905,0000000..42d69d9
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/i18n/GatewaySpiMessages.java
@@@ -1,91 -1,0 +1,94 @@@
+/**
+ * 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
+ *
+ * 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.apache.knox.gateway.i18n;
+
+import org.apache.knox.gateway.i18n.messages.Message;
+import org.apache.knox.gateway.i18n.messages.MessageLevel;
+import org.apache.knox.gateway.i18n.messages.Messages;
+import org.apache.knox.gateway.i18n.messages.StackTrace;
+
+@Messages(logger="org.apache.knox.gateway")
+public interface GatewaySpiMessages {
+
+ @Message(level = MessageLevel.ERROR, text = "Failed to load the internal principal mapping table: {0}" )
+ void failedToLoadPrincipalMappingTable( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to execute filter: {0}" )
+ void failedToExecuteFilter( @StackTrace( level = MessageLevel.DEBUG ) Throwable t );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to encrypt passphrase: {0}" )
+ void failedToEncryptPassphrase( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to generate secret key from password: {0}" )
+ void failedToGenerateKeyFromPassword( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to create keystore [filename={0}, type={1}]: {2}" )
+ void failedToCreateKeystore( String fileName, String keyStoreType, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to load keystore [filename={0}, type={1}]: {2}" )
+ void failedToLoadKeystore( String fileName, String keyStoreType, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to add credential: {1}" )
+ void failedToAddCredential( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message(level = MessageLevel.ERROR, text = "Failed to remove credential: {1}")
+ void failedToRemoveCredential(@StackTrace(level = MessageLevel.DEBUG) Exception e);
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to get credential: {1}" )
+ void failedToGetCredential(@StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to persist master secret: {0}" )
+ void failedToPersistMasterSecret( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to encrypt master secret: {0}" )
+ void failedToEncryptMasterSecret( @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to initialize master service from persistent master {0}: {1}" )
+ void failedToInitializeFromPersistentMaster( String masterFileName, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to add self signed certificate for Gateway {0}: {1}" )
+ void failedToAddSeflSignedCertForGateway( String alias, @StackTrace( level = MessageLevel.DEBUG ) Exception e );
+
+ @Message( level = MessageLevel.ERROR, text = "Failed to get key {0}: {1}" )
+ void failedToGetKey(String alias, @StackTrace( level = MessageLevel.DEBUG ) Exception e);
+
+ @Message( level = MessageLevel.DEBUG, text = "Loading from persistent master: {0}" )
+ void loadingFromPersistentMaster( String tag );
+
+ @Message( level = MessageLevel.DEBUG, text = "ALIAS: {0}" )
+ void printClusterAlias( String alias );
+
+ @Message( level = MessageLevel.DEBUG, text = "MASTER SERVICE == NULL: {0}" )
+ void printMasterServiceIsNull( boolean masterServiceIsNull );
+
+ @Message( level = MessageLevel.ERROR, text = "Gateway has failed to start. Unable to prompt user for master secret setup. Please consider using knoxcli.sh create-master" )
+ void unableToPromptForMasterUseKnoxCLI();
+
+ @Message( level = MessageLevel.ERROR, text = "Error in generating certificate: {0}" )
+ void failedToGenerateCertificate( @StackTrace( level = MessageLevel.ERROR ) Exception e );
+
+ @Message(level = MessageLevel.ERROR, text = "Failed to read configuration: {0}")
+ void failedToReadConfigurationFile(final String filePath, @StackTrace(level = MessageLevel.DEBUG) Exception e );
+
+ @Message(level = MessageLevel.ERROR, text = "Invalid resource URI {0} : {1}")
+ void invalidResourceURI(final String uri, final String reason, @StackTrace(level = MessageLevel.DEBUG) Exception e );
+
++ @Message( level = MessageLevel.ERROR, text = "Topology {0} cannot be manually overwritten because it was generated from a simple descriptor." )
++ void disallowedOverwritingGeneratedTopology(final String topologyName);
++
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/2c69152f/gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
index 815c218,0000000..e46197d
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/topology/Topology.java
@@@ -1,151 -1,0 +1,160 @@@
+/**
+ * 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
+ *
+ * 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.apache.knox.gateway.topology;
+
+import org.apache.commons.collections.map.HashedMap;
+import org.apache.commons.collections.map.MultiKeyMap;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Topology {
+
+ private URI uri;
+ private String name;
+ private String defaultServicePath = null;
+ private long timestamp;
++ private boolean isGenerated;
+ public List<Provider> providerList = new ArrayList<Provider>();
+ private Map<String,Map<String,Provider>> providerMap = new HashMap<>();
+ public List<Service> services = new ArrayList<Service>();
+ private MultiKeyMap serviceMap;
+ private List<Application> applications = new ArrayList<Application>();
+ private Map<String,Application> applicationMap = new HashMap<>();
+
+ public Topology() {
+ serviceMap = MultiKeyMap.decorate(new HashedMap());
+ }
+
+ public URI getUri() {
+ return uri;
+ }
+
+ public void setUri( URI uri ) {
+ this.uri = uri;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName( String name ) {
+ this.name = name;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp( long timestamp ) {
+ this.timestamp = timestamp;
+ }
+
+ public String getDefaultServicePath() {
+ return defaultServicePath;
+ }
+
+ public void setDefaultServicePath(String servicePath) {
+ defaultServicePath = servicePath;
+ }
+
++ public void setGenerated(boolean isGenerated) {
++ this.isGenerated = isGenerated;
++ }
++
++ public boolean isGenerated() {
++ return isGenerated;
++ }
++
+ public Collection<Service> getServices() {
+ return services;
+ }
+
+ public Service getService( String role, String name, Version version) {
+ return (Service)serviceMap.get(role, name, version);
+ }
+
+ public void addService( Service service ) {
+ services.add( service );
+ serviceMap.put(service.getRole(), service.getName(), service.getVersion(), service);
+ }
+
+ public Collection<Application> getApplications() {
+ return applications;
+ }
+
+ private static String fixApplicationUrl( String url ) {
+ if( url == null ) {
+ url = "/";
+ }
+ if( !url.startsWith( "/" ) ) {
+ url = "/" + url;
+ }
+ return url;
+ }
+
+ public Application getApplication(String url) {
+ return applicationMap.get( fixApplicationUrl( url ) );
+ }
+
+ public void addApplication( Application application ) {
+ applications.add( application );
+ List<String> urls = application.getUrls();
+ if( urls == null || urls.isEmpty() ) {
+ applicationMap.put( fixApplicationUrl( application.getName() ), application );
+ } else {
+ for( String url : application.getUrls() ) {
+ applicationMap.put( fixApplicationUrl( url ), application );
+ }
+ }
+ }
+
+ public Collection<Provider> getProviders() {
+ return providerList;
+ }
+
+ public Provider getProvider( String role, String name ) {
+ Provider provider = null;
+ Map<String,Provider> nameMap = providerMap.get( role );
+ if( nameMap != null) {
+ if( name != null ) {
+ provider = nameMap.get( name );
+ }
+ else {
+ provider = (Provider) nameMap.values().toArray()[0];
+ }
+ }
+ return provider;
+ }
+
+ public void addProvider( Provider provider ) {
+ providerList.add( provider );
+ String role = provider.getRole();
+ Map<String,Provider> nameMap = providerMap.get( role );
+ if( nameMap == null ) {
+ nameMap = new HashMap<>();
+ providerMap.put( role, nameMap );
+ }
+ nameMap.put( provider.getName(), provider );
+ }
+
+}