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 com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
025import java.io.IOException;
026import java.io.StringReader;
027import java.io.StringWriter;
028import java.util.Base64;
029import javax.ws.rs.core.MediaType;
030import javax.xml.bind.JAXBContext;
031import javax.xml.bind.JAXBException;
032import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
033import org.apache.hadoop.hbase.rest.provider.JAXBContextResolver;
034import org.junit.Test;
035
036public abstract class TestModelBase<T> {
037
038  protected String AS_XML;
039
040  protected String AS_PB;
041
042  protected String AS_JSON;
043
044  protected JAXBContext context;
045
046  protected Class<?> clazz;
047
048  protected ObjectMapper mapper;
049
050  protected TestModelBase(Class<?> clazz) throws Exception {
051    super();
052    this.clazz = clazz;
053    context = new JAXBContextResolver().getContext(clazz);
054    mapper = new JacksonJaxbJsonProvider().locateMapper(clazz,
055        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)
077      mapper.readValue(json, clazz);
078  }
079
080  public T fromXML(String xml) throws JAXBException {
081    return (T)
082      context.createUnmarshaller().unmarshal(new StringReader(xml));
083  }
084
085  @SuppressWarnings("unused")
086  protected byte[] toPB(ProtobufMessageHandler model) {
087    return model.createProtobufOutput();
088  }
089
090  protected T fromPB(String pb) throws
091      Exception {
092    return (T)clazz.getMethod("getObjectFromMessage", byte[].class).invoke(
093        clazz.getDeclaredConstructor().newInstance(),
094        Base64.getDecoder().decode(AS_PB));
095  }
096
097  protected abstract  void checkModel(T model);
098
099  @Test
100  public void testBuildModel() throws Exception {
101    checkModel(buildTestModel());
102  }
103
104  @Test
105  public void testFromPB() throws Exception {
106    checkModel(fromPB(AS_PB));
107  }
108
109  @Test
110  public void testFromXML() throws Exception {
111    checkModel(fromXML(AS_XML));
112  }
113
114  @Test
115  public void testToXML() throws Exception {
116    // Uses fromXML to check model because XML element ordering can be random.
117    checkModel(fromXML(toXML(buildTestModel())));
118  }
119
120  @Test
121  public void testToJSON() throws Exception {
122    try {
123      ObjectNode expObj = mapper.readValue(AS_JSON, ObjectNode.class);
124      ObjectNode actObj = mapper.readValue(toJSON(buildTestModel()), ObjectNode.class);
125      assertEquals(expObj, actObj);
126    } catch(Exception e) {
127      assertEquals(AS_JSON, toJSON(buildTestModel()));
128    }
129  }
130
131  @Test
132  public void testFromJSON() throws Exception {
133    checkModel(fromJSON(AS_JSON));
134  }
135}
136