SpringFox Swagger make Definition properties required with XSD model - properties

I have a REST webapp which uses Swagger for the documentation and it's working great except for the body parameter. All the properties of the body are optional
My Project object is generated with an XSD file and i made sure all the element where minOccurs=1 maxOccurs=1 or unbounded and all my attributes are set to use=required. This doesn't seem to have any effect on it. The next thing I tried was adding
#ApiParam(value = "The project body", required = true) #RequestBody ProjectInfo project
But this had no effect either because the Project object itself is already required. Is there anyway to tell Swagger that the properties of Project are also required? I'm using the SpringFox dependency for Swagger.
Update
I managed to get it required by adding #ApiModel and #ApiModelProperty(value = "The unique name of the project", required = true) to my generated model.
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.11
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2016.02.12 at 09:33:59 AM CET
//
package be.smartask.api.model.post;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.*;
/**
* <p>Java class for anonymous complex type.
* <p>
* <p>The following schema fragment specifies the expected content contained within this class.
* <p>
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
#XmlRootElement(name = "projectInfo")
#ApiModel
public class ProjectInfo {
#XmlAttribute(name = "name", required = true)
protected String name;
/**
* Gets the value of the name property.
*
* #return possible object is
* {#link String }
*/
#ApiModelProperty(value = "The unique name of the project", required = true)
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* #param value allowed object is
* {#link String }
*/
public void setName(String value) {
this.name = value;
}
}
But now my question changed to Can I add Swagger annotations in the XSD file so it will generate by itself?

The Annotation I need was #ApiModelProperty(value = "", required = true)
To get this generated from my quit a challenge but I managed to do it by doing the next steps.
Add this to you pom.xml
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.1</version>
<configuration>
<forceRegenerate>true</forceRegenerate>
<extension>true</extension>
<args>
<arg>-Xannotate</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>1.0.2</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-annotate-plugin-test-annox-annotations</artifactId>
<version>1.0.0</version>
</plugin>
</plugins>
</configuration>
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</plugin>
The dependency is required or he won't find your annotation at compile time.
In your XSD file add the following
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.1"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="annox">
Now you should be able to add annotation add class level like this
<xs:element name="projectInfo">
<xs:complexType>
<xsd:annotation>
<xsd:appinfo>
<annox:annotate target="getter">#io.swagger.annotations.ApiModel(value = "project")</annox:annotate>
</xsd:appinfo>
</xsd:annotation>
</xs:complexType>
</xs:element>
and at method level like this
<xs:element name="projectInfo">
<xs:complexType>
<xsd:annotation>
<xsd:appinfo>
<annox:annotate target="getter">#io.swagger.annotations.ApiModel(value = "project")</annox:annotate>
</xsd:appinfo>
</xsd:annotation>
<xs:attribute type="xs:string" name="name" use="required">
<xsd:annotation>
<xsd:appinfo>
<annox:annotate target="getter">#io.swagger.annotations.ApiModelProperty(value="Must be unique", required = true)</annox:annotate>
</xsd:appinfo>
</xsd:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
More info can be found here
https://github.com/highsource/jaxb2-annotate-plugin
https://java.net/jira/browse/JAXB2_COMMONS-32

Related

Deploying Custom RoleMapper to WebLogic

I am trying to deploy a Custom Role Mapper in WebLogic 10.3.5.0 - this is very similar to this question - Weblogic Providers, but I cannot get the provider to appear in the poplist.
Config file:
<MBeanType Name="DatabaseRoleMapping"
DisplayName="DatabaseRoleMapping"
Package="com.bynx.weblogic.mbean.rolemapping"
Extends="weblogic.management.security.authorization.RoleMapper"
PersistPolicy = "OnUpdate">
<MBeanAttribute
Name = "ProviderClassName"
Type = "java.lang.String"
Writeable = "false"
Preprocessor = "weblogic.management.configuration.LegalHelper.checkClassName(value)"
Default = ""com.bynx.weblogic.mbean.rolemapping.DatabaseRoleMappingProvider""
/>
<MBeanAttribute
Name = "Description"
Type = "java.lang.String"
Writeable = "false"
Default = ""Provider that performs Role Mapping held in a database""
/>
<MBeanAttribute
Name = "Version"
Type = "java.lang.String"
Writeable = "false"
Default = ""1.0""
/>
<!--
<MBeanAttribute
Name = "DataSourceJNDI"
Type = "java.lang.String"
Default = ""UserDataSource""
Description = "DataSource JNDI name"
/> -->
</MBeanType>
Provider Imlementation:
package com.bynx.weblogic.mbean.rolemapping;
import weblogic.management.security.ProviderMBean;
import weblogic.security.spi.RoleMapper;
import weblogic.security.spi.RoleProvider;
import weblogic.security.spi.SecurityServices;
public class DatabaseRoleMappingProvider implements RoleProvider
{
DatabaseRoleMapper mapper;
private String description;
#Override
public String getDescription()
{
return description;
}
#Override
public void initialize(ProviderMBean provider, SecurityServices services)
{
//DatabaseRoleMappingProviderMBean mBean = (DatabaseRoleMappingProviderMBean)provider;
//mapper = new DatabaseRoleMapper(mBean.getDataSourceJNDI());
mapper = new DatabaseRoleMapper("UserDataSource");
description = provider.getName() + " " + provider.getVersion();
}
#Override
public void shutdown()
{
}
#Override
public RoleMapper getRoleMapper()
{
return mapper;
}
}
Build file:
<?xml version="1.0"?>
<project name="dbuser_authentication_provider" default="all" basedir=".">
<!-- global properties -->
<property environment="env"/>
<property name="jdk" value="C:/Program Files (x86)/Java/jdk1.6.0_26"/>
<property name="lib" value="P:/Web_Dev/Projects/WebLogic_Home/wlserver_10.3/server/lib"/>
<property name="mbeantypes" value="${lib}/mbeantypes"/>
<property name="sampleprovidersjar" value="databaseRoleMapping.jar"/>
<property name="sample_dir" location="."/>
<property name="src_dir" value="${sample_dir}/src"/>
<property name="provider_src_dir" value="${src_dir}/com"/>
<property name="build_dir" value="${sample_dir}/build"/>
<property name="class_dir" value="${sample_dir}/classes"/>
<property name="namespace" value="http://www.bea.com/ns/90/weblogic/security/samples"/>
<target name="all" depends="clean">
<!-- Set up the build directories -->
<mkdir dir="${build_dir}"/>
<mkdir dir="${class_dir}"/>
<!-- Only copy over the commo dtd and sample provider xml files for now -->
<copy todir="${build_dir}" flatten="true">
<fileset dir="${lib}">
<include name="commo.dtd"/>
</fileset>
</copy>
<copy todir="${build_dir}" flatten="true">
<fileset dir="${provider_src_dir}">
<include name="**/*.xml"/>
<include name="**/*.java"/>
</fileset>
</copy>
<!-- Build the sample security providers' jar file -->
<java classname="weblogic.management.commo.WebLogicMBeanMaker" fork="true" failonerror="true">
<jvmarg line="-cp '${jdk}/lib/tools.jar';${lib}/weblogic.jar -Dfiles=${build_dir} -DMDFDIR=${build_dir} -DMJF=${build_dir}/${sampleprovidersjar} -DtargetNameSpace=${namespace} -DpreserveStubs=true -DcreateStubs=true"/>
</java>
</target>
<target name="clean">
<delete quiet="true" dir="${build_dir}"/>
<delete quiet="true" dir="${class_dir}"/>
</target>
</project>
Everything compiles fine and there don't appear to be any missing class files in the generated jar, but putting the jar in the mbeantypes directory and restarting it doesn't appear in the list. It will eventually look at a database, but I have stripped it down to the minimum to try and get it working. Any suggestions - or where to look in the logs for any issues would be appreciated.
I've managed to get this working, so thought I would share my solution in case anyone else stumbles upon this.
First the statement in the documentation:
However, if you want WebLogic Server to look for MBean types in additional directories, use the -Dweblogic.alternateTypesDirectory= command-line flag when starting your server, where is a comma-separated list of directory names. When you use this flag, WebLogic Server will always load MBean types from WL_HOME\server\lib\mbeantypes first, then will look in the additional directories and load all valid archives present in those directories (regardless of their extension).
Doesn't appear to be correct. We are using the alternateTypesDirectory parameter and I could only get WebLogic to pickup my custom MBean if I put the jar in one of the directories in the command-line flag.
Secondly, if you have anything deployed that uses versioning (e.g. one or more of the optional deployable libraries), your custom provider must implement the weblogic.security.spi.VersionableApplicationProvider interface and haveImplements = "weblogic.management.security.ApplicationVersioner" in the MBeanType element of the definition XML.

Kundera No Entity metadata found for the class

I get an error "No Entity metadata found for the class" using Kundera a similiar
question is here,
No Entity metadata found for the class
but didn't find an answer (answer put META-INF into classes dir, didn't help me.
This is the error I get
3168 [main] WARN com.impetus.kundera.metadata.KunderaMetadataManager - No Entity metadata found for the class class kundega.rules.Rule. Any CRUD operation on this entity will fail.If your entity is for RDBMS, make sure you put fully qualified entity class name under <class></class> tag in persistence.xml for RDBMS persistence unit. Returning null value.
Exception in thread "main" com.impetus.kundera.KunderaException: java.lang.IllegalArgumentException: Entity object is invalid, operation failed. Please check previous log message for details
at com.impetus.kundera.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:174)
at kundega.rules.AppMain.main(AppMain.java:27)
Caused by: java.lang.IllegalArgumentException: Entity object is invalid, operation failed. Please check previous log message for details
at com.impetus.kundera.graph.ObjectGraphBuilder.getNode(ObjectGraphBuilder.java:101)
at com.impetus.kundera.graph.ObjectGraphBuilder.getObjectGraph(ObjectGraphBuilder.java:75)
at com.impetus.kundera.persistence.PersistenceDelegator.persist(PersistenceDelegator.java:135)
at com.impetus.kundera.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:168)
So here is my files.
Persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="UNIT">
<provider>com.impetus.kundera.KunderaPersistence</provider>
<class>kundega.rules.Rule</class>
<properties>
<property name="kundera.client.lookup.class" value="com.impetus.client.rdbms.RDBMSClientFactory" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://130.230.141.228:3306/fastory" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="mysql" />
</properties>
</persistence-unit>
</persistence>
Start of Entity class
#Entity
#Table(name="eplrules", schema="fastory")
public class Rule {
#Id
//#GeneratedValue (strategy=GenerationType.AUTO)
#Column (name ="rule_id")
private long ruleId;
#Column (name ="rule")
private String rule;
Main class
public static void main(String[] args) {
System.out.println("start");
BasicConfigurator.configure();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("UNIT");
Rule r = new Rule();
r.setRuleId(103);
r.setRuleName("SomeRuleName");
r.setRule("SomeRule");
EntityManager em = emf.createEntityManager();
em.persist(r);
Query q = em.createQuery("select p from Rule p");
List<Rule> rules = q.getResultList();
em.close();
System.out.println(rules);
System.out.println("stop");
em.close();
emf.close();
}
When I got this I checked:
<class>package.name.DaoClass</class>
was defined in persistence.xml, this resolved the error. Also check
<property name="kundera.annotations.scan.package" value="package.name"/>
matches correctly to your package name.
"kundega.rules.Rule" package name is correct? Or is it "kundera.rules.Rule" ?

Infinispan cache.put does not work

I have created a two node cluster running Infinispan cache in replication mode. I see the cache comes up fine. and both the nodes connect to each other. I am here using TreeCache Api to convert the Map based structure to tree based as below:
private static Cache<Object, Object> Cache1;
private static TreeCache<Object, Object> Cache;
Cache1 = new DefaultCacheManager("infinispan.xml").getCache();
Cache = new TreeCacheFactory().createTreeCache(Cache1);
If i call Cache.put , I dont get any error but the entry does not get saved to the cache. I confirmed it by getting the data again which returns NULL.
Cache.put(fqn,key, value);
if(Cache.get(fqn, key) == null)
{
System.out.println("Entry is not saved");
}
Below is the config file,
<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.3 http://www.infinispan.org/schemas/infinispan-config-5.3.xsd"
xmlns="urn:infinispan:config:5.3">
<global>
<globalJmxStatistics enabled = "true" allowDuplicateDomains = "true"/>
<transport clusterName = "test_cluster">
<properties>
<property name="configurationFile" value="tcp.xml" />
</properties>
</transport>
</global>
<default>
<clustering mode="replication">
<async asyncMarshalling="true" useReplQueue="true" replQueueInterval="10" replQueueMaxElements="100" />
<stateTransfer timeout="2000000"/>
</clustering>
<invocationBatching enabled = "true"/>
<locking isolationLevel = "REPEATABLE_READ"
writeSkewCheck = "false"
concurrencyLevel = "1000"/>
<jmxStatistics enabled="true"/>
</default>
</infinispan>
Is it that I am missing to initialize any thing?

arquillian-glassfish-embedded-3.1 1.0.0.CR3 configuring JDBC datasource

I was trying to use arquillian-glassfish-embedded-3.1 container to test and EJB3 application. I was trying to figure out how to set up a simple JDBC datasource that could be injected as a resource to a Stateless ejb.
Here is what I have :
#Stateless
public class HelloEJBBean implements HelloEJB {
#Resource(name="myDataSource")
private DataSource datasource;
public String sayHelloEJB(String name) {
return "Hello " + name;
}
}
also have arquillian.xml with the following content:
<?xml version="1.0"?>
<arquillian xmlns="http://jboss.com/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:glassfish="urn:arq:org.jboss.arquillian.container.glassfish.embedded_3">
<glassfish:container>
<glassfish:bindHttpPort>9090</glassfish:bindHttpPort>
<glassfish:instanceRoot>src/test/resources</glassfish:instanceRoot>
<glassfish:autoDelete>false</glassfish:autoDelete>
</glassfish:container>
</arquillian>
and a domain.xml with
<domain>
<applications />
<resources>
<jdbc-resource pool-name="ArquillianEmbeddedOraclePool" jndi-name="myDataSource"
object-type="user" enabled="true"/>
<jdbc-connection-pool name="ArquillianEmbeddedOraclePool" res-type="javax.sql.DataSource"
datasource-classname="oracle.jdbc.driver.OracleDriver">
<property name="user" value="user"/>
<property name="password" value="password"/>
<property name="serverName" value="servername"/>
<property name="DatabaseName" value="dbname"/>
<property name="url" value="jdbc:oracle:thin:#servername:1521/dbname"/>
</jdbc-connection-pool>
</resources>
</domain>
and the simple test looks like this:
#RunWith(Arquillian.class)
public class HelloEJBTest {
#Deployment
public static JavaArchive createTestArchive() {
return ShrinkWrap.create(JavaArchive.class, "helloEJB.jar")
.addClasses(HelloEJB.class, HelloEJBBean.class);
}
#EJB
private HelloEJB helloEJB;
#Test
public void testHelloEJB() {
String result = helloEJB.sayHelloEJB("Michael");
assertEquals("Hello Michael", result);
}
}
I get the following error:
... 108 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Res-Ref-Env-Property: myDataSource#javax.sql.DataSource# resolved as: jndi: myDataSource#res principal: null#mail: null
No Runtime properties
... 108 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Res-Ref-Env-Property: myDataSource#javax.sql.DataSource# resolved as: jndi: myDataSource#res principal: null#mail: null
No Runtime properties
Any help is appreciated.
Thanks

Why is my WCF Data Services method not appearing in the OData collections list?

When I view the root of my WCF Data Services service (http://localhost/MyService.svc/) in a browser I see this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<service xml:base="http://localhost/MyService.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
<workspace>
<atom:title>Default</atom:title>
</workspace>
</service>
I would expect to see a list of collections.
When I go to the $metadata URL I see this:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="1.0">
<Schema Namespace="MyApp" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm">
<ComplexType Name="Package">
<Property Name="Id" Type="Edm.String" Nullable="true" />
</ComplexType>
</Schema>
<Schema Namespace="MyApp" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://schemas.microsoft.com/ado/2007/05/edm">
<EntityContainer Name="PackageService" m:IsDefaultEntityContainer="true">
<FunctionImport Name="GetQueryablePackages" ReturnType="Collection(MyApp.Package)" m:HttpMethod="GET" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Why might my GetQueryablePackages collection not be appearing?
I'm using these access settings:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
Service operations (the function import in the EDM) is not exposed in the service document. Only entity sets are exposed there.
If you want your data to be exposed in the service document make an entity set out of it. Depending on the provider model this differs. Typically it means exposing a property of type IQueryable on your context class. Note that T has to be an entity type (must have a key).
Can you share the context definition where you have defined the IQueryable <> properties. There are 2 things that come to my mind: First the properties must be of type IQueryable<> or some type that derives from it. Second, the element type refered by the IQueryable<> must be an entity type i.e. they must have key properties declared in them.
Hope this helps.
Thanks
Pratik
Or you can create an extension method like this:
public static class TestEntitiesExtensions
{
public static IEnumerable<Package> GetQueryablePackages(this TestEntities context)
{
var uri = new Uri(context.BaseUri, "GetQueryablePackages");
return context.Execute<Package>(uri);
}
}