Bug 3800 - Fix usage of global SimpleDateFormat 93/22993/5
authorVaclav Demcak <vdemcak@cisco.com>
Fri, 19 Jun 2015 13:11:15 +0000 (15:11 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 26 Jun 2015 13:02:14 +0000 (13:02 +0000)
* fix usage of thread-safe SimpleDateFormater

Change-Id: I445739c22ecc8da9e5b9c51687fa6077f914de30
Signed-off-by: Vaclav Demcak <vdemcak@cisco.com>
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java
opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/BaseYangSwaggerGenerator.java

index c2774b581248832510b947674089a87cbbd7d2da..1a47c1284273268d2cd34bff837bcbb5d1425d4c 100644 (file)
@@ -60,6 +60,7 @@ import org.opendaylight.controller.sal.streams.listeners.Notificator;
 import org.opendaylight.controller.sal.streams.websockets.WebSocketServer;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
@@ -110,8 +111,6 @@ public class RestconfImpl implements RestconfService {
 
     private static final String MOUNT_POINT_MODULE_NAME = "ietf-netconf";
 
-    private static final SimpleDateFormat REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
-
     private static final String SAL_REMOTE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
 
     private static final String SAL_REMOTE_RPC_SUBSRCIBE = "create-data-change-event-subscription";
@@ -413,7 +412,7 @@ public class RestconfImpl implements RestconfService {
         try {
             final String moduleName = pathArgs.get(0);
             final String revision = pathArgs.get(1);
-            final Date moduleRevision = REVISION_FORMAT.parse(revision);
+            final Date moduleRevision = SimpleDateFormatUtil.getRevisionFormat().parse(revision);
             return QName.create(null, moduleRevision, moduleName);
         } catch (final ParseException e) {
             LOG.debug("URI has bad format. It should be \'moduleName/yyyy-MM-dd\' " + identifier);
@@ -1070,7 +1069,7 @@ public class RestconfImpl implements RestconfService {
                 (listModuleSchemaNode), "revision");
         final DataSchemaNode revisionSchemaNode = Iterables.getFirst(instanceDataChildrenByName, null);
         Preconditions.checkState(revisionSchemaNode instanceof LeafSchemaNode);
-        final String revision = REVISION_FORMAT.format(module.getRevision());
+        final String revision = SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision());
         moduleNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) revisionSchemaNode).withValue(revision)
                 .build());
 
index c8bf6e6675e1f10278fe218986e54313ba0bb79a..ffa76fc98908e47ebb8d629ff3111f03b337c722 100644 (file)
@@ -14,9 +14,7 @@ import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
 import com.google.common.base.Preconditions;
 import java.io.IOException;
 import java.net.URI;
-import java.text.DateFormat;
 import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -40,6 +38,7 @@ import org.opendaylight.controller.sal.rest.doc.swagger.Parameter;
 import org.opendaylight.controller.sal.rest.doc.swagger.Resource;
 import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
@@ -60,7 +59,6 @@ public class BaseYangSwaggerGenerator {
     protected static final String RESTCONF_CONTEXT_ROOT = "restconf";
 
     static final String MODULE_NAME_SUFFIX = "_module";
-    protected final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
     private final ModelGenerator jsonConverter = new ModelGenerator();
 
     // private Map<String, ApiDeclaration> MODULE_DOC_CACHE = new HashMap<>()
@@ -77,21 +75,21 @@ public class BaseYangSwaggerGenerator {
      * @param operType
      * @return list of modules converted to swagger compliant resource list.
      */
-    public ResourceList getResourceListing(UriInfo uriInfo, SchemaContext schemaContext, String context) {
+    public ResourceList getResourceListing(final UriInfo uriInfo, final SchemaContext schemaContext, final String context) {
 
-        ResourceList resourceList = createResourceList();
+        final ResourceList resourceList = createResourceList();
 
-        Set<Module> modules = getSortedModules(schemaContext);
+        final Set<Module> modules = getSortedModules(schemaContext);
 
-        List<Resource> resources = new ArrayList<>(modules.size());
+        final List<Resource> resources = new ArrayList<>(modules.size());
 
         LOG.info("Modules found [{}]", modules.size());
 
-        for (Module module : modules) {
-            String revisionString = SIMPLE_DATE_FORMAT.format(module.getRevision());
-            Resource resource = new Resource();
+        for (final Module module : modules) {
+            final String revisionString = SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision());
+            final Resource resource = new Resource();
             LOG.debug("Working on [{},{}]...", module.getName(), revisionString);
-            ApiDeclaration doc = getApiDeclaration(module.getName(), revisionString, uriInfo, schemaContext, context);
+            final ApiDeclaration doc = getApiDeclaration(module.getName(), revisionString, uriInfo, schemaContext, context);
 
             if (doc != null) {
                 resource.setPath(generatePath(uriInfo, module.getName(), revisionString));
@@ -107,30 +105,30 @@ public class BaseYangSwaggerGenerator {
     }
 
     protected ResourceList createResourceList() {
-        ResourceList resourceList = new ResourceList();
+        final ResourceList resourceList = new ResourceList();
         resourceList.setApiVersion(API_VERSION);
         resourceList.setSwaggerVersion(SWAGGER_VERSION);
         return resourceList;
     }
 
-    protected String generatePath(UriInfo uriInfo, String name, String revision) {
-        URI uri = uriInfo.getRequestUriBuilder().path(generateCacheKey(name, revision)).build();
+    protected String generatePath(final UriInfo uriInfo, final String name, final String revision) {
+        final URI uri = uriInfo.getRequestUriBuilder().path(generateCacheKey(name, revision)).build();
         return uri.toASCIIString();
     }
 
-    public ApiDeclaration getApiDeclaration(String module, String revision, UriInfo uriInfo, SchemaContext schemaContext, String context) {
+    public ApiDeclaration getApiDeclaration(final String module, final String revision, final UriInfo uriInfo, final SchemaContext schemaContext, final String context) {
         Date rev = null;
 
         try {
             if(revision != null && !revision.equals("0000-00-00")) {
-                rev = SIMPLE_DATE_FORMAT.parse(revision);
+                rev = SimpleDateFormatUtil.getRevisionFormat().parse(revision);
             }
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             throw new IllegalArgumentException(e);
         }
 
         if(rev != null) {
-            Calendar cal = new GregorianCalendar();
+            final Calendar cal = new GregorianCalendar();
 
             cal.setTime(rev);
 
@@ -139,42 +137,42 @@ public class BaseYangSwaggerGenerator {
             }
         }
 
-        Module m = schemaContext.findModuleByName(module, rev);
+        final Module m = schemaContext.findModuleByName(module, rev);
         Preconditions.checkArgument(m != null, "Could not find module by name,revision: " + module + "," + revision);
 
         return getApiDeclaration(m, rev, uriInfo, context, schemaContext);
     }
 
-    public ApiDeclaration getApiDeclaration(Module module, Date revision, UriInfo uriInfo, String context, SchemaContext schemaContext) {
-        String basePath = createBasePathFromUriInfo(uriInfo);
+    public ApiDeclaration getApiDeclaration(final Module module, final Date revision, final UriInfo uriInfo, final String context, final SchemaContext schemaContext) {
+        final String basePath = createBasePathFromUriInfo(uriInfo);
 
-        ApiDeclaration doc = getSwaggerDocSpec(module, basePath, context, schemaContext);
+        final ApiDeclaration doc = getSwaggerDocSpec(module, basePath, context, schemaContext);
         if (doc != null) {
             return doc;
         }
         return null;
     }
 
-    protected String createBasePathFromUriInfo(UriInfo uriInfo) {
+    protected String createBasePathFromUriInfo(final UriInfo uriInfo) {
         String portPart = "";
-        int port = uriInfo.getBaseUri().getPort();
+        final int port = uriInfo.getBaseUri().getPort();
         if (port != -1) {
             portPart = ":" + port;
         }
-        String basePath = new StringBuilder(uriInfo.getBaseUri().getScheme()).append("://")
+        final String basePath = new StringBuilder(uriInfo.getBaseUri().getScheme()).append("://")
                 .append(uriInfo.getBaseUri().getHost()).append(portPart).append("/").append(RESTCONF_CONTEXT_ROOT)
                 .toString();
         return basePath;
     }
 
-    public ApiDeclaration getSwaggerDocSpec(Module m, String basePath, String context, SchemaContext schemaContext) {
-        ApiDeclaration doc = createApiDeclaration(basePath);
+    public ApiDeclaration getSwaggerDocSpec(final Module m, final String basePath, final String context, final SchemaContext schemaContext) {
+        final ApiDeclaration doc = createApiDeclaration(basePath);
 
-        List<Api> apis = new ArrayList<Api>();
+        final List<Api> apis = new ArrayList<Api>();
 
-        Collection<DataSchemaNode> dataSchemaNodes = m.getChildNodes();
+        final Collection<DataSchemaNode> dataSchemaNodes = m.getChildNodes();
         LOG.debug("child nodes size [{}]", dataSchemaNodes.size());
-        for (DataSchemaNode node : dataSchemaNodes) {
+        for (final DataSchemaNode node : dataSchemaNodes) {
             if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) {
 
                 LOG.debug("Is Configuration node [{}] [{}]", node.isConfiguration(), node.getQName().getLocalName());
@@ -190,9 +188,9 @@ public class BaseYangSwaggerGenerator {
             }
         }
 
-        Set<RpcDefinition> rpcs = m.getRpcs();
-        for (RpcDefinition rpcDefinition : rpcs) {
-            String resourcePath = getDataStorePath("/operations/", context);
+        final Set<RpcDefinition> rpcs = m.getRpcs();
+        for (final RpcDefinition rpcDefinition : rpcs) {
+            final String resourcePath = getDataStorePath("/operations/", context);
             addRpcs(rpcDefinition, apis, resourcePath, schemaContext);
         }
 
@@ -227,8 +225,8 @@ public class BaseYangSwaggerGenerator {
         }
     }
 
-    protected ApiDeclaration createApiDeclaration(String basePath) {
-        ApiDeclaration doc = new ApiDeclaration();
+    protected ApiDeclaration createApiDeclaration(final String basePath) {
+        final ApiDeclaration doc = new ApiDeclaration();
         doc.setApiVersion(API_VERSION);
         doc.setSwaggerVersion(SWAGGER_VERSION);
         doc.setBasePath(basePath);
@@ -236,37 +234,37 @@ public class BaseYangSwaggerGenerator {
         return doc;
     }
 
-    protected String getDataStorePath(String dataStore, String context) {
+    protected String getDataStorePath(final String dataStore, final String context) {
         return dataStore + context;
     }
 
-    private String generateCacheKey(Module m) {
-        return generateCacheKey(m.getName(), SIMPLE_DATE_FORMAT.format(m.getRevision()));
+    private String generateCacheKey(final Module m) {
+        return generateCacheKey(m.getName(), SimpleDateFormatUtil.getRevisionFormat().format(m.getRevision()));
     }
 
-    private String generateCacheKey(String module, String revision) {
+    private String generateCacheKey(final String module, final String revision) {
         return module + "(" + revision + ")";
     }
 
-    private void addApis(DataSchemaNode node, List<Api> apis, String parentPath, List<Parameter> parentPathParams, SchemaContext schemaContext,
-            boolean addConfigApi) {
+    private void addApis(final DataSchemaNode node, final List<Api> apis, final String parentPath, final List<Parameter> parentPathParams, final SchemaContext schemaContext,
+            final boolean addConfigApi) {
 
-        Api api = new Api();
-        List<Parameter> pathParams = new ArrayList<Parameter>(parentPathParams);
+        final Api api = new Api();
+        final List<Parameter> pathParams = new ArrayList<Parameter>(parentPathParams);
 
-        String resourcePath = parentPath + createPath(node, pathParams, schemaContext) + "/";
+        final String resourcePath = parentPath + createPath(node, pathParams, schemaContext) + "/";
         LOG.debug("Adding path: [{}]", resourcePath);
         api.setPath(resourcePath);
 
         Iterable<DataSchemaNode> childSchemaNodes = Collections.<DataSchemaNode> emptySet();
         if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) {
-            DataNodeContainer dataNodeContainer = (DataNodeContainer) node;
+            final DataNodeContainer dataNodeContainer = (DataNodeContainer) node;
             childSchemaNodes = dataNodeContainer.getChildNodes();
         }
         api.setOperations(operation(node, pathParams, addConfigApi, childSchemaNodes));
         apis.add(api);
 
-        for (DataSchemaNode childNode : childSchemaNodes) {
+        for (final DataSchemaNode childNode : childSchemaNodes) {
             if (childNode instanceof ListSchemaNode || childNode instanceof ContainerSchemaNode) {
                 // keep config and operation attributes separate.
                 if (childNode.isConfiguration() == addConfigApi) {
@@ -278,7 +276,7 @@ public class BaseYangSwaggerGenerator {
     }
 
     private boolean containsListOrContainer(final Iterable<DataSchemaNode> nodes) {
-        for (DataSchemaNode child : nodes) {
+        for (final DataSchemaNode child : nodes) {
             if (child instanceof ListSchemaNode || child instanceof ContainerSchemaNode) {
                 return true;
             }
@@ -291,18 +289,18 @@ public class BaseYangSwaggerGenerator {
      * @param pathParams
      * @return
      */
-    private List<Operation> operation(DataSchemaNode node, List<Parameter> pathParams, boolean isConfig, Iterable<DataSchemaNode> childSchemaNodes) {
-        List<Operation> operations = new ArrayList<>();
+    private List<Operation> operation(final DataSchemaNode node, final List<Parameter> pathParams, final boolean isConfig, final Iterable<DataSchemaNode> childSchemaNodes) {
+        final List<Operation> operations = new ArrayList<>();
 
-        OperationBuilder.Get getBuilder = new OperationBuilder.Get(node, isConfig);
+        final OperationBuilder.Get getBuilder = new OperationBuilder.Get(node, isConfig);
         operations.add(getBuilder.pathParams(pathParams).build());
 
         if (isConfig) {
-            OperationBuilder.Put putBuilder = new OperationBuilder.Put(node.getQName().getLocalName(),
+            final OperationBuilder.Put putBuilder = new OperationBuilder.Put(node.getQName().getLocalName(),
                     node.getDescription());
             operations.add(putBuilder.pathParams(pathParams).build());
 
-            OperationBuilder.Delete deleteBuilder = new OperationBuilder.Delete(node);
+            final OperationBuilder.Delete deleteBuilder = new OperationBuilder.Delete(node);
             operations.add(deleteBuilder.pathParams(pathParams).build());
 
             if (containsListOrContainer(childSchemaNodes)) {
@@ -318,32 +316,32 @@ public class BaseYangSwaggerGenerator {
      * @param pathParams
      * @return
      */
-    private List<Operation> operationPost(final String name, final String description, final DataNodeContainer dataNodeContainer, List<Parameter> pathParams, boolean isConfig) {
-        List<Operation> operations = new ArrayList<>();
+    private List<Operation> operationPost(final String name, final String description, final DataNodeContainer dataNodeContainer, final List<Parameter> pathParams, final boolean isConfig) {
+        final List<Operation> operations = new ArrayList<>();
         if (isConfig) {
-            OperationBuilder.Post postBuilder = new OperationBuilder.Post(name, description, dataNodeContainer);
+            final OperationBuilder.Post postBuilder = new OperationBuilder.Post(name, description, dataNodeContainer);
             operations.add(postBuilder.pathParams(pathParams).build());
         }
         return operations;
     }
 
-    private String createPath(final DataSchemaNode schemaNode, List<Parameter> pathParams, SchemaContext schemaContext) {
-        ArrayList<LeafSchemaNode> pathListParams = new ArrayList<LeafSchemaNode>();
-        StringBuilder path = new StringBuilder();
-        String localName = resolvePathArgumentsName(schemaNode, schemaContext);
+    private String createPath(final DataSchemaNode schemaNode, final List<Parameter> pathParams, final SchemaContext schemaContext) {
+        final ArrayList<LeafSchemaNode> pathListParams = new ArrayList<LeafSchemaNode>();
+        final StringBuilder path = new StringBuilder();
+        final String localName = resolvePathArgumentsName(schemaNode, schemaContext);
         path.append(localName);
 
         if ((schemaNode instanceof ListSchemaNode)) {
             final List<QName> listKeys = ((ListSchemaNode) schemaNode).getKeyDefinition();
             for (final QName listKey : listKeys) {
-                DataSchemaNode _dataChildByName = ((DataNodeContainer) schemaNode).getDataChildByName(listKey);
+                final DataSchemaNode _dataChildByName = ((DataNodeContainer) schemaNode).getDataChildByName(listKey);
                 pathListParams.add(((LeafSchemaNode) _dataChildByName));
 
-                String pathParamIdentifier = new StringBuilder("/{").append(listKey.getLocalName()).append("}")
+                final String pathParamIdentifier = new StringBuilder("/{").append(listKey.getLocalName()).append("}")
                         .toString();
                 path.append(pathParamIdentifier);
 
-                Parameter pathParam = new Parameter();
+                final Parameter pathParam = new Parameter();
                 pathParam.setName(listKey.getLocalName());
                 pathParam.setDescription(_dataChildByName.getDescription());
                 pathParam.setType("string");
@@ -355,12 +353,12 @@ public class BaseYangSwaggerGenerator {
         return path.toString();
     }
 
-    protected void addRpcs(RpcDefinition rpcDefn, List<Api> apis, String parentPath, SchemaContext schemaContext) {
-        Api rpc = new Api();
-        String resourcePath = parentPath + resolvePathArgumentsName(rpcDefn, schemaContext);
+    protected void addRpcs(final RpcDefinition rpcDefn, final List<Api> apis, final String parentPath, final SchemaContext schemaContext) {
+        final Api rpc = new Api();
+        final String resourcePath = parentPath + resolvePathArgumentsName(rpcDefn, schemaContext);
         rpc.setPath(resourcePath);
 
-        Operation operationSpec = new Operation();
+        final Operation operationSpec = new Operation();
         operationSpec.setMethod("POST");
         operationSpec.setNotes(rpcDefn.getDescription());
         operationSpec.setNickname(rpcDefn.getQName().getLocalName());
@@ -368,7 +366,7 @@ public class BaseYangSwaggerGenerator {
             operationSpec.setType("(" + rpcDefn.getQName().getLocalName() + ")output");
         }
         if (rpcDefn.getInput() != null) {
-            Parameter payload = new Parameter();
+            final Parameter payload = new Parameter();
             payload.setParamType("body");
             payload.setType("(" + rpcDefn.getQName().getLocalName() + ")input");
             operationSpec.setParameters(Collections.singletonList(payload));
@@ -379,16 +377,16 @@ public class BaseYangSwaggerGenerator {
         apis.add(rpc);
     }
 
-    protected SortedSet<Module> getSortedModules(SchemaContext schemaContext) {
+    protected SortedSet<Module> getSortedModules(final SchemaContext schemaContext) {
         if (schemaContext == null) {
             return new TreeSet<>();
         }
 
-        Set<Module> modules = schemaContext.getModules();
+        final Set<Module> modules = schemaContext.getModules();
 
-        SortedSet<Module> sortedModules = new TreeSet<>(new Comparator<Module>() {
+        final SortedSet<Module> sortedModules = new TreeSet<>(new Comparator<Module>() {
             @Override
-            public int compare(Module o1, Module o2) {
+            public int compare(final Module o1, final Module o2) {
                 int result = o1.getName().compareTo(o2.getName());
                 if (result == 0) {
                     result = o1.getRevision().compareTo(o2.getRevision());
@@ -399,7 +397,7 @@ public class BaseYangSwaggerGenerator {
                 return result;
             }
         });
-        for (Module m : modules) {
+        for (final Module m : modules) {
             if (m != null) {
                 sortedModules.add(m);
             }