Package org.jembi.openhim

Source Code of org.jembi.openhim.DefaultChannelComponent$URLMapping

package org.jembi.openhim;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jembi.openhim.RestfulHttpRequest.Scheme;
import org.jembi.openhim.exception.DefaultChannelInvalidConfigException;
import org.jembi.openhim.exception.URLMappingNotFoundException;
import org.mule.api.MuleEventContext;
import org.mule.api.MuleMessage;
import org.mule.api.lifecycle.Callable;
import org.mule.api.transport.PropertyScope;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;

public class DefaultChannelComponent implements Callable {

  protected static List<URLMapping> mappings = new ArrayList<URLMapping>();
 
  private static final String MAPPING_FILE = "/defaultchannel-mapping.json";
  private static final String HTTP_AUTH_TYPE_BASIC = "basic";

  @Override
  public Object onCall(MuleEventContext eventContext) throws Exception {

    if (mappings.size() < 1) {
      readMappings();
    }

    MuleMessage msg = eventContext.getMessage();
    RestfulHttpRequest req = (RestfulHttpRequest) msg.getPayload();
    String actualPath = req.getPath();

    URLMapping mapping = findURLMapping(req.getScheme(), actualPath);
   
    if (mapping == null) {
      throw new URLMappingNotFoundException("A URL mapping was not found for the URL: " + req.getPath());
    }
   
    setMessagePropertiesFromMapping(req, msg, mapping);
   
    return msg;
  }
 
  protected void setMessagePropertiesFromMapping(RestfulHttpRequest request, MuleMessage msg, URLMapping mapping) throws DefaultChannelInvalidConfigException {
    msg.setProperty("http.host", mapping.getHost(), PropertyScope.OUTBOUND);
    msg.setProperty("http.port", mapping.getPort(), PropertyScope.OUTBOUND);

    if (mapping.getAuthType() != null) {
      if (mapping.getAuthType().equals(HTTP_AUTH_TYPE_BASIC)) {
        setBasicAuthProperty(msg, mapping);
      }
    }
   
    if (mapping.getPath()!=null || mapping.getPathTransform()!=null) {
      setRequestPath(request, mapping);
    }
    msg.setProperty("path", request.buildUrlWithRequestParams(), PropertyScope.OUTBOUND);
  }
 
  private void setBasicAuthProperty(MuleMessage msg, URLMapping mapping) {
    String username = mapping.getUsername();
    String password = mapping.getPassword();
       
    byte[] encodedBytes = Base64.encodeBase64((username + ":" + password).getBytes());
    String authHeader = "Basic " + new String(encodedBytes);
       
    msg.setProperty("http.auth", authHeader, PropertyScope.OUTBOUND);
  }
 
  private void setRequestPath(RestfulHttpRequest request, URLMapping mapping) throws DefaultChannelInvalidConfigException {
    if (mapping.getPath()!=null && mapping.getPathTransform()!=null) {
      throw new DefaultChannelInvalidConfigException("Cannot specify both path and pathTransform");
    }
   
    String path = null;
   
    if (mapping.getPathTransform()!=null) {
      path = transformPath(request.getPath(), mapping.getPathTransform());
    } else {
      path = mapping.getPath();
    }

    request.setPath(path);
  }
 
  private String transformPath(String path, String sPattern) throws DefaultChannelInvalidConfigException {
    //replace all \/'s with a temporary ~ so that we don't split on those
    String pattern = sPattern.replaceAll("\\\\/", "~");
    String[] sub = pattern.split("/");

    if (sub.length<2 || !sub[0].equals("s")) {
      throw new DefaultChannelInvalidConfigException("Malformed pathTransform expression. Expected \"s/from/to\"");
    }
     
    String from = sub[1].replaceAll("~", "/");
    String to = (sub.length>2) ? sub[2] : "";
    to = to.replaceAll("~", "/");

    return path.replaceAll(from, to);
  }
   

  protected URLMapping findURLMapping(Scheme scheme, String actualPath) {
    for (URLMapping mapping : mappings) {
      if (scheme.equals(Scheme.HTTP) && !"true".equalsIgnoreCase(mapping.getAllowUnsecured())) {
        continue;
      }

      String urlPattern = mapping.getUrlPattern();

      Pattern p = Pattern.compile(urlPattern);
      Matcher m = p.matcher(actualPath);
      boolean match = m.matches();
     
      if (match) {
        return mapping;
      }
    }
   
    return null;
  }

  protected void readMappings() throws IOException, JsonParseException,
      JsonMappingException {
    // Read mapping out of JSON file
    ObjectMapper mapper = new ObjectMapper();
    JsonFactory factory = new JsonFactory();
    InputStream is = this.getClass().getResourceAsStream(MAPPING_FILE);
    JsonParser jp = factory.createParser(is);

    jp.nextToken();
    mappings.clear();
    while (jp.nextToken() == JsonToken.START_OBJECT) {
      URLMapping mapping = mapper.readValue(jp, URLMapping.class);
      mappings.add(mapping);
    }
  }

  public static class URLMapping {
    private String urlPattern;
    private String host;
    private String port;
    private String username;
    private String password;
    private String authType;
    private String allowUnsecured;
    private String path;
    private String pathTransform;

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof URLMapping)) {
        return false;
      }
      URLMapping mapping = (URLMapping) obj;
      if (urlPattern.equals(mapping.getUrlPattern())
        && host.equals(mapping.getHost())
        && port.equals(mapping.getPort())) {
       
        return true;
      }
      return false;
    }
   
    public String getAuthType() {
      return authType;
    }

    public void setAuthType(String authType) {
      this.authType = authType;
    }

    public String getUsername() {
      return username;
    }

    public void setUsername(String username) {
      this.username = username;
    }

    public String getPassword() {
      return password;
    }

    public void setPassword(String password) {
      this.password = password;
    }

    public String getUrlPattern() {
      return urlPattern;
    }

    public void setUrlPattern(String urlPattern) {
      this.urlPattern = urlPattern;
    }

    public String getHost() {
      return host;
    }

    public void setHost(String host) {
      this.host = host;
    }

    public String getPort() {
      return port;
    }

    public void setPort(String port) {
      this.port = port;
    }

    public String getAllowUnsecured() {
      return allowUnsecured;
    }

    public void setAllowUnsecured(String allowUnsecured) {
      this.allowUnsecured = allowUnsecured;
    }

    public String getPath() {
      return path;
    }

    public void setPath(String path) {
      this.path = path;
    }

    public String getPathTransform() {
      return pathTransform;
    }

    public void setPathTransform(String pathTransform) {
      this.pathTransform = pathTransform;
    }
  }

}
TOP

Related Classes of org.jembi.openhim.DefaultChannelComponent$URLMapping

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.