I am trying to perform a liquibase rollback command on an application
I have my changeset:
<changeSet id="dmsTestSQL" author="ahmed"
dbms="mysql">
<sqlFile path="db/changelog/sql/add.sql"
encoding="UTF-8"
splitStatements="true"
stripComments="true"/>
<rollback>
<sqlFile path="db/changelog/sql/rollback.sql"/>
</rollback>
</changeSet>
and I have my configuration class:
#Configuration
public class LiquibaseConfiguration {
#Value("${com.autogravity.dms.liquibase.changelog}")
private String changelog;
#Value("${spring.datasource.url}")
private String url;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
/*#Value("${liquibase.rollback-file}")
private String rollback;*/
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource());
liquibase.setChangeLog(changelog);
//liquibase.setRollbackFile(new File(rollback));
return liquibase;
}
public MysqlDataSource dataSource() {
MysqlDataSource ds=new MysqlDataSource();
ds.setURL(url);
ds.setUser(username);
ds.setPassword(password);
ds.setAutoReconnect(true);
ds.setCreateDatabaseIfNotExist(true);
return ds;
}
}
I also have created mvn plugin in my pom file:
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.2</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tag>${project.version}</tag>
<dropFirst>false</dropFirst>
<changeLogFile>classpath:/db/changelog/db.changelog.xml</changeLogFile>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost:3306/db</url>
<username>root</username>
<password>test</password>
</configuration>
<goals>
<goal>rollback</goal>
<goal>tag</goal>
</goals>
</execution>
</executions>
</plugin>
I try to run command liquibase:rollback -Dliquibase.rollbackTag=1.0 but then I get the error :
Failed to execute goal org.liquibase:liquibase-maven-plugin:2.0.2:rollback (default-cli) on project dealer-microservice: The driver has not been specified either as a parameter or in a properties file. -> [Help 1]
I don't understand the previous error and I tried to search it but found nothing. can I get help in interpreting this error
Related
I have an application with the following structure (simplified for brevity):
project structure
myApp
src/main/java/
com.something
controllers
UserApi
UserController
model
UpsertRequest
pom.xml
myApp-generated-client
target
pom.xml
UserApi
#PutMapping(USER_UPSERT_PATH)
UpsertResponse userUpsert(
#RequestBody UpsertRequest upsertRequest,
#RequestHeader(name = COMPRESSED_DATA, required = false) byte[] compressedData);
pom.xml (myApp):
<plugin>
<groupId>com.github.kongchen</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>3.1.8</version>
<configuration>
<skipSwaggerGeneration>false</skipSwaggerGeneration>
<apiSources>
<apiSource>
<schemes>http,https</schemes>
<swaggerDirectory>
${project.basedir}/../myApp-generated-client/
</swaggerDirectory>
<locations>
<location>com.something.controllers</location>
</locations>
<springmvc>true</springmvc>
<outputFormats>json</outputFormats>
<attachSwaggerArtifact>true</attachSwaggerArtifact>
</apiSource>
</apiSources>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
pom.xml (myApp-generated-client)
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>4.1.2</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>
${project.basedir}/swagger.json
</inputSpec>
<supportingFilesToGenerate>
ApiClient.java,JSON.java,OAuth.java,Authentication.java,ApiKeyAuth.java,HttpBasicAuth.java,ApiException.java,ApiResponse.java,Configuration.java,Pair.java,RFC3339DateFormat.java,StringUtil.java,CustomInstantDeserializer.java,Client.java
</supportingFilesToGenerate>
<skipValidateSpec>true</skipValidateSpec>
<apiPackage>com.something.api</apiPackage>
<generatorName>java</generatorName>
<templateDirectory>${project.basedir}/templates</templateDirectory>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<generateModels>true</generateModels>
<configOptions>
<library>jersey2</library>
</configOptions>
<typeMappings>Resource=File</typeMappings>
<importMappings>
<importMapping>UpsertRequest=com.something.model.upsertRequest</importMapping>
</importMappings>
<modelPackage>com.something.api</modelPackage>
<modelsToGenerate/>
</configuration>
</execution>
</executions>
</plugin>
The problem is after compiling, my generated client keeps using List<byte[]> instead of byte[] for the upsert endpoint:
public ApiResponse<UpsertResponse> userUpsertWithHttpInfo(List<byte[]> compressedData, UpsertRequest body) throws ApiException
I read here that
Arrays become lists when you use the Swagger Codegen tool to generate Java clients.
For example, a field of type String[] becomes List.
Is there any way of overcoming this limitation (i.e., some converter class or some annotation)? For that matter, is there any good explanations/documentation about how to use converters to resolve types?
Update:
After seeing this link, I added the following code and updated my generated-client pom, but am getting the same results:
package com.something.converter;
public class ByteArrayFixerModelConverter extends AbstractModelConverter {
public ByteArrayFixerModelConverter() {
super(Json.mapper());
}
#Override
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
if (isByteArray(type)) {
//bypass the chain! It would convert the ByteArrayProperty to an Array of ByteArrayProperty (bug in ModelModifier I think)
return new ByteArraySchema();
}
return chain.hasNext()
? chain.next().resolve(type, context, chain)
: null;
}
private boolean isByteArray(AnnotatedType annotatedType) {
Type type = annotatedType.getType();
boolean ret = type instanceof Class && type == byte[].class;
if (!ret && type instanceof ArrayType) {
ArrayType at = (ArrayType) type;
JavaType contentType = at.getContentType();
if (contentType instanceof SimpleType) {
SimpleType st = (SimpleType) contentType;
ret = st.getRawClass() == byte.class;
}
}
return ret;
}
}
pom.xml (myApp-generated-client, updated)
<plugin>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<modelConverterClasses>com.something.converter.ByteArrayFixerModelConverter</modelConverterClasses>
</configuration>
</plugin>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
... //same as before
</plugin>
I am migrating a web service into spring boot.
From wsdl i am able to generate following interface
#WebService(targetNamespace = "http://tsb.hcl.com/terp/ws/v2", name = "Terp-v2")
#XmlSeeAlso({com.hcl.psi.tsb.schema.common.ObjectFactory.class, com.hcl.psi.tsb.schema.offering.ObjectFactory.class, com.hcl.psi.kil.system.message.ObjectFactory.class, com.hcl.tsb.terp.ws.schema.ObjectFactory.class, com.hcl.psi.tsb.schema.task.ObjectFactory.class, com.hcl.psi.tsb.schema.servicecontract.ObjectFactory.class, com.hcl.psi.tsb.schema.project.ObjectFactory.class, com.hcl.tsb.tsb.ObjectFactory.class, com.hcl.psi.tsb.schema.customer.ObjectFactory.class})
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface TerpV2 {
#WebMethod(operationName = "GetServiceContracts")
#WebResult(name = "GetServiceContractsResponseType", targetNamespace = "http://tsb.hcl.com/terp/ws/schema", partName = "payload")
public com.hcl.tsb.terp.ws.schema.GetServiceContractsResponseType getServiceContracts(
#WebParam(partName = "payload", name = "GetServiceContractsType", targetNamespace = "http://tsb.hcl.com/terp/ws/schema")
com.hcl.tsb.terp.ws.schema.GetServiceContractsType payload
) throws TerpServiceFault;
I am not sure how to initiate it in Spring Boot application form baeldung website. I tried implementing following code:
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "TerpService")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("Terp-v2");
wsdl11Definition.setLocationUri("/tsb/tone/ws/v2/TerpService/");
wsdl11Definition.setTargetNamespace("http://www.baeldung.com/springsoap/gen");
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
}
#Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource("countries.xsd"));
}
}
But I am not sure how to initiate above interface or it's implementation into spring boot context?
Do i need to write whole contract classes manually?
Can anyone guide me about same. Thanks
I have a similar project and it works.
Try making your interface instead of
#WebService(targetNamespace = "http://tsb.hcl.com/terp/ws/v2", name = "Terp-v2")
#XmlSeeAlso({com.hcl.psi.tsb.schema.common.ObjectFactory.class, com.hcl.psi.tsb.schema.offering.ObjectFactory.class, com.hcl.psi.kil.system.message.ObjectFactory.class, com.hcl.tsb.terp.ws.schema.ObjectFactory.class, com.hcl.psi.tsb.schema.task.ObjectFactory.class, com.hcl.psi.tsb.schema.servicecontract.ObjectFactory.class, com.hcl.psi.tsb.schema.project.ObjectFactory.class, com.hcl.tsb.tsb.ObjectFactory.class, com.hcl.psi.tsb.schema.customer.ObjectFactory.class})
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface TerpV2 {
#WebMethod(operationName = "GetServiceContracts")
#WebResult(name = "GetServiceContractsResponseType", targetNamespace = "http://tsb.hcl.com/terp/ws/schema", partName = "payload")
public com.hcl.tsb.terp.ws.schema.GetServiceContractsResponseType getServiceContracts(
#WebParam(partName = "payload", name = "GetServiceContractsType", targetNamespace = "http://tsb.hcl.com/terp/ws/schema")
com.hcl.tsb.terp.ws.schema.GetServiceContractsType payload
) throws TerpServiceFault;
like this
#Endpoint
public class TerpV2 {
private static final String NAMESPACE_URI = "Terp-v2";
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "GetServiceContractsType")
#ResponsePayload
public YourCustomResponseObject getServiceContracts(#RequestPayload GetServiceContractsType getServiceContractsType) {
//this could be constructed in a service class
YourCustomResponseObject response = new YourCustomResponseObject();
return response;
}
Also in your configurations
wsdl11Definition.setTargetNamespace("Terp-v2");
Also in your pom.xml configure the build like following
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- Configuration excecutable=true i have added this to make the jar excecutable-->
<configuration>
<executable>true</executable>
</configuration>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<!-- Configuration classifier=exec i have added this to force maven create one Fat
excecutable jar but also another jar for the dependencies of the payload modules-->
<!-- <classifier>exec</classifier>-->
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/resources/countries.xsd</source>
</sources>
</configuration>
</plugin>
</plugins>
</build>
After you build your project it will compile your xsd and will produce in target some DTO classes. Those DTO classes you can copy then in your project and use them like actual DTOs. That's the easies way to convert your XSD to DTO to be used by spring boot.
To do this you must add the following dependency in your pom.xml
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
I'm getting started with hibernate and I'm following this tutorial
https://www.javaguides.net/2018/11/hibernate-hello-world-tutorial.html
But when running my jar I get
Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/service/ServiceRegistry
Which is pretty self-explaining but I can't figure out how to get it
I've tried adding
import org.hibernate.service.ServiceRegistry;
But with no luck
The minimal structure from the tutorial is:
pom file:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.7.Final</version>
</dependency>
</dependencies>
App.java
package net.javaguides.hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class App {
public static void main(String[] args) {
Student student = new Student("Ramesh", "Fadatare", "rameshfadatare#javaguides.com");
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.save(student);
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
}
}
}
HibernateUtil.java
package net.javaguides.hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
registry = new StandardServiceRegistryBuilder().configure().build();
MetadataSources sources = new MetadataSources(registry);
Metadata metadata = sources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return sessionFactory;
}
public static void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
I'm using Manjaro Linux, if it matters
Apparently the problem was that Hibernate itself was missing from my produced jar(and it's target folder)
The solution is to either pack the dependencies in the jar itself or in the target folder(and have a classpath reference them?)
I went with the first but this slows down re-compiles:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.fistmedia.javapp.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
My spring RestApi Application successfully generates snippets using RestDoc but I'm not able use the snippets to automatically generate pages to run on frontend. http://localhost/docs returns 404 and no html is generated in static/docs/
so far my pom.xml looks like this
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<outputDirectory>
${project.build.outputDirectory}/static/docs
</outputDirectory>
<attributes>
<snippets>${project.build.directory}/generated-snippets</snippets>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
My Junit Api Test looks like this
#AutoConfigureMockMvc
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = AppLoader.class)
public class ApiDocumentationJUnit5IntegrationTest {
#Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");
#Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
private ObjectMapper objectMapper = new ObjectMapper();
private RestDocumentationResultHandler documentationHandler;
#Before
public void setUp() {
this.documentationHandler = document("{method-name}",
preprocessRequest(removeHeaders("Authorization")),
preprocessResponse(prettyPrint()));
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.build();
}
#Test
public void responseCodeTest() throws Exception {
this.mockMvc.perform(
get("/cms/status")
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andDo(
document("status")
);
}
#Test
public void retrieveDocumentTest() throws Exception {
this.mockMvc.perform(get("/api/active", 1L))
.andExpect(status().isOk()).andDo(
document("active")
);
}
}
I'm trying to use jaxb2-maven-plugin to generate xsd from java beans.
But I constantly get the following error:
java.time.LocalDate is a non-static inner class, and JAXB can't handle those.
this problem is related to the following location:
at java.time.LocalDate (Unknown Source)
The bean is like:
public class MyBean {
private LocalDate date;
}
I therefore created a jaxb mapping file and an adapter converting between java.time.LocalDate and xs:date. But the error just remains the same.
public class LocalDateAdapter {
private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");
public static LocalDate unmarshal(String v) throws Exception {
return fmt.parseLocalDate(v);
}
public static String marshal(LocalDate v) throws Exception {
return v.toString("yyyyMMdd");
}
}
src/main/resources/xsdbindings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<globalBindings>
<javaType name="java.time.LocalDate" xmlType="xs:date"
parseMethod="my.path.LocalDateAdapter.unmarshal"
printMethod="my.path.LocalDateAdapter.marshal"
/>
</globalBindings>
</bindings>
maven pom.xml
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>schemagen</id>
<goals>
<goal>schemagen</goal>
</goals>
</execution>
</executions>
<configuration>
<bindingFiles>xsdbindings.jaxb</bindingFiles>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
</project>