001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.rest.model;
019
020import static org.junit.Assert.assertEquals;
021
022import com.fasterxml.jackson.databind.ObjectMapper;
023import com.fasterxml.jackson.databind.node.ObjectNode;
024import java.io.IOException;
025import java.io.StringReader;
026import java.io.StringWriter;
027import java.util.Base64;
028import javax.xml.bind.JAXBContext;
029import javax.xml.bind.JAXBException;
030import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
031import org.apache.hadoop.hbase.rest.provider.JAXBContextResolver;
032import org.junit.Test;
033
034import org.apache.hbase.thirdparty.com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
035import org.apache.hbase.thirdparty.javax.ws.rs.core.MediaType;
036
037public abstract class TestModelBase<T> {
038
039  protected String AS_XML;
040
041  protected String AS_PB;
042
043  protected String AS_JSON;
044
045  protected JAXBContext context;
046
047  protected Class<?> clazz;
048
049  protected ObjectMapper mapper;
050
051  protected TestModelBase(Class<?> clazz) throws Exception {
052    super();
053    this.clazz = clazz;
054    context = new JAXBContextResolver().getContext(clazz);
055    mapper = new JacksonJaxbJsonProvider().locateMapper(clazz, MediaType.APPLICATION_JSON_TYPE);
056  }
057
058  protected abstract T buildTestModel();
059
060  @SuppressWarnings("unused")
061  protected String toXML(T model) throws JAXBException {
062    StringWriter writer = new StringWriter();
063    context.createMarshaller().marshal(model, writer);
064    return writer.toString();
065  }
066
067  protected String toJSON(T model) throws JAXBException, IOException {
068    StringWriter writer = new StringWriter();
069    mapper.writeValue(writer, model);
070    // original marshaller, uncomment this and comment mapper to verify backward compatibility
071    // ((JSONJAXBContext)context).createJSONMarshaller().marshallToJSON(model, writer);
072    return writer.toString();
073  }
074
075  public T fromJSON(String json) throws JAXBException, IOException {
076    return (T) mapper.readValue(json, clazz);
077  }
078
079  public T fromXML(String xml) throws JAXBException {
080    return (T) context.createUnmarshaller().unmarshal(new StringReader(xml));
081  }
082
083  @SuppressWarnings("unused")
084  protected byte[] toPB(ProtobufMessageHandler model) {
085    return model.createProtobufOutput();
086  }
087
088  protected T fromPB(String pb) throws Exception {
089    return (T) clazz.getMethod("getObjectFromMessage", byte[].class)
090      .invoke(clazz.getDeclaredConstructor().newInstance(), Base64.getDecoder().decode(AS_PB));
091  }
092
093  protected abstract void checkModel(T model);
094
095  @Test
096  public void testBuildModel() throws Exception {
097    checkModel(buildTestModel());
098  }
099
100  @Test
101  public void testFromPB() throws Exception {
102    checkModel(fromPB(AS_PB));
103  }
104
105  @Test
106  public void testFromXML() throws Exception {
107    checkModel(fromXML(AS_XML));
108  }
109
110  @Test
111  public void testToXML() throws Exception {
112    // Uses fromXML to check model because XML element ordering can be random.
113    checkModel(fromXML(toXML(buildTestModel())));
114  }
115
116  @Test
117  public void testToJSON() throws Exception {
118    try {
119      ObjectNode expObj = mapper.readValue(AS_JSON, ObjectNode.class);
120      ObjectNode actObj = mapper.readValue(toJSON(buildTestModel()), ObjectNode.class);
121      assertEquals(expObj, actObj);
122    } catch (Exception e) {
123      assertEquals(AS_JSON, toJSON(buildTestModel()));
124    }
125  }
126
127  @Test
128  public void testFromJSON() throws Exception {
129    checkModel(fromJSON(AS_JSON));
130  }
131}